Questions about this topic? Sign up to ask in the talk tab.

Difference between revisions of "Kolkata"

From NetSec
Jump to: navigation, search
Line 1: Line 1:
<syntaxhighlight lang="perl">
+
=Description=
 +
==Dependencies==
 +
==Usage==
 +
=Source=
 +
{{code|text=<syntaxhighlight lang="perl">
 
#!/usr/bin/perl
 
#!/usr/bin/perl
 
# @url http://www.blackhatacademy.org/
 
# @url http://www.blackhatacademy.org/
 
# @author fxm+hats
 
# @author fxm+hats
 
 
use strict;
 
use strict;
use warnings;
+
use YAML;
#use diagnostics;
+
use LWP::Simple;
+
use Getopt::Long;
+
 
use YAML::XS;
 
use YAML::XS;
use LWP::UserAgent;
 
use HTTP::Request;
 
use HTTP::Response;
 
 
use Digest::MD5 qw(md5_hex);
 
use Digest::MD5 qw(md5_hex);
use Data::Dumper;
+
use LW2;
+
use Getopt::Std;
my $opts;
+
 
my %tree;
+
my @apps;
my $sigtree = \%tree;
+
my %opts;
my $sigdir = '/home/fxm/Desktop/Code/appscan/sigs';
+
 
+
getopts('c:p:d:v', \%opts);
my ($custom,$host,$path,$debug) = undef;
+
 
my @urls;
+
usage() unless $opts{d};
+
 
&check_args;
+
my $domain  = $opts{d};
&load_sigs;
+
my $verbose = 0;
&setup_scanner;
+
$verbose = 1 if $opts{v};
&do_eet;
+
my $path = '';
+
$path    = $opts{p} if ($opts{p});
sub setup_scanner
+
 
{
+
 
  my @keys = keys %tree;
+
 
  if (not defined $custom)
+
opendir(SIGDIR, "./sigs/") or die $!;
  {
+
my @filenames = grep {
    for my $fp (@keys)
+
    /\.yml$/
    {
+
      && -f "./sigs/$_"
      print "Setting up scanner for fingerprint $fp\n";
+
} readdir(SIGDIR);
      my $fullurl = sprintf("http://%s/%s/%s", $host, $path, $sigtree->{$fp}->{config}[0]{'file_check'});
+
 
      push(@urls, $fullurl);
+
my $i = 0;
    }
+
 
  } else {
+
foreach my $file (@filenames) {
     my $fullurl = sprintf("http://%s/%s/%s", $host, $path, $sigtree->{$custom}->{config}[0]{'file_check'});
+
     $apps[$i] = YAML::XS::LoadFile("./sigs/$file");
     push(@urls, $fullurl);
+
     $i++;
  }
+
 
}
 
}
+
 
sub do_eet {
+
 
+
foreach my $app (@apps) {
  die "Not done yet\n";
+
     print "Downloading " . $path . $app->{'config'}->{'check_file'} . " to check for " . $app->{'config'}->{'app_name'} . "\n";
+
     my $contents = download($path . $app->{'config'}->{'check_file'}, $domain);  
  foreach my $scan (@urls)
+
     my $target_md5 = md5_hex($contents);
  {
+
     foreach my $sig (keys %{$app->{'sigs'}}) {
     my $digestobj = Digest::MD5->new;
+
        print "Comparing $target_md5 with " . $app->{'sigs'}->{$sig} . " for " . $app->{'config'}->{'app_name'} . " " . $sig . " detection.\n" if ($verbose > 0);
     my $ua        = new LWP::UserAgent;
+
        die($app->{'config'}->{'app_name'} . " version " . $sig ."\n") if ($app->{'sigs'}->{$sig} eq $target_md5);
     my $content;
+
     $ua->agent("Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10");
+
    my $req = new HTTP::Request GET => "$scan";
+
    my $res = $ua->request($req);
+
    if ($res->is_error) {
+
      print $res->status_line;
+
 
     }
 
     }
 
    if ($res->is_success) {
 
    $content = $res->content;
 
    my $md5 = $digestobj->add("$content");
 
    my $final = $md5->hexdigest;
 
    find_sum_version($final);
 
#    print "MD5:\t\t$final\n" if (defined $debug);
 
#    print "Version:\t$ver_hash{$final}\n\n";
 
    }
 
  }
 
 
}
 
}
+
 
sub load_sigs {
+
sub usage {
  if (defined $custom && -f "$sigdir/$custom.yml")
+
     print "kolkata.pl -d domain.tld [-v -p [remote_path_to_web_application]]\n";
  {
+
     exit(0);
     print "Loaded custom profile $custom\n";
+
    $sigtree->{$custom} = YAML::XS::LoadFile("$sigdir/$custom.yml");
+
  } else {
+
    opendir(SIGDIR, "$sigdir") or die $!;
+
    my @fingerprints = grep {
+
      /\.yml$/
+
      && -f "$sigdir/$_"
+
    } readdir(SIGDIR);
+
    foreach my $yf (@fingerprints)
+
    {
+
      my $yfname = $yf;
+
      $yfname =~ s/\.yml//;
+
      $sigtree->{$yfname} = YAML::XS::LoadFile("$sigdir/$yf");
+
      print Dumper $sigtree->{$yfname}->{'config'};
+
      printf "Loaded '%s' (%s)\n", $sigtree->{$yfname}->{'config'}[0]{'app_name'}, $yf;
+
     }
+
  }
+
  closedir(SIGDIR);
+
 
}
 
}
+
 
sub check_args {
+
sub download
  $opts = GetOptions(
+
    "custom=s" => \$custom,
+
    "debug" => \$debug,
+
    "host=s" => \$host,
+
    "path=s" => \$path
+
  );
+
  $host = "localhost" if (not defined $host);
+
  $path = "" if (not defined $path);
+
}
+
+
sub find_sum_version($)
+
 
{
 
{
  my $val = shift;
+
    my $uri = shift;
  my @keys = keys %tree;
+
    my $try = 5;
  for my $mod (@keys)
+
    my $host = shift;
  {
+
    my %request;
     my @matches = grep { $sigtree->{$mod}->{'sigs'} eq $val } keys %{$sigtree->{'sigs'}};
+
     my %response;
  }
+
    LW2::http_init_request(\%request);
# delete($tmp_tree);
+
    $request{'whisker'}->{'method'} = "GET";
 +
    $request{'whisker'}->{'host'} = $host;
 +
    $request{'whisker'}->{'uri'} = $uri;
 +
    $request{'whisker'}->{'encode_anti_ids'} = 9;
 +
    $request{'User-Agent'} = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10";
 +
    LW2::http_fixup_request(\%request);
 +
    if(LW2::http_do_request(\%request, \%response)) {
 +
        if($try < 5) {
 +
            print "Failed to fetch $uri on try $try. Retrying...\n";
 +
            return undef if(!download($uri, $try++));
 +
        }
 +
        print "Failed to fetch $uri.\n";
 +
        return undef;
 +
    } else {
 +
        return ($response{'whisker'}->{'data'}, $response{'whisker'}->{'data'});
 +
    }
 
}
 
}
  
</syntaxhighlight>
+
</syntaxhighlight>}}
 
