首页
社区
课程
招聘
[旧帖] [漏洞exploit工具-mona系列2]mona手册 0.00雪花
发表于: 2015-2-26 11:15 6206

[旧帖] [漏洞exploit工具-mona系列2]mona手册 0.00雪花

2015-2-26 11:15
6206
原文地址 https://www.corelan.be/index.php/2011/07/14/mona-py-the-manual/
原文是mona作者发表于2011/6/14的虽然久远,但是作为一本手册没什么影响。

ps: 之所以将它命名为一个系列,我希望大家通过这个系列,能系统的了解、学习、使用mona。以及汲取使用中的经验。

Introduction 介绍

这个文档描述了很多关于mona.py的命令、功能、行为。

发行于6月16,这个pycommand用于immunityDebugger取代pvefindaddr,解决了性能问题,做了很多改进也引入了很多新特性。直到mona完全取代prefindaddr之前,prefindaddr都是可以下载的。

Downloading mona.py 下载 mona.py

mona项目位于这里 http://redmine.corelan.be/projects/mona
你也可以在这里下载最新版的https://redmine.corelan.be/projects/mona/repository/raw/mona.py
连同文档一起发行,我们自豪的能够发行 mona.py v1.1
重要: Mona只能工作于ImmDbg 1.83以及以上版本和WinDBG上。

下载了mona.py,简单地把文件保存到PyCommands 文件夹下就行。默认安装的话,文件夹在这里:
C:\Program Files\Immunity Inc\Immunity Debugger\PyCommands

就这样,mona.py就被安装好了。

Basic usage基本的使用

打开ImmDBG ,在程序的底部你应该看到一个输入框(叫 commandbar)
输入 !mona 并且回车。
打开日志窗口(ALT-L)你应该看到一个充满关于mona选项和命令的信息的窗口。

在顶部,你可能发现全局的选项。输出的后半部包含了可用的所有命令。
如果你想获得关于适用那些命令的更多信息,你可以简单的运行 !mona help <命令>.
假定你想获得更多关于“assemble"命令的更多信息,执行:
!mona help assemble

输出:


Keeping mona.py up-to-date保持 mona.py的更新

在使用mona之前,我强烈建议确保你运行的mona是最新版本。如果你使用的稳定发行版,你就不要看那些更新了(新的发行版经常宣布在twitter和google+上)

如果你使用主干发布的mona.py,你该定期更新。

更新是很简单,确保你的设备已经连接到了redmine.corelan.be(https or http) 运行:
[/CODE]
输出:
[CODE]https://www.corelan.be/wp-content/uploads/2011/07/image14.png

默认连接到  https://redmine.corelan.be 。如果不知为何你不能使用https,你可以用 -http 指令切换到http:
!mona update -http

从mona.py v1.1版开始你可以通过使用 -t <version>选项 来切换稳定版和主干发行版。
所以,如果你运行主干发行版,你想切换到发行版,运行
!mona update -t release


如果你想切换到最新的主干发行版,运行:
!mona update -t trunk


安装和更新mona的基本使用,可以在线观看视频  http://www.youtube.com/watch?v=Nj1EsQu8cHU (ps: 翻墙才可以看的,别说我没告诉你)

Setting up your debugger environment 设置你调试器的环境

working folder

关于prefindaddr,我们的问题其中之一就是实际上所有的输出都写入到了ImmDBG程序的目录里了。因为输出文件是为给定的命令准备的,运行不同的程序,带有相同的名字,基本结束的时候你将重写先前的输出!

mona允许你分类输出并且将输出写入到程序特定的目录下。为了激活这个特性,你需要配置一个参数,例如:
!mona config -set workingfolder c:\logs\%p


这将告诉mona将输出写入到c:\logs的子目录中,%p变量将被当前调试进程的名字取代。注意,如果你没有调试程序的话,ImmDBG返回先前调试的程序的名字,为了防止mona此时将文件写入到程序的文件夹,mona 总是检查调试程序进程的ID。如果PID为0(=没有附加),输出将写入到”_no_name“文件夹下。

如果你想更进一步的分类输出,你甚至可以在 工作目录参数中用%i 变量。这个变量将被被调试程序的进程ID所取代。

这个配置参数被写入到脚mona.ini的文件中,位于ImmDBG程序的目录下。

exclude modules 排除模块

Mona还有第二个配置参数,允许你每次搜索操作时总是去排除某些模块。如果你想忽略那些被shell扩展加载的、用户增加的虚拟的、杀毒软件自带的模块,等等,你可以简单的告诉mona通过使用以下的命令忽略它们。
!mona config -set excluded_modules "module1.dll,module2.dll"
!mona config -add excluded_modules "module3.dll"


如果你想移除从列表中移除一个模块的话,你可以在ImmDBG程序的目录下找到mona.ini并且编辑它。

author 作者

当制作与metasploit兼容的输出时,这个变量可能会被用到。如果你设置这个变量,将会被用在metasploit模块的作者章节中。
!mona config -set author corelanc0d3r


Global options 全局的选项
全局的选项允许你影响和微调任何查询命令的结果。

选项  -n

如果你使用选项-n,所有起始包含null字节的模块都将被跳过。这将加快查询速度,但是这将错过一些结果,因为一些模块可能事实上包含不以null字节起始的指针。如果这个行为太过于明显 如果你仅仅想排除一些空指针,你可以使用 -cp nonull 或者 -cpb '\x00' 其中一个(稍后将看到)

选项  -o

这个选项将告诉mona搜索操作时忽略系统模块。同样的你将在文档中看到每个命令,这都是默认的行为。你使用 -cm选项驳回表现。(撤销)

选项  -p

这个选项带有一个参数: 1个数字值,选项 -p允许你限制返回的结果数目。如果你只想要5个指针的话,你可以用 选项 -p 5

option -m

这个选项允许你指定在哪些模块上执行查找操作。如果你指定 -m ,这将忽略所有的其他的模块。
(通过 -cm 设置默认的表现)你可以通过使用逗号指定了多个模块。

例如:假定你想列入所有以 “gtk"开头"的模块 ,所有包含 ”win"词"的模块  以及模块 “shell32.dll 选项应该如下:
-m "gtk*,*win*,shell32.dll"


如果你想搜索所有的模块,你可以简单实用 -m *

