PWN手成长之路-07-bjdctf_2020_babystack2-栈溢出+整型溢出

image

远程交互以下。
image

file 查看文件属性。64 位,LSB 可执行文件。
image

checksec 查看文件安全属性。开启了 NX 保护,栈上无法执行。
image

IDA 打开文件查看 main 函数。
image
代码流程:让用户输入一个整数,再将其存到 nbytes 变量中,之后通过 if 判断用户输入的整数是否大于 10 了,如果大于则终止程序。若为大于 10,则询问用户的名字,并将该名字存储到 buf 缓冲区中。

解题思路:绕过 if 的判断,使 read()函数溢出,但是输入大于 10 的整数会触发 exit(-1) 而终止程序,所以就需要一个既小于 10 而又大于 10 的整数

仔细查看 main 函数,在 read() 函数读取时, 将第一次的输入转换成了 unsigned int,即无符号整数。
image

unsigned int 是是一种无符号整数类型,即其存储的二进制位全部用于表示数值大小不包含符号位,它的二进制形式是一个纯数值编码,所有位均参与数值计算。例如,在32位系统中 unsigned int 占用4字节(32位),其取值范围为:0 到 2^32 - 1(即 0 到 4,294,967,295)。

但是,当 unsigned int 与有符号整型混合运算时,有符号数可能被隐式转换为无符号数,导致数值语义变化(如 -1 变为 4294967295)。

所以当我们输入-1时,可以成功绕过if,并且程序在执行到read函数时,读取的字节会变成4294967295个字节。

之后就是溢出 read() 函数,覆盖返回地址。

查看 buf 的栈,可以知道溢出的大小为:0x10+8=0x18→24
image

并且存在 backdoor 地址为:0x400726
image

编写exp:

from pwn import *

r=remote('node5.buuoj.cn',25304)
backdoor_addr=0x400726
payload=b'a'*(0x18)+p64(backdoor_addr)
r.sendlineafter('name','-1')
r.sendline(payload)
r.interactive()

PWN!
image

posted @ 2025-10-04 01:06  B0rry  阅读(4)  评论(0)    收藏  举报