Windows shellcode实行手艺入门指南 | 申博官网
登录
  • 欢迎进入申博官网!
  • 如果您觉得申博官网对你有帮助,那么赶紧使用Ctrl+D 收藏申博官网并分享出去吧
  • 这里是申博官方网!
  • 申博官网是菲律宾sunbet官网品牌平台!
  • 申博开户专业品牌平台!

Windows shellcode实行手艺入门指南

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

本文旨在引见如安在历程的内存空间中实行shellcode的基础手艺,之所以要特地拿出一篇文章来零丁议论这个手艺,是由于天天都邑涌现完成隐身代码实行的新手艺。不过要将这些新观点完全明白则没有那末简朴。

本文将引见以下四种实行手艺:

1.动态内存分派;

2.函数指针的实行

3..TEXT-Segment实行;

4.RWX-Hunter实行;

个中前两种手艺是尽人皆知的,大多数人应当熟习这些,然则,后两种手艺能够比较新,大多数人并非很熟习。

这些手艺都形貌了在差别内存部份中实行代码的要领,因而有必要先说一说历程内存规划。

历程内存规划

起首须要明白的观点是,全部假造内存空间分为两个相干部份:为用户历程预留的假造内存空间(用户空间)和为体系历程预留的假造内存空间(内核空间),以下图所示:

细致的可视化历程,请浏览Microsoft的细致形貌。

起首,每一个历程都有本身的私有假造地点空间,个中“内核空间”是一种“同享环境”,这意味着每一个内核历程能够在任何它想要的处所读写假造内存。请注意,“同享环境”只适用于没有基于假造化的安全性(VBS)的环境,但这是另一个话题了,不属于本文的议论局限。

上示意显现了全局假造地点空间的款式,如今让我们把该款式转化成一个历程。

Windows shellcode实行手艺入门指南

能够看出,单个历程的假造内存空间由多个部份构成,这些部份经由过程地点空间规划随机化(ASLR)安排在可用空间边界内的某个位置。这些部份行内的人应当很熟习了,但为了让每一个人都处于统一明白水平线上,我列出了这些部份的提要,轻易你相识:

.text段是递次代码段:这是可实行历程映像地点的位置,在这个地区中,你将找到可实行文件的主条目,即实行流最先的处所。

.data段:.data部份包括全局初始化或静态变量。任何没有绑定到特定函数的变量都存储在这里。

.bss段:与.data段相似,此段包括任何未初始化的全局变量或静态变量。

HEAP(堆):这是存储一切动态部分变量的处所,每次建立在运转时肯定所需空间的对象时,都邑在HEAP中动态分派所需的地点空间(一般运用alloc()或相似的体系挪用)。

STACK(栈):栈是分派给每一个静态部分变量的位置,假如在函数中部分初始化一个变量,该变量将被放在STACK上。

动态分派内存

相识了基础学问后,让我们看看在历程内存空间中实行shellcode须要什么。为了实行你的shellcode,你须要完成以下三个搜检:

1.是不是须要标记为可实行的假造地点空间,不然DEP将抛出异常;

2.是不是须要将shellcode放入该地点空间;

3.是不是须要将代码流定向到该内存地区;

完成这三个步骤的要领是运用WinAPI挪用动态分派可读、可写和可实行(RWX)内存,并启动一个指向新分派内存地区的线程。用C言语编写这个代码应当是以下如许的:

#include <windows.h>
int main()
{
char shellcode[] = "\xcc\xcc\xcc\xcc\x41\x41\x41\x41";
// Alloc memory
LPVOID addressPointer = VirtualAlloc(NULL, sizeof(shellcode), 0x3000, 0x40);
// Copy shellcode
RtlMoveMemory(addressPointer, shellcode, sizeof(shellcode));
// Create thread pointing to shellcode address
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)addressPointer, NULL, 0, 0);
// Sleep for a second to wait for the thread
Sleep(1000);
return 0;
}

正如以下屏幕截图所示,在编译和实行上述代码时,shellcode将从堆中实行,默许状况下遭到Windows XP中引入的体系局限数据实行庇护(DEP)战略的庇护,细致历程,请点此浏览。关于启用DEP的历程,这将防备在此内存地区实行代码。为了战胜这个停滞,我们请求体系将所需的内存地区标记为RWX。这是经由过程将VirtualAlloc的末了一个参数指定为0x40来完成的,这就相当于PAGE_EXECUTE_READWRITE。至于细致缘由,请参考此文。

到目前为止一切顺遂,然则这些代码在内存中的表现怎样呢?为了剖析这一点,我们将运用WinDbg。Windows 调试器 (WinDbg) 可用于调试内核形式和用户形式代码,来剖析毛病转储,并搜检代码时 CPU 寄存器实行,概况请点此相识,假如你之前从未设置过WinDbg,请参考下面的截图,相识怎样将WinDbg指向源代码,列出一切已加载的模块,设置断点并运转递次。

Windows shellcode实行手艺入门指南

在WinDbg命令行中输入“g”后,递次将进入可实行文件的主函数。假如在挪用RtlMoveMemory以后逐渐实行代码,就会在WinDbg中碰到以下状况。

