#!/usr/bin/perl
#
#####################################################################
# Outlook Web Access - Address Book Enumeration 
#####################################################################
#
# Copyright (C) 2010 Joe Mondloch
# JoMo-Kun / jmk@foofus.net
#
# This script retrieves all names from the "Find Names" feature in OWA 
#

use LWP::UserAgent;
use HTTP::Cookies;

$ua = new LWP::UserAgent;

if ($#ARGV != 2) {
        print "Usage: $0 Host User Password\n";
        exit(1);
}

$host = $ARGV[0];
$username = $ARGV[1];
$password = $ARGV[2];

# Creating initial connection to OWA
$req = new HTTP::Request GET => "https://$host/exchange/logon.asp";
$req->authorization_basic($username, $password);
my $jar = HTTP::Cookies->new();
$ua->cookie_jar($jar);
my $res = $ua->request($req);
$jar->extract_cookies($res);

print "Connecting to OWA: ";
if ($res->is_success) { print "Success\n"; }
else { print $res->status_line, "\n"; }  

# Grabbing OWA Mailbox... we seem to need to make this connection twice
$req = new HTTP::Request GET => "https://$host/exchange/LogonFrm.asp?isnewwindow=0&mailbox=$username";
$req->authorization_basic($username, $password);
$jar->add_cookie_header($req);
my $res = $ua->request($req);
$jar->extract_cookies($res);

$req = new HTTP::Request GET => "https://$host/exchange/LogonFrm.asp?isnewwindow=0&mailbox=$username";
$req->authorization_basic($username, $password);
$jar->add_cookie_header($req);
my $res = $ua->request($req);
$jar->extract_cookies($res);

print "Connecting to OWA mailbox: ";
if ($res->is_success) { print "Success\n"; }
else { print $res->status_line, "\n"; }  

# Retrieve all user accounts
print "Retrieving OWA user names:\n";

getNames('a'..'z');

# a little recursion to get all those names...
sub getNames {
   my @letters = @_;
   foreach $letter (@letters) {
      if ( ! printNames($letter) ) { 
         foreach ('a'..'z') {
            getNames($letter . $_); 
         } 
      }
   }
}

# connect to OWA and grab the users
sub printNames {
   my $LastName = shift @_;
   $req = new HTTP::Request POST => "https://$host/exchange/finduser/fumsg.asp";
   $req->authorization_basic($username, $password);
   $req->content_type('application/x-www-form-urlencoded');
   $req->content("DN=&FN=&LN=$LastName&TL=&AN=&CP=&DP=&OF=&CY=&ST=&CO=");
   $jar->add_cookie_header($req);
   my $res = $ua->request($req);

   @results = split /\n/, $res->content;

   if (grep /This query would return too many addresses!/, @results) { return 0; }
   else {
      for (my $i=0; $i <= $#results; $i++) { 
         next unless $results[$i] =~ /JavaScript:openNewWindow\('details.asp/;
         my ($name) = $results[$i] =~ /">(.*)<\/A><\/td>/; 
         my ($phone) = $results[$i+1] =~ /<td>(.*)<\/td>/; 
         my ($userid) = $results[$i+2] =~ /<td>(.*)<\/td>/; 
         my ($dept) = $results[$i+3] =~ /<td>(.*)<\/td>/; 
         my ($office) = $results[$i+4] =~ /<td>(.*)<\/td>/; 

         print $name, "::", $userid, "::", $phone, "::", $dept, "::", $office, "\n";
      }
      return 1;
   }
}
