作者丨selph
分析MSFWindows/execShellcode
最近分析漏洞用到msf生成的样本进行测试,其中用到payload选项为Windows/execcmd="calc.exe"的这个payload,本着一定要知道利用代码是怎么运行的想法,开始对该shellcode的详细分析。
实验环境
虚拟机:KaliLinux.1x64
物理机:WindowsH2家庭版
软件:x86dbg,scdbg,windbg,Editor
生成shellcode
使用KaliLinux生成shellcode:
┌──(selphkali)-[~/桌面/shellcode]└─$msfvenom-pwindows/execcmd=calc.exe-fraw-oshellcode.bin[-]Noplatformwasselected,choosingMsf::Module::Platform::Windowsfromthepayload[-]Noarchselected,selectingarch:x86fromthepayloadNoencoderspecified,outputtingrawpayloadPayloadsize:bytesSavedas:shellcode.bin
前置知识补充
通过fs寄存器获取模块信息
使用windbg可以很方便查看用到的这些结构
fs寄存器指向线程的TEB结构:
0:dt_TEBntdll!_TEB+0xNtTib:_NT_TIB+0x01cEnvironmentPointer:Ptr32Void+0xClientId:_CLIENT_ID+0xActiveRpcHandle:Ptr32Void+0x02cThreadLocalStoragePointer:Ptr32Void+0xProcessEnvironmentBlock:Ptr32_PEB
TEB[0x30]指向当前的PEB结构:
0:dt_pebntdll!_PEB+0xInheritedAddressSpace:UChar+0xReadImageFileExecOptions:UChar+0xBeingDebugged:UChar+0xBitField:UChar+0xImageUsesLargePages:Pos0,1Bit+0xIsProtectedProcess:Pos1,1Bit+0xIsImageDynamicallyRelocated:Pos2,1Bit+0xSkipPatchingUser32Forwarders:Pos3,1Bit+0xIsPackagedProcess:Pos4,1Bit+0xIsAppContainer:Pos5,1Bit+0xIsProtectedProcessLight:Pos6,1Bit+0xIsLongPathAwareProcess:Pos7,1Bit+0xMutant:Ptr32Void+0xImageBaseAddress:Ptr32Void+0x00cLdr:Ptr32_PEB_LDR_DATA+0xProcessParameters:Ptr32_RTL_USER_PROCESS_PARAMETERS
PEB[0xC]指向_PEB_LDR_DATA结构,这里保存了模块相关的信息:
0:dt_PEB_LDR_DATAntdll!_PEB_LDR_DATA+0xLength:Uint4B+0xInitialized:UChar+0xSsHandle:Ptr32Void+0x00cInLoadOrderModuleList:_LIST_ENTRY+0xInMemoryOrderModuleList:_LIST_ENTRY+0x01cInInitializationOrderModuleList:_LIST_ENTRY+0xEntryInProgress:Ptr32Void+0xShutdownInProgress:UChar+0x02cShutdownThreadId:Ptr32Void
这里的三个_LIST_ENTRY双向链表结构都是连接本进程内所有模块的_LDR_DATA_TABLE_ENTRY结构,这里有更详细的模块信息:
例如0x18偏移处的模块基址,0x2c偏移处的模块名称等....
0:dt_LDR_DATA_TABLE_ENTRYntdll!_LDR_DATA_TABLE_ENTRY+0xInLoadOrderLinks:_LIST_ENTRY+0xInMemoryOrderLinks:_LIST_ENTRY+0xInInitializationOrderLinks:_LIST_ENTRY+0xDllBase:Ptr32Void+0x01cEntryPoint:Ptr32Void+0xSizeOfImage:Uint4B+0xFullDllName:_UNICODE_STRING+0x02cBaseDllName:_UNICODE_STRING+0xFlagGroup:[4]UChar+0xFlags:Uint4B+0xPackagedBinary:Pos0,1Bit+0xMarkedForRemoval:Pos1,1Bit+0xImageDll:Pos2,1Bit+0xLoadNotificationsSent:Pos3,1Bit+0xTelemetryEntryProcessed:Pos4,1Bit+0xProcessStaticImport:Pos5,1Bit+0xInLegacyLists:Pos6,1Bit+0xInIndexes:Pos7,1Bit+0xShimDll:Pos8,1Bit+0xInExceptionTable:Pos9,1Bit+0xReservedFlags1:Pos10,2Bits+0xLoadInProgress:Pos12,1Bit+0xLoadConfigProcessed:Pos13,1Bit+0xEntryProcessed:Pos14,1Bit+0xProtectDelayLoad:Pos15,1Bit+0xReservedFlags3:Pos16,2Bits+0xDontCallForThreads:Pos18,1Bit+0xProcessAttachCalled:Pos19,1Bit+0xProcessAttachFailed:Pos20,1Bit+0xCorDeferredValidate:Pos21,1Bit+0xCorImage:Pos22,1Bit+0xDontRelocate:Pos23,1Bit+0xCorILOnly:Pos24,1Bit+0xChpeImage:Pos25,1Bit+0xReservedFlags5:Pos26,2Bits+0xRedirected:Pos28,1Bit+0xReservedFlags6:Pos29,2Bits+0xCompatDatabaseProcessed:Pos31,1Bit+0xObsoleteLoadCount:Uint2B+0x03aTlsIndex:Uint2B+0x03cHashLinks:_LIST_ENTRY+0xTimeDateStamp:Uint4B+0xEntryPointActivationContext:Ptr32_ACTIVATION_CONTEXT+0x04cLock:Ptr32Void+0xDdagNode:Ptr32_LDR_DDAG_NODE+0xNodeModuleLink:_LIST_ENTRY+0x05cLoadContext:Ptr32_LDRP_LOAD_CONTEXT+0xParentDllBase:Ptr32Void+0xSwitchBackContext:Ptr32Void+0xBaseAddressIndexNode:_RTL_BALANCED_NODE+0xMappingInfoIndexNode:_RTL_BALANCED_NODE+0xOriginalBase:Uint4B+0xLoadTime:_LARGE_INTEGER+0xBaseNameHashValue:Uint4B+0xLoadReason:_LDR_DLL_LOAD_REASON+0xImplicitPathOptions:Uint4B+0x09cReferenceCount:Uint4B+0x0a0DependentLoadFlags:Uint4B+0x0a4SigningLevel:UChar
手动解析PE文件拿到导出表
关于PE文件解析,可以使用Editor的exe.bt模板来辅助解析
使用Editor随便打开一个DLL(一般都有导出表),界面如下:
这里通过下面模板的表格去找对应的偏移即可辅助理解分析中用到的结构,跟着shellcode的反汇编中给出的偏移去找结构,本文中足够用了
具体操作这里就不再介绍,有需要深入了解可自行学习
分析shellcode
准备工作
把生成的shellcode传到物理机,使用editor打开:
复制,二进制,打开x86dbg(用随便一个测试进程),选中一片空白区域,二进制编辑:
把刚刚复制的shellcode黏贴进去,然后确定,修改eip为我们复制shellcode的首