程序缓冲区溢出漏洞定位及GDB调试方法问询
程序缓冲区溢出漏洞定位及GDB调试方法问询
嘿,我来帮你梳理下思路——先从你提供的代码里揪出潜在的缓冲区溢出点,再教你用GDB一步步定位验证:
一、先看代码里的明显漏洞点
你肯定漏看了administration函数里的这个细节:
unsigned char password[20] = {0}; // ... read_string(password, 54);
这里password数组只有20字节的栈空间,但read_string却允许读取最多54字节的输入!read_string的逻辑是只要没到指定长度len(这里是54),就会一直往buf里写数据,完全没做缓冲区大小的校验——这就是典型的栈缓冲区溢出漏洞。
而且你之前试大输入没触发崩溃,大概率是因为没走到这个输入分支:其他输入都是用read_int(底层是scanf),输入超长字符串会直接触发scanf失败,程序调用exit(1)退出,不会触发溢出;只有进入「Administration」菜单,输入密码时的这个输入点,才会触发溢出。
二、用GDB定位漏洞的实操步骤
1. 先编译带调试信息的程序
编译时要关掉栈保护(默认的栈金丝雀会阻止溢出后的正常执行),同时保留调试符号:
gcc -g -fno-stack-protector -z execstack your_program.c -o your_program -lcrypto
(-lcrypto是因为代码用到了OpenSSL的SHA1函数)
2. 启动GDB并调试
- 启动GDB:
gdb ./your_program - 设置断点在
administration函数,方便我们跟踪密码输入的过程:b administration - 运行程序:
r - 在程序菜单里选择「2) Administration」,程序会停在
administration的断点处,此时再给read_string设断点:b read_string - 继续执行:
c,此时程序会提示输入密码
3. 测试溢出并观察栈变化
输入超长字符串(比如用python -c 'print "A"*60'生成60个A),程序会停在read_string的断点处,或者执行完read_string后:
- 查看
password变量的地址和内容:print &password得到地址后,用x/60xb 0xxxxxxxx(替换成实际地址)查看内存,会看到后面的栈内存已经被A覆盖了 - 查看局部变量的状态:
info locals,能看到fptr(函数指针)、salted_password这些变量的值是否被篡改 - 如果继续执行
c,你会发现程序大概率会崩溃,或者你可以手动修改栈上的返回地址/函数指针,验证是否能跳转到read_flag函数(这就是后续利用的思路)
额外提示:
如果想更直观看到栈布局,可以用frame命令查看当前栈帧,x/32gx $rsp(64位)或x/32wx $esp(32位)查看栈上的所有数据,对比溢出前后的变化,就能清晰看到溢出覆盖了哪些关键内存区域。
备注:内容来源于stack exchange,提问作者user14486870
相关产品推荐
相关产品推荐