Windows shellcode实行手艺入门指南

如紫线标识的处所,我们当前正处于挪用RtlMoveMemory以后。假如我们参考上面的代码,RtlMoveMemory将从VirtualAlloc猎取一个指针,将shellcode写入给定的位置。由于从VirtualAlloc返回的指针是RtlMoveMemory的第一个参数,由于函数参数是按相反的递次被推送到栈上的,所以在挪用函数之前,它将末了被推送到栈上(在寄存器ecx中)。假如我们在挪用RtlMoveMemory之前就住手了,则ecx寄存器将显现地点位置为‘0x420000’,在上面的屏幕截图中,该地点位置在WinAPI挪用以后被安排到eax寄存器中。

搜检上面屏幕截图中地点0x420000处的内存位置,显现我们的shellcode已安排在此地点。别的,请注意栈基址(ebp)显现为0x5afa34,栈指针(esp -栈的顶部地点)指向0x5af938,逾越此局限内的地点栈。由于shellcode的内存位置不在栈局限内,我们能够得出结论,它已被安排在堆上。

小结

WinAPI体系挪用用于在堆中动态分派RWX内存,将shellcode移动到新分派的内存地区,并启动一个新的实行线程。

长处

1.运用WinAPI挪用是实行代码的规范要领,异常牢靠。

2.分派的内存地区不仅是可实行的,而且是可写和可读的,这许可在这个内存地区内修正shellcode,并对shellcode编码或加密。

瑕玷

WinAPI挪用的运用很轻易被成熟的AV/EDR体系检测到。

函数指针的实行

与上面的一般要领差别,在内存中实行shellcode的另一种手艺是运用函数指针,以下面的代码片断所示:

#include <windows.h>
int main()
{
char buf[] = "\xcc\xcc\xcc\xcc";
// One way to do it
int (*func)();
func = (int (*)()) (void*)buf;
(int)(*func)();
              // Shortcut way to do it
// (*(int(*)()) buf)();
// sleep for a second
Sleep(1000);
              return 0;
}

此代码的工作体式格局以下:

1.声清楚明了一个函数的指针,在上面的代码片断中,函数指针被命名为’func’;

2.声明的函数指针被分派了要实行的代码的地点(由于任何变量将被赋值,所以func指针也被给予地点);

3.末了挪用函数指针,这意味着实行流程已被定向到指定的地点。

CVE-2019-15512:Total Defense反病毒软件权限提升漏洞分析

概述 Total Defense Common Scheduler服务默认情况下会在C:\ProgramData\TotalDefense\Consumer\ISS\9\ccschedulersvc中创建日志文件。只有Total Defense的特权进程(SYSTEM)才可以创建、访问和操作该文件。日志和文件夹有访问特权可以允许非特权用户添加或删除文件,并修改一些特征。 受影响的版本是V9.0.0.773,研究人员称其他版本和产品也可能受到影响,但未进行验证和测试。 漏洞分析 日志文件是由SYSTEM进程创建的,但是每个组都有写权限。通过滥用日

运用与上面雷同的步骤,我们能够运用WinDbg在内存中对此举行剖析,这将实行以下操纵:

Windows shellcode实行手艺入门指南

在这类状况下,致使代码实行的关键步骤以下:

1.包括在部分变量中的shellcode在初始化时期进入栈(比较靠近ebp,由于这是main-method中起首发作的事变之一);

2.shellcode从栈加载到eax中,如地点0x00fd1753所示;

3.shellcode经由过程挪用eax来实行,如地点0x00fd1758所示;

返回参考上面所示的单个历程的假造存储器规划,声明栈仅标记为关于DEP的RW存储器部份。一样的题目发作在堆内存的动态分派中,在这类状况下,运用WinAPI函数(VirtualAlloc)将内存部份标记为可实行文件。在本文的示例中,我们没有运用任何WinAPI函数,但荣幸的是,我们能够经由过程设置/NXCOMPAT:NO标志来简朴地为已编译的可实行文件禁用DEP(关于VisualStudio,能够在高等链接器选项中设置)。如许,shellcode就会被顺遂的实行。

小结

函数指针用于挪用shellcode,在栈上作为部分变量分派。

长处

1.没有运用WinAPI挪用,这能够用来防止AV/EDR检测。

2.栈是可写和可读的,这许可在这个内存地区内修正shellcode,从而对shellcode编码或加密。

瑕玷

默许状况下,DEP会阻挠栈中的代码实行,这就须要在没有DEP支撑的状况下编译代码。别的,体系局限的DEP强制实行将阻挠代码实行。

.TEXT段实行

到目前为止,我们已在堆和栈中完成了代码实行。由于这些代码在默许状况下都不可实行,因而我们须要运用WinAPI函数并离别禁用DEP来战胜这个题目。

我们能够防止在已标记为可实行的内存地区中实行代码时运用这类要领,对上面内存规划的疾速援用显现. text段就是如许一个内存地区。

.TEXT段须如果可实行的,由于这是包括可实行代码的部份,比方主函数。