选项 -cm

这个选项允许你去设置一个模块应遵循的规则,包含在一些查询操作中。

适用的规则有:

    》aslr
    》rebase
    》safeseh
    》nx
    》os

如果你想包含aslr 和rebase 模块,但是排除safeseh模块,你可以这么用:
-cm aslr=true,rebase=true,safeseh=false

(注:这将总包含 没有aslr 和没有rebase的模块) 你可以使用true值去重写那些给定命令的默认值。你可以用”false"值去强制某些模块不被排除)

选项 -cp

cp选项允许你给定一个指针应该匹配的规则。pvefindaddr 已经在输出文件中标记了指针是否它们是unicode或者ascii 再者包含空字节,但是mona更给力,在标注的指针上面(mona也可以这么做)你可以限制返回的指针仅仅是那些符合给定规则的。

可适用的规则有:
   
    unicode (this will include unicode transforms as well)
    ascii
    asciiprint
    upper
    lower
    uppernum
    lowernum
    numeric
    alphanum
    nonull
    startswithnull

如果你给定多个规则,指针结果将符合所有的规则。如果你想对规则使用 or 的话,你必须多次执行查询。

我们相信这个是一个非常强状的特性。特别是在 ROP利用中(大部分由指针组成payload 而不仅仅是shellcode) 能够微调指针规则的能力是非常重要的(这是其他搜索工具都没有的特性)

例如: 仅显示那些包含可打印ascii码字节的指针。
-cp asciiprint

例如:仅仅显示不包含null字节的指针

-cp nonull


选项 -cpb

这个选项允许你给定坏字节为指针。这个特性将主要的跳过那些包含任何一个命令行给定的坏字符的指针。

假定你的利用不包含 \x00, \x0a or \x0d,你可以用以下全局的选项去跳过包含这些坏字符的指针。
-cpb '\x00\x0a\x0d'


选项 -x

这个选项允许你对指针结果设置预期的访问权限。在大部分情况下,指针应该是可执行页的一部分,但是在一些情况下,你可能需要在不可执行的区域寻找指针或者数据。

-x选项使用的有:

     *
    R
    RW
    RX
    RWX
    W
    WX
    X
在所有情况下, 默认的设置是 X ( 包含 x Rx WX RWX)

Output files输出文件

在查看多种多样的命令之前,我们先看下输出文件包含什么:

首先,他包含一个头,表明mona版本,系统版本,进程是被调试的,pid,和时间戳
================================================================================
  Output generated by mona.py v1.1-dev
  Corelan Team - http://www.corelan.be
================================================================================
  OS : xp, release 5.1.2600
  Process being debugged : GenBroker (pid 7012)
================================================================================
  2011-06-21 18:33:18
================================================================================


下面,将有一个关于所有加载模块的模块信息表格。
Module info :
----------------------------------------------------------------------------------------------------------------------------------
 Base       | Top        | Size       | Rebase | SafeSEH | ASLR  | NXCompat | OS Dll | Version, Modulename & Path
----------------------------------------------------------------------------------------------------------------------------------
 0x002d0000 | 0x00326000 | 0x00056000 | True   | True    | False |  False   | True   | 7.10.3052.4 [MSVCR71.dll] (C:\WINDOWS\system32\MSVCR71.dll)
 0x77b20000 | 0x77b32000 | 0x00012000 | False  | True    | False |  False   | True   | 5.1.2600.5875 [MSASN1.dll] (C:\WINDOWS\system32\MSASN1.dll)
 0x74980000 | 0x74aa3000 | 0x00123000 | False  | True    | False |  False   | True   | 8.100.1052.0 [msxml3.dll] (C:\WINDOWS\system32\msxml3.dll)
 0x77a80000 | 0x77b15000 | 0x00095000 | False  | True    | False |  False   | True   | 5.131.2600.5512 [CRYPT32.dll] (C:\WINDOWS\system32\CRYPT32.dll)
 0x00c10000 | 0x00ed5000 | 0x002c5000 | True   | True    | False |  False   | True   | 5.1.2600.5512 [xpsp2res.dll] (C:\WINDOWS\system32\xpsp2res.dll)
 0x7c800000 | 0x7c8f6000 | 0x000f6000 | False  | True    | False |  False   | True   | 5.1.2600.5781 [kernel32.dll] (C:\WINDOWS\system32\kernel32.dll)
 0x76780000 | 0x76789000 | 0x00009000 | False  | True    | False |  False   | True   | 6.00.2900.5512 [SHFOLDER.dll] (C:\WINDOWS\system32\SHFOLDER.dll)
 0x7c3a0000 | 0x7c41b000 | 0x0007b000 | False  | True    | False |  False   | True   | 7.10.3077.0 [MSVCP71.dll] (C:\WINDOWS\system32\MSVCP71.dll)
 0x7c900000 | 0x7c9b2000 | 0x000b2000 | False  | True    | False |  False   | True   | 5.1.2600.6055 [ntdll.dll] (C:\WINDOWS\system32\ntdll.dll)
 0x015b0000 | 0x015b8000 | 0x00008000 | True   | False   | False |  False   | False  | 9.20.200.49 [GenRegistrarServerps.dll] (C:\Program Files\Common Files\ICONICS\GenRegistrarServerps.dll)
 0x71a90000 | 0x71a98000 | 0x00008000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [wshtcpip.dll] (C:\WINDOWS\System32\wshtcpip.dll)
 0x00270000 | 0x0029f000 | 0x0002f000 | True   | False   | False |  False   | True   | 9.20.200.49 [TraceWorX.DLL] (C:\WINDOWS\system32\TraceWorX.DLL)
 0x77fe0000 | 0x77ff1000 | 0x00011000 | False  | True    | False |  False   | True   | 5.1.2600.5834 [Secur32.dll] (C:\WINDOWS\system32\Secur32.dll)
 0x71ad0000 | 0x71ad9000 | 0x00009000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [WSOCK32.dll] (C:\WINDOWS\system32\WSOCK32.dll)
 0x71aa0000 | 0x71aa8000 | 0x00008000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [WS2HELP.dll] (C:\WINDOWS\system32\WS2HELP.dll)
 0x774e0000 | 0x7761e000 | 0x0013e000 | False  | True    | False |  False   | True   | 5.1.2600.6010 [ole32.dll] (C:\WINDOWS\system32\ole32.dll)
 0x77f60000 | 0x77fd6000 | 0x00076000 | False  | True    | False |  False   | True   | 6.00.2900.5912 [SHLWAPI.dll] (C:\WINDOWS\system32\SHLWAPI.dll)
 0x7e410000 | 0x7e4a1000 | 0x00091000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [USER32.dll] (C:\WINDOWS\system32\USER32.dll)
 0x010e0000 | 0x010ef000 | 0x0000f000 | True   | True    | False |  False   | True   | 9.20.200.49 [MwxPS.dll] (C:\WINDOWS\system32\MwxPS.dll)
 0x71b20000 | 0x71b32000 | 0x00012000 | False  | True    | False |  False   | True   | 5.1.2600.5512 [MPR.dll] (C:\WINDOWS\system32\MPR.dll)


