因此,在系统上执行内存转储的笔试工具太多了.它们到底是如何工作的-到底发生了什么?
发布于 2011-07-12 11:19:39
一个堆芯,或者是整个系统中的一个,或者是单个可执行文件,是该进程的内存的全部内容,或者在系统的情况下,所有的内存都写到一个文件中。在这样的转储中可以有很多数据-下面是gvim内存空间的缩写形式,我目前正在运行它:
pmap 19133
19133: gvim fsstate.py
0000000000400000 2184K r-x-- /usr/bin/gvim ; program code
0000000000821000 100K rw--- /usr/bin/gvim ; program code again
000000000083a000 52K rw--- [ anon ]
0000000000a39000 56K rw--- /usr/bin/gvim ; more program code
0000000002469000 3592K rw--- [ anon ]
0000003d53c00000 16K r-x-- /lib64/libuuid.so.1.3.0 ; shared object
0000003d53c04000 2044K ----- /lib64/libuuid.so.1.3.0
0000003d53e03000 4K rw--- /lib64/libuuid.so.1.3.0
0000003d55000000 28K r-x-- /usr/lib64/libSM.so.6.0.1
0000003d55007000 2044K ----- /usr/lib64/libSM.so.6.0.1
...
00007f46d66c7000 20K r---- /usr/share/locale/en_GB/LC_MESSAGES/gdk-pixbuf.mo
00007f46d66cc000 4K r---- /usr/share/locale/en_GB/LC_MESSAGES/libc.mo
00007f46d66cd000 56K r---- /usr/share/locale/en_GB/LC_MESSAGES/gtk20.mo
00007f46d66db000 28K r--s- /usr/lib64/gconv/gconv-modules.cache
00007f46d66e5000 4K rw--- [ anon ]
00007fffc9ed9000 132K rw--- [ stack ] ; stack!
00007fffc9f9b000 4K r-x-- [ anon ]
ffffffffff600000 4K r-x-- [ anon ]
从这个地址空间,共享对象不会被转储,但是其他的东西,堆栈,堆,都会被转储。地址将相对于某些版本的共享对象,并且可能使用ASLR,它们可能无法对进程进行处理。内核转储可以配置为包含不同数量的信息,从小转储到所有信息。
这能告诉你什么?系统或程序在被转储时的确切状态--它在堆栈上有什么(所以很可能是它所处的功能)。大多数核心转储还包含其他有用的信息,如转储时处理器寄存器中的信息。
就如何确定正在发生的事情而言,EIP或RIP on x86 (x64)将告诉您进程正在执行的是哪个内存地址。rbp或ebp会告诉您您的函数在堆栈上的位置。你会期望在那里找到局部变量。您还可以查找所有系统调用及其在核心转储中的参数。
所有这些都可以告诉你,在特定的时间点,一个过程是怎么回事。它也不仅仅是一种笔试工具,还可以将核心转储作为调试应用程序的一种形式进行分析,特别是在运行调试器很难或不可能运行的情况下。例如,您可能会分析内核内核转储,找出内核崩溃的原因(当内核恐慌时,它在做什么?)而不是附加一个调试器和再次尝试-它也允许其他人发送转储给你进行分析。
这对笔试有什么帮助?同样,调试有助于笔式测试。您可以看到内存中加载了什么,当前状态是什么。当您使用转储时,您可以计算出一个进程可能正在做什么,最重要的是,内存中任何可执行文件(堆、堆栈等)中存储的任何数据也将在核心转储中结束,包括以明文形式存储在内存中的密码。
分析工具是做什么的?查找表示潜在漏洞的模式和结构(或错误,如果您是在调试之后)。对此的完整解释可能超出了本框的范围--有许多专门讨论分析内存转储的技术的书籍。这在很大程度上也与系统和体系结构有关;Windows的技术与x86上的Linux技术不同。
作为一个可能表明错误的例子,下面是一个AviD会非常欣赏的例子:
push rbp
mov rbp, rsp
sub rsp, 32
mov QWORD PTR [rbp-24], rdi ; this is a char* argument stored on stack
mov rdx, QWORD PTR [rbp-24] ; and this is a pointer loading it into a register
lea rax, [rbp-16] ; this is only 8 bytes further down
mov rcx, QWORD PTR [rdx] ; load contents of rdx into rcx
mov QWORD PTR [rax], rcx ; put those 8 bytes to rbp-16
mov rcx, QWORD PTR [rdx+8] ; load next 8 butes
mov QWORD PTR [rax+8], rcx ; write to rbp-8
mov rcx, QWORD PTR [rdx+16]
mov QWORD PTR [rax+16], rcx ; write to rbp
mov rcx, QWORD PTR [rdx+24]
mov QWORD PTR [rax+24], rcx ; write to rbp+8
mov rcx, QWORD PTR [rdx+32]
mov QWORD PTR [rax+32], rcx ; write to rbp+16
mov rcx, QWORD PTR [rdx+40]
mov QWORD PTR [rax+40], rcx ; write to rbp+24
mov rcx, QWORD PTR [rdx+48]
mov QWORD PTR [rax+48], rcx ; write to rbp+32
mov rdx, QWORD PTR [rdx+56]
mov QWORD PTR [rax+56], rdx ; write to rbp+40
lea rax, [rbp-16]
正如您所看到的,这个函数对于局部变量的第一个可用空间是rbp-16
及以下。除此之外,我们还愉快地用一堆数据砸了一个堆栈帧,可能导致程序崩溃。但是,这段代码很可能表示有可能利用该漏洞。在崩溃转储中寻找这样的模式使它们非常有用,而且在本例中,rip
会告诉您到底是哪种内存访问导致了问题,因为它会指向错误的指令(理论上)。
如果您想知道,这段冒犯的代码只是一个从无界缓冲区到一个小得多的目标空间的memcpy
。优化了对memcpy的函数调用。
发布于 2011-07-12 12:15:02
首先,有两个主要用户的内存转储在安全-取证和利用写作的家伙。笔试员,没那么多--当然,这取决于五人;)
转储内存工作的常用方法是打开内存伪设备并将所有内容读取到文件中。
例如,对于windows中的dd,您将执行类似于dd if=\\.\Device\PhysicalMemory of=memory.bin bs=4096
的操作(在此之后,您需要一个内核驱动程序)。
这同样适用于linux,例如dd if=/dev/mem of=/home/john/mem.bin bs=1024
当然,这是最简单的方法。获取内存的其他方法是使用崩溃转储,如LiveKd转储、通过虚拟机管理程序获取内存、如果存在休眠文件,甚至通过防火墙或另一个DMA接口获取内存。当然,也有冷靴攻击。
拥有一个文件上的内存,你可以做很多事情,这取决于你想要什么。常见的方法是搜索字符串,例如密码令牌、私钥和其他,这是最简单的。
如果您想做更多的事情,通常需要做更多的工作,但是使用商业或开放源码工具可以实现不同程度的自动化。主要思想是转储中的物理内存将分散在页面中。为了理解它,您可以通过启发式搜索页面表来定位,并尝试重构内存的逻辑视图。这样,您就可以执行其他搜索,并找到各种正在运行的进程、打开的文件、网络连接等的结构。这取决于您的目标是什么。
发布于 2011-07-12 09:21:35
如果您列出了哪些工具,这会有帮助,因为有差异--例如整个内存与特定区域。我想不出我经常使用的任何攻击工具都会转储内存。
但是简单地说,让我们看看内存的转储,我们不仅在原地查看应用程序代码,还可以查看变量值。
内存只是复制到磁盘上,类似于正常使用中将内存页交换到磁盘的方式,或者工具直接读取内存。
https://security.stackexchange.com/questions/5194
复制相似问题