透析挖洞神器mona.py插件新特性

前言

这里不得不用简单的篇幅介绍一下mona.py。这是由corelan team整合的一个可以自动构造Rop Chain而且集成了metasploit计算偏移量功能的强大挖洞辅助插件,详情可以参照他们的官方网站。

当我在准备Derbycon的高级开发课程之前,还一直在玩IE的原始堆分配。其中有些问题给我带来了挫折(至少说,让我的整个研究进度都慢了许多)。反观,这也提高了我快速识别对象的能力,也是一个不错的机遇。毕竟,我是在尝试找一个包含任意数据的对象,或者指针,这做起来并不那么容易!

我决定给mona.py插件增加一些新的特性,以便让大家可以更快的寻找到感兴趣的对象。这些新特性仅仅在WinDBG下有效。

dumpobj (do)

这第一个新特性就是dumpobj。这条mona.py命令会转储对象中的内容,并提供内容中的有用信息。该命令有以下几个参数:

Usage of command 'dumpobj' :
-----------------------------
Dump the contents of an object.
 
Arguments:
    -a <address>      : Address of object
    -s <number>       : Size of object (default value: 0x28 or size of chunk)
Optional arguments:
    -l <number>       : Recursively dump objects
    -m<number>       : Size forrecursive objects (default value: 0x28)

正如你看到的帮助信息,我们至少需要提供两个参数。

-a <address> : 开始的位置(对象的地址。当然,这个你可以自己随意定义)

-s <number> :对象的大小,如果你指定-s参数,mona会尝试自己定义一个大小。如果定义失败,那么mona会对这个对象转储0x28字节。

此外,你也可以告诉mona转储一些链接对象。-l参数后跟上一个数字,这个数字代表了递归转储的等级。由于性能的原因,会限制输出的大小,链接对象中只有第一个0x28字节的内容会输出给用户。当然,你也可以使用-m参数,看到更多内容。

在WinDBG中转储对象中的内容很繁琐。在某些情况下,dds/dc命令力度还是不够的,还需要做一些额外的工作才能够进一步分析这个对象和可选对象。

让我们来看看下面这个例子,假设我们在0x023a1bc0有一个0x78字节的对象。我们可以使用WinDBG命令转储这个对象中的内容。

0:001> dds 0x023a1bc0 L 0x78/4
023a1bc0  023a1d30
023a1bc4  023a1818
023a1bc8  00000000
023a1bcc  023a1d3c
023a1bd0  023a1824
023a1bd4  baadf00d
023a1bd8  00020000
023a1bdc  00000001
023a1be0  00160014
023a1be4  023a1a38
023a1be8  013a0138
023a1bec  023a1a68
023a1bf0  00000000
023a1bf4  00000001
023a1bf8  023a18a8
023a1bfc  00000000
023a1c00  00000000
023a1c04  00000007
023a1c08  00000007
023a1c0c  023a18d0
023a1c10  00000000
023a1c14  00000000
023a1c18  00000000
023a1c1c  00000000
023a1c20  00000000
023a1c24  00000000
023a1c28  00000000
023a1c2c  00000000
023a1c30  00000000
023a1c34  00000000
 
0:001> dc 0x023a1bc0 L 0x78/4
023a1bc0  023a1d30 023a1818 00000000 023a1d3c  0.:...:.....<.:.
023a1bd0  023a1824 baadf00d 00020000 00000001  $.:.............
023a1be0  00160014 023a1a38 013a0138 023a1a68  ....8.:.8.:.h.:.
023a1bf0  00000000 00000001 023a18a8 00000000  ..........:.....
023a1c00  00000000 00000007 00000007 023a18d0  ..............:.
023a1c10  00000000 00000000 00000000 00000000  ................
023a1c20  00000000 00000000 00000000 00000000  ................
023a1c30  00000000 00000000                    ........

Nice!我们可以看到很多东西—似乎是指针的值,nulls,以及一些垃圾数据。

使用mona,我们可以转储相同的对象,mona会尝试在对象中收集更多有关dword的信息。

0:001> !py mona do -a 0x023a1bc0
Hold on...
[+] No size specified, checking if address is part of known heap chunk
    Address found in chunk 0x023a1bb8, heap 0x00240000, (user)size 0x78
 