+
== Wordpress ==
+
 
+
<pre>
+
---
+
sigs:
+
- 2.0: a306a72ce0f250e5f67132dc6bcb2ccb
+
- 2.1: 4f04728cb4631a553c4266c14b9846aa
+
- 2.2: 25e1e78d5b0c221e98e14c6e8c62084f
+
- 2.3: 83c83d0f0a71bd57c320d93e59991c53
+
- 2.5: 7293453cf0ff5a9a4cfe8cebd5b5a71a
+
- 2.6: 61740709537bd19fb6e03b7e11eb8812
+
- 2.7: e6bbc53a727f3af003af272fd229b0b2
+
- 2.8.5: 56c606da29ea9b8f8d823eeab8038ee8
+
- 2.9.1: 128e75ed19d49a94a771586bf83265ec
+
- 3.0.0: 128e75ed19d49a94a771586bf83265ec
+
- 3.0.1: 0711a6aa3862ac0dd2f9ef1a3d26f809
+
- 3.0.2: 0711a6aa3862ac0dd2f9ef1a3d26f809
+
- 3.0.3: 0711a6aa3862ac0dd2f9ef1a3d26f809
+
- 3.0.4: 0711a6aa3862ac0dd2f9ef1a3d26f809
+
- 3.0.5: 0711a6aa3862ac0dd2f9ef1a3d26f809
+
- 3.0.6: 0711a6aa3862ac0dd2f9ef1a3d26f809
+
- 3.1: c67211f73b63e773e626127aa95338c2
+
- 3.1.1: 1786644689f0495f07d5ae1737395108
+
- 3.1.2: 1786644689f0495f07d5ae1737395108
+
- 3.1.3: 1786644689f0495f07d5ae1737395108
+
- 3.1.4: 1786644689f0495f07d5ae1737395108
+
- 3.2: b2c6b6d221c816948248b453046355eb
+
- 3.2.1: b2c6b6d221c816948248b453046355eb
+
- 3.3.1: 9754385dabfc67c8b6d49ad4acba25c3
+
config:
+
- app_name: Wordpress
+
- check_file: /wp-includes/js/tinymce/tiny_mce.js
+
 
+
</pre>
+
 
+
== Joomla ==
+
 
+
<pre>
+
---
+
sigs:
+
- 1.0.11: 1d28094f16c310591b855982759bc992
+
- 1.0.14: 9570ccaab7cdac45e6727740515ce69a
+
- 1.0.15: 9570ccaab7cdac45e6727740515ce69a
+
- 1.0.4: 1080567bb801a301e3be618805a55125
+
- 1.0.6: 1080567bb801a301e3be618805a55125
+
- 1.0.8: 222ab5eb9cb8136619053a4f8358b9a5
+
- 1.5.1: b891f61dc9b85a9193592c9d13e9c97a
+
- 1.5.10: 326412fc179cb787500adffada69c4e7
+
- 1.5.11: 326412fc179cb787500adffada69c4e7
+
- 1.5.14: 326412fc179cb787500adffada69c4e7
+
- 1.5.15: 326412fc179cb787500adffada69c4e7
+
- 1.5.4: 326412fc179cb787500adffada69c4e7
+
- 1.5.5: 326412fc179cb787500adffada69c4e7
+
- 1.5.8: 326412fc179cb787500adffada69c4e7
+
- 1.5.9: 326412fc179cb787500adffada69c4e7
+
config:
+
- app_name: Joomla
+
- check_file: /includes/js/joomla.javascript.js
+
</pre>
+
  
== MediaWiki ==
 
  
<pre>
+
=Signature Bundles=
---
+
{{info|Each signature bundle is written in yaml.}}
sigs:
+
==Wordpress==
- 1.10.0: 31ef23cbcdf689bd68d957ae0d8b8a19
+
{{code|text=
- 1.10.2: 31ef23cbcdf689bd68d957ae0d8b8a19
+
}}
- 1.10.3: 31ef23cbcdf689bd68d957ae0d8b8a19
+
==Joomla==
- 1.13.0: 6781b4412fbc451b792c4cdc88b0a1fa
+
{{code|text=
- 1.13.5: 6781b4412fbc451b792c4cdc88b0a1fa
+
}}
- 1.14.0: 846eec3b6696476a79548b82bf48e492
+
==MediaWiki==
- 1.14.1: 846eec3b6696476a79548b82bf48e492
+
{{code|text=
- 1.15.1: b6301262680144f1709d995a6c097db8
+
}}
- 1.5.2: 2fb3891102f9fe2d37a4bdb47b8f42de
+
- 1.5.8: 2fb3891102f9fe2d37a4bdb47b8f42de
+
- 1.8.2: 5d52c4473189e70e4878a5a7b38e3a82
+
- 1.9.2: 24b79f325b32661fd24c93d7d2e8ccef
+
- 1.9.4: 24b79f325b32661fd24c93d7d2e8ccef
+
config:
+
- app_name: MediaWiki
+
- check_file: /skins/simple/main.css
+
</pre>
+

Revision as of 01:17, 28 April 2012

Description

Dependencies

Usage

Source

<syntaxhighlight lang="perl">

  1. !/usr/bin/perl
  2. @url http://www.blackhatacademy.org/
  3. @author fxm+hats

use strict; use YAML; use YAML::XS; use Digest::MD5 qw(md5_hex); use LW2; use Getopt::Std;

my @apps; my %opts;

getopts('c:p:d:v', \%opts);

usage() unless $opts{d};

my $domain = $opts{d}; my $verbose = 0; $verbose = 1 if $opts{v}; my $path = ; $path = $opts{p} if ($opts{p});


opendir(SIGDIR, "./sigs/") or die $!; my @filenames = grep {

    /\.yml$/
     && -f "./sigs/$_"

} readdir(SIGDIR);

my $i = 0;

foreach my $file (@filenames) {

   $apps[$i] = YAML::XS::LoadFile("./sigs/$file");
   $i++;

}


foreach my $app (@apps) {

   print "Downloading " . $path . $app->{'config'}->{'check_file'} . " to check for " . $app->{'config'}->{'app_name'} . "\n";
   my $contents = download($path . $app->{'config'}->{'check_file'}, $domain);    
   my $target_md5 = md5_hex($contents);
   foreach my $sig (keys %{$app->{'sigs'
) {
       print "Comparing $target_md5 with " . $app->{'sigs'}->{$sig} . " for " . $app->{'config'}->{'app_name'} . " " . $sig . " detection.\n" if ($verbose > 0);
       die($app->{'config'}->{'app_name'} . " version " . $sig ."\n") if ($app->{'sigs'}->{$sig} eq $target_md5);
   }

}

sub usage {

   print "kolkata.pl -d domain.tld [-v -p [remote_path_to_web_application]]\n";
   exit(0);

}

sub download {

   my $uri = shift;
   my $try = 5;
   my $host = shift;
   my %request;
   my %response;
   LW2::http_init_request(\%request);
   $request{'whisker'}->{'method'} = "GET";
   $request{'whisker'}->{'host'} = $host;
   $request{'whisker'}->{'uri'} = $uri;
   $request{'whisker'}->{'encode_anti_ids'} = 9;
   $request{'User-Agent'} = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.237 Safari/534.10";
   LW2::http_fixup_request(\%request);
   if(LW2::http_do_request(\%request, \%response)) {
       if($try < 5) {
           print "Failed to fetch $uri on try $try. Retrying...\n";
           return undef if(!download($uri, $try++));
       }
       print "Failed to fetch $uri.\n";
       return undef;
   } else {
       return ($response{'whisker'}->{'data'}, $response{'whisker'}->{'data'});
   }

}

</syntaxhighlight>}}


Signature Bundles

c3el4.png Each signature bundle is written in yaml.

Wordpress

Joomla

MediaWiki