#!/usr/bin/perl # _____ _ # | ___| | _____ __ # | |_ | |/ _ \ \ /\ / / # | _| | | (_) \ V V / # |_| |_|\___/ \_/\_/ # Security group. # # fl0w-s33ker.pl v1.4 # # Description: Simple tool for tracking overflow. # It uses GDB calls to get # regiters addresses at overflow time. # # I wrote no README or Changelog just # becouse i have no patience at all. # In doubt make me questions # on irc.flowsecurity.org at #flowsecurity. # # Try: ./fl0w-s33ker.pl -h # # 1: Simple test. Ex. ./vulnerable "$buffer" # 2: Adjacent mem test. Ex. ./vulnerable 512 "$buffer" # 3: Environment test. Ex. export HACK="AAAA" ; ./vulnerable # 4: Lame Integer test. Ex. ./vulnerable slot-number integer # # Enjoy # # Author: nuTshell -=nutshell@flowsecurity.org=- # # Greetz: # Friends from irc.flowsecurity.org # and friends from everywhere. # use strict; use Switch; use Devel::GDB; use Term::ANSIColor; my $version = "fl0w-s33ker.pl v1.4"; my $string = "\x41"; my $space = "\x20"; my $sigsegv = 35584; my $barloop =0; my $bar = 0; my $simple = 0; my $counter = 1; my $debugeipcounter = 0; my $buff = "$string"; my $intcounter = -1073746000; my $intcounterend = 1073746000; my $inteip = "0xbfffff*"; my $logfile2 = "LOG-s33ker.txt"; my $ret = ""; my $firstsigsegv = ""; my $gdb = ""; my $blimit = ""; my $bugfile = ""; my $logfile = ""; my $logname = ""; my $status = ""; my $adjstring = ""; my $adjlength = ""; my $output = ""; my $option = ""; my $errlog = ""; my $HACK = ""; my $CMD = ""; my $execargs = ""; my $debug = ""; my $debugeip = ""; my $debugeipcounterlmt = ""; my $debugeipinput = ""; my $counterlmt = ""; my $date = ""; sub info1() { printf <>$logfile2") or die "$!\n"; printf(LOGCOMOM "\n -= $date =- \n"); printf(LOGCOMOM " Tested file: $bugfile\n"); printf(LOGCOMOM "First SIGSEGV occurs at $firstsigsegv bytes.\n"); printf(LOGCOMOM "At $ret bytes:\n"); printf(LOGCOMOM "$output\n"); close(LOGCOMOM); printf("Log saved!\n"); exit(0); } sub log2() { open(LOGCOMOM, ">>$logfile2") or die "$!\n"; printf(LOGCOMOM "\n -= $date =- \n"); printf(LOGCOMOM " Tested file: $bugfile\n"); printf(LOGCOMOM "$debugeip"); printf(LOGCOMOM "Got \$esp address at value $intcounter\n"); close(LOGCOMOM); printf("Log saved!\n"); exit(0); } sub log3() { open(LOGCOMOM, ">>$logfile2") or die "$!\n"; printf(LOGCOMOM "\n -= $date =-\n"); printf(LOGCOMOM " Tested file: $bugfile\n"); printf(LOGCOMOM "SIGSEGV occurs at $ret bytes.\n"); close(LOGCOMOM); printf("Log saved!\n"); } sub menu () { printf < Filename [Vulnerable filename] Options: [1] simple test [2] adjacent test [3] environment test (no dubugging) [4] integer overflow test +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ EOF } sub printbar() { $bar = $barloop + 1; $barloop++; if ($bar == 20) {printf("-") ; $bar = 0 ; $barloop = 0}; } sub cmdarg () { printf("Enter as many arguments as needed.\n"); printf("Each arg must be followed by \n"); printf("To finish just type \"quit\":\n"); $CMD = ; chop($CMD); $CMD .= $space; while ($CMD !~ /quit/) { $CMD .= ;chop($CMD); $CMD .= $space; } $CMD =~ s/quit//g; } if ("$ARGV[0]" eq "-h") {&menu and exit(0)} if ("$ARGV[0]" eq "-v") {printf "$version\n" and exit(0)} if ("$ARGV[0]" eq "-lw" || "$ARGV[0]" eq "-lall") { $logfile = ">> LOG-s33ker.weird.txt 2>&1"; $logname = $logfile; $logname =~ s/2>&1//g; printf color("bold"); printf("\nWARNING"); printf color("reset"); printf(": \"-lw and -lall\" flags can be dangerous..well what isn`t??\n"); printf("Logging stderr can get big files depending on your test.\n"); printf("Ctrl+c...? \"Warned were you\" -yoda :)\n"); printf("Logname $logname\n"); } else {$logfile = ">/dev/null 2>&1"} printf("\n-= $version =-\n-= Coded by nuTshell =-\n"); printf("\nFilename:\n"); printf("option> "); $bugfile = ; chop($bugfile); if (! -f $bugfile) {die "$bugfile $!\n"} printf("Options:\n"); printf("[1] simple test\n"); printf("[2] adjacent test\n"); printf("[3] environment test (no dubugging)\n"); printf("[4] integer overflow test\n"); printf("option> "); $option = ; chop($option); if ($option <= 0 || $option >= 5) { die "Invalid option\n" } switch($option) { case "1" { printf("Command arguments? [y/N]:\n"); printf("option> "); $execargs = ; chop($execargs); if ("$execargs" eq "y") {&cmdarg} } case "2" { printf("Command arguments? [y/N]:\n"); printf("option> "); $execargs = ; chop($execargs); if ("$execargs" eq "y") {&cmdarg} printf("Adjacent fixed buffer length:\n"); printf("option> "); $adjlength = ; chop($adjlength); if(!$adjlength) {printf("Adjacent fixed buffer length REQUIRED! Try again.\n") ; exit(1)} $adjstring = "$string"x$adjlength; } case "3" { printf("Command arguments? [y/N]:\n"); printf("option> "); $execargs = ; chop($execargs); if ("$execargs" eq "y") {&cmdarg} printf("Variable name:\n"); printf("option> "); $HACK = ; chop($HACK); } case "4" { printf("Command arguments? [y/N]:\n"); printf("option> "); $execargs = ; chop($execargs); if ("$execargs" eq "y") {&cmdarg} } } if ("$option" ne "4") { printf("Buffer limit [1500]:\n"); printf("option> "); $blimit = ; chop($blimit); if (!$blimit) {$blimit = 1500} } else { printf("\nBegin: $intcounter\n"); printf("End: $intcounterend\n\n"); } if (!$bugfile || !$option) {&menu and exit(1)} if ("$option" eq "3") {if (!$HACK) {&menu and exit(0)}} sub exec() { if ("$option" eq "-h") {&menu and exit(0)} if ("$option" eq "1") {$status = system("$bugfile $CMD $buff $logfile")} if ("$option" eq "2") {$status = system("$bugfile $CMD $adjstring $buff $logfile")} if ("$option" eq "3") {local($ENV{"$HACK"}) = $buff ; $status = system("$bugfile $CMD $logfile")} } sub run1 () { &info1 ; printf("["); while ($counter <= $blimit) { &exec; &printbar; $status != $sigsegv or $ret = $counter + 4 and printf("> Done!\n$bugfile is vulnerable at $counter bytes!\n") and last; $buff .= "$string"; $counter++; } if ($counter > $blimit) { printf(" Done!\n$bugfile is not vulnerable at least until $blimit bytes\n"); } } if ("$option" eq "1" || "$option" eq "2" || "$option" eq "3" ) { &run1 } sub run2 () { &info2; $gdb = new Devel::GDB (-file => $bugfile ) ; while ($intcounter <= $intcounterend) { $gdb -> get ( "r $CMD $intcounter" ); $debugeip = $gdb -> get ( "i r eip" ); if($debugeip =~ /$inteip/) { printf("...Done!\n"); $debugeip = $gdb -> get ( "i r esp ebp esi edi eip"); printf("$debugeip"); printf("Got return address at value: $intcounter\n"); last; } $intcounter++; if($intcounter == $intcounterend) {printf("Sorry, no results.\n") ; exit(0)} } } switch($option) { case "1" { if($status == $sigsegv) {printf("Debug? [n/Y]:\n"); printf("option> "); $debug = ; chop($debug); if("$debug" eq "n") {exit(0)}} $gdb = new Devel::GDB (-file => $bugfile ) ; $debugeip = $gdb -> get ( "i r eip" ); if($status != $sigsegv) {exit(1)} if($debugeip =~ /0x42424242/) { printf("\n[!] Status at $ret bytes:\n\n"); } $buff .= "\x42\x42\x42\x42"; $firstsigsegv = (length($buff) - 4); $gdb -> get ( "r $CMD $buff" ); $debugeip = $gdb -> get ( "i r eip" ); if($debugeip !~ /0x42424242/) { printf("\$eip wasn`t overwritten."); printf("\n[!] Status at $ret bytes:\n\n"); printf("$debugeip\n"); printf("Shall i use brute force to get correct addresses? [n/Y]:\n"); printf("option> "); $debugeipinput = ; chop($debugeipinput); if("$debugeipinput" ne "n") { printf("Max bytes number to increase on buffer [20]:\n"); printf("option> "); $debugeipcounterlmt = ; chop($debugeipcounterlmt); if(!$debugeipcounterlmt) {$counterlmt = 20} else {$counterlmt = $debugeipcounterlmt} while($debugeipcounter <= $counterlmt) { $buff .= "\x42"; $gdb -> get ( "r $CMD $buff" ); $debugeip = $gdb -> get ( "i r eip" ); $ret++; $debugeipcounter++; $debugeip !~ /0x42424242/ or last ; } } printf("\n[!] Status at $ret bytes:\n\n"); } $output = $gdb -> get ( "i r esp ebp esi edi eip" ); printf("$output\n"); } case "2" { if($status == $sigsegv) {printf("Debug? [n/Y]:\n"); printf("> "); $debug = ; chop($debug); if("$debug" eq "n") {exit(0)}} $gdb = new Devel::GDB (-file => $bugfile ) ; $debugeip = $gdb -> get ( "i r eip" ); if($status != $sigsegv) {exit(1)} if($debugeip =~ /0x42424242/) { printf("\n[!] Status at $ret bytes:\n\n"); } $buff .= "\x42\x42\x42\x42"; $firstsigsegv = (length($buff) - 4); $gdb -> get ( "r $CMD $adjstring $buff" ); $debugeip = $gdb -> get ( "i r eip" ); if($debugeip !~ /0x42424242/) { printf("\$eip wasn`t overwritten."); printf("\n[!] Status at $ret bytes:\n\n"); printf("$debugeip\n"); printf("Shall i use brute force to get correct address? [n/Y]:\n"); printf("option> "); $debugeipinput = ; chop($debugeipinput); if("$debugeipinput" ne "n") { printf("Max bytes number to increase on buffer [20]:\n"); printf("option> "); $debugeipcounterlmt = ; chop($debugeipcounterlmt); if(!$debugeipcounterlmt) {$counterlmt = 19} else {$counterlmt = $debugeipcounterlmt} while($debugeipcounter <= $counterlmt) { $buff .= "\x42"; $gdb -> get ( "r $CMD $adjstring $buff" ); $debugeip = $gdb -> get ( "i r eip" ); $ret++; $debugeipcounter++; $debugeip !~ /0x42424242/ or last ; } } printf("\n[!] Status at $ret bytes:\n\n"); } $output = $gdb -> get ( "i r esp ebp esi edi eip" ); printf("$output\n"); } case "3" { printf("Warning: Gdb calling does not support env-method untill now.\n"); if ($status == $sigsegv) { printf("With $ret bytes maybe is possible to control \$eip register.\n") } } case "4" { &run2; } } if("$ARGV[0]" eq "-lo" || "$ARGV[0]" eq "-lall") { $date = localtime(); switch($option) { case "1" {&log1} case "2" {&log1} case "3" {&log3} case "4" {&log2} } } #eof (end of FUCK)