Der Code ist nicht sehr groß und sollte ziemlich selbsterklärend sein... trotzdem noch ein paar Worte von mir:
Entstanden ist das ganze weil ich mir vor ein paar Tagen ein Buch über Perl gekauft habe und h0yt3r im IRC seinen "Shellcode grabber for h0yt3rstuff.phpnet.us/shellgen.php" gepostet hat...
Ich hab also ein bisschen damit rumgespielt und versucht den Shellcode mit RegEx etwas zu formatieren (z.B. 16 Bytes pro Zeile usw.).
Da ich (auch wegen h0yt3r) vor ein paar Wochen mal an ein paar Wargames zum Thema BoF rumgespielt habe und es ziemlich umständlich fand meinen geschriebenen Shellcode in die richtige Form zu bringen, ist dann eben das hier entstanden.
Das Programm liest alle Bytes einer gegebenen Datei aus und dumpt sie nach vorgegebenen Maßstäben entweder als Stringliteral in einer Variable (C Stil), oder nur so als Hex.
[code]Syntax:
./sc.pl [<option1> <option2> <optionN>] <file>
Options:
-c --nocstyle just output a hexdump
-h --header add #ifndef-directive
-U --uppercase print uppercase hexdump
-b --nolnbrk do not use linebreaks
--scvar=<name> set the name of the shellcode variable[code]
Hier ist mal die Ausgabe des Programms mit Standardoptionen (einfach nur Datei angegeben - in diesem Fall das Script selbst... da wo [...] steht hab ich mal abgeschnitten, damit es nicht so lang ist - soll ja nur ein Beispiel sein):
Code:
/* size: 2468 bytes; generated: 14:09 20/08/2009 */
static char shellcode[] =
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0d"
"\x0a\x0d\x0a\x75\x73\x65\x20\x73\x74\x72\x69\x63\x74\x3b\x0d\x0a"
[...]
"\x20\x22\x5c\x6e\x22\x3b\x0d\x0a\x09\x09\x70\x72\x69\x6e\x74\x20"
"\x22\x23\x65\x6e\x64\x69\x66\x5c\x6e\x22\x3b\x0d\x0a\x09\x7d\x0d"
"\x0a\x7d\x0d\x0a"
;
/* ((void (*)(void)) shellcode)(); */
Die Ausgabe erfolgt nach STDOUT und kann beliebig in andere Dateien umgelenkt werden (mit > für Datei erstellen und >> für zu Datei hinzufügen).
Beispiel:
./sc.pl datei.bin > meinShellcode.c
Lange Rede, kurzer Sinn - der Sourcecode:
Code:
#!/usr/bin/perl
use strict;
use warnings;
if (!"@ARGV")
{
die(
"Syntax:\n"
. " $0 [<option1> <option2> <optionN>] <file>\n\n"
. "Options:\n"
. " -c --nocstyle just output a hexdump\n"
. " -h --header add #ifndef-directive\n"
. " -U --uppercase print uppercase hexdump\n"
. " -b --nolnbrk do not use linebreaks\n"
. " --scvar=<name> set the name of the shellcode variable\n"
);
}
my $nocstyle = undef;
my $header = undef;
my $nolnbrk = undef;
my $frmstr = "\\x%.02x";
my $file = $ARGV[-1];
my $scvar = 'shellcode';
delete $ARGV[-1];
foreach my $param (@ARGV)
{
if ($param eq '--nocstyle' || $param eq '-c')
{
$nocstyle = 1;
$frmstr = " %.02X";
}
elsif ($param eq '--header' || $param eq '-h')
{
$header = 1;
}
elsif ($param eq '--uppercase' || $param eq '-U')
{
$frmstr = "\\x%.02X";
}
elsif ($param eq '--nolnbrk' || $param eq '-b')
{
$nolnbrk = 1;
}
elsif ($param =~ /--scvar=/)
{
$scvar = substr($param, 8);
my $len = length $scvar;
$len eq 0
and die("Error: Invalid value in --scvar option\n");
$scvar =~ /[^A-Z_\$]/i
and die("Error: Invalid value in --scvar option\n");
}
else
{
die("Error: no such option '$param'\n");
}
}
if (defined($header) && defined($nocstyle))
{
die("Error: conflicting options; --header and --nocstyle\n");
}
my $sc = '';
my $size = 0;
open FILE, $file or die "Error: $!\n";
binmode FILE;
while((my $n = read FILE, my $char, 1) != 0)
{
$size++;
$sc .= sprintf($frmstr, ord($char));
}
close FILE;
if (defined($nocstyle))
{
if (!defined($nolnbrk))
{
$sc =~ s/(( ..){1,16})/$1\n/ig;
$sc =~ s/ (([A-Z0-9][A-Z0-9](( )?))+)\n/$1\n/gi;
}
print $sc;
}
else
{
if (defined($header))
{
print "#ifndef SHELLCODE_H\n";
print "#define SHELLCODE_H\n";
print "\n";
}
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time);
my $datestr = sprintf("%.02d:%.02d %.02d/%.02d/%.02d", $hour, $min, $mday, $mon + 1, $year + 1900);
print "/* size: $size bytes; generated: $datestr */\n";
if (defined($nolnbrk))
{
print "static char ${scvar}[] = \"$sc\";\n";
}
else
{
$sc =~ s/((\\x..){1,16})/\t"$1"\n/ig;
print "static char ${scvar}[] =\n";
print $sc;
print ";\n";
}
print "/* ((void (*)(void)) $scvar)(); */\n";
if (defined($header))
{
print "\n";
print "#endif\n";
}
}
Vielleicht kann es ja jemand gebrauchen - wegen dem Sinn, oder wegen dem Code - wer weiß.
Viel Spaß damit!
mfG. BlackBerry
PS: großes THX natürlich an h0yt3r <3