预备知识
1.关于Immunity Debugger
位于迈阿密的专业渗透测试技术公司immunity发布了一种新的工具。这种工具能够加快编写利用安全漏洞代码、分析恶意软件和二进制文件逆向工程等过程的速度。这个名为“debugger”的调试工具。immunity称,这个调试工具能够帮助研究人员和渗透测试人员把制作利用安全漏洞代码的时间减少一半,使用简单的、容易理解的界面和强大的脚本语言自动进行智能调试。这家公司还称,这个工具能够把黑客工具fuzzer与利用安全漏洞的开发工具更好地连接起来。
2.IsDebuggerPresent
用于确定调用进程是否由用户模式的调试器调试,如果没有调试,返回0,如果正在调试返回非0。
3.进程枚举
一些病毒或者特殊的程序会枚举进程,一旦找到调试器的进程(od,Immunity Debugger等)就会退出,其实我们让下面两个函数返回0就行了,Process32First,Process32Next,熟悉windows编程的就对这函数很熟悉了。
当我们利用函数CreateToolhelp32Snapshot()获得当前运行进程的快照后,可用Process32First获得第一个进程的句柄,Process32Next获得下一个进程的句柄。
4.FS寄存器的某些偏移的含义,及TEB,PEB
TEB,PEB就是记录线程和进程的一些信息的结构体。
FS:[0x18]:TEB(Thread Environment Block)首地址。
更多请查看:
link
下面给一下这两个结构体的详情:
实验目的
通过该实验了解windows的两个反调试机制——IsDebuggerPresent和进程枚举,学习使用Immunity Debugger,能够手动或者使用python脚本搞定这两个基础的反调试机制。
实验环境
服务器:Windows 7,IP地址:随机分配
辅助工具:Immunity Debugger,python,VC++ 6.0
实验步骤一
任务描述:手动,或者用python调用immlib干掉IsDebuggerPresent,其实这个吾爱的od默认就会干掉它,不过我们要知道原理,尝试手动绕过。
首先我们编写一个简单的小程序:
运行一下:
再以调试模式运行:
我们载入Immunity Debugger看看,拖进去按F9运行,如果一开始不是停在用户领空,就要按两次F9了:
我们可以看到这函数确实能检测到我们正在调试它。
那我们单步跟到那函数那,首先跟到main函数:
F7跟进后,看到了我们的目标函数IsDebuggerPresent了,继续F7跟进:
再几次F8我们就看到它的具体实现了:
第一行就是获取TEB了:
第二行再利用TEB获取PEB:
最后将PEB偏移2的地方作为返回赋值给EAX了:
那么偏移2处刚好就是BeingDebugged字段。
如果进程处于被调试状态,那么PEB里面的BeingDebugged标志会被操作系统置为非0,一般为1,如果没在调试操作系统就会把它置0咯。
那我们单步到第3行,此时的EAX就是PEB,我们在数据窗口中跟随:
可以看到偏移为2处确实为1:
这时我们尝试手动绕过,将其改为0。
点击那个字节,按ctrl+e,将01改为00即可:
接下来我们再按f9然程序跑起来,成功了:
但是每次这样肯定很烦锁,用一条python搞定它。
可以点击下面按钮重新载入程序:
跟着打开内置的python命令行:
输入以下python语句,意思也很明白,就是获取PEB偏移2处的地址,跟着写入0x00:
直接让程序运行起来:
当然可以写成一个python文件放到PyCommands目录,直接在内置命令行调用。
基本格式如下:
import immlib
def main(args):
# 实例化
imm = immlib.Debugger()
# 接下来进行一系列操作
return “一个字符串”
命名为killIsDebuggerPresent.py:
最后放到Immunity Debugger的PyCommands目录。
我们重新载入程序,输入下面的命令,就是一个叹号,再加文件名,不要输入后缀:
回车,我们看到我们的返回值出现在下面的状态栏中啦:
看看运行后的程序:
实验步骤二
任务描述:一些病毒或者特殊的程序会枚举进程,一旦找到调试器的进程(od,Immunity Debugger等)就会退出,那么我们让下面两个函数返回0就好了,Process32First,Process32Next,让它枚举不了进程。
1.这里使用我之前编写的简单进程管理器进行实验:
枚举进程的代码:
我们目标是使它看不到任何进程。
载入程序,再下个断点:
F9运行到断点处:
向下看,可以看到函数返回后,esp要+8,等下我们写汇编时要考虑到栈平衡:
那我们手动绕过,在函数开始处开始改代码,就改了下面两行:
好了,我们运行看看,可以看到进程管理器什么进程都获取不到了:
当然除了sub eax,eax,用xor eax,eax,也是可以的,如下图:
还有一个问题,我们发现里面调用了Process32FirstW,我们单步跟一下确实是,那我们改Process32FirstW应该也是可以的吧,接下来试试:
F7跟进去,发现也是retn 8:
我们尝试改一下:
发现也是可以的:
那么接下来我们开始写脚本吧,保存为killenumerateprocess.py:
载入程序后,输入命令,可以看到两个函数的地址,也可以看出写入成功了:
那我们F9运行程序看看,成功了,当然代码中的函数应该可以是宽字节版本的Process32FirstW: