12

Exploit开发系列教程-Mona 2& SEH | WooYun知识库

 6 years ago
source link:
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Exploit开发系列教程-Mona 2& SEH

0x00 Mona 2 前言 & 准备


Mona 2是一种非常有用的插件,它由Corelan Team开发。起初是为Immunity Debugger写的,现在它适用于WinDbg调试器。

你将需要为WinDbg x86 和 WinDbg x64安装一些工具:

安装Python 2.7 (从这里可下载到) 。

x86 和 x64版本的工具分别安装在不同的目录里,如c:\python27(32) 和c:\python27。

这里下载正确的zip包(请下载pykd-0.2.0.29-python-2.7.zip这个压缩包),接着提取并运行vcredist_x86.exe 和 vcredist_x64.exe。

从这里下载两个exe程序(x86版和x64版),接着执行它们。

从这里下载windbglib.py和mona.py,并将它们放置到WinDbg.exe所在的目录中。

enter image description here

配置符号搜索路径如下:

通过 File→Symbol File Path

输入

SRV*C:\windbgsymbols*http://msdl.microsoft.com/download/symbols

3.保存工作区(File→Save Workspace).

在WinDbg下运行mona.py

用WinDbg运行mona.py的范例:

1.使用如下命令加载pykd插件

.load pykd.pyd

2.运行mona使用命令如下:

!py mona

enter image description here

更新mona 输入如下:

!py mona update

enter image description here

0x01 配置


工作目录

在mona的工作目录里,mona的多数函数将数据转储到已创建的文件中。我们可以具体指定某个工作目录,这取决于使用的格式说明符%p (process name) 和 %i (process id)指定的进程名和id。

例如,输入:

workingfolder "C:\mona_files\%p_%i"

排除模块

你可以用如下操作排除指定模块:

!mona config -set excluded_modules "module1.dll,module2.dll"
!mona config -add excluded_modules "module3.dll,module4.dll"

作者

你也可以设定作者:

!mona config -set author Kiuhnm

当产生与metasploit兼容的输出内容时可以使用该信息。

重点

如果WinDbg和mona都没有出错,那么请试试以管理员身份运行WinDbg。

0x02 Mona的手册


你可以在这里找到更多关于Mona的信息。

范例

该范例引用自Mona的手册. 现在来说明如下代码中我们控制的ECX的值:

MOV   EAX, [ECX]
CALL   [EAX+58h]

我们想要使用那段代码以jmp到我们的shellcode(即我们注入到进程中的代码),它的地址位于ESP+4,因此我们需要调用如上调用的一些指令,如“ADD ESP, 4 | RET“。上面的代码有许多间接的操作:

(ECX = p1) → p2
p2+58h → p3 → “ADD ESP,4 | RET”

首先我们需要找到p3:

!py mona config -set workingfolder c:\logs
!py mona stackpivot -distance 4,4

如上使用的命令可以让你在stackpivots内的指定偏移范围在mix~max之间找到等价于ADD ESP, X | RET代码的指针,通过选项-distance min,max来指定偏移范围。

已发现指针/地址会被写入到c:\logs\stackpivot.txt

现在我们已经有我们的p3指针(许多p3指针!)了,我们还需找到p1:

!py mona find -type file -s "c:\logs\stackpivot.txt" -x * -offset 58 -level 2 -offsetlevel 2

下面来了解那些选项的含义:

使用“-x *”选项意味着你要 “accept addresses in pages with any access level” (正如另一个范例所示, 用 “-x X”选项说明我们仅在可执行页中定位).

“-level 2”具体指定要间接操作的指令层级,它告知mona找出“a pointer (p1) to a pointer (p2)to a pointer (p3)”。 前两个选项 (-type 和 -s)指定ps必须是指针,它被列出在文件“c:\logs\stackpivot.txt“里。

使用“-offsetlevel 2” 和 “-offset 58”选项告知mona用偏移58h来进行增值操作时,第二个指针(p2)必须指向第三个指针(p3)。

如果这个范例并不能让你对其内容有较好的理解,请你不要担心。这个范例仅向你展示了WinDbg中利用Mona插件可以实现的一些功能。当然,我也承认这个命令的语法不是非常易懂。

范例

使用findwild命令可以让你找到带有特殊形式的指令链。 细想如下范例:

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

选项”-s”指定链的形态:

用 ‘#‘将指令分隔开

r32 为任意32位寄存器

  • 为任意指令序列

可选参数为:

  • -depth <nr>: maximum length of the chain
  • -b <address>: base address for the search
  • -t <address>: top address for the search
  • -all: returns also chains which contain “bad” instructions, i.e. instructions that might break the chain (jumps, calls, etc…)

ROP链

Mona可以找到ROP gadgets并利用它们构造ROP链,但是我将不在这部分讲解这方面的相关内容,因为这里我假设你并不知道ROP链的含义及关于ROP的概念。正如我曾说过的,如果这篇文章讲述的内容让你难以理解,那么请不要担心。尽管学习该系列的下一部分文章吧。

0x03 结构化异常处理(SEH)


异常处理器以一种单链表的形式存在,它和每个线程有关。一般说来,链表的节点被分配在栈上。某一位于TEB (Thread Environment Block)的起始位置的指针指向链表头,因此当代码想要添加一个新的异常处理器时,某一新节点会被添加到链表头并且在TEB里的指针所指向的位置会被改变,进而指向新节点。

每个节点固有_EXCEPTION_REGISTRATION_RECORD类型并且会存储处理器的地址及链表下个节点的一个指针。奇怪的是,链表上一节点的“next pointer”不是null但是它等价于0xffffffff。

确切的定义如下:

0:000> dt _EXCEPTION_REGISTRATION_RECORD
ntdll!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : Ptr32 _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : Ptr32     _EXCEPTION_DISPOSITION

TEB可被段选择子fs访问(始于 fs:[0]), 因此通常可看到代码如下:

mov    eax, dword ptr fs:[00000000h]      ; retrieve the head
push   eax                                ; save the old head
lea    eax, [ebp-10h]
mov    dword ptr fs:[00000000h], eax      ; set the new head
.
.
.
mov    ecx, dword ptr [ebp-10h]           ; get the old head (NEXT field of the current head)
mov    dword ptr fs:[00000000h], ecx      ; restore the old head

编译器通常会注册单个全局句柄,它能意识到被程序执行过的区域(这依赖于某一全局变量)并且当它被调用时会有根据地作出行为。

因为每个线程都有一个不同的TEB,因此操作系统会确保段被fs选择,fs总会引用准确的TEB(即当前线程之一)。 通过读取与TEB的Self区域相符的 fs:[18h]得到TEB的地址。

列出TEB的信息如下:

0:000> !teb
TEB at 7efdd000
    ExceptionList:        003ef804          -----------------------
    StackBase:            003f0000
    StackLimit:           003ed000
    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 7efdd000
    EnvironmentPointer:   00000000
    ClientId:             00001644 . 00000914
    RpcHandle:            00000000
    Tls Storage:          7efdd02c
    PEB Address:          7efde000
    LastErrorValue:       2
    LastStatusValue:      c0000034
    Count Owned Locks:    0
    HardErrorMode:        0

现在我们可以证实fs引用TEB:

0:000> dg fs
                                  P Si Gr Pr Lo
Sel    Base     Limit     Type    l ze an es ng Flags
---- -------- -------- ---------- - -- -- -- -- --------
0053 7efdd000 00000fff Data RW Ac 3 Bg By P  Nl 000004f3

正如我们在之前讲述过的, fs:18h含有TEB的地址:

0:000> ? poi(fs:[18])
Evaluate expression: 2130563072 = 7efdd000

记住:poi会对某一指针进行解引用操作并且使用‘?’来对某一表达式进行求值操作。 我们看看ExceptionList 指向的结构体名:

0:000> dt nt!_NT_TIB ExceptionList
ntdll!_NT_TIB
   +0x000 ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD

正如我们已经说过的那样,这意味着每个节点会是_EXCEPTION_REGISTRATION_RECORD的某一实例。使用!slist命令展示出整个链表的信息:

0:000> !slist $teb _EXCEPTION_REGISTRATION_RECORD
SLIST HEADER:
   +0x000 Alignment          : 3f0000003ef804
   +0x000 Next               : 3ef804
   +0x004 Depth              : 0
   +0x006 Sequence           : 3f

SLIST CONTENTS:
003ef804
   +0x000 Next             : 0x003ef850 _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x6d5da0d5     _EXCEPTION_DISPOSITION  MSVCR120!_except_handler4+0
003ef850
   +0x000 Next             : 0x003ef89c _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x00271709     _EXCEPTION_DISPOSITION  +0
003ef89c
   +0x000 Next             : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x77e21985     _EXCEPTION_DISPOSITION  ntdll!_except_handler4+0
ffffffff
   +0x000 Next             : ???? 
   +0x004 Handler          : ???? 
Can't read memory at ffffffff, error 0

记住$teb表示的是TEB的地址.

以下使用了一种更简洁的方法来展示异常处理链的信息:

0:000> !exchain
003ef804: MSVCR120!_except_handler4+0 (6d5da0d5)
  CRT scope  0, func:   MSVCR120!doexit+116 (6d613b3b)
003ef850: exploitme3+1709 (00271709)
003ef89c: ntdll!_except_handler4+0 (77e21985)
  CRT scope  0, filter: ntdll!__RtlUserThreadStart+2e (77e21c78)
                func:   ntdll!__RtlUserThreadStart+63 (77e238cb)
We can also examine the exception handler chain manually:
0:000> dt 003ef804 _EXCEPTION_REGISTRATION_RECORD
MSVCR120!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : 0x003ef850 _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x6d5da0d5     _EXCEPTION_DISPOSITION  MSVCR120!_except_handler4+0
0:000> dt 0x003ef850 _EXCEPTION_REGISTRATION_RECORD
MSVCR120!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : 0x003ef89c _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x00271709     _EXCEPTION_DISPOSITION  +0
0:000> dt 0x003ef89c _EXCEPTION_REGISTRATION_RECORD
MSVCR120!_EXCEPTION_REGISTRATION_RECORD
   +0x000 Next             : 0xffffffff _EXCEPTION_REGISTRATION_RECORD
   +0x004 Handler          : 0x77e21985     _EXCEPTION_DISPOSITION  ntdll!_except_handler4+0

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK