Windows x86 Shellcode开辟:寻觅Kernel32.dll地点 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

申博_新闻事件 申博 131次浏览 已收录 0个评论

申博网络安全巴士站

申博-网络安全巴士站是一个专注于网络安全、系统安全、互联网安全、信息安全,全新视界的互联网安全新媒体。

————————————-

媒介

针对一个已进修了Linux Shellcode开辟,并最先在Windows上实验的研究人员来讲,这一历程可以或许要比设想的越发困难。Windows内核与Linux完全分歧。尽管如此,但Linux内核要比Windows更轻易明白,缘由在于其开源的特征,而且与Windows比拟,Linux只具有相称少的功用。另一方面,Windows在曩昔几年中举行了严重的革新,由于这一革新,新版本与老版本比拟已发生了许多转变。在本文中,我们将专注于对Windows 10 x86举行剖析,但其他旧版本可以或许与之比拟没有太多的分歧。如今,已有许多关于PEB LDR的博客文章,但我们还没有看到有任何文章中展示了完全的逻辑,并论述其本质缘由的。大多数研究人员只是经由过程WinDBG举行剖析,并请求读者具有肯定水平的后端基础。我撰写这篇文章的重要缘由,是愿望从C言语转到ASM,并愿望我们能配合相识在ASM x86中举行Shellcode开辟时,后端的事变道理。

.data段

在我们最先处置惩罚Shellcode局部之前,我发起起首应当明白内存是怎样事变的,由于我们行将做的统统操纵都是在内存中。若是我们已相识像LPWSTR、LPSTR如许的Windows数据范例,那末无疑是一个好消息,由于我们必须要知道:

规范的C言语其实不等同于Windows C编程

接下来,独一须要重点控制的,就是基础的Assembly x86。默许情况下,除体系挪用或API挪用以外,ASM在Linux或Windows中是雷同的。因而,相识寄存器的事变道理就显得异常重要。

最重要的是,我们应当相识怎样对二进制文件举行反汇编。我重要运用x32dbg和WinDBG x86。我会同时运用这两个对象举行调试,由于有一些我们不能在x32dbg中完成的事变,在WinDBG x86中是可以或许的,反之亦然。因而,我们将赓续切换运用这两个对象。

.text段

在我们最先运用Shellcode之前,明白其在较低级别的事变体式格局,这一点异常重要。我们起首将从一个异常简朴的例子最先,找到体系的以后主机名。我们来看看下面是运用C言语编写的Windows API示例:

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

在上图中,我建立了两个变量,分别是compName和compNameSize。这些将是供应给函数GetComputerNameA的参数。请记着,GetComputerNameA和GetComputerNameW有两个相似的函数。 W代表宽Unicode字符,而A代表ANSI CHAR字符串。我们将在全部博客系列中运用ANSI。下面是MSDN对GetComputerNameA函数的申明:

BOOL GetComputerNameA(LPSTR lpBuffer, LPDWORD nSize);

上面的代码透露表现,GetComputerNameA接收LPSTR,透露表现长指针字符串,而LPDWORD则透露表现长指针双字。一个字的巨细是16位,因而DWORD在一切平台上都是32位。如今,若是运用g++编译上述递次,我们将看到以下内容:

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

如今在这里,在递次的最最先,有#include <windows.h>,这也就意味着Windows库将被引入到代码中,它应当在这里动态链接默许依靠项。然则,我们不能对ASM举行雷同的操纵。在ASM的场景中,我们须要动态地找到函数GetComputerNameA地点的地点,在客栈上加载参数,并挪用具有函数指针的寄存器。我们要知道的一件重要事变是,Windows的大多数功用,都是经由过程三个重要DLL接见的:NTDLL.DLL、Kernel32.DLL和Kernelbase.DLL。因而,不管任何时候实行任何二进制文件,这些都是一直要加载的须要DLL。为了加载函数GetComputerNameA,我们必需找到这个函数地点的DLL,并在那边找到它的基址。接下来,我们在x32dbg上实验加载任何x86二进制文件,看看能获得甚么。我将加载我们编译的上述exe文件,但现实上,我们可以或许加载任何随机的32位可实行文件,由于我们只会阅读上面提到的那些DLL。运用x32dbg翻开exe文件,并导航到Log局部,可以或许看到加载了这三个DLL,和其特定的地点:

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

接下来,我们将导航到凸起显现的Symbols局部,可以或许看到加载的分歧DLL的称号。在这里,我们可以或许阅读DLL,并检察它们供应的一切功用。

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

如今,若是我们在搜刮框中搜刮函数GetComputerNameA,它将显现Kernel32.DLL加载该函数。另外,还将打印出函数地点的地点0x74F69AC0。在理论和现实测试中,这一点都可以或许很好地展示。接下来,让我们经由过程C编程然后经由过程ASM来完成,我们要实行的步调以下:

1. 运用函数LoadLibraryA WinAPI在内存中加载Kernel32.dll;

2. 运用GetProcAddress在Kernel32.dll中找到函数GetComputerNameA的地点;

3. 将GetProcAddress返回值范例转换为接收2个参数的WinAPI函数(由于GetComputerNameA接收2个参数);

4. 为ComputerName及其Length建立缓冲区。

将Address作为函数指针来实行。

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

接见LoadLibraryA的MSDN页面,可以或许发明它返回一个HMODULE,这意味着它将一个句柄返回到一个被加载的模块。因而,我们建立了一个变量hmod_libname。相似地,GetProcAddress返回从DLL加载的函数的地点。我们须要将GetProcAddress返回的地点范例转换为GetComputerNameA函数,以使其可以或许一般事变。为此,我们建立了一个typedef,它基础上复制了函数GetComputerNameA的构造。在上图中,我们加载库Kernel32.dll,并运用GetProcAddress查找函数GetComputerNameA的基址,将地点存储在GetComputerNameProc中。末了,我们建立两个变量CompName和CompNameSize,并运用(*GetComputerNameProc)作为函数指针,实行存储在GetComputerNameProc中的地点,并为其供应所需的变量。上面的代码中,还打印了函数GetComputerNameA的地点。我们实验对其举行编译,看看效果怎样:

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

不错!地点0x74F69AC0与上面用x32dbg调试时发明的地点一致。

_start

我们接下来进入到风趣的局部。一切DLL及其函数的地点在从新启动时都邑发生转变,而且在每一个其他体系中都邑有所分歧。这就是我们没法对ASM代码中的任何地点举行硬编码的缘由。然则,重要题目依然存在,那就是我们怎样找到kernel32.dll自身的地点?

我在一最先说过,每一个exe都加载了Kernel32.dll、NTDLL.DLL和Kernelbase.dll。事实上,这些DLL是操纵体系中异常重要的一局部,每次在实行任何操纵时,都邑加载这些DLL。因而,这些DLL到内存中的加载递次老是雷同的。但是,这可以或许因操纵体系而异。这就意味着,在Windows XP与Windows 10之间可以或许有所分歧,但一切Windows 10中的加载递次将连结稳定。

以是,我们在继承下一步之前,须要完成下面的事变:

1. 找到Kernel32.dll的加载递次;

2. 找到Kernel32.dll的地点;

3. 找到GetComputerNameA的地点;

4. 在栈上加载GetComputerNameA的参数;

5. 挪用GetComputerNameA函数指针。

可以或许听起来很轻易?我们来现实实验一下。

查找kernel32.dll的地点其实不简朴。当我们实行任何exe时,在操纵体系中起首建立的就是TEB(线程情况块)和PEB(历程情况块)。

我们的重要关注点在于PEB构造(称为LDR),由于这是与历程相干的一切信息都被加载的处所。从流程参数到流程ID的一切内容都存储在这个地位。在PEB中,有一个名为PEB_LDR_DATA的构造,它包罗三个症结局部。这些被称为链接列表(Linked Lists)。

真假文件夹?FakeFolder病毒再次扰乱企业内网

1. 背景概述 近期,深信服安全团队接到客户反馈,内网中出现了大量伪造成文件夹的可疑exe文件,删掉以后仍会反复。经深信服安全团队分析发现,这是一个蠕虫病毒FakeFolder,该病毒会通过U盘及共享文件夹进行传播,一旦主机感染了该病毒,

1. InLoadOrderModuleList – 加载模块(exe或dll)的递次;

2. InMemoryOrderModuleList – 模块(exe或dll)存储在内存中的递次;

3. InInitializationOrderModuleList – 在历程情况块中初始化模块(exe或dll)的递次。

在链表中加载模块的递次是流动的。这意味着,我们若是可以或许在上面的列表中找到kernel32.dll的递次,就可以或许搜刮kernel32.dll的地点,并继承举行。如今,我们启动WinDBG x86。若是列位还没有装置WinDBG及其依靠项,你可以或许在SLAER上找到一篇关于WinDBG的文章。一旦装置WinDBG以后,就可以或许像我们之前那样翻开恣意的exe文件。

在WinDBG中加载exe文件后,会显现一些输出。限定,我们将疏忽输出内容,并鄙人面的敕令提示符中输入.cls以消灭屏幕并从新最先。如今,我们在敕令提示符下输入!peb,看看在这里可以或许获得甚么:

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

如人人所见,我们获得了LDR(PEB构造)的地点,即779E0C40。这异常重要,由于我们要运用该地点来盘算行进的地点。接下来,我们输入敕令dt nt!_TEB,以查找PEB构造的偏移量。

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

如我们所见,_PEB位于偏移量0x030的地位。以相似的体式格局,我们可以或许运用dt nt!_PEB检察_PEB构造的内容。

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

