|
|
|
|
| |
Credit:
The information has been provided by nuTshell.
To keep updated with the tool visit the project's homepage at: http://www.flowsecurity.org/tools.php
|
| |
The following is a simple tool for tracking buffer overflows. It uses GDB calls to get register's addresses during the overflow.
Tool source:
#!/usr/bin/perl
# _____ _
# | ___| | _____ __
# | |_ | |/ _ \ \ /\ / /
# | _| | | (_) \ V V /
# |_| |_|\___/ \_/\_/
# Security group.
#
# fl0w-s33ker.pl v1.4
#
#
# 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 <<EOF
Limit is set: $blimit bytes
Filling up $bugfile`s buffer with 0x41 (A`s)
until we get SIGSEGV, if progress bar stop try ctrl+c.
Wait...
EOF
}
sub info2() {
printf <<EOF
Lame integer overflow test.
Starting from $intcounter to $intcounterend.
We must have $inteip as \$eip address.
Wait...Go get a coffee :]
EOF
}
sub log1 () {
open(LOGCOMOM, ">>$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 <<EOF
+-+-+-+-+-+-+-+-+-+-+-+-+-+- fl0w-s33ker +-+-+-+-+-+-+-+-+-+-+-+-+-+
Coded by nuTshell -= nuTshell\@flowsecurity.org =-
Usage: $0 [-h|-v|-lwo|-lo|-lall]
-h [This menu]
-v [Version]
-lw [Log WeIrD output]
-lo [Log results output]
-lall [Log WeIrD & results]
Usage: $0 <ENTER>
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 <ENTER>\n");
printf("To finish just type \"quit\":\n");
$CMD = <STDIN> ; chop($CMD);
$CMD .= $space;
while ($CMD !~ /quit/) {
$CMD .= <STDIN> ;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 = <STDIN> ; 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 = <STDIN> ; chop($option);
if ($option <= 0 || $option >= 5) { die "Invalid option\n" }
switch($option) {
case "1" { printf("Command arguments? [y/N]:\n");
printf("option> ");
$execargs = <STDIN> ; chop($execargs);
if ("$execargs" eq "y") {&cmdarg}
}
case "2" { printf("Command arguments? [y/N]:\n");
printf("option> ");
$execargs = <STDIN> ; chop($execargs);
if ("$execargs" eq "y") {&cmdarg}
printf("Adjacent fixed buffer length:\n");
printf("option> ");
$adjlength = <STDIN> ; 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 = <STDIN> ; chop($execargs);
if ("$execargs" eq "y") {&cmdarg}
printf("Variable name:\n");
printf("option> ");
$HACK = <STDIN> ; chop($HACK);
}
case "4" { printf("Command arguments? [y/N]:\n");
printf("option> ");
$execargs = <STDIN> ; chop($execargs);
if ("$execargs" eq "y") {&cmdarg}
}
}
if ("$option" ne "4") {
printf("Buffer limit [1500]:\n");
printf("option> ");
$blimit = <STDIN> ; 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 = <STDIN> ; 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 = <STDIN> ; chop($debugeipinput);
if("$debugeipinput" ne "n") {
printf("Max bytes number to increase on buffer [20]:\n");
printf("option> ");
$debugeipcounterlmt = <STDIN> ; 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 = <STDIN> ; 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 = <STDIN> ; chop($debugeipinput);
if("$debugeipinput" ne "n") {
printf("Max bytes number to increase on buffer [20]:\n");
printf("option> ");
$debugeipcounterlmt = <STDIN> ; 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)
|
|
|
|
|