被列出的字段有

   Base
   Top
   Size
   Rebase
   SafeSEH
   ASLR
   NX
   OS dll ?
   Module version
   Module name
   Path

最后,搜索的结果将被列出来,(每行一个)。每行将包含一个指针,指针相关的信息,以及指针所属模块的信息。

如果可能 的话,在输出文件夹里有个相同名字的文件,先前的文件将被重命名为.old,如果假设不成立的话 就直接写。

Commands命令

在看个中繁杂的命令之前,记住大部分的命令都有默认的表现不管是在指针还是模块规则方面 这是很重要的。

我们将清楚的记载那些价值是什么。你可以无视那些通过使用一个或者多个上面列出的全局选项的默认。

a
“a"命令是”seh“的别名,在pvefindaddr中 这个命令用 add esp+8/ret指令初始化搜素。但在mona中所有的搜索都结合”seh"

如果你运行“a" 将以”seh"开始,执行一个全面的指针搜索,这些指针将带你回到下个seh,更多的信息请看下面的 “seh“。

assemble

”assemble"允许你将一条或者多条汇编指令转化为作业码。

法定的变量:

    -s <指令>

你也可以给定多条指令通过#将其分割开来

例如:获取pop eax ,inc ebx 和ret 的作业码:

assemble


输出:

Log data
Address    Message
0BADF00D   Opcode results :
0BADF00D   ----------------
0BADF00D    pop eax = \x58
0BADF00D    inc ebx = \x43
0BADF00D    ret = \xc3
0BADF00D    Full opcode : \x58\x43\xc3
0BADF00D   Action took 0:00:00.018000


bf

bf 命令允许你在所选择的模块中的导入函数和导出函数设置断点。

法定的参数:

    -t <type>: type 是 add 或者是 DEL

可选择的参数:
    -f <函数类型> : 设置是“导入”或者“导出” 去读取 IAT 或者 EAT。默认是:export (导出)
    -s<func,func,func> :指定你想设置(或者移除断点)的函数,你可以使用通配符 *func, *func*,func* .如果你想给所有的函数设置断点,用-s *

例如:设置给myapp.exe所有含有“mem"的导入函数设置断点:
!mona bf -t ADD -f import -s *mem* -m myapp.exe


bp

bp 命令允许你设置一个断点到给定的地址,如果这个地址被写或者被读取将触发断点。

法定的变量

    -a <address>
    -t <type > :这里的type不是READ就是WRITE

注: 当设置断点的时候地址应该存在,如果不存在,你将获得一个错误.
例如: 设置一个当程序从0012c431处读取时触发的断点。

!mona bp -a 0x0012C431 -t READ


bytearray



bytearray 这个选项被用于协助exploit开发者发现坏字符。它将产生一个从\x00到\xff 所有字节组成的数组,并将数组写入到2个文件中。

    一个文本文件包含ascii码形式的数组(bytearry.txt)
    一个二进制的文件包含同样数组(bytearry.bin)

可选择的变量:

    -b <bytes>: 阻止这些数组
    -r :倒序显示数组

我们相信在写exploit中发现坏字节是一个紧要的事情。最近的几周、几个月,很多朋友问我如何去执行这个工作,所以这里几步骤去发现坏字节:

让我们来看一下你的exploit的结构(典型的覆盖返回地址法) 像这样:

[ 280 bytes of junk ] [ EIP ] [ 500 bytes (shellcode) ]

我们应该试着将整个过程做的越可靠越流畅越好,所以我们必须确保我们不与payload必要的部分以及控制EIp的部分混杂。

我们保持前280字节和4字节(保存返回地址)不动。如果我们改变这些,前280字节包含坏字符的话,我们可能甚至再也不能控制EIP了,使得更难调试、发现坏的字符。

在重写保存的返回地址后,我们将有很多可用的字节。那将是很好的放置我们数组的地方。这将确保我们可以通过稳定的方式使程序崩溃,允许我们在EIP上设置断点,然后将内从中的数组字节与原始的数组字节比较。

在创建和使用字节数组前,你应给问自己"什么样的字节有可能中断payload 或者变更程序的表现”。如果,举个例子,因为字符串复制函数导致的缓冲区溢出触发,null字节很有可能导致payload 中断。 一组回车/换行(\0xa\0xd)是常见的字节,这个将改变程序读取和处理payload的方式。假如是一个字符串造成溢出,你可能发现那些是坏字节。

所以,让我们从数组中排除那三个字节。(当然,这些都是基于假设的,如果你想去确定下,不要从数组中排除任何的字节)

!mona bytearray -b '\x00\x0a\x0d'




打开 bytearry.txt 并且复制数组,打开你的exploit并且在重写的EIP后粘帖上数组(用数组取代那500字节)

然后,设置必要的断点,触发崩溃。你的断点将被碰到,并且 字节数组(或者数组的部分)应该在内存的某个地方。

发现坏字节的过程是很简单的。我们可以用mona的另一个特性去读取原始的字节数组从已经创建2进制文件中,并且将这些字节与崩溃时内存里的数组比较。

mona将读取2进制文件,从文件中取出8字节,找出所有内存中8字节的场合,然后将数组中的每一个字节与内存中的比较,列出哪些没有改变,哪些变化了/毁坏了。
!mona compare -f bytearray.bin


此时,在检查命令输出时,你应注意2个事情:
   
1. 找到EIP将要跳转去的位置(在这个例子里位于栈上)。如果你正在建立一个覆盖换回地址的exploit的话,你很有可能发现你的payload在ESP上,看看esp (payload是否位于那里)或者少许向下的位置。打开compare.txt,查找那个地址,你将会获得那些被毁坏的字节列表。由2字节导致的毁坏的表现:字节变化了(其他的都很好)或者所有的字节都不同了,总之,除非你知道你怎么去做,写下第一个改变的字节,并加到坏字节列表中。重复整个过程(创建bytearry 粘帖数组到exploit中,触发崩溃,比较)。所以,如果你发现\x5c是一个坏字符,再次运行以下bytearry命令

!mona bytearray -b '\x00\x0a\x0d\x5c'


重复整个过程,做另一个比较,如果致使数组在正确的位置被发现,没有修改,那么你已经确定了所有的坏字符,如果没有,仅仅去发现下一个坏字符,从数组中排除他,再次尝试。过程可能是很消耗时间的。可能有更好的办法去做到这样,不过这个技术工作的很好。

2. 查找另外一个你的数组被发现的位置。可能这些位置中有 没被破坏数组的副本。提供给你一个可选择的位置去放你的shellcode并不用担心会被坏字符破坏。你所要做的是写一些jumpcode或者 egghunter 去跳转到那个位置。

使用bytearry和建议的视频。

发现坏字节

视频在这里  http://www.youtube.com/watch?v=-D2QQYuneu8 (要翻墙的)

compare



我们在文档中先前的命令中已经讨论了“compare”的基本使用功能

法定的变量:

    -f <filename> :filename 指向包含字节的2进制文件,并且在内存中比较
你可能使用这个命令去发现坏字节(很容易)。你还可以使用它去看看是否你的shellcode在内存里遭到了破坏。

举个例子,你可能写了 tag+tag+shellcode(egghunter egg)到你的2进制文件,并且使用“compare"命令发现了eggs并且显示他们是否遭到了破坏。如果有的变了,有的没破坏,你竟知道是否如何去微调hunter的开始位置,或者仅仅使用校验历程。

The compare routine will also try to find unicode versions of the binary file There’s no need to write the shellcode in unicode expanded format into the binary.

config

我们已经在文档的开头讨论了配置命令的所有特征。

dump 存储

这个dump命令允许你从内存中存储一块

强制的参数:

    -s <address>: 开始地址
    -f <filename>: 字节将要写入的文件名称

可选择的参数:
    -n :写入或者读取文件字节的大小
    -e : 结束地址

结束地址和缓冲区的大小其中之一必须指定。

例如: 将从 0012F100到0012F200的字节写入到 c:\tmp\test.bin文件中。

!mona dump -s 0x0012F100 -e 0x0012F200 -f "c:\tmp\test.bin"


egg

这个命令将创建一个egghunter的常规。

可选的参数

    -t : 标签,默认值是w00t.
    -c: 启用校验和的常规。仅仅和参数 -f 一起工作。
    -f <filename>: 包含shellcode的文件
    -depmethod < method>: method可以是 ”Virtualprotect","copy" or "copy_size".
    -depreg <reg> : 设置那个包含一个指向可以绕过DEP的API函数指针的寄存器。默认的情况下是ESI
    -depsize <value> : 设置绕过DEP常规的大小。
    -depdest <reg> : 这个寄存器指向egghunter自己的位置。当绕过DEP后,egghunter 早已经被标注为可执行了。所以当使用 copy 或者 copy_size 方法时,egghunter中的 DEP bypass将做一次自我复制。为了能够这样做,这需要一个寄存器作为复制shellcode目的地。如果,将这个留作空白的话,代码将包含一个GetPc(这个在下面讲到)的常规。

如果你不指定包含shellcode的文件的话,它将简单的生成一个正规的egghunter常规。如果指定了一个文件,你将能够使用选项 -c ,将会将shellcode的校验和常规放入到文件中。校验和常规仅仅工作于那些挑剔的shellcode(或者任何其他有相同大小的shellcode将生成相同的校验和值)

使用各种-dep* 参数,你可以告诉egghunter常规创建一个基于found egg 可绕过DEP的代码,在运行它前。你可以在这里获取到更多关于这项技术的信息  https://www.corelan.be/index.php/2011/05/12/hack-notes-ropping-eggs-for-breakfast/

filecompare 文件对比

这个filecompare命令允许你去和另一个系统上同一条mona命令生成的输出,查找匹配的指向相同结构的指针,举个例子:如果你正在找那些跨操作系统指针,这些命令你可能需要。

强制的参数:

    -f "file1,file2": 给定所有要比较的文件,用逗号隔开。列表中的第一个文件将作为参考。

供选择的参数

    -contains "blah" :仅仅考录那些包含某些字符串的行。
    -nostrict: 将列出指针,尽管与指针相关的结构有所不同。

“seh_xpsp3.txt "在xp SP3上创建的,”seh_win2k3.txt“是在windows2003的服务器上创建的,这条命令将证明存在着两个文件中的指针:

!mona filecompare -f "c:\temp\seh_xpsp3.txt,c:\temp\seh_win2k3.txt"


filecompare命令将产生2个文件:

     filecompare.txt (包含所有文件中存在的指针)
    fielcompare_not.txt (包含所有文件不存在的指针)

注: 更多(更大的文件),这个过程将会花费更长的时间(嵌套的迭代)

find

find指令对于最初在pvefindaddr中的实现来说有了很大的改善。它变得更快了,更重要的是灵活,他还有一个闪亮的新 ”递归“搜索特性。

强制的参数:

    -s <search>: 查询一个字符串,一系列的字节,一个结构,或者一个包含有多行以指针开头的文件名(与 -type <file>一起用)。

可选择的参数:

    -type <type> :设置搜索方式的类型。type可以是asc , bin ,ptr ,instr ,file .
    -b <address > : 搜索范围的底部。
    -t <address> :搜索范围的顶部。
    -c :跳过连贯的指针,取而代之地,尝试获取总字符串的长度。
    -p2p:  在你的搜索模式中发现指针的指针(这个设置相当与设置 -level 1)
    -r <number>: 与p2p一起使用;允许你发现最近的指针的指针,数字指示结果中最近的字节可以高于真实位置的数量。
    -level <number> : 通过递归的查找(指针的指针)。如果你设置级别为1,在查找模式中它将查找指针的指针,如果你将级别设置更高的值,将会演示更深入的查询(指针的指针的指针....)。毋庸置疑这是find最有效的特点。
    -offset <value> :  这个值将被减去指针给定的级别数(看下offsetlevel ), 与 -level and -offsetlevel 一起使用
    -offsetlevel <value> :this is the level where the value will be subtracted from the pointer to search

通常情况下,find将查找所有的位置(访问级别设置为 *) .此外 通常它将搜索整个内存空间(包括被排除在外的模块的内存空间)

例如: 查找所有能发现w00t字符串的位置。

!mona find -type asc -s "w00t"


例如:查找所有可执行的指向 ”jmp ecx"的位置。

!mona find -type instr -s "jmp ecx" -p2p -x X


例如:查找所有指向文件 c:\temp\seh.txt 指针的位置 。

!mona find -type file -s "c:\temp\seh.txt" -p2p -x *


例如:让我们假设你控制了ECX,并且你的payload在 ESP+4的位置

这些代码,给你去控制EIP。

    mov eax,dword ptr ds:[ecx]
    call [eax+58]

主意是返回到位于ESP+4位置的payload 去开开始一个rop链。

思考一下,我们需要什么指针去放到ecx中呢?

回到: 我们需要一个指针指向另一个指针(2),指针(2)-0x58的位置指向 ADD ESP,4 /RET .

如果你有时间的话,你一定会手工的发现一条的。

为了去教 mona 去发现所有的指针,你需要2条指令:

    One to find all stackpivots of 4
    One to find the ptr to ptr-0x58 to ptr to one of the stackpivots

解决方案:

# first, get all stackpivots, save output to c:\logs\stackpivot.txt
#首先 获取所有的栈中心 将输出存到  c:\logs\stackpivot.txt
!mona config -set workingfolder c:\logs
!mona stackpivot -distance 4,4

# read the file and find ptr to ptr-58 to each of the pointers
#读取文件,
!mona find -type file -s "c:\logs\stackpivot.txt" -x *
      -offset 88 -level 2 -offsetlevel 2