从理论上来讲,这是一个实行shellcode的适宜位置,然则我们如安在.TEXT段中安排和实行shellcode呢?很明显,我们不能运用WinAPI函数简朴地将shellcode移到这里,由于. text段是不可写的,而且我们不能还运用函数指针,由于这里没有指向的援用。

因而,解决方案只能是内联汇编(inline assembly)中。

@MrUn1k0d3r在这里展现了这类手艺的完成历程,下面是一个精简的代码段:

#include <Windows.h>
int main() {
asm(".byte 0xde,0xad,0xbe,0xef,0x00\n\t"
"ret\n\t");
return 0;
}

要编译此代码,由于运用了“.byte”指令,因而须要GCC编译器。荣幸的是,MinGW项目中包括一个GCC编译器,MinGW,是Minimalist GNUfor Windows的缩写。它是一个可自在运用和自在宣布的Windows特定头文件和运用GNU东西集导入库的鸠合,许可你在GNU/Linux和Windows平台天生当地的Windows递次而不须要第三方C运转时(C Runtime)库。MinGW 是一组包括文件和端口库,其功用是许可控制台形式的递次运用微软的规范C运转时(C Runtime)库(MSVCRT.DLL),该库在一切的 NT OS 上有效,在一切的 Windows 95发行版以上的 Windows OS 有效,运用基础运转时,你能够运用 GCC 写控制台形式的相符美国规范化构造(ANSI)递次,能够运用微软供应的 C 运转时(C Runtime)扩大,与基础运转时相结合,就能够有充足的权益既运用 CRT(C Runtime)又运用 WindowsAPI功用。我们能够按以下体式格局轻松编译:

mingw32-gcc.exe -c Main.c -o Main.o
mingw32-g++.exe -o Main.exe Main.o

在IDA中检察此内容后,我们发明shellcode已嵌入到.TEXT段中:

Windows shellcode实行手艺入门指南

被定义的shellcode’0xdeadbeef’在挪用__main以后就被置于汇编代码中,__ main用作初始化例程。一旦__main函数完成初始化,我们就马上实行shellcode。

小结

内联递次集用于将shellcode嵌入可实行递次的. text段中。

长处

没有运用WinAPI挪用,这能够用来防止AV/EDR检测。

瑕玷

.TEXT段不可写,因而不能运用任何shellcode编码器或加密器。

因而,假如不举行定义,AV/EDR很轻易检测到这类歹意shellcode。

RWX-Hunter实行

末了,在运用默许的可实行.TEXT段举行代码实行并运用WinAPI函数建立非默许的可实行内存部份并禁用DEP以后,另有末了一条途径,即搜刮已被标记为读(R),写(W)和可实行(X)的内存部份。细致的思绪,请浏览这个帖子。

Windows shellcode实行手艺入门指南

RWX-Hunter的基础思绪是遍历历程的假造内存空间,搜刮标记为RWX的内存部份。

仔细的读者能够会注意到,这只完成了我最初设置的代码实行的步骤的1/3,即:查找可实行内存。至于怎样将shellcode放入这个内存地区,以及怎样将代码流程定向到该内存地区,第一步并没有提到。

须要回覆的第一个题目是搜刮RWX内存部份的局限,让我们再次回到历程私有假造内存空间的初始形貌,这里声明历程内存空间的局限是从0x00000000到0x7FFFFFFFF,所以这应当是搜刮局限。

long MaxAddress = 0x7fffffff;
long address = 0;
do
{
MEMORY_BASIC_INFORMATION m;
int result = VirtualQueryEx(process, (LPVOID)address, &m, sizeof(MEMORY_BASIC_INFORMATION));
if (m.AllocationProtect == PAGE_EXECUTE_READWRITE)
{
printf("YAAY - RWX found at 0x%x\n", m.BaseAddress);
return m.BaseAddress;
}
if (address == (long)m.BaseAddress + (long)m.RegionSize)
break;
address = (long)m.BaseAddress + (long)m.RegionSize;
} while (address <= MaxAddress);

这个要领异常直接地完成了我们想要完成的目的。搜刮处置惩罚专用假造存储器空间(用户地区假造存储器空间)以寻觅用PAGE_EXECUTE_READWRITE标记的存储器部份,其再次映射到0x40,如先前示例中所示。假如找到该空间,则返回该空间,不然将下一个搜刮地点设置为下一个存储地区(基地点+内存地区)。

为了完成代码实行,你须要将shellcode移动到找到的内存地区并实行。如第一种手艺所示,一种简朴的要领是返回到WinAPI挪用,然则这类要领的瑕玷你也要斟酌进来。在这篇文章的末了,我将分享一些有效的PoC,以参考怎样完成这一步。

小结

在历程内存空间中搜刮可读、可写和可实行(RWX)内存部份,以防止动态建立此类内存。

长处

防止了对VirtuallAlloc/VirtuallAllocEx的挪用,而且应用历程不会动态建立RWX内存。

瑕玷

须要很强的网络安全学问来防止WinAPI挪用将shellcode和代码流重定向到安排的shellcode。

PoC

完全PoC,请点此。

本文翻译自:https://www.contextis.com/en/blog/a-beginners-guide-to-windows-shellcode-execution-techniques


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

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

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