20165120马鹏云 Exp1+ 逆向进阶=v=
建议的实践内容包括:
Task1 (5-10分)
自己编写一个64位shellcode。参考shellcode指导。
自己编写一个有漏洞的64位C程序,功能类似我们实验1中的样例pwn1。使用自己编写的shellcode进行注入。
Task 2 (5-10分)
进一步学习并做ret2lib及rop的实践,以绕过“堆栈执行保护”。参考ROP
Task 3 ( 5-25分)
可研究实践任何绕过前面预设条件的攻击方法;可研究Windows平台的类似技术实践。
或任何自己想弄明白的相关问题。包括非编程实践,如:我们当前的程序还有这样的漏洞吗?
同学们可跟踪深入任何一个作为后续课题。问题-思考-验证-深入...。根据实践量,可作为5-25分的期末免考题目。
Task1:
shellcode就是一段机器指令(code),通常这段机器指令的目的是为获取一个交互式的shell
。
在许多情况下,标准的shellcode可能无法满足特定的任务,因此需要创建自己的shellcode。
shellcode的编写方式主要有以下三种:
- 直接编写十六进制操作码;
- 使用如C语言等高级语言编写程序,然后进行编译并反汇编,以获取汇编指令及十六进制操作码;
- 编写汇编程序,将该程序汇编,然后从二进制中提取十六进制操作码。
我通过查阅了一定的资料,学习了如何构造shellcode。
shellcode源代码:
#include <stdio.h> #include <unistd.h> int main(int argc, char *argv[]) { char *code[2]; code[0] = "/bin/sh"; code[1] = NULL; execve(code[0], code, NULL); return 0; }
以上的代码编译运行可以得到一个shell
反汇编:
我们将上面的代码进行编译然后反汇编:
main.s 是我们得到的反汇编代码, 我们只需要关注main部分的:
参照上面的反汇编代码,我们手工用汇编语言重写上面的main.c,如下:
.section .text .global _start _start: jmp cl pp: popq %rcx pushq %rbp mov %rsp, %rbp subq $0x20, %rsp movq %rcx, -0x10(%rbp) movq $0x0,-0x8(%rbp) mov $0, %edx lea -0x10(%rbp), %rsi mov -0x10(%rbp), %rdi mov $59, %rax syscall cl:call pp .ascii "/bin/sh"
上面的汇编代码,我们保存为文件: scode.s
代码基本无问题,下面进行编译和连接:
编译: as -o scode.o scode.s
连接: ld -o scode scode.o
最后得到的shellcode代码如下:
\xeb\x2b\x59\x55\x48\x89\xe5\x48\x83\xec\x20\x48\x89\x4d\xf0\x48\xc7\x45\xf8\x00\x00\x00\x00\xba\x00\x00\x00\x00\x48\x8d\x75\xf0\x48\x8b\x7d\xf0\x48\xc7\xc0\x3b\x00\x00\x00\x0f\x05\xe8\xd0\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68
最后用C语言写一个测试shellcode的程序:
#include <stdio.h> unsigned char code[] = "\xeb\x2b\x59\x55\x48\x89\xe5\x48" "\x83\xec\x20\x48\x89\x4d\xf0\x48" "\xc7\x45\xf8\x00\x00\x00\x00\xba" "\x00\x00\x00\x00\x48\x8d\x75\xf0" "\x48\x8b\x7d\xf0\x48\xc7\xc0\x3b" "\x00\x00\x00\x0f\x05\xe8\xd0\xff" "\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68" ; /* code 就是我们上面构造的 shellcode */ void main(int argc, char *argv[]) { long *ret; ret = (long *)&ret + 2; (*ret) = (long)code; }
之后进行测试:
实验完成。
实验中碰到的问题:
这个问题卡了我很久,因为一直连不上,后来查阅资料了之后才知道这是因为ld在将所有目标文件链接起来时,不知道程序的入口点在哪里。由内核的启动过程知其从scode.s中开始执行,因此给scode.s的 .text 段添加一句 .globl startup_32,然后给 ./Makefile 中的ld加上选项 -e startup_32 以指定入口点。
task3:
可研究实践任何绕过前面预设条件的攻击方法;可研究Windows平台的类似技术实践。
我平时打ctf比赛的时候主要是打reverse方向,主要是做pe类型的题目,pe是windows平台的,所以这次我就写个reserve题目的wp当做技术实践:
这道题是第三届上海市大学生网络安全大赛的题crackme,首先我们拿到这个文件先丢到ExeinfoPe里面查壳:
发现是个nSPack的壳
最近在练手动脱壳,所以这次就自己试试:
OD自动载入之后停在了这里,发现是pushfd和pushad
所以有两种方法
A:popad寻找法
用Ctrl+F去查找popad
B:ESP定律法
第一个命令先F8,单步执行
在ESP右击,选择数据窗口中跟随
跟踪这个值
选中46 02 00 00这四个字节,右击断点,硬件访问,Dword,选择
然后F9运行,跳转到这儿
看到了这个长跳转,知道了401336离OEP很近了,单步F8,再次单步
所以,1621是OEP的RVA
接下来是用PETools来DUMP文件
在PETools选中这个crackme,右击选择,完整转存
然后是使用Import REC
点击IAT AutoSearch,Get Imports
然后把OEP改成1621
然后看看是不是都是YES
发现都是YES就可以点击Fix Dump
选中我们刚才Dump的文件
然后再使用PETools
Tools - Rebuild PE,重建那个DUMP文件
发现,脱壳成功!
IDA查看Strings,发现有error和right:
然后就是简单算法逆向了~~~
发现就是个简单的算法逆向了
实验结束=。=