----------------------------------------------------
[+] Dumping object at 0x023a1bc0, 0x78 bytes
 
[+] Preparing output file 'dumpobj.txt'
    - (Re)setting logfile c:\logs\HeapAlloc2\dumpobj.txt
[+] Generating module info table, hang on...
    - Processing modules
    - Done. Let's rock 'n roll.
 
>> Object at 0x023a1bc0 (0x78 bytes):
Offset  Address      Contents    Info
------  -------      --------    -----
+00     0x023a1bc0 | 0x023a1d30  (Heap) ptr to ASCII '0::'
+04     0x023a1bc4 | 0x023a1818  (Heap) ptr to ASCII ':'
+08     0x023a1bc8 | 0x00000000  
+0c     0x023a1bcc | 0x023a1d3c  (Heap) ptr to 0x77e46464 : ADVAPI32!g_CodeLevelObjTable+0x4
+10     0x023a1bd0 | 0x023a1824  (Heap) ptr to ASCII ':'
+14     0x023a1bd4 | 0xbaadf00d  
+18     0x023a1bd8 | 0x00020000  = UNICODE ' ' 
+1c     0x023a1bdc | 0x00000001  
+20     0x023a1be0 | 0x00160014  = UNICODE '' 
+24     0x023a1be4 | 0x023a1a38  (Heap) ptr to UNICODE 'Basic User'
+28     0x023a1be8 | 0x013a0138  (Heap) ptr to ASCII 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...'
+2c     0x023a1bec | 0x023a1a68  (Heap) ptr to UNICODE 'Allows programs to execute as a user that does not have Administrator or Power User access rights, but can still access resouces accessible by normal users.'
+30     0x023a1bf0 | 0x00000000  
+34     0x023a1bf4 | 0x00000001  
+38     0x023a1bf8 | 0x023a18a8  
+3c     0x023a1bfc | 0x00000000  
+40     0x023a1c00 | 0x00000000  
+44     0x023a1c04 | 0x00000007  
+48     0x023a1c08 | 0x00000007  
+4c     0x023a1c0c | 0x023a18d0  (Heap) ptr to ASCII ' :H:p:'
+50     0x023a1c10 | 0x00000000  
+54     0x023a1c14 | 0x00000000  
+58     0x023a1c18 | 0x00000000  
+5c     0x023a1c1c | 0x00000000  
+60     0x023a1c20 | 0x00000000  
+64     0x023a1c24 | 0x00000000  
+68     0x023a1c28 | 0x00000000  
+6c     0x023a1c2c | 0x00000000  
+70     0x023a1c30 | 0x00000000  
+74     0x023a1c34 | 0x00000000  
 
[+] This mona.py actiontook 0:00:00.579000

很显然,对象中的某些值指向了字符串(ASCII and Unicode),其他的似乎指向了另外一个对象(ADVAPI32!g_CodeLevelObjTable+0x4)。这个看起来是不是要比使用dds/dc命令更方便呢?其实,我们还可以做得更好,我们还可以通知mona自动打印链接对象。接下来,我们再次使用mona命令并带上-L参数看看效果吧。

0:001> !py mona do -a 0x023a1bc0 -l 1
Hold on...
[+] No size specified, checking if address is part of known heap chunk
    Address found in chunk 0x023a1bb8, heap 0x00240000, (user)size 0x78
 
----------------------------------------------------
[+] Dumping object at 0x023a1bc0, 0x78 bytes
[+] Also dumping up to 1 levels deep, max size of nested objects: 0x28 bytes
 
[+] Preparing output file 'dumpobj.txt'
    - (Re)setting logfile c:\logs\HeapAlloc2\dumpobj.txt
[+] Generating module info table, hang on...
    - Processing modules
    - Done. Let's rock 'n roll.
 
>> Object at 0x023a1bc0 (0x78 bytes):
Offset  Address      Contents    Info
------  -------      --------    -----
+00     0x023a1bc0 | 0x023a1d30  (Heap) ptr to ASCII '0::'
+04     0x023a1bc4 | 0x023a1818  (Heap) ptr to ASCII ':'
+08     0x023a1bc8 | 0x00000000  
+0c     0x023a1bcc | 0x023a1d3c  (Heap) ptr to 0x77e46464 : ADVAPI32!g_CodeLevelObjTable+0x4
+10     0x023a1bd0 | 0x023a1824  (Heap) ptr to ASCII ':'
+14     0x023a1bd4 | 0xbaadf00d  
+18     0x023a1bd8 | 0x00020000  = UNICODE ' ' 
+1c     0x023a1bdc | 0x00000001  
+20     0x023a1be0 | 0x00160014  = UNICODE '' 
+24     0x023a1be4 | 0x023a1a38  (Heap) ptr to UNICODE 'Basic User'
+28     0x023a1be8 | 0x013a0138  (Heap) ptr to ASCII 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...'
+2c     0x023a1bec | 0x023a1a68  (Heap) ptr to UNICODE 'Allows programs to execute as a user that does not have Administrator or Power User access rights, but can still access resouces accessible by normal users.'
+30     0x023a1bf0 | 0x00000000  
+34     0x023a1bf4 | 0x00000001  
+38     0x023a1bf8 | 0x023a18a8  (Heap) ptr to 0x00000101 : 
+3c     0x023a1bfc | 0x00000000  
+40     0x023a1c00 | 0x00000000  
+44     0x023a1c04 | 0x00000007  
+48     0x023a1c08 | 0x00000007  
+4c     0x023a1c0c | 0x023a18d0  (Heap) ptr to ASCII ' :H:p:'
+50     0x023a1c10 | 0x00000000  
+54     0x023a1c14 | 0x00000000  
+58     0x023a1c18 | 0x00000000  
+5c     0x023a1c1c | 0x00000000  
+60     0x023a1c20 | 0x00000000  
+64     0x023a1c24 | 0x00000000  
+68     0x023a1c28 | 0x00000000  
+6c     0x023a1c2c | 0x00000000  
+70     0x023a1c30 | 0x00000000  
+74     0x023a1c34 | 0x00000000  
 
>> Object at 0x023a1d3c (0x28 bytes):
Offset  Address      Contents    Info
------  -------      --------    -----
+00     0x023a1d3c | 0x77e46464  ADVAPI32!g_CodeLevelObjTable+0x4
+04     0x023a1d40 | 0x023a1bcc  (Heap) ptr to ASCII '<:$:'
+08     0x023a1d44 | 0xbaadf00d  
+0c     0x023a1d48 | 0x00040000  = UNICODE ' ' 
+10     0x023a1d4c | 0x00000101  
+14     0x023a1d50 | 0x001a0018  = UNICODE '' 
+18     0x023a1d54 | 0x023a1c50  (Heap) ptr to UNICODE 'Unrestricted'
+1c     0x023a1d58 | 0x0090008e  (Heap) ptr to ASCII 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...'
+20     0x023a1d5c | 0x023a1c88  (Heap) ptr to UNICODE 'Software access rights are determined by the access rights of the user.'
+24     0x023a1d60 | 0x00000000  
 
>> Object at 0x023a18a8 (0x28 bytes):
Offset  Address      Contents    Info
------  -------      --------    -----
+00     0x023a18a8 | 0x00000101  
+04     0x023a18ac | 0x05000000  
+08     0x023a18b0 | 0x0000000a  
+0c     0x023a18b4 | 0xabababab  
+10     0x023a18b8 | 0xabababab  
+14     0x023a18bc | 0xfeeefeee  
+18     0x023a18c0 | 0x00000000  
+1c     0x023a18c4 | 0x00000000  
+20     0x023a18c8 | 0x0005000a  = UNICODE '' 
+24     0x023a18cc | 0x051807c2  
 
[+] This mona.py actiontook 0:00:00.640000

在上面的输出我们可以看到,mona确定源对象中包含了对2个链接对象的引用,并且转储了链接对象。最重要的是要知道mona不会把字符串 (ASCII or Unicode) 当作对象处理,因为mona已经显示了字符串,dumpobj命令的输出,最终会写入一个名为“dumpobj.txt”的文本文件中。

dumplog (dl)

显然,dumpobj命令能够十分轻松的获得一个对象的重要信息。如果你已经知道起始对象,这对你来说就更加方便了。

