知识点1
在linux shell中,假如有如下语句,这就是shell注入方面
echo ‘’;ls;cat 1.txt;/bin/sh;’’
则ls、cat 1.txt、/bin/sh这三个命令会依次执行,这也就是本题突破的关键
知识点2
C语言或C++ 申请内存后,用free或delete释放堆后,指针的值还在,如果不手动设置为NULL,就可以被我们利用。
堆内存的分配有规律,我们用如下的代码做试验
知识点1
在linux shell中,假如有如下语句,这就是shell注入方面
echo ‘’;ls;cat 1.txt;/bin/sh;’’
则ls、cat 1.txt、/bin/sh这三个命令会依次执行,这也就是本题突破的关键
知识点2
C语言或C++ 申请内存后,用free或delete释放堆后,指针的值还在,如果不手动设置为NULL,就可以被我们利用。
堆内存的分配有规律,我们用如下的代码做试验
本题,用checksec检查二进制,发现开启了CANARY、NX、以及RELRO保护,CANARY是用来检测栈溢出的,canary是一个随机数,存储在栈里。程序通过对比栈里的canary值和读取到的实际canary值进行对比,如果不相等,则抛出异常。因此,为了绕过canary机制,我们需要先想泄露canary的值,然后利用栈溢出,把这个值放到payload中对应的位置里,这样,程序发现canary的值没变,我们就成功绕过。
我们知道 x86都是靠栈来传递参数的 而x64换了 它顺序是rdi, rsi, rdx, rcx, r8, r9, 如果多于6个参数 才会用栈 我们要先知道这个特性
这题,里面既没有现成的system也没有/bin/sh字符串,也没有提供libc.so给我们,那么我们要做的就是想办法泄露libc地址,拿到system函数和/bin/sh字符串,这题呢,我们可以利用put来泄露read函数的地址,然后再利用LibcSearcher查询可能的libc。
这题ROP,我们先构造payload来执行puts函数泄露read的地址
popedi是pop edi这条指令所在的地址,我们可以在二进制文件里查找,发现了地址0x400763处可以供我们使用,然后我们传入read的got地址,接下来是popedi的返回地址,我们设为putaddr,接下来是puts的返回地址,我们设为mainaddr,这样我们又能重新执行主函数,执行第二次rop
以下payload相当于
开始拿到本题我也一脸茫然,也没有游戏说明。于是就随便看了看,发现菜单上的三个选项都提示Nope doesn’t work yet!,即这三个功能都不能用,再看看这个题目的分类是Menu,我想,这题就是要我们让这三个选项能正常使用吧,就类似于Crackme041那题,要我们加代码。开始呢,我想到的就是在结尾处添加代码,用ollydbg搜索了一下,发现很多必要的Api函数没有导入进去,手动添加又太麻烦。而且要加三个功能,汇编代码量肯定很大。于是就想起了dll注入,这个技术,我也是现学现用。它的原理是通过某种手段,让程序加载我们的dll,dll中的DllMain函数就会自动执行,我们可以把一些代码放这个函数里。这种技术也应用于许多病毒程序中。
为什么dll注入后可以控制应用程序?
在Windows中,每个应用程序都是独立运行在自己的内存空间,有没有发现,我们用ollydbg打开exe,第一行指令的地址总是0x401000 ,程序A从这个地址开始执行,程序B也从这个地址开始执行,但是他们互不影响,即这些地址并不是物理地址,而是一个相对的地址。每个程序有独立的地址空间,自己空间里的线程可以随便操控自己的内存,那么,如果我们把自己的dll加载到程序的空间里去,这个dll就成了程序的一部分,可以操控这个程序的内存。
本题要求在不修改源程序的情况下要去除开始的那个对话框
我们使用了调试的方法控制程序的执行,大概hook也可以用这种原理实现
1 | //调试器原理大概就是这样了吧 |