文章目录
背景知识
Immunity Debugger
Immunity Debugger是位于迈阿密的专业渗透测试技术公司发布的一种工具,这个工具能够加快编写利用安全漏洞代码,分析恶意软件和二进制文件逆向工程等的速度。Immunity称这个调试工具能帮助渗透测试人员制作利用安全漏洞代码的时间减少一半。尤其是Immunity Debugger的插件mona.py更是软件漏洞挖掘的神器。
Windbg
Windbg是在windows平台下,强大的用户态和内核态调试工具。虽然windbg也提供图形界面操作,但它最强大的地方还是有着强大的调试命令,一般情况会结合GUI和命令行进行操作,常用的视图有:局部变量、全局变量、调用栈、线程、命令、寄存器、白板等。其中“命令”视图是默认打开的。
Python
一种面向对象的解释性的计算机程序设计语言,也是一种功能强大而完善的通用型语言,已经具有十多年的发展历史,成熟且稳定。Python 具有脚本语言中最丰富和强大的类库,足以支持绝大多数日常应用。Python在漏洞利用方面是理想的Exploit工具。
实验目的
熟悉常用的软件漏洞挖掘工具,为软件漏洞挖掘奠定基础。
实验环境
服务器:Windows 7 SP1 ,IP地址:随机分配
辅助工具:Windbg,ImmunityDebugger,python2.7,mona.py
mona.py是由corelan team整合的一个可以自动构造Rop Chain而且集成了metasploit计算偏移量功能的强大挖洞辅助插件
实验步骤
熟悉Immunity Debugger的基本使用
- Immunity Debugger窗口介绍
双击桌面上的Immunity Debugger图标,把桌面上的/软件漏洞挖掘/1/hello world.exe,拖进Immunity Debugger将会看到下面窗口
从左到右、从上到下依次是反汇编窗口、寄存器窗口、内存窗口和堆栈窗口。
hello world源码如下:
#include<stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
Immunity Debugger主界面有四个窗口,分别是反汇编窗口、寄存器窗口、内存窗口和堆栈窗口。
反汇编窗口
反汇编窗口又分为四列:地址,机器码,机器码对应的汇编指令,注释。在漏洞挖掘中我们经常需要知道某句汇编指令对应的机器码。比如我想知道jmp esp对应的机器码。那么我们可以在反汇编窗口按空格键,在弹出的窗口输入jmp esp
然后点Assemble。可以看到第二列为机器码,值为FFE4
寄存器窗口
这里显示了某时刻EAX(累加器),EBX(基址寄存器),ECX(计数器),EDX(数据寄存器),ESI(源变址寄存器),EDI(目的变址寄存器),EBP(基址指针),ESP(堆栈指针),EIP(指令指针)等寄存器的值。
内存窗口
这个可以查看某个地址的内容比如我想看看0x401000这个地址有什么东西,那么只需要在内存窗口Ctrl+g然后输入401000回车
可以看到0x401000以后的数据是68 30 70 40 00….【注:这是十六进制数】
堆栈窗口
堆栈窗口是非常有用的一个窗口,在程序崩溃时候,我们可以在堆栈窗口查看ESP指向,shellcode在堆栈的位置等。
2. Immunity Debugger与Python 脚本
file下面那个蓝紫色logo:
Immunity Debugger内部集成了python解释器。可以在调试的时候执行python命令。
Immunity调试器的另外一个好用的功能是创建函数图形。
view下面那个紫色的图标:
这个图类似于一个流程图,它是一个函数组成的流程图,更加直观地展示了汇编语言程序的逻辑结构。
3. Immunity Debugger插件
Immunity调试器拥有众多的实用插件,官方原版调试器只内置了两个插件。我们可以使用网上的插件,还可以开发自己的插件,这可以通过Immunity提供的API实现。点击Help-Open API Help file
"""Author:www.netfairy.net
"""
__VERSION__ = '1.0'
import immlib
def usage(imm):
imm.log("hello world")
def main(args):
imm = immlib.Debugger()
if not args:
usage(imm)
else:
usage(imm)
上述代码功能是输出hello world!
将上述代码保存为netfairy.py,放到Immunity Debugger安装目录下的/PyCommands文件夹,重新载入Immunity Debugger,在调试器底部命令行输入!netfairy
4. Immunity Debugger的mona.py插件
接下来介绍Immunity Debugger的一个插件mona.py。后面我们会经常用到它。在Immunity Debugger下方的命令行输入!mona即可查看插件所有信息
我们这个系列教程用到的命令有!mona pc N (产生N个随机字符串),!mona po str (计算str在N个字符中出现的位置),!mona seh (找出没有开启safeseh模块中的pop pop retn序列)。如果你不懂某个命令怎么用请输入 !mona help 某个命令。
熟悉Windbg的基本使用
Windbg基本命令以使用示例
1)我们打开windbg后,默认是这个界面,清新,简洁。
WinDbg支持以下三种类型的命令:
·常规命令,用来调试进程
·点命令,用来控制调试器
·扩展命令,可以添加叫WinDbg的自定义命令,一般由扩展dll提供这些命令
1.启动WinDbg
双击windbg图标或者在命令行下执行cd windbg切换到windbg安装目录,然后然后执行 windbg 启动调试器。【注】要用WinDbg(x86)调式32位程序,用WinDbg(x64)调试64位程序。
2.使用帮助
任何时候都可以使用!help命令来获取帮助,查看命令的使用方法。
3.设置SymbolFile Path,指定了符号库,我们才能看到详细的类型信息
SRVc:\symbolshttp://msdl.microsoft.com/download/symbols
WinDbg会将微软的符号库下载指定的本地目录中
4.重新加载符号
如果进入调试之后才指定的符号路径,需要使用命令来重新加载符号
.reload
5.Ctrl+Break终止一个很长时间没有完成的命令, Ctrl+Break也可以让正在运行的程序暂停
6.保存dump文件
.dump /ma c:\test.dmp 保存full-dump
.dump /m c:\test.dmp 保存mini-dump
-
分析Dump
一般先 !analyze –v Windbg会根据上面命令自动分析, 然后 ~* kv 打印所有线程的堆栈 -
察看模块信息
lm显示所有模块信息
lmf 显示所有模块及其路径
lmD 显示所有模块详细信息 -
单步调试
g 继续运行(go), 热键F5
t 单步越过(step over), 热键F10
p 单步进入(step into), 热键 F11 -
设置断点(break point)
bp [address] [“command”] 设置软件断点。
比如 bp kernel32!CreateProcessW表示在调用这个CreateProcess时设置断点。
如bp kernel32!CreateFileW “du poi(esp+4); g” 表示在调用CreateFile时打印出文件路径(第一个参数),然后继续执行
针对某线程设置断点,只要在命令前加~线程号:
比如 ~0 bp 0x441242, 表示0号线程执行到地址0x441242时中断
ba [access size] [command]设置硬断点。
其中,access指定访问方式(e执行指令, r读取数据,w写入数据)
size 表示监视数据的大小(1, 2, 4)
比如ba r4 0x414422, 表示在地址0x414422写入4字节数据是触发断点
11.管理断点
bl 列出所有当前断点的状态
bc 清除断点, bc * 清除所有断点, bc 0 清除0号断点
bd 禁用某个断点(disable)
be 打开某个断点(enable)
12.察看堆栈
kn [frame count]察看当前堆栈及其索引, frame count指定要显示多少桢
kb显示堆栈桢地址,返回地址,参数,函数名等
kv在kb的基础上增加了函数调用约定等信息, 所以推荐用kv命令察看堆栈.
.frame [frame index] 将当前堆栈切换到某个堆栈桢, 比如.frame 1 切换到第1桢
dv 命令察看当前堆栈桢的局部变量
13.察看和修改寄存器
r 显示所有寄存器的值
r eax=0x100 将eax寄存器的改成0x100
14.搜索内存(search memory)
s –[type] range pattern
其中type, b表示byte, w表示word, d 表示dword, a表示ASCII string,u表示unicde string
Range 表示地址范围,可以用2种表示:一是起始地址加终止地址, 二是起始地址加L长度(不是字节长度,是单位长度)。如果搜索空间长度超过256M,用L?length。
Pattern指定要搜索的内容.
比如 s -u 522e0000 527d1000 "web"表示在522e0000 和527d1000之间搜索Unicode 字符串”web”
比如s -w 522e0000 L0x100 0x1212 0x2212 0x1234 表示在起始地址522e0000之后的0x100个单位内搜索0x1212 0x2212 0x1234系列的起始地址
15.反汇编某一地址
u address, 比如u 0x410040表示反汇编地址0x410040的代码
uf 反汇编某个函数, 比如uf test!main
ub 反汇编某地址之前的代码,比如ub 0x 0x410040 L20
!lmi [module name] 显示某一模块的详细信息
以上只是一部分命令,不用死记硬背,需要用的时候现查就行了。
下面使用Windbg实际分析一个程序:
#include<stdio.h>
#include<windows.h>
//主函数
int main()
{
char buffer[8];
MessageBox(NULL,"Hello This is a test","Netfairy",NULL);
strcpy(buffer,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
return 0;
}
strcpy(buffer,"AAAAAAAAAAAAAAAAAAAAAAAAAAAAA");会造成典型的缓冲区溢出,程序将不能正常返回,我们看看Windbg捕获并分析这个异常。编译这个程序,你可以在桌面软件漏洞挖掘/1中找到 test1.exe。用Windbg打开
程序中断
这里提供了三个重要信息:1:程序加载的模块列表,其中有模块的加载基址和介绍地址。 2:当前各寄存器的值 3:当前执行的指令。我们输入 g命令让程序跑起来
到这里还没有出现任何异常,但是当我们按下确定之后
报错了orz。下面用 !analyze –v分析程序出错原因
ExceptionAddress: 41414141指明出错地址为0x41414141。
ExceptionCode: c0000005 (Access violation) 异常代码为c0000005,这是一个访问异常,因为0x41414141不是一个合法的地址。
STACK_TEXT:
WARNING: Frame IP not in any known module. Following frames may be wrong.
0018ff4c 41414141 41414141 41414141 00000041
0018ff88 74cf338a 7efde000 0018ffd4 77549f72
0018ff94 77549f72 7efde000 7763a520 00000000
0018ffd4 77549f45 00401130 7efde000 00000000
0018ffec 00000000 00401130 7efde000 00000000
显示异常时刻堆栈信息。还有其它很多无关信息,我们无须理会。可以看到Windbg捕获到了缓冲区溢出异常。
熟悉python的基本使用
Python是一种十分强大的脚本语言,你可以直接的在Python解释器中编写代码或储存在文本中以便于直接执行,【注】有其他编程经验特别是进行过C/C++语言入门学习的读者需要注意Python中强制使用缩进,我们从打开Python解释器开始。打开桌面IDLE (Python GUI)启动python解释器终端。
这部分省略。
课后习题
分析与思考
socket通信见Python3 网络编程和基于python的tcp socket通信