Malware ანალიზი 'NativeApp_G4QLIQRa.exe' ნაწილი #4
entry0 გრძელდება!
წინა ნაწილში ვისაუბრე entry0-ის ციკლზე, რომელიც ხდებოდა ოპერაციული სისტემის ვერსიის შემოწმების შემდეგ. ახლა კი დროა ვისაუბრო იმაზე, თუ რახდება ამ ყველაფრის შემდეგ.
1
2
push 0xa
call fcn.00406694
აქ 0x00406694 მეხსიერების მისამართზე მყოფი ფუნქცია არის გამოყენებული და მისი პარამეტრია 10(თექვსმეტობით თვლის სისტემაში 0xa ნიშნავს 10-ს). ანუ გამოდის, რომ მას გადაეცემა რიცხვი, და სწორედ ეს რიცხვია მოდულის ე.წ. Handle-ის მაიდენტიფიცირებელი.
ამის შემდეგ მოდის:
1
2
push 8
call fcn.00406694
აქაც იგივე ხდება, მაგრამ ამ შემთხვევაში რიცხვი ათობით თვლის სისტემაშია ჩაწერილი, რაც ნიშნავს იმას, რომ ფუნქციას რიცხვი 8 გადაეცა.
მოკლედ, ეს ფუნქცია რამდენჯერმე მეორდება. ეს ნიშნავს იმას, რომ წინა ფუნქციიდან წამოღებული .dll ფაილიდან რამდენიმე ფუნქცია/ცვლადი ჩაიტვირთა პროცესში.
აქ ჩანს, რომ COMCTL32.dll ფაილია გამოყენებული, რომელიც ასევე GUI აპლიკაციებისათვის გამოიყენება. ამ ფაილიდან შესაძლოა გამოყენებული იქნას ფუნქციები ღილაკებისათვის და კიდევ ბევრი სხვა რამისთვის. მოკლედ, იმის თქმას ვცდილობ, რომ აქ საქმე აშკარად GUI აპლიკაციასთან გვაქვს. ეს ეჭვი EXTHEME-მაც გამიჩინა. დიდი ალბათობაა იმისა, რომ ამ პროცესმა პრივილეგიის ესკალაცია, შემდეგ კი ყველა ფაილის დაშიფვრა სცადოს.
- SHGetFileInfoW
- GetCommandLineW
ეს ორი ფუნქციაა საინტერესო. ორივე ფუნქცია WinAPI-ს ნაწილია. პირველი ფუნქცია FS-დან(File System) ობიექტის შესახებ ინფორმაციას აგროვებს(ეს შეიძლება იყოს ფაილი, დირექტორია და ა.შ.). მეორე ფუნქცია კი კონკრეტული ფაილის ადგილმდებარეობას აბრუნებს.
მაგალითად, თუ Action.exe მდებარეობს D:\Programs\Bin\ დირექტორიაში და ეს პროგრამა ასე დაიწერა:
1
2
3
4
5
6
7
8
9
#include <windows.h>
#include <iostream>
int main() {
LPWSTR location = GetCommandLineW();
std::wcout << location << std::endl;
return 0;
}
ეს დაიწერება ტერმინალში:
1
D:\Programs\Bin\Action.exe
ანუ, მავნე კოდი ცდილობს თავისი ადგილმდებარეობის დადგენას. ასევე აქ საინტერესო ისაა, რომ SHGetFileInfoW-ს შემდეგ 0x004062ba მეხსიერების მისამართზე მდებარე ფუნქცია ეშვება და მხოლოდ მას შემდეგ ხდება GetCommandLineW ფუნქციის გამოძახება.
fcn.0x004062ba
ეს ძალიან პატარა ფუნქციაა. ორი პარამეტრი გადაეცემა, arg_ch_2 და arg_ch. ამის გამო შესაძლებელია ვივარაუდოთ, რომ ეს პარამეტრები არ არის რიცხვები. ისინი ან სიმბოლოები ან ტექსტია. პირველი რაც აქ ხდება არის ის, რომ 0x2000 შედის სტაკზე. ეს შესაძლოა ტექსტის სასურველი ზომა იყოს. ამის შემდეგ სტაკზე შედის ორი პარამეტრი, რომელიც ამ ფუნქციას გადაეცა. საბოლოოდ, lstrcpynW ფუნქციის გამოძახება ხდება და ბოლოს ეს ინსტრუქციაა აღებული:
1
ret 8
ანუ, return address-თან ერთად კიდევ 8 ბაიტი მოშორდება სტაკს, როდესაც ეს ფუნქცია შეწყვეტს მუშაობას. შესაძლებელია ეს 8 ბაიტი ის სამი რამაა, რაც ფუნქციის გამოყენების დროს სტაკზე შედის.
1
2
3
4
5
LPWSTR lstrcpynW(
[out] LPWSTR lpString1,
[in] LPCWSTR lpString2,
[in] int iMaxLength
);
როგორც ვივარაუდე, ფუნქცია აბრუნებს LPWSTR ტექსტს, მაგრამ ის იღებს ერთ ტექსტს და მაქსიმუმ სიგრძეს. ამ ფუნქციაში lpString1 არის ე.წ. buffer, სადაც უნდა ჩაიწეროს ინფორმაცია, lpString2 არის ის ტექსტი, რაც უნდა ჩაჯდეს lpString1-ში და ბოლოს iMaxLength არის lpString1-ის ზომა. ეს ცვლადი Buffer Overflow შეტევის პრევენციას ახდენს.
Buffer Overflow ტიპის შეტევებზე მეტი ინფორმაციის გასაგებად აქ შესვლა შეიძლება: https://44b4c0.github.io/posts/Explanation-of-Buffer-Overflows/.
მოკლედ, როგორც ვაკვირდები ჰაკერი ცდილობს გარკვეული ფუნქციებით ანალიტიკოსის დაბნევას და Anti Debugging ტექნიკების დანერგვას, მაგრამ ე.წ. Proxy ფუნქციები ხელს არ მიშლის საერთოდ.
ოდნავ ქვემოთ ჩამოვედი და ეს აღმოვაჩინე:
აქ კიდევ უფრო მეტი დეტალია მოცემული.
კიდევ ორი ფუნქცია?
რა თქმა უნდა, ამ კოდში ბევრი ფუნქციაა. ახლა მაინტერესებს რა ფუნქციებია განლაგებული ამ მეხსიერების მისამართებზე:
0x0040335e0x00402edd
fcn.0x0040335e
საკმაოდ პატარა ფუნქციაა და წესით მალე გავივლი ამას.
დავიწყოთ იმით, რომ აქაც ორი არგუმენტია მოცემული. პირველ არგუმენტს eax დაიკავებს, ხოლო მეორეს ebx. აქ ხუთი ფუნქციაა გამოძახებული და ყოველი მათგანი არასტანდარტულია. ამის გამო მომიწევს ხუთივეს დამოუკიდებლად ანალიზი.
რა შეიძლება იყოს ეს? დიდი ალბათობით ეს მახეა, რომელიც სპეციალურადაა ჩაშენებული იმისთვის, რომ რევერს ინჟინერს ყურადღება გაუფანტოს ვირუსმა და მთავარი საქმე გადამალოს. მაგრამ შესაძლოა ვცდები და ეს კოდი მართლა აკეთებს რაღაც ღირებულს(ვირუსისთვის).
კოდის ანალიზიდან დგინდება, რომ პირველი ოთხი ფუნქცია ერთ პარამეტრს მიიღებს, და ყოველი მათგანი esi რეგისტრატორის მნიშვნელობაა. უბრალოდ ეს მნიშვნელობა სტაკზე უნდა შევიდეს სანამ ფუნქციის გამოძახება მოხდება, რადგან ასე მუშაობს CPU და პარამეტრების გადაწოდების სხვა მეთოდი არ არსებობს. მხოლოდ მეხუთე ფუნქცია იღებს ორ პარამეტრს. ამ ორი პარამეტრიდან ერთ-ერთი არის რიცხვი 0x4db000.
fcn.0x00402edd
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
; CALL XREF from entry0 @ 0x403642(x)
/ 569: fcn.00402edd (int32_t arg1, int32_t arg2, uint32_t arg_8h);
| `- args(eax, ebx, sp[0x4..0x4]) vars(10:sp[0x8..0x2c])
| 0x00402edd 55 push ebp
| 0x00402ede 8bec mov ebp, esp
| 0x00402ee0 83ec28 sub esp, 0x28
| 0x00402ee3 53 push ebx ; arg2
| 0x00402ee4 56 push esi
| 0x00402ee5 33db xor ebx, ebx
| 0x00402ee7 57 push edi
| 0x00402ee8 895df8 mov dword [var_8h], ebx
| 0x00402eeb 895dfc mov dword [var_4h], ebx
| 0x00402eee ff157c804000 call dword [sym.imp.KERNEL32.dll_GetTickCount] ; 0x40807c ; "v\x8b"
| 0x00402ef4 be00704e00 mov esi, 0x4e7000
| 0x00402ef9 6800200000 push 0x2000
| 0x00402efe 05e8030000 add eax, 0x3e8 ; 1000 ; arg1
| 0x00402f03 56 push esi
| 0x00402f04 53 push ebx
| 0x00402f05 a3f0ae4700 mov dword [0x47aef0], eax ; [0x47aef0:4]=0 ; arg1
| 0x00402f0a ff1584804000 call dword [sym.imp.KERNEL32.dll_GetModuleFileNameW] ; 0x408084
| 0x00402f10 6a03 push 3 ; 3
| 0x00402f12 6800000080 push 0x80000000
| 0x00402f17 56 push esi
| 0x00402f18 e8932e0000 call fcn.00405db0
| 0x00402f1d 8bf8 mov edi, eax
| 0x00402f1f 83ffff cmp edi, 0xffffffff
| 0x00402f22 897df4 mov dword [var_ch], edi
| 0x00402f25 893d18a04000 mov dword [0x40a018], edi ; [0x40a018:4]=-1
| ,=< 0x00402f2b 750a jne 0x402f37
| | 0x00402f2d b8e8a14000 mov eax, str.Error_launching_installer ; 0x40a1e8 ; u"Error launching installer"
| ,==< 0x00402f32 e9d8010000 jmp 0x40310f
| || ; CODE XREF from fcn.00402edd @ 0x402f2b(x)
| |`-> 0x00402f37 56 push esi
| | 0x00402f38 be00704d00 mov esi, 0x4d7000
| | 0x00402f3d 56 push esi
| | 0x00402f3e e877330000 call fcn.004062ba
| | 0x00402f43 56 push esi
| | 0x00402f44 e8922c0000 call fcn.00405bdb
| | 0x00402f49 50 push eax
| | 0x00402f4a 6800b04e00 push 0x4eb000
| | 0x00402f4f e866330000 call fcn.004062ba
| | 0x00402f54 53 push ebx
| | 0x00402f55 57 push edi
| | 0x00402f56 ff1580804000 call dword [sym.imp.KERNEL32.dll_GetFileSize] ; 0x408080
| | 0x00402f5c 3bc3 cmp eax, ebx
| | 0x00402f5e a304424300 mov dword [0x434204], eax ; [0x434204:4]=0
| | 0x00402f63 8bf0 mov esi, eax
| |,=< 0x00402f65 0f8ee7000000 jle 0x403052
| || 0x00402f6b bb08424300 mov ebx, 0x434208
| || ; CODE XREF from fcn.00402edd @ 0x40304a(x)
| .---> 0x00402f70 a1f8ae4700 mov eax, dword [0x47aef8] ; [0x47aef8:4]=0
| :|| 0x00402f75 8bfe mov edi, esi
| :|| 0x00402f77 f7d8 neg eax
| :|| 0x00402f79 1bc0 sbb eax, eax
| :|| 0x00402f7b 25007e0000 and eax, 0x7e00
| :|| 0x00402f80 0500020000 add eax, 0x200 ; 512
| :|| 0x00402f85 3bf0 cmp esi, eax
| ,====< 0x00402f87 7c02 jl 0x402f8b
| |:|| 0x00402f89 8bf8 mov edi, eax
| |:|| ; CODE XREF from fcn.00402edd @ 0x402f87(x)
| `----> 0x00402f8b 57 push edi
| :|| 0x00402f8c 53 push ebx
| :|| 0x00402f8d e89f030000 call fcn.00403331
| :|| 0x00402f92 85c0 test eax, eax
| ,====< 0x00402f94 0f8422010000 je 0x4030bc
| |:|| 0x00402f9a 833df8ae47.. cmp dword [0x47aef8], 0 ; [0x47aef8:4]=0
| ,=====< 0x00402fa1 757a jne 0x40301d
| ||:|| 0x00402fa3 6a1c push 0x1c ; 28
| ||:|| 0x00402fa5 8d45d8 lea eax, [var_28h]
| ||:|| 0x00402fa8 53 push ebx
| ||:|| 0x00402fa9 50 push eax
| ||:|| 0x00402faa e8bc2d0000 call fcn.00405d6b
| ||:|| 0x00402faf 8b45d8 mov eax, dword [var_28h]
| ||:|| 0x00402fb2 a9f0ffffff test eax, 0xfffffff0 ; 4294967280
| ,======< 0x00402fb7 7572 jne 0x40302b
| |||:|| 0x00402fb9 817ddcefbe.. cmp dword [var_24h], 0xdeadbeef
| ,=======< 0x00402fc0 7569 jne 0x40302b
| ||||:|| 0x00402fc2 817de8496e.. cmp dword [var_18h], 0x74736e49 ; 'Inst' ; string "InstsoftNull"
| ========< 0x00402fc9 7560 jne 0x40302b
| ||||:|| 0x00402fcb 817de4736f.. cmp dword [var_1ch], 0x74666f73 ; 'soft'
| ========< 0x00402fd2 7557 jne 0x40302b
| ||||:|| 0x00402fd4 817de04e75.. cmp dword [var_20h], 0x6c6c754e ; 'Null'
| ========< 0x00402fdb 754e jne 0x40302b
| ||||:|| 0x00402fdd 094508 or dword [arg_8h], eax
| ||||:|| 0x00402fe0 8b4508 mov eax, dword [arg_8h]
| ||||:|| 0x00402fe3 8b0df8814200 mov ecx, dword [0x4281f8] ; [0x4281f8:4]=0
| ||||:|| 0x00402fe9 83e002 and eax, 2
| ||||:|| 0x00402fec 0905a0af4700 or dword [0x47afa0], eax ; [0x47afa0:4]=0
| ||||:|| 0x00402ff2 8b45f0 mov eax, dword [var_10h]
| ||||:|| 0x00402ff5 3bc6 cmp eax, esi
| ||||:|| 0x00402ff7 890df8ae4700 mov dword [0x47aef8], ecx ; [0x47aef8:4]=0
| ========< 0x00402ffd 0f8fb2000000 jg 0x4030b5
| ||||:|| 0x00403003 f6450808 test byte [arg_8h], 8
| ========< 0x00403007 7506 jne 0x40300f
| ||||:|| 0x00403009 f6450804 test byte [arg_8h], 4
| ========< 0x0040300d 7541 jne 0x403050
| ||||:|| ; CODE XREF from fcn.00402edd @ 0x403007(x)
| --------> 0x0040300f ff45fc inc dword [var_4h]
| ||||:|| 0x00403012 8d70fc lea esi, [eax - 4]
| ||||:|| 0x00403015 3bfe cmp edi, esi
| ========< 0x00403017 7612 jbe 0x40302b
| ||||:|| 0x00403019 8bfe mov edi, esi
| ========< 0x0040301b eb0e jmp 0x40302b
| ||||:|| ; CODE XREF from fcn.00402edd @ 0x402fa1(x)
| ||`-----> 0x0040301d f6450802 test byte [arg_8h], 2
| ||,=====< 0x00403021 7508 jne 0x40302b
| ||||:|| 0x00403023 6a00 push 0
| ||||:|| 0x00403025 e84ffeffff call fcn.00402e79
| ||||:|| 0x0040302a 59 pop ecx
| ||||:|| ; XREFS: CODE 0x00402fb7 CODE 0x00402fc0 CODE 0x00402fc9
| ||||:|| ; XREFS: CODE 0x00402fd2 CODE 0x00402fdb CODE 0x00403017
| ||||:|| ; XREFS: CODE 0x0040301b CODE 0x00403021
| ```-----> 0x0040302b 3b3504424300 cmp esi, dword [0x434204] ; [0x434204:4]=0
| ,=====< 0x00403031 7d0d jge 0x403040
| ||:|| 0x00403033 57 push edi
| ||:|| 0x00403034 53 push ebx
| ||:|| 0x00403035 ff75f8 push dword [var_8h]
| ||:|| 0x00403038 e84a370000 call fcn.00406787
| ||:|| 0x0040303d 8945f8 mov dword [var_8h], eax
| ||:|| ; CODE XREF from fcn.00402edd @ 0x403031(x)
| `-----> 0x00403040 013df8814200 add dword [0x4281f8], edi ; [0x4281f8:4]=0
| |:|| 0x00403046 2bf7 sub esi, edi
| |:|| 0x00403048 85f6 test esi, esi
| |`===< 0x0040304a 0f8f20ffffff jg 0x402f70
| | || ; CODE XREF from fcn.00402edd @ 0x40300d(x)
| --------> 0x00403050 33db xor ebx, ebx
| | || ; CODE XREF from fcn.00402edd @ 0x402f65(x)
| | |`-> 0x00403052 6a01 push 1 ; 1
| | | 0x00403054 e820feffff call fcn.00402e79
| | | 0x00403059 391df8ae4700 cmp dword [0x47aef8], ebx ; [0x47aef8:4]=0
| | | 0x0040305f 59 pop ecx
| | |,=< 0x00403060 7453 je 0x4030b5
| | || 0x00403062 395dfc cmp dword [var_4h], ebx
| |,===< 0x00403065 7422 je 0x403089
| |||| 0x00403067 ff35f8814200 push dword [0x4281f8]
| |||| 0x0040306d e8d5020000 call fcn.00403347
| |||| 0x00403072 8d4508 lea eax, [arg_8h]
| |||| 0x00403075 6a04 push 4 ; 4
| |||| 0x00403077 50 push eax
| |||| 0x00403078 e8b4020000 call fcn.00403331
| |||| 0x0040307d 85c0 test eax, eax
| ,=====< 0x0040307f 7434 je 0x4030b5
| ||||| 0x00403081 8b45f8 mov eax, dword [var_8h]
| ||||| 0x00403084 3b4508 cmp eax, dword [arg_8h]
| ,======< 0x00403087 752c jne 0x4030b5
| |||||| ; CODE XREF from fcn.00402edd @ 0x403065(x)
| |||`---> 0x00403089 ff75ec push dword [var_14h]
| ||| || 0x0040308c 6a40 push 0x40 ; '@' ; 64
| ||| || 0x0040308e ff1534814000 call dword [sym.imp.KERNEL32.dll_GlobalAlloc] ; 0x408134 ; "j\x8a"
| ||| || 0x00403094 8bf0 mov esi, eax
| ||| || 0x00403096 a1f8ae4700 mov eax, dword [0x47aef8] ; [0x47aef8:4]=0
| ||| || 0x0040309b 83c01c add eax, 0x1c ; 28
| ||| || 0x0040309e 50 push eax
| ||| || 0x0040309f e8a3020000 call fcn.00403347
| ||| || 0x004030a4 ff75ec push dword [var_14h]
| ||| || 0x004030a7 56 push esi
| ||| || 0x004030a8 53 push ebx
| ||| || 0x004030a9 6aff push 0xffffffffffffffff
| ||| || 0x004030ab e866000000 call fcn.00403116
| ||| || 0x004030b0 3b45ec cmp eax, dword [var_14h]
| |||,===< 0x004030b3 7411 je 0x4030c6
| |||||| ; CODE XREFS from fcn.00402edd @ 0x402ffd(x), 0x403060(x), 0x40307f(x), 0x403087(x), 0x4030c4(x)
| .``---`-> 0x004030b5 b850a04000 mov eax, str.Installer_integrity_check_has_failed._Common_causes_include_nincomplete_download_and_damaged_media._Contact_the_ninstallers_author_to_obtain_a_new_copy._n_nMore_information_at:_nhttp:__nsis.sf.net_NSIS_Error ; 0x40a050 ; u"Installer integrity check has failed. Common causes include\nincomplete download and damaged media. Contact the\ninstaller's author to obtain a new copy.\n\nMore information at:\nhttp://nsis.sf.net/NSIS_Error"
| : |||,=< 0x004030ba eb53 jmp 0x40310f
| : |||| ; CODE XREF from fcn.00402edd @ 0x402f94(x)
| : `----> 0x004030bc 6a01 push 1 ; 1
| : ||| 0x004030be e8b6fdffff call fcn.00402e79
| : ||| 0x004030c3 59 pop ecx
| `=======< 0x004030c4 ebef jmp 0x4030b5
| ||| ; CODE XREF from fcn.00402edd @ 0x4030b3(x)
| `---> 0x004030c6 f645d801 test byte [var_28h], 1
| || 0x004030ca 8935f4ae4700 mov dword [0x47aef4], esi ; [0x47aef4:4]=0
| || 0x004030d0 8b06 mov eax, dword [esi]
| || 0x004030d2 a3fcae4700 mov dword [0x47aefc], eax ; [0x47aefc:4]=0
| ,===< 0x004030d7 7406 je 0x4030df
| ||| 0x004030d9 ff0500af4700 inc dword [0x47af00]
| ||| ; CODE XREF from fcn.00402edd @ 0x4030d7(x)
| `---> 0x004030df 6a08 push 8 ; 8
| || 0x004030e1 8d4644 lea eax, [esi + 0x44]
| || 0x004030e4 59 pop ecx
| || ; CODE XREF from fcn.00402edd @ 0x4030eb(x)
| .---> 0x004030e5 83e808 sub eax, 8
| :|| 0x004030e8 0130 add dword [eax], esi
| :|| 0x004030ea 49 dec ecx
| `===< 0x004030eb 75f8 jne 0x4030e5
| || 0x004030ed 6a01 push 1 ; 1
| || 0x004030ef 53 push ebx
| || 0x004030f0 53 push ebx
| || 0x004030f1 ff75f4 push dword [var_ch]
| || 0x004030f4 ff1544814000 call dword [sym.imp.KERNEL32.dll_SetFilePointer] ; 0x408144
| || 0x004030fa 89463c mov dword [esi + 0x3c], eax
| || 0x004030fd 83c604 add esi, 4
| || 0x00403100 6a40 push 0x40 ; '@' ; 64
| || 0x00403102 56 push esi
| || 0x00403103 6820af4700 push 0x47af20
| || 0x00403108 e85e2c0000 call fcn.00405d6b
| || 0x0040310d 33c0 xor eax, eax
| || ; CODE XREFS from fcn.00402edd @ 0x402f32(x), 0x4030ba(x)
| ``-> 0x0040310f 5f pop edi
| 0x00403110 5e pop esi
| 0x00403111 5b pop ebx
| 0x00403112 c9 leave
\ 0x00403113 c20400 ret 4
ეს არის სრული ASM კოდი. აქვე რამდენიმე საინტერესო ტექსტია:
Error launching installerInstsoftNullInstaller integrity check has failed. Common causes include nincomplete download and damaged media.
თანდათან ვხვდები, რომ სტატიკური ანალიზის დრო იწურება და დროა დინამიურ ანალიზზე გადავიდე. შესაძლოა მართლა რაღაცის ინსტალერია, მაგრამ აშკარაა, რომ შიგნით რაღაც ცუდი ხდება.