为了让世界清净下来,我决定使用dumplog去解析日志文件(基于某一语法),并在已经分配好的对象中执行dumpobj命令。在当前这个版本,dumplog并不能够转储链接对象,但是我准备给他加上这一特性。

Dumplog在使用前,需要进行一些设置。我们需要告诉WinDBG创建一个遵循特定协议的日志文件,当然了,我们需要在同一个调试会话中运行mona。

Dumplog的帮助信息如下:

Usage of command 'dl' :
------------------------
Dump all objects recorded in an alloc/free log
Note: dumplog will only dump objects that have not been freed in the samelogfile.
Expected syntax for log entries:
    Alloc : 'alloc(size in hex) =address'
    Free  : 'free(address)'
Additional text after the alloc & free info is fine.
Just make sure the syntax matches exactly with the examples above.
Arguments:
    -f <path/to/logfile>: Full path to the logfile

这个想法是为了记录所有的堆分配以及自由操作。在WinDBG中可以通过以下步骤实现:

.logclose
.logopen c:\\allocs.txt

接下来,记录2个断点

bp !ntdll + 0002e12c ".printf \"alloc(0x%x) = 0x%p\",poi(esp+c), eax; .echo; g"
bp ntdll!RtlFreeHeap "j (poi(esp+c)!=0)'.printf \"free(0x%p)\", poi(esp+c); .echo; g'; 'g';"

(基于kernel32.dll最新版本, Windows7 SP1).

当RtlAllocateHeap 和RtlFreeHeap被调用时,这两个断点就会向WinDBG发送一个消息。

当你准备分析漏洞时,不要关闭WinDBG,关闭日志文件时使用.logclose命令。我们现在就可以使用mona解析日志文件了。

!py mona dl -fc:\allocs.txt

输出将被写入dump_alloc_free.txt文件

最后,希望你能够喜欢这两个新特性。

[参考来源Corelan,文/实习编辑 鸢尾,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)]

原文发布于微信公众号 - FreeBuf(freebuf)

原文发表时间:2015-01-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏liuchengxu

[译]27个Jupyter Notebook小提示与技巧

Jupyter notebook, 前身是 IPython notebook, 它是一个非常灵活的工具,有助于帮助你构建很多可读的分析,你可以在里面同时保留代码...

2852
来自专栏nice_每一天

Java线程池实现原理之自定义线程池(一)

1.7K2
来自专栏IT开发技术与工作效率

Redis 全中文总结

3234
来自专栏java相关

Spring中的线程池和定时任务功能

2672
来自专栏有趣的django

面试题目及答案

1 Python的函数参数传递 看两个例子: a = 1 def fun(a): a = 2 fun(a) print a # 1 a = [] de...

1.2K9
来自专栏积累沉淀

Java批处理

批处理 JDBC对批处理的操作,首先简单说一下JDBC操作sql语句的简单机制。 JDBC执行数据库操作语句,首先需要将sql语句打包成为网络字...

4715
来自专栏阿杜的世界

《七周七并发模型》阅读笔记(一)一、线程与锁——第一天二、线程与锁——第二天三、线程与锁——第三天

线程与锁模型其实是对底层硬件运行过程的形式化,这种形式化既是该模型最大的优点,也是它最大的缺点。我们借助Java语言来学习线程与锁模型,不过内容也适用于其他语言...

1292
来自专栏老九学堂

【面试】找工作必看的十道XML面试题

XML并不依赖于其他编程语言,与SQL一样是编程人员所必备的技能之一,因此在任何技术工作面试之前准备一些XML问题都是很有意义的。老九君为大家整合了十道有关XM...

4577
来自专栏程序猿DD

Spring Boot使用@Async实现异步调用:使用Future以及定义超时

之前连续写了几篇关于使用 @Async实现异步调用的内容,也得到不少童鞋的反馈,其中问题比较多的就是关于返回 Future的使用方法以及对异步执行的超时控制,所...

2163
来自专栏ChaMd5安全团队

0ctf2018 babystack、babyheap、blackhole解析

0ctf2018 babystack writeup 赛题链接 https://github.com/eternalsakura/ctf_pwn/tree/ma...

5298

扫码关注云+社区

领取腾讯云代金券