#!/usr/bin/perl # ##################################################################### # Outlook Web Access Light - Address Book Enumeration ##################################################################### # # Copyright (C) 2010 Joe Mondloch # JoMo-Kun / jmk@foofus.net # # This script retrieves all names from the OWA Light Address Book # use HTTP::Cookies; use LWP::UserAgent; use Authen::NTLM; use Getopt::Long; #use LWP::Debug qw(+); $|++; # don't buffer my $VERSION = "0.1"; my %opt, %data; my $ua = new LWP::UserAgent(keep_alive=>1); push @{ $ua->requests_redirectable }, 'POST'; my $jar = HTTP::Cookies->new(); $opt{'domain'} = ''; $opt{'ssl'} = 0; $opt{'proxy'} = 0; $ua->cookie_jar($jar); GetOptions ( 'host=s' => \$opt{'host'}, 'username=s' => \$opt{'username'}, 'password=s' => \$opt{'password'}, 'domain=s' => \$opt{'domain'}, 'type=s' => \$opt{'type'}, 'ssl' => sub { $opt{'ssl'} = 1 }, 'proxy' => sub { $opt{'proxy'} = 1 }, ); print "\nJoMo-Kun M\$ OWA Find User Enumerator\n\n"; if ( !( defined($opt{'host'}) && defined($opt{'username'}) && defined($opt{'password'}) && defined($opt{'type'}) ) ) { print "getOWAnames V. $VERSION\n"; print "Usage:\n"; print " $0\n"; print " --host \n"; print " --username \n"; print " --password \n"; print " --domain \n"; print " --type <1,2,3>\n"; print " 1: CookieAuth.dll?Logon?GetLogon?url=Z2F (** Z2F **)\n"; print " 2: owa/auth/owaauth.dll (Outlook Light w/ ISA 2007)\n"; print " 3: owa/auth.owa (Outlook Web App w/ Exchange 2010)\n"; print " --ssl\n"; print " --proxy\n"; print "\n\n"; exit(1); } ############################################################################### # Creating initial connection to OWA if ($opt{'proxy'}) { $ua->proxy(['http', 'https'], 'http://localhost:8008/'); } if ($opt{'ssl'}) { $req = new HTTP::Request GET => "https://$opt{'host'}"; } else { $req = new HTTP::Request GET => "http://$opt{'host'}"; } $req->user_agent('Mozilla/5.0'); $jar->add_cookie_header($req); if ($opt{'domain'} ne "") { print STDERR "Basic Auth: $opt{'domain'}\\$opt{'username'} $opt{'password'}\n"; $req->authorization_basic("$opt{'domain'}\\$opt{'username'}", $opt{'password'}); } else { $req->authorization_basic($opt{'username'}, $opt{'password'}); } my $res = $ua->request($req); $jar->extract_cookies($res); #print "RESPONSE: ", $res->as_string, "\n"; if ($res->as_string =~ /401 Unauthorized/) { print STDERR "SERVER CHECK: 401 Unauthorized\n"; $result = 1; } if ($res->as_string =~ /WWW-Authenticate: Basic realm="(.*)"/) { print STDERR "SERVER CHECK: WWW-Authenticate: Basic realm=\"$1\"\n"; $result = 1; } if ($res->as_string =~ /Error: Access is Denied./) { print STDERR "SERVER CHECK: Error: Access is Denied.\n"; $result = 1; } print STDERR "\n"; print "Connecting to OWA: "; if (($res->is_success) && ($res->code != 302)) { print "Success\n"; } else { print $res->status_line, "\n"; exit(1); } ############################################################################### # Authenticate to OWA if ($opt{'type'} eq "1") { if ($opt{'ssl'}) { $req = new HTTP::Request POST => "https://$opt{'host'}/CookieAuth.dll?Logon"; $req->referer("https://$opt{'host'}/CookieAuth.dll?GetLogon?curl=Z2F&reason=2&formdir=1"); } else { $req = new HTTP::Request POST => "http://$opt{'host'}/CookieAuth.dll?Logon"; $req->referer("http://$opt{'host'}/CookieAuth.dll?GetLogon?curl=Z2F&reason=2&formdir=1"); } $req->content("curl=Z2FExchangeZ2F&flags=0&forcedownlevel=0&formdir=3&trusted=0&username=$opt{'username'}&password=$opt{'password'}&SubmitCreds=Log+On"); } elsif ($opt{'type'} eq "2") { # Outlook Web Access Light w/ Microsoft ISA 2007 print "Type 2: Outlook Web Access Light w/ Microsoft ISA 2007\n"; if ($domain ne "") { $user = "$opt{'domain'}%5C$opt{'username'}"; } else { $user = $opt{'username'}; } $path = "owa/auth/owaauth.dll"; if ($opt{'ssl'}) { $req = new HTTP::Request POST => "https://$opt{'host'}/$path"; $req->referer("https://$opt{'host'}/owa/auth/logon.aspx?url=https://$host/owa/&reason=0"); $req->content("destination=https%3A%2F%2F$opt{'host'}%2Fowa%2F&flags=0&forcedownlevel=0&trusted=0&username=$user&password=$opt{'password'}&isUtf8=1"); } else { $req = new HTTP::Request POST => "http://$opt{'host'}/$path"; $req->referer("http://$host/owa/auth/logon.aspx?url=https://$opt{'host'}/owa/&reason=0"); $req->content("destination=http%3A%2F%2F$opt{'host'}%2Fowa%2F&flags=0&forcedownlevel=0&trusted=0&username=$user&password=$opt{'password'}&isUtf8=1"); } } elsif ($opt{'type'} eq "3") { # Outlook Web App w/ Exchange 2010 print "Type 3: Outlook Web App w/ Exchange 2010\n"; if ($domain ne "") { $user = "$opt{'domain'}%5C$opt{'username'}"; } else { $user = $opt{'username'}; } $path = "owa/auth.owa"; if ($opt{'ssl'}) { $req = new HTTP::Request POST => "https://$opt{'host'}/$path"; $req->referer("https://$opt{'host'}/owa/auth/logon.aspx?replaceCurrent=1&reason=2&url=https%3a%2f%2f$opt{'host'}%2fowa%2f"); $req->content("destination=https%3A%2F%2F$opt{'host'}%2Fowa%2F&flags=0&forcedownlevel=0&trusted=0&username=$user&password=$opt{'password'}&isUtf8=1"); } else { $req = new HTTP::Request POST => "http://$opt{'host'}/$path"; $req->referer("http://$opt{'host'}/owa/auth/logon.aspx?replaceCurrent=1&reason=2&url=http%3a%2f%2f$opt{'host'}%2fowa%2f"); $req->content("destination=http%3A%2F%2F$opt{'host'}%2Fowa%2F&flags=0&forcedownlevel=0&trusted=0&username=$user&password=$opt{'password'}&isUtf8=1"); } $req->header(Cookie => "PBack=0"); } $req->content_type('application/x-www-form-urlencoded'); $req->user_agent('Mozilla/5.0'); $jar->add_cookie_header($req); my $res = $ua->request($req); $jar->extract_cookies($res); print "Connecting to OWA: "; if (($res->is_success) && ($res->code != 302)) { print "Success\n"; } else { print $res->status_line, "\n"; exit(1); } ############################################################################### # Retrieve all user accounts print "Retrieving OWA user names:\n"; my $page = 1; while(1) { if ($page == 1) { if ($opt{'ssl'}) { $req = new HTTP::Request GET => "https://$opt{'host'}/OWA/?ae=Dialog&t=AddressBook&ctx=1"; } else { $req = new HTTP::Request GET => "http://$opt{'host'}/OWA/?ae=Dialog&t=AddressBook&ctx=1"; } } else { if ($opt{'ssl'}) { $req = new HTTP::Request POST => "https://$opt{'host'}/OWA/?ae=Dialog&t=AddressBook&ctx=1"; $req->referer("https://$opt{'host'}/OWA/?ae=Dialog&t=AddressBook&ctx=1"); } else { $req = new HTTP::Request POST => "http://$opt{'host'}/OWA/?ae=Dialog&t=AddressBook&ctx=1"; $req->referer("http://$opt{'host'}/OWA/?ae=Dialog&t=AddressBook&ctx=1"); } $req->content("hidpnst=&hidss=&hidri=&hidchk=&hidAB=$hidAB&hidpg=$page&hidcid=12&hidso=1&hidid=&hidcmdpst=addrcp&hidrcptid=&hidrw=1&hidpid=AddressBook&hidcanary=$hidcanary"); $req->content_type('application/x-www-form-urlencoded'); $req->user_agent('Mozilla/5.0'); } $jar->add_cookie_header($req); $req->authorization_basic($opt{'username'}, $opt{'password'}); my $res = $ua->request($req); $jar->extract_cookies($res); print "Retrieving address book entries from page $page: "; if (($res->is_success) && ($res->code != 302)) { print "Success\n"; } else { print $res->status_line, "\n"; exit(1); } # Extract hidAB and hidcanary values if ($page == 1) { # # input type=hidden name="hidcanary" value="cc396cfc71894ed680a485752208b89d"> if ($res->as_string =~ /name="hidAB" value="(.*)">/) { $hidAB = $1; $hidAB =~ s/;/%3B/; $hidAB =~ s/==/%3D%3D/g; print "hidAB: $hidAB\n"; } if ($res->as_string =~ /name="hidcanary" value="(.*)">/) { $hidcanary = $1; print "hidcanary: $hidcanary\n"; } } @results = split /\n/, $res->content; if (grep /There are no items to show in this view./, @results) { exit(0); } else { for (my $i=0; $i <= $#results; $i++) { next unless $results[$i] =~ /Content Area<\/caption>/i; my @row = split /(.*)<\/a><\/h1>/i; my ($userid) = $col[1] =~ /nowrap>(.*) /i; my ($phone) = $col[2] =~ /nowrap>(.*) /i; my ($office) = $col[3] =~ /nowrap>(.*) /i; my ($title) = $col[4] =~ /nowrap>(.*) /i; my ($company) = $col[5] =~ /nowrap>(.*?) /i; my ($email) = ""; my ($department) = ""; if (/Distribution List/) { $name =~ s/^.*alt="Distribution List">//; $name = $name . " (Distribution List)"; } else { # retrieve user's full information $id =~ s/\+/%2b/g; $id =~ s/\//%2f/g; $id =~ s/=/%3d/g; if ($opt{'ssl'}) { $req = new HTTP::Request GET => "https://$opt{'host'}//owa/?ae=Item&t=AD.RecipientType.User&id=$id&ctx=1"; } else { $req = new HTTP::Request GET => "http://$opt{'host'}//owa/?ae=Item&t=AD.RecipientType.User&id=$id&ctx=1"; } $req->user_agent('Mozilla/5.0'); $jar->add_cookie_header($req); $req->authorization_basic($opt{'username'}, $opt{'password'}); my $res = $ua->request($req); $jar->extract_cookies($res); print "Retrieving information for user ID $id\n"; if (($res->is_success) && ($res->code != 302)) { ($email) = $res->as_string =~ / nowrap>E-mail<\/td>(.*?)<\/td>/; ($department) = $res->as_string =~ / nowrap>Department<\/td>(.*?)<\/td>/; } else { print $res->status_line, "\n"; } } print $name, "::", $userid, "::", $phone, "::", $office, "::", $title, "::", $company, "::", $email, "::", $department, "\n"; } last; } } $page++; }