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

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

(2) JNE:条件转移指令,如果不相等则跳转。(机器码:75)

(3) JE:条件转移指令,如果相等则跳转。(机器码:74)

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

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

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

(1) 十六进制编程器,是用来以16进制视图进行文本编辑的编辑工具软件。其实我们只需要用各系统都兼容的“vim”编辑器就可以实现十六进制编辑的功能。

具体步骤如下:

输入命令:vi pwn1'看可执行文件内容,为ASCII码形式显示;

输入:%!xxd将显示模式切换为16进制模式;

进行相关操作后,输入:%!xxd -r转换16进制为为ASCII码形式。

(2) 之前在云班课《机械指令与汇编语言》一课中提到反汇编,于是进行如下操作对老师所提供的pwn1进行反汇编操作。

具体步骤如下:

输入命令:objdump –d pwn1

objdump是gcc工具,用来查看编译后目标文件的组成

nios ii汇编指令 汇编指令jne_机器码

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

(1)在完成了第二步的反汇编操作后,我们进行直接修改程序机器指令,改变程序执行流程的操作

nios ii汇编指令 汇编指令jne_机器码_02

(2)首先我们找到main主函数,在其中汇编语言里找到call 8048491

nios ii汇编指令 汇编指令jne_机器码_03

此条汇编指令为调用位于8048491处的foo函数,此条对应的机械指令为e8 d7 ff ff ff

根据实验指导,我们需要让main函数中的call指令调用foo函数变为调用getshell函数,所以我们需要对其机械指令e8 d7 ff ff ff进行修改,e8在机械指令上有着跳转的含义

在这里我们需要搞清楚一个概念,call指令是怎么从e8 d7 ff ff ff这条指令跳转到8048491这一地址的。

因为d7 ff ff ff是补码,且求原码顺序要从右到左,因为都是f所以省略,d7的原码为29,故原码为-0X29。而call指令的跳转地址起始是下条指令的地址,在此处为80484ba。所以计算过程为80484ba- 0X29 = 8048491这样就搞明白了跳转的原理,我们就可以逆向操作使其跳转到我们需要的地址了。

由图我们可以知道,getShell函数的地址为804847d,故地址数为80484ba-804847d=0X3d,0X3d的补码为C3,故指令应该改为C3 ff ff ff

(3) 原理搞清楚之后我们就可以对文件进行修改,在此我将文件备份为pwn2进行下一步的操作。

nios ii汇编指令 汇编指令jne_机器码_04

(4)在vim pwn2后发现乱码,摁下Esc后输入:%!xxd,将其转换为16进制。

查找要修改的内容e8d7ffffff,将其修改为c3ffffff,之后再使用:%!xxd -r转换为原格式后保存并退出。

nios ii汇编指令 汇编指令jne_反汇编_05

(5)使用objdump –d pwn2 对pwn2进行反汇编,检查call指令是否正常调用getShell

nios ii汇编指令 汇编指令jne_反汇编_06

(6)我们运行一下pwn2,发现会得到shell提示符,证明我们的修改成功使得call指令跳转到了getshell这个函数,得到了我们想要的结果

nios ii汇编指令 汇编指令jne_nios ii汇编指令_07

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

Ⅰ实验步骤

(1)构造并验证输入参数

nios ii汇编指令 汇编指令jne_机器码_08

(2)运行验证

nios ii汇编指令 汇编指令jne_机器码_09

Ⅱ.原理分析

(1)通过试验确定覆盖返回地址的位置

方法一:

反汇编pwn1,分析预留空间大小

nios ii汇编指令 汇编指令jne_反汇编_10

由上图可知,程序执行时先由main函数跳转到foo函数。
foo函数再获取字符前,先预留了0x1c的空间,转换为十进制也就是28字节的空间,这就是预留的缓冲区。
若输入的字符串超过28字节,则会覆盖ebp,其中ebp占4个字节,即使是这样也不妨碍程序正常执行,因为leave会将ebp弹栈,而且不影响eip的值。
若输入的字符串超过32字节,及已经越过ebp,覆盖了eip,那么程序的运行将会受到影响。
并且,eip存放了下一条指令的内存地址,那么,我们只需要在第33-36字节动手脚,将其改为想要执行的函数的内存地址,就达到了攻击效果了。

方法二:

gdb碰撞

nios ii汇编指令 汇编指令jne_机器码_11

通过观察可发现 eip寄存器被试验字符串中的5覆盖(0x35在ascii码中代表数字5),同理ebp寄存器被4覆盖,而其他寄存器看起来无异常,可以推测缓冲区预留了28字节空间,而28字节后的“44445555”分别覆盖了ebp寄存器和eip寄存器的值。

(2)验证eip覆盖的位置

nios ii汇编指令 汇编指令jne_反汇编_12

通过观察可发现eip寄存器被“4321”覆盖,因此可以确定构造参数的第33字节到36字节会覆盖eip寄存器,因此只要将getshell的地址写入这四个字节就可以实现弹出shell,由于kali系统是小端系统,构造的输入参数为"11111111222222223333333344444444\x7d\x84\x04\x08\x0a"。

5.注入Shellcode并执行

Ⅰ 实验步骤

(1)下载prelink

nios ii汇编指令 汇编指令jne_反汇编_13

nios ii汇编指令 汇编指令jne_寄存器_14

(2)设置栈可执行

execstack -s pwn1 查询栈是否可执行 execstack -q pwn1

(3)关闭地址随机化

echo "0" > /proc/sys/kernel/randomize_va_space

nios ii汇编指令 汇编指令jne_nios ii汇编指令_15

"more /proc/sys/kernel/randomize_va_space"用于查询randomize_va_space的值,2为完全随机,0为关闭状态,"execstack -q pwn1"用于查询pwn1是否可执行,X为可执行。

(4)构造shellcode并执行

nios ii汇编指令 汇编指令jne_寄存器_16

前四个字节0xffff1d60是Shellcode的位置。

Ⅱ.shellcode地址

(1)在终端1运行pwn1

(cat input_shellcode;cat) | ./pwn1 input_shellcode前四字节可以用NOP填充

(2)在终端2调试

ps -ef | grep pwn1
gdb
attach 33724
disassemble foo
break *0x080484ae
c
info r esp

nios ii汇编指令 汇编指令jne_nios ii汇编指令_17

6.结合nc模拟远程攻击

(1)主机1,模拟一个有漏洞的网络服务:

nc -l 127.0.0.1 -p 28234 -e ./pwn1 -l 表示listen, -p 后加端口号 -e 后加可执行文件,网络上接收的数据将作为这个程序的输入。
将一个终端弄成服务器,也就是被攻击机。

(2)主机2,连接主机1并发送攻击载荷:

(cat input_shellcode; cat) | nc 127.0.0.1 28234

nios ii汇编指令 汇编指令jne_反汇编_18