_PEB_LDR_DATA的偏移量为0x00c。接下来,我们实验查找_PEB_LDR_DATA构造中的内容。我们可以或许用相似的体式格局完成这一点:

dt nt!_PEB_LDR_DATA

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

在这里,我们可以或许看到InLoadOrderModuleList位于偏移量0x00c处,InMemoryOrderModuleList位于偏移量0x014处,InInitializationOrderModuleList位于偏移量0x01c处。另外,若是要检察每一个列表地点的地点,可以或许运用我们此前找到的地点779E0C40(LDR的地点)和敕令dt nt!_PEB_LDR_DATA 779E0C40。这将向我们显现链接列表的响应肇端地点和完毕地点,以下所示:

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

有一个处所,可以或许会被一些人误会,就是上图中展示出InMemoryOrderModuleList的范例为_LIST_ENTRY,但在MSDN上已尚有申明:

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

因而,MSDN声明它是LDR_DATA_TABLE_ENTRY范例而不是_LIST_ENTRY范例。我们实验检察构造中加载的模块,并指定该构造的肇端地点为0x7041e8,以便可以或许看到加载的模块的基址。须要注重的是,0x7041e8是此构造的地点,因而第一个条目将比此地点少8个字节。因而,我们的敕令是:

dt nt!_LDR_DATA_TABLE_ENTRY 0x7041e8-8

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

第一个涌现的BaseDllName是gethost.exe。这就是我之前实行的exe文件。另外,我们可以或许看到如今InMemoryOrderLinks的地点是0x7040e0。偏移量0x018处的DllBase中包罗BaseDllName的基址。如今,我们下一个加载的模块必需间隔0x7040e0有8个字节,也就是0x7040e0-8。

dt nt!_LDR_DATA_TABLE_ENTRY 0x7040e0-8

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

以是,我们的第二个模块是ntdll.dll,它的地点是0x778c000,下一个模块位于0x704690以后的8个字节。以是,我们的下一个敕令是:

dt nt!_LDR_DATA_TABLE_ENTRY 0x704690-8

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

由此,就获得了第三个模块Kernel32.dll,其地点是0x74f50000,其偏移量时0x018。模块加载的递次老是流动的,最少这适用于Windows 10、Windows 7、Windows 8(包孕8.1)。因而,当我们编写ASM时,我们可以或许遍历全部PEB LDR构造体,并找到Kernel32.dll的地点,并将其加载到我们的Shellcode中。以相似的体式格局,我们还可以或许找到Kernelbase.dll的地点,这是第四个模块。

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

如今,我们总结一下须要举行的事变:

1. PEB位于间隔文件段寄存器偏移量为0x030的地位;

2. LDR位于偏移量为PEB + 0x00C的地位;

3. InMemoryOrderModuleList位于偏移量LDR + 0x014的地位;

4. 第一个模块进口是exe自身;

5. 第二个模块进口是ntdll.dll;

6. 第三个模块进口是kernel32.dll;

7. 第四个模块进口是Kernelbase.dll。

我们如今最感兴趣的,就是Kernel32.dll。每次加载DLL时,地点都将存储在DllBase的偏移量0x018的地位。我们链接列表的肇端地点将存储在InMemoryOrderLinks的偏移量中,即0x008。因而,偏移量之间的干系将是 DllBase – InMemoryOrderLinks = 0x018 – 0x008 = 0x10。因而,Kernel32.dll的偏移量将是LDR + 0x10。更细致的明白,可以或许鄙人图中看到,这张图是我从这里偷过来的。

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

如今,若是我们在ASM中做一样的事变,将会是以下所示:

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

我们运用NASM来编译,并在x32dbg中加载它。人人可以或许从这里下载NASM。

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

现实上,一旦我们的末了一条指令被运转,就应当在EAX寄存器中加载Kernel32.dll的地点。我们来看看它在x32dbg中看起来是不是雷同。

Windows x86 Shellcode开辟:寻觅Kernel32.dll地点

如我们所见,在末了一条指令以后,加载到EAX中的地点与我们鄙人面运用lm敕令在WinDBG中看到的地点雷同,都是74F50000,这是Kernel32.dll的地点。

如今,我们已有了Kernel32.dll的地点,下一步就是运用LoadLibraryA找到GetComputerNameA的地点,并挪用该函数。我们将鄙人一篇文章中重点议论这一题目,完美ASM代码,完成猎取盘算机称号并将其打印在屏幕上,然后打印到Shellcode局部。

深入剖析BokBot的中间人攻击方式(下)

八、流量操作:代理视角 BokBot的代理模块依赖于流量操作来窃取受害者的敏感信息。受害者浏览器生成的Web流量与目标url列表(webinjects)进行匹配,如果匹配成功,代理将执行下列操作之一:重定向到钓鱼网站(webfake);页面抓取;页面截图;或


申博|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明Windows x86 Shellcode开辟:寻觅Kernel32.dll地点
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址