所以基本上,我们需要应用offset 级别到2 ,(在这种情况下就是 查找 ptr to ptr to ptr ",因为我们已经读取了指向stackpivot中结构的的指针。)

在我们在那个级别上去查找指针的指针之前,首先offset要从大的指针中减去。

示意:为了调试该程序,你将必须在读取[ecx]上设置断点,假定你在ecx中放置7a10b473 ,在触发BUG之前,先设置一个读取那个位置的断点:

!mona bp -t READ -a 0x7a10b473


findmsp

findmsp指令将发现内存、寄存器(等)中的所有实例或者某些循环模式的引用。

这个命令还有一个很重要必要条件:你必须在你的目标程序中使用循环模式去触发崩溃。

在崩溃的时候,简单的运行findmsp  你将得到以下信息:

    可以被发现的循环模式的位置 和 循环模式的长度。
    被循环模式的4字节重写寄存器 和 重写寄存器数据在模式中的偏移
    被循环模式中4字节重写的SEH记录 以及偏移 和大小
    当前线程栈中的指针, 在循环模式里(偏移+大小)
    在栈中循环模式的部分,从循环模式开始的偏移以及模式的大小

就所有的情况说: findmsp 将查找普通的模式,大写字母的,小写字母的以及UNICODE版本的循环模式。

可选择的参数:
    -distance <value> :这个value 从设置从ESP算起到查找循环模式指针的距离或者是到部分循环模式的距离(可+可-)。如果你不指定距离,findmsp将搜索整个栈(这可能将等一小会)

就模式怎么用而言其他的可选择参数:去看 pattern_create 吧

findwild

findwild命令将允许你使用通配符在内存中查找。它将使用以下法定的参数:

    -s <指令链>

可选择的参数:
   
    -depth <nr> : 向前搜索的数量。默认是8,这个值表明整个指令链的长度。
    -b <address> : 搜索的基地址
    -t <address> : 搜索的上限
    -all :表明你也想返回那些包含可能坏指令的指令链(其中一个可能被损坏了)

指令要用#分开。 你用*表明你允许任何的指令。你可以用 r32 表明你想运行任意的寄存器。

例如: 搜索 push (任意一个寄存器) ,然后 pop eax 接着 inc eax 最后 retn

!mona findwild -s "push r32#*#pop eax#inc eax#*#retn"


当然,你可以用全局选项来微调/限制查询。

输出信息将写入到 findwild.txt中。

getpc

#####################
GetPC,也即Get Program Counter,取得程序计数器的值,在x86下就是GetEIP了,其作用是在进程的内存空间中得到当前的EIP的值,通常用于需要对代码自身进行操作的场合下,比如自解码和自修改代码(更一般的来说常见于病毒、溢出攻击代码等,也称之为代码重定位技术)。因为在x86下无法直接操作EIP寄存器,所以需要一些特殊的方法来获取EIP寄存器的值。
###################### 这段是我从http://www.programlife.net/shellcode-getpc.html 拷贝的一段,为了大家更好的理解 GetPC  译者 AN94

GetPc将输出3种不同的GetPC历程(将获取到的EIP值放寄存器) 。这方便你去写自己定制的shellcode。

法定的参数:

    -r <reg> : reg是一个有效的寄存器

例如:


getiat

################
iat(import address table,导入函数地址表,在这里说明一下:导入表是image import table,导入函数地
址表是 image import address table,这是两个不同的pe文件中的表)
##################

getiat命令允许你将所选择的模块的IAT存储下来。

可选的参数:
    -s <keyword,keyword> :仅仅显示整个IAT中包含其中一个关键字的。你也可以用通配符 *keyword *keyword* keyword* 等 让输出更特殊

header

header命令将读取文件,并将输出内容可能作为exploit(做为一个好头)

法定参数:

    -f <filename>:读取的文件名

例如: 将定你正在创建一个文件格式exploit ,一个文件头像这样(在16进制编辑器里):



!mona header -f c:\temp\song.s3m


header命令将返回这样:



(主:这是ruby格式的输出)

heap


heap命令允许你去存储块表列表(lookaside list) 和 整个快表(freelists )在xp上。不用参数的话将显示进程中所有可用的堆。

可选择的参数:

    -a <address>: 堆的起始地址。如果忽略了这个参数,将显示所有堆的信息。
    -t <type> : 这个type可以是 lal (lookaside lists)、 freelist 或者 all (l两者)

help

help命令提供给你更多有关给定命令的信息。

法定的参数:

    <command> :命令的名字

例如:假定你想去获得关于findmsp命令的更多信息。

!mona help findmsp


info

这个命令将显示更多关于给定指针的信息

法定参数:

   -a <address>

输出将包含这些:

   指针的信息
   指针所属的模块信息(或者表明它是否是栈指针)
   在那个地址的指令
   指针所属的内存页的访问级别

j

这个命令仅是 jmp 命令的别名,J作为pvefindaddr中的一部分,之所以要保留它是为了做到向后兼容。

jmp

这个指令将搜索那些将引导去执行位于给定寄存器所指定位置代码的指针。

法定的参数:

     -r <reg> :reg 是有效的寄存器

默认的模块标准: 跳过aslr 和变基的模块。默认搜索系统模块。但是你可以用全局选项 -cm os=false来否决这个行为。

命令将搜索指向如下指令的指针。

jmp reg
call reg
push reg + ret (+ offsets)
push reg + pop r32 + jmp r32
push reg + pop r32 + call r32
push reg + pop r32 + push r32 + ret (+ offset)
xchg reg,r32 + jmp r32
xchg reg,r32 + call r32
xchg reg,r32 + push r32 + ret (+ offset)
xchg r32,reg + jmp r32
xchg r32,reg + call r32
xchg r32,reg + push r32 + ret (+ offset)
mov r32,reg + jmp r32
mov r32,reg + call r32
mov r32,reg + push r32 + ret (+offset)
   

jop

这个命令将查找可用于JOP(Jump Oriented Programming)payload的小部件。当前的这个装置可能很基础的,随后的几周或者几个月更多的工作将在这个领域去做。

搜索小部件的代码将以以下指令结束:

jmp r32
jmp [esp]
jmp [esp+offset]
jmp [r32]
jmp [r32+offset]

输出结构将写入到 jop.txt中。

jseh

这个命令是“SEH”在在pvefindaddr一个别名,这个命令将在加载模块以为的内存中搜索绕过safeseh的指针。mona用 seh命令也可以做到这些。

modules

modules命令显示关于载入的模块的信息。在没有参数的情况下,将显示所有模块的信息,(但是你可以用全局的指令来过滤这些模块)

noaslr

这个命令是对 "modules"命令的包装。通过启用全局选项 -cm aslr =false , 它将显示所有没有启用 aslr的模块.

nosafeseh

这个命令是对 "modules"命令的包装。通过启用全局选项 -cm safeseh=false , 它将显示所有没有启用 safeseh的模块.

nosafesehaslr

这个命令是对 "modules"命令的包装。通过启用全局选项 -cm safeseh=false,aslr=false , 它将显示所有没有启用 safeseh和 aslr的模块.

offset

这个命令将显示2个地址间的距离, 它将以16进制的的数据显示,可以被用做向前或者向后的跳转。

法定的参数:

    -a1: 开始的地址或者寄存器
    -a2: 结束的地址或这寄存器

p

这个命令是seh的别名。 默认情况下,p命令将在没有safeseh和不变址的模块中查询。

p1

这个命令是seh的别名。 默认情况下,p命令将在没有safeseh、没还有aslr 和 不变址的模块中查询。

p2

这个命令是seh的别名。 默认情况下,p2命令将在所有被加载模块中查询。

pattern_create

这个命令将创建一个给定大小的循环的模型(又名 metasploit模型) 并将它写入到pattern.txt中

法定的参数:

    <number>: 这个数字就是想得到的模型长度

例如:你想生成5000字节的样式,

!mona pattern_create 5000


默认情况下,模型将使用以下三种字符集被创建。
   
    1 大写字母
    2 小写字母
    3 数字

你可以使用以下可选择的参数来改变默认的表现:

    extended :你可以添加额外的字符集到 第三种中(数字)
    c1 <string > :设置你自己的字符取代第一种字符集
    c2 <string> :设置你自己的字符取代第二种字符集
    c3 <string> :设置你自己的字符取代第三种字符集

如果你想使用定制的模型字符集,不要忘记想关的命令使用同一个字符集选项(pattern_offset, findmsp, suggest)。

pattern_offset

这个命令将在循环模型中找出给出的4字节 并且返回这4字节在模型中的位置(偏移)

法定的参数:

    <search> :search 是要查找的4字节。 你可以指定4字节作为一个字符串 、字节、或者指针。

pattern_offset  将在正常模式、大写模式、小写模式中查找4字节,并将尝试发现反转的查询字节在那些模式中。(以防你把参数弄翻了)

工选择的参数: 看看 pattern_create 吧

pc

pattern_create的别名。

po

pattern_offset 的别名。

rop

rop命令将使你在构建基于ROP的exploits时生活变得更容易。它将做多个事情:

    查找rop 部件 (rop.txt)
    归类rop部件,并建立一个建议的部件列表(rop_suggestions.txt)
    找到 stackpivots (rop_stackpivots,txt)
    尝试生成4个完整的rop链,(基于VirtualProtect 、VirtualAlloc, NtSetInformationProcess and SetProcessDEPPolicy)(输出将写入到rop_chains)(是的! ROP将是自动的)

默认情况下,它将在没有aslr、 没有变址、非系统模块中查找ROP小部件。再次说明,你可以使用一个或者多个全局选项来 微调/否定 这些标准。

可选的参数:

    -offset <value> :  设置RETN指令的最大偏移,(在小部件的最后) 默认40
    -distance <value> :设置 stack pivots最小的值/距离。 如果你想设置值的最大值和最小值 用 -distance min,max(一般用2个值,用逗号分开)
    -depth :设置从末尾指令回顾的最大指令数。默认6
    -split:不去将所有的小部件都存到一个rop.txt文件中,而是通过模块划分部件。
    -fast :跳过不感兴趣的部件,这可能加快过程,但是也可能使你错过非常重要的部件。
    -end <instruction> :指定一个定制的指令结尾。默认的情况下,以RETN指令结束。
    -f "file1,file2,file3"  取代内存查找,而从一个或多个rop.txt文件中读取小部件。如果你想使用更多的文件,你可以用逗号将他们隔开。建议使用这个选项去用调试器去附加应用程序。以至 mona可以找到建立ROP链所需的所有信息。
    -rva: 不用这个参数的话,rop链将使用绝对地址(监管资源模块是变址的,启用aslr的)。启用这个选项,所有的地址将等于  模块基础地址 + rva

例如: 生成rop部件,并自动尝试使用4个特地的模块去产生ROP链 并列出 距离在 800到1200字节 中的 stackpivots

!mona rop -m "libglib,libatk,libgdk-win32,libgtk-win32" -distance 800,1200


结果:


注意:再次强调下,输出是ruby的(它和metasploit是非常有亲和力的)

基于多个模块的查询,rop的历程可能很快或者很慢。 你给mona更准确的指令 ,结果就会更快更准确。

作为一个例子,可以看看这个文章 https://www.corelan.be/index.php/2011/07/03/universal-depaslr-bypass-with-msvcr71-dll-and-mona-py/

我使用mona生成了一条只用1个模块的rop链只用了17秒。模块是不完整的,所以我必须找到3个多的小部件,这些部件都是可以从rop_suggestions.txt and rop.txt找到的 。为了找到他们我花费了几分钟,修复了链 并有了一个普通/通用的绕过 DEP/ASLR 的rop链。

另一个例子证明建立一条通用rop链的可能性。类似,msvcr71.dll ,mona产生了链的大部分。我们必须简单的去修复一个问题(获得一个想要的值放在EDX中),但是使用rop_suggestions.txt文件仅仅用了几秒钟。

用mfc71u.dll 创建的通用的rop链:
# MFC71U.DLL generic ROP Chain
# Module: [MFC71U.DLL]
# ASLR: False, Rebase: False, SafeSEH: True, OS: False,
# v7.10.3077.0 (C:\Program Files\CyberLink\PowerProducer\MFC71U.DLL)
# mona.py
rop_gadgets =
	[
	0x7c259e0c,	# POP ECX # RETN (MFC71U.DLL)
	0x7c2512f0,	# <- *&VirtualProtect()
	0x7c2fe7bc,	# MOV EAX,DWORD PTR DS:[ECX] # RETN (MFC71U.DLL)
	0x7c26f014,	# XCHG EAX,ESI # RETN (MFC71U.DLL)
	0x7c2c0809,	# POP EBP # RETN (MFC71U.DLL)
	0x7c289989,	# ptr to 'jmp esp' (from MFC71U.DLL)
	0x7c259e0c,	# POP ECX # RETN (MFC71U.DLL)
	0x7c32b001,	# RW pointer (lpOldProtect) (-> ecx)
	0x7c2de810,	# POP EDI # RETN (MFC71U.DLL)
	0x7c2de811,	# ROP NOP (-> edi)
	0x7c284862,	# POP EAX # RETN (MFC71U.DLL)
	0xffffffc0,	# value to negate, target 0x00000040, -> reg : edx, via ebx
	0x7c252ea0,	# NEG EAX # RETN (MFC71U.DLL)
	0x7c316b89,	# XCHG EAX,EBX # RETN (MFC71U.DLL)
	0x7c288c52,	# XOR EDX,EDX # RETN (MFC71U.DLL)
	0x7c265297,	# ADD EDX,EBX # POP EBX # RETN 10 (MFC71U.DLL)
	0x41414141,	# EBX
	0x7c284862,	# POP EAX # RETN (MFC71U.DLL)
	0x41414141,
	0x41414141,
	0x41414141,
	0x41414141, 	# compensate for RETN 10
	0xfffffdff,	# value to negate, target 0x00000201, target reg : ebx
	0x7c252ea0,	# NEG EAX # RETN (MFC71U.DLL)
	0x7c316b89,	# XCHG EAX,EBX # RETN (MFC71U.DLL) (dwSize)
	0x7c284862,	# POP EAX # RETN (MFC71U.DLL)
	0x90909090,	# NOPS (-> eax)
	0x7c2838ef,	# PUSHAD # RETN (MFC71U.DLL)
	].pack("V*")


如果你用生成了一个通用的(可以绕过DEP和ASLR并能工作在所有的情况下)链。请发给我(peter.ve@corelan.be) .如果链符合所有的条件,我将把它放在这里 CorelanROPdb https://www.corelan.be/index.php/security/corelan-ropdb/)

我在巴黎的AthCon and Hack In大会上用!mona rop生成的一个小样本!

视频  http://www.youtube.com/watch?v=0rRLcFd6_Jk

ropfunc

在绕过DEP方面而言,ropfunc 将尝试去找出感兴趣方法的指针。输出将写入ropfunc.txt中。

它将查找这些:

virtualprotect
virtualalloc
heapalloc
winexec
setprocessdeppolicy
heapcreate
setinformationprocess
writeprocessmemory
memcpy
memmove
strncpy
createmutex
getlasterror
strcpy
loadlibrary
freelibrary
getmodulehandle

seh

这条指令将寻找指向历程的指针,这个历程将导致在SEHowverwrite exploit中的代码执行。默认,它将尝试排除那些在变址、aslr以及有safeseh保护的模块中的指针来绕过SafeSEH。如果给定 -all 参数,它也会搜索模块以外内存的指针。输出写入到seh.txt中

命令将搜索以下指令部件:
pop r32 / pop r32 / ret (+ offset)
pop r32 / add esp+4 / ret (+ offset)
add esp+4 / pop r32 / ret (+offset)
add esp+8 / ret (+offset)
call dword [ebp+ or -offset]
jmp dword [ebp+ or -offset]
popad / push ebp / ret (+ offset)

如果你不能找到可工作的指针,你还可以用 stackpivot 命令  -distance 8,8

stackpivot

在给定一个距离当前ESP的偏移情况下,这条命令将查找将导致旋转回栈中的小部件。通常情况下呢,他只在没有 aslr 、不变址 、非系统的模块中查找旋转(pivots) 并且组合safeseh 、没有safeseh保护的模块一起。

工选择的参数:

    -offset <value> : 定义一个RET指令的最大偏移 (整数,默认40)
    -distance <value> : 定义一个stackpivots 最小的距离(整数,默认8) 如果你想指定一个最小和最大的距离,将值设置如 最小,最大。
    -depth <value> :定义一个在每个小部件中的指令最大值(不是结尾指令)(整数,默认6)

输出将写入到  rop_stackpivot.txt 中。

小建议: 如果你正在寻找一种利用重写SEH 返回到你payload中的方法。你也可以查找 pop r32/pop r32/pop esp/ret, 这将带你返回到 nseh中(但是要将在nseh中的4字节视为指针,而不是指令) 用12的距离去寻找stackpivots 将能够发现候选者,在nseh中,你可以简单的在SEH中放置一个指向ADD ESP,4 + RETN  命令的指针来跳过指针。并在SHE记录后开始防止rop链。

stacks

这条命令将列出应用程序中每一个线程的栈信息,(base ,top,size 线程ID)

suggest

这条指令将自动的运行 findmsp (所以你必须用一个循环模式去触发崩溃),然后带着那些信息去建议一个exploit 骨架。

pvefindaddr 已经建议了一个基于那些信息的payload的布局了,mona将做些更进一步的事情。事实上,它将尝试创建一个成熟的Metasploit 模块,包含所需的所有的指针和exploit布局。

如果findmsp(作为suggest的一部分自动运行)发现你控制了EIP和重写了SEH记录,它将会尝试去创建一个Metasploit的模块。

首先,它将会让你去选择 exploit的类型, 你可以选择:

fileformat
network client (tcp)
network client (udp)

##########文件类型 、tcp 、udp

(简单的选择一个相关的,以后你也可以显然地改变它)

如果你选择了文件格式,它将提示你文件的类型。 如果你选择 "network client"类型,它将会要求你提供一个端口号。

接下来,mona将询问你是否有一个exploit-db的顾问链接。 如果你正在移植一个来自exploit-db的exploit ,你可以简单的将整个URL(或者是exploit-db的ID)给顾问,并且mona将尝试这去提取exploit的名字以及原作者从explot-db的头中。

如果你没有一个能连接到exploit-db的连接条目的话,仅要留空 “exploit-db"这条就行了。

最后 mona将会基于用findmsp命令获取的或者你提供的信息建立一个metasploit的文件(exploit.rb).

然而结果的模块可能不能正常工作(你可能必须去添加一个头,处理修复一些事), 它将尝试建立/建议一些有用的事情)

模型方面的可用变量去  pattern_create 中找找。

视频 http://www.youtube.com/watch?v=k6C7kWBe0Vs

skeleton 框架

这个命令允许你根据给定的格式((fileformat, tcp or udp client))创建一个空的metasploit的框架,并使用循环模式作为payload.如果你尝试从头建立一个exploit,这可以是一个好的开始。 输出将写入到 msfskeleton.rb中。

可选择的参数:

    -c <number> :循环模式的长度,默认5000

Metasploit

你可能已经注意到: mona rop 和mona suggest的输出与metasploit多么的友善呀(至少可以这么说)。事实上,欣赏这种把所有艰难工作都投入到 框架中,这只是其中一个corelan团队喜欢metasploit的原因。我们相信写Metasploit模块将会使你写更好、更稳定的exploit 。弄清楚坏字符,决定好可用的payload的大小,为你的exploit 铺设好最理想的结构。对于Metasploit模块来说,创建可跨系统、绕过DEP/ASLR等的稳定的exploit 仅仅是个要求。要弄清楚:这需要更多的贡献和,在某些情况下比写一个因为你的走远,使用硬编码payload、而正常工作的脚本更多的技巧。

无路如何,如果在你的exploit开发经历中,mona.py可以辅助你,那么我们达到了我们的目的。这不是一个完美的工具。这需要你和你的技巧命令它 ,使它返回你所查找的。

记住: 不要忘记提交你的exploit模块到Metasploit(msfdev@metasploit.com)

Discovered a bug, suggest new features / want to contribute ?  发现BUG , 建议新的特性/ 想去投稿

到这个 https://redmine.corelan.be/ 站点,注册一个新用户。 当你的账户被许可了,你就可以创建一个BUG报告了/或者特性需求。

导航到https://redmine.corelan.be/projects/mona/issues/new 这里创建一个关于 BUG 或者 特性的追踪。保证要用一个意味深长的话题和冗长详细的描述。

你可以看到所有开放的标签 在这里 https://redmine.corelan.be/projects/mona/issues/

Want to learn how to write exploits ? 想去学习如何写exploit吗

看下corelan 团队的 exploit写作教程吧:

https://www.corelan.be/index.php/category/security/exploit-writing-tutorials/ (
开始的在列表的底部)

最为一个选择,如果你新欢培训课,你可以查看我们的Corelan现场win32 Exploite训练营。https://www.corelan-training.com/index.php/training/corelan-live/

Need help ?

如果你有问题,你可以在论坛发布他们  https://www.corelan.be/index.php/forum/writing-exploits/

如果你喜欢直接和corelan的会员谈话,或者和社区的其他人。连接到 IRC (irc.freenode.net)   注册一个帐号,加入#corelan频道。

Mona.py on the web

如果你想分享你关于mona.py的经验,发布文章或者文档演示使用mona的新特性。让我们知道,我们很高兴链接到你的网站。

如果你喜欢mona ,请将它告诉世界,如果你不喜欢mona请让我们知道。

谢谢 。

--------------------------------------------end up 剧终-----------------------------------

2015/2/28 晚

by - AN94(译者)

个人观点:

mona确实是个很不错的exploit开发工具。 我打算把mona相关的帖子写成一个系列。随后,发布一些关于mona实战的文章,让更多的朋友了解和使用mona....

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (5)
雪    币: 69
活跃值: (270)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf
2
未完待续 今天继续翻译
2015-2-27 08:36
0
雪    币: 69
活跃值: (270)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf
3
翻译真慢呀!  不过印象深刻
2015-2-27 13:08
0
雪    币: 69
活跃值: (270)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf
4
mona手册 汉化完毕。。。。 有歧义的地方 参考原文呀
2015-2-28 23:24
0
雪    币: 69
活跃值: (270)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf
5
mona摸哪,好工具大家齐分享
2015-3-9 09:27
0
雪    币: 69
活跃值: (270)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
msf
6
mona很不错的呀
2015-3-23 22:43
0
游客
登录 | 注册 方可回帖
返回
//