2019-2020-2 network technology 20175217 Exp1 PC platform against reverse break

First, the test target

  • The practice of object is a linux executable file named pwn1 of.

  • The normal flow of execution is: main function calls foo, foo function would simply echo any user input string.

  • The program contains another code segment, getShell, will return a usable Shell. This code is not normally run. The goal of our practice is to find ways to run this code snippet. We will learn two ways to run this code snippet, and then learn how to inject any Shellcode run.

Second, the experimental content

  • Manually modify the executable file, changing the program execution flow, jump directly to getShell function.

  • Bof using the function foo vulnerability, an attacker construct input string, overwriting the return address, trigger getShell function.

  • Injecting a shellcode to produce their own and run this shellcode.

Third, the basics

1.NOP, JNE, JE, JMP, CMP machine code instructions compiled

  • NOP:90
  • Etc: 75
  • IS: 74
  • CMP:38~3D

2. Disassemble the master programmer hex

  • Disassembly instructions
objdump -d <file(s)>: 将代码段反汇编;
objdump -S <file(s)>: 将代码段反汇编的同时,将反汇编代码与源代码交替显示,编译时需要使用-g参数,即需要调试信息;
objdump -C <file(s)>: 将C++符号名逆向解析
objdump -l <file(s)>: 反汇编代码中插入文件名和行号
objdump -j section <file(s)>: 仅反汇编指定的section
  • Hex programmer: used for text editing in hexadecimal view of software tools
vim <filename>:以ASCII码形式显示可执行文件的内容
:%!xxd:将显示模式切换为16进制模式
:%!xxd:将16进制切换回ASCII码模式

3. What are the loopholes, loopholes What is the harm? (Their words)

  • What is the vulnerability?
漏洞是与计算机有关的,可以被攻击者利用从而进行攻击的细节。
  • Vulnerability What is the harm?
漏洞如果被攻击者所利用,就可能给计算机、网络等造成严重损害,可能导致系统破坏、信息泄露、网络崩溃等问题。

Four other knowledge

1. pipe (|)

  • "|" Is a command pipeline operator, referred to as the pipe character. Linux using the pipe symbol provided by the "|" two commands separated by pipe character to the left output of the command will be used as input pipe symbol to the right of command. Continuous use of pipelines means that the first command will output the second command as input, the output of the second command will enter as the third command, and so on.

2. output redirection:

  • ">": Representatives to cover the correct output of the command to which the specified file or device.

  • ">>": representative append mode output.

3. Enter the redirection:

  • Command <file name: the file as a command input, such as statistical lines, words and characters in the book when wc command.

4.EIP

  • After each execution of the controller reads the CPU, a read instruction corresponding to the work performed by the EIP register to another. Each time the CPU read instruction to instruction buffer, the corresponding increase in the value of the EIP register, increasing the size of the instruction is read byte size.

5.NOP (taxiing area)

  • 即滑行区,返回地址只要落在任何一个nop上,自然会滑到我们的shellcode
  • 起到填充和“着陆、滑行”的作用

五、实验任务

任务一 直接修改程序机器指令,改变程序执行流程

原理(思路):

  • 1.对目标文件进行反汇编,找到main函数,和要攻击的foo函数
  • 2.通过汇编指令找到main函数跳转到foo函数的指令,分析其对应的机器指令
  • 3.修改目标文件的对应的机器指令,使得main函数跳转到getShell函数

步骤:

  • 对pwn1进行备份,备份为pwn1.bak

  • 输入指令objdump -d pwn1 | morepwn1文件进行反汇编

  • 找到main函数跳转到foo函数的指令,对反汇编的结果进行分析
    • 可以看到函数的地址为08048491,main函数中的call 8048491 <foo>指令的机器码为e8 d7 ff ff ff,下一条指令的地址为80484ba。机器码中的0xffffffd7 = 0x080484ba - 0x08048491为主函数执行位置和foo函数起始地址的差
    • 因此,想要让程序执行到getShell需更改call指令的机器码为相应地址的差,计算地址差为0x080484ba - 0x0804847d = 0xffffffc3

  • 修改目标文件机器码
    • 输入指令vi pwn1打开以ASCII码显示的文件
    • 输入指令:%!xxd将文件转换为16进制查看
    • 找到d7ffffff位置,输入i进入插入模式,将d7修改为c3
    • 输入指令:%!xxd -r 将文件转化为ASCII码形式,保存并退出

  • 此时输入指令objdump -d pwn1 | more查看,发现pwn1文件已经被修改了

结果:

  • 运行更改后的pwn1,执行getShell,得到shell提示符
  • 运行备份pwn1.bak,正常执行foo函数,实现回显功能

任务二 通过构造输入值,造成BOF攻击,从而改变程序执行顺序

原理(思路):

  • 1.通过观察main函数调用的函数,观察系统预留的缓冲区的大小,用该大小加上4字节(ebp),即可得出eip(返回地址)的位置,只要让getShell的地址覆盖该eip就可以让程序执行getShell
  • 2.经分析可知应该输入缓冲区大小+4字节(ebp)+getShell的地址,使得getShell的地址覆盖eip
  • 3.因为我们没法通过键盘输入16进制值,所以先通过perl语言生成包括这样字符串的一个文件,并使用输出重定向“>”将perl生成的字符串存储到文件input中
  • 4.将input的输入,通过管道符“|”,作为目标文件的输入

步骤:

  • 通过反汇编指令查看foo函数中为输入预留的空间

  • 计算出实现缓冲区溢出的字符数为28+4=32字节(4为EBP占用的内存空间),我们希望执行getShell函数,因此需要将getShell函数的地址放在eip(返回地址)处,即33~36字节,接下对猜想进行验证

  • 我们在gdb中输入至少36字节的数据,可以看到给出了Segmentation fault 的错误提示,同时可以查看到eip寄存器的地址为0x34333231 ,验证了将getShell的地址放在33~36字节的猜想

  • 我们将33~36字节的内容替换为getShell的地址,即\x7d\x84\x04\x08,前32字节可以任意输入

  • 由于我们无法从键盘输入16进制的值,因此运用perl语言和>输出重定向构造输入文件perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input构造输入,我们可以通过catxxd指令查看我们构造的输入文件

结果:

  • 然后通过管道符|,输入命令(cat input; cat ) | ./pwn2将构造的输入input作为pwn2的输入并运行,结果如下:

任务三 注入shellcode并执行

原理(思路):

  • 1.设置堆栈可执行、关闭地址随机化
  • 2.根据我们的目的构造shellcode
  • 3.以retaddr+nop+shellcode(缓冲区小)或nop+shellcode+retaddr(缓冲区大)的方式构造攻击buf
  • 4.先构造一个任意的返回地址(最后不能是\x0a(回车)),然后注入这段buf并运行改进程
  • 5.再打开另一个终端来调试该进程,并找到滑动区nop的地址,以确定retaddr的值
  • 6.用调试确定的返回值填入retaddr,再次注入此时的buf并运行,即可发现进程成功运行shellcode

步骤:

  • execstack -s pwn3设置堆栈可执行
  • execstack -q pwn3查询文件的堆栈是否可执行,结果为X表示可执行
  • linux系统为了防范shellcode的注入攻击,在多次运行程序时寄存器的地址会发生改变,因此需关闭地址随机化
    • more /proc/sys/kernel/randomize_va_space查看随机化是否关闭
    • echo "0" > /proc/sys/kernel/randomize_va_space关闭随机化
    • more /proc/sys/kernel/randomize_va_space再次查看,结果为0证明已关闭

  • 参考老师给出的代码,我们首先构造一个input_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"'
 > input_shellcode
  • 在该终端中通过(cat input_shellcode;cat) | ./pwn3运行pwn3
  • 在另一个终端中输入ps -ef | grep pwn查看pwn3的进程号

  • 启用gdb调试并定位pwn3进程
  • disassemble foo进行反编译,可以看到ret指令的地址为0x080484ae,在此处设置断点break *0x080484ae

  • 在第运行终端中按下回车继续运行, 程序执行到断点停止
  • 再在调试终端输入c继续运行程序
  • info r esp查看esp寄存器地址,此时esp的地址即为eip的地址
  • 输入x/16x 0xffffd1ac以16进制形式查看0xffffd1ac地址后面的内容
  • 可以观察到、最先出现0x90(滑行区)的位置地址为0xffffd1ac+0x00000004=0xffffd1b0

  • 将注入代码buf的地址改为0xffffd1b0

  • 输入(cat input_shellcode;cat) | ./pwn3

结果:

  • 成功运行了shellcode

六、遇到的问题和解决

问题一:

  • 在做任务一时,改完机器指令后,忘记将其转换成ASCLL码形式,就保存退出了,导致后续无法进行反汇编

解决一:

  • 又重做了一遍,记得用:%!xxd -r转成ASCLL码形式就不会出问题

问题二:

  • 在参考组长的博客时,发现他任务三,在调试的过程中,一直不理解为什么通过寻找esp的地址,来确定eip的地址

解决二:

  • 后来经过组内讨论,发现是自己没有注意到断点的位置ret指令之前,已经执行过leave指令,即已经执行过pop ebp,此时esp已经指向eip了

七、实验心得体会

       之前自己对网络攻防这方面也算是有点兴趣、有点好奇吧,这次,在看了老师的视频讲解之后,自己实操了一把,感觉还不错,可能是前期看视频、学知识准备的比较久,做完还有那么一点点小成就感。
       这次实验的主要困难就是在于对机器码、汇编指令、十六进制数、堆栈原理的掌握还不是很充分,一些地方理解起来比较费劲,我是看完老师的视频就开始参考着组长的博客开做了,在做的过程中,有不懂的地方,就直接上网上去查,没有的话就去问同学,和组内同学讨论,边做边学,摸着石头过河。
       最后做下来,整体感觉还是不错的,也没有遇到太大的问题,所有遇到问题都得到了解决,对这次的实验内容也有了基本的了解,同时也有了很大的收获。也还有很多地方掌握的不是太好,如机器指令、汇编语言之类的,之后我也会加强学习,争取做的更好!

八、参考链接

Guess you like

Origin www.cnblogs.com/wyf20175217/p/12391190.html