-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
276 lines (267 loc) · 42.2 KB
/
search.xml
File metadata and controls
276 lines (267 loc) · 42.2 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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>从一次前端js加密再到mitm中间人脚本</title>
<url>/2024/02/10/js_to_mitmproxy/</url>
<content><![CDATA[<h2 id="从一次前端-js-加密再到-mitm-中间人脚本"><a href="#从一次前端-js-加密再到-mitm-中间人脚本" class="headerlink" title="从一次前端 js 加密再到 mitm 中间人脚本"></a>从一次前端 js 加密再到 mitm 中间人脚本</h2><h3 id="0X00-前端-JS-加密的加解密"><a href="#0X00-前端-JS-加密的加解密" class="headerlink" title="0X00 前端 JS 加密的加解密"></a>0X00 前端 JS 加密的加解密</h3><h4 id="1、前因"><a href="#1、前因" class="headerlink" title="1、前因"></a>1、前因</h4><ul>
<li>在一次渗透测试中,项目经理给了一批小程序的资产,在挖洞的过程中,发现了一个流量加密的点,因为以前看过很多文章通过分析 js 文件来实现加解密数据,自己也想来实战一下通过分析 js 文件来实现加解密<ul>
<li>谢公子的文章:<a href="https://mp.weixin.qq.com/s?__biz=MzI2NDQyNzg1OA==&mid=2247486046&idx=1&sn=e529bd2e2e781cb3def94225e2e3e863&chksm=eaad8a63ddda0375efd13f4df685d26bffe6ab29cee006ee2a43943cad2de80c98a4923864e0&mpshare=1&scene=1&srcid=1207cJo0qLHhjril5xmW6Kvi&sharer_sharetime=1607352511438&sharer_shareid=13de7cf246df94cfb693d05988b76aac&key=41897554b8f6847ed8cfccee66c19bd9540ee8deb6d245378561f9771d6c0900ac6656056db1cb710da3a96f9fff53e26778ebca5b8bdb9ed6cde840a767cac7d2c83546be85abe9675edd1755fa3a01fb4960bd5f16eaacfb30dc2be9abcf93a03af13a0391a107b76ddabf5c4f1c5e71804bb6df28018ae76fda9721aabe85&ascene=1&uin=MjYzNzU1MTExOQ%3D%3D&devicetype=Windows+10+x64&version=6300002f&lang=zh_CN&exportkey=A3p7YMO5z2%2B7s6erXBDQ8iY%3D&pass_ticket=j3w8TlVmPs9N80MO5TFJBD7B5UBteDVgYV%2F8ZHp9b5yGtAXAvTP9pPL5H0yBeKHA&wx_header=0" target="_blank" rel="noopener">浅析绕过 js 加密</a></li>
<li>酒仙桥六号部队的文章:<a href="https://mp.weixin.qq.com/s?__biz=MzAwMzYxNzc1OA==&mid=2247487489&idx=1&sn=742d096897ec68aa56b5ca6f1487ff8a&chksm=9b3936b0ac4ebfa6c7bdccff3bb2925060890124909d677be38e739a1b53266c2f85b66d2d69&mpshare=1&scene=1&srcid=1207OrxzaeK9ckVL9857JMtf&sharer_sharetime=1607352591412&sharer_shareid=13de7cf246df94cfb693d05988b76aac&key=ed33fadcd7748f6a66b9261cd211185fb382047b4897da09ba209d7f06af9e1aff0c86d9b3e1c874d0393a538cc27daf36d40279ea1b7f6b5be038c57e6562f57fc9bb2d40284a7759ce3ac613af175a719706f1f9afa135276b87ef4abac0923702de4150cf27dcedfa5119e07ccfeb7b551b9f1b52600024ebf9d60b1e67b9&ascene=1&uin=MjYzNzU1MTExOQ%3D%3D&devicetype=Windows+10+x64&version=6300002f&lang=zh_CN&exportkey=AzOgolmxO3RY7b1N0n5f2RE%3D&pass_ticket=j3w8TlVmPs9N80MO5TFJBD7B5UBteDVgYV%2F8ZHp9b5yGtAXAvTP9pPL5H0yBeKHA&wx_header=0" target="_blank" rel="noopener">前端加密加签之 sqlmap 自动化测试</a></li>
</ul>
</li>
<li>在 Burpsuite 中可以发现数据包中 POST 的 body 字段和响应包的 body 字段数据都是加密的,想到公司大佬的一句话“只要是前端加密,我都能给你解密”</li>
</ul>
<p><img src="/images/js/image-20201207132142502.png" alt="image-20201207132142502"></p>
<h4 id="2、拖下小程序源码"><a href="#2、拖下小程序源码" class="headerlink" title="2、拖下小程序源码"></a>2、拖下小程序源码</h4><ul>
<li>思路过程:adb 连接模拟器 -> 找到小程序的源码包 wxapkg -> 使用 adb pull 进行拉取到本地 -> 通过 unpack 工具来解出源码,具体的小程序脱包教程以及工具文章,感兴趣的大哥可以从雷神众测上查看<a href="https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzI0NzEwOTM0MA==&action=getalbum&album_id=1368680445315235841&scene=173&from_msgid=2652476342&from_itemidx=1&count=3#wechat_redirect" target="_blank" rel="noopener">Poc Sir</a>的文章<ul>
<li>xuedingmiaojun 大佬的不带 GUI 界面:<a href="https://github.com/xuedingmiaojun/wxappUnpacker" target="_blank" rel="noopener">wxappUnpacker</a></li>
<li>xuedingmiaojun 大佬的带 GUI 界面:<a href="https://github.com/xuedingmiaojun/mp-unpack" target="_blank" rel="noopener">mp-unpack</a>(实测此工具能较完善解析 wxapkg 包)</li>
</ul>
</li>
</ul>
<p><img src="/images/js/image-20201207132433238.png" alt="image-20201207132433238"></p>
<p><img src="/images/js/image-20201207132822003.png" alt="image-20201207132822003"></p>
<h4 id="3、快速分析源码"><a href="#3、快速分析源码" class="headerlink" title="3、快速分析源码"></a>3、快速分析源码</h4><ul>
<li>使用 Sublime 打开压缩包的文件,来进行源码的查看</li>
</ul>
<p><img src="/images/js/image-20201207133009652.png" alt="image-20201207133009652"></p>
<ul>
<li>从刚才抓取的 Burpsuite 的数据包中的请求连接,全局匹配对应的句子,发现了在/pages/myInfo 目录下的 A.api.js 文件进行了 POST 请求</li>
</ul>
<p><img src="/images/js/image-20201207133237727.png" alt="image-20201207133237727"></p>
<ul>
<li>跟进对应的 js 文件,发现通过 t.request 方法来发送一个 POST 请求</li>
</ul>
<p><img src="/images/js/image-20201207133443596.png" alt="image-20201207133443596"></p>
<ul>
<li>跟进 t.request 方法,发现是导入/utils 目录下的 request 模块</li>
</ul>
<p><img src="/images/js/image-20201207133615515.png" alt="image-20201207133615515"></p>
<ul>
<li>跟进 request.js 文件,发现默认导出为 a,a 又通过函数 p 来进行赋值,在这个过程中,又通过引入 o.default 来进行传参</li>
</ul>
<p><img src="/images/js/image-20201207134041254.png" alt="image-20201207134041254"></p>
<ul>
<li>跟进 o.default,发现是通过导入/miniprogram_npm/wx-weapp-tool/index 下的 index 模块来实现的</li>
</ul>
<p><img src="/images/js/image-20201207134147765.png" alt="image-20201207134147765"></p>
<ul>
<li>跟进 index.js 文件,发现默认导出为 y,y 又通过 g 去赋值,搜索包含 g 的参数或者函数,发现 g 函数,g 函数中有对 o 的处理,通过 c.default.encrypt 来进行加密</li>
</ul>
<p><img src="/images/js/image-20201207134453778.png" alt="image-20201207134453778"></p>
<ul>
<li>搜索 c 的相关函数或者其他变量,发现是导入 d2jk-share-templates 目录下的 aes 模块</li>
</ul>
<p><img src="/images/js/image-20201207141754540.png" alt="image-20201207141754540"></p>
<ul>
<li>跟进 aes.js 文件,发现此文件就是最后的加密函数,以及加解密方法为 AES 加密结合 Base64 加密,可以通过导入 crypto-js 库来实现</li>
</ul>
<p><img src="/images/js/image-20201207141849011.png" alt="image-20201207141849011"></p>
<ul>
<li>将此文件进行导出,重新定义为 ase.js 文件,在终端进行加解密尝试,发现解密成功</li>
</ul>
<p><img src="/images/js/image-20201207142451440.png" alt="image-20201207142451440"></p>
<ul>
<li>对响应包的内容进行解密,发现了身份证以及手机号</li>
</ul>
<p><img src="/images/js/image-20201207142919931.png" alt="image-20201207142919931"></p>
<ul>
<li>在 lo 出数据后,发现通过黏贴密文,再输入 key 的方式效率实在是太低了,准备打算写一个自动化的中间人脚本来实现此过程</li>
</ul>
<h3 id="0X01-mitm-中间人脚本编写"><a href="#0X01-mitm-中间人脚本编写" class="headerlink" title="0X01 mitm 中间人脚本编写"></a>0X01 mitm 中间人脚本编写</h3><h4 id="1、需求前提"><a href="#1、需求前提" class="headerlink" title="1、需求前提"></a>1、需求前提</h4><ul>
<li>实现原理图</li>
</ul>
<p><img src="/images/js/image-20201208001317260.png" alt="image-20201208001317260"></p>
<ul>
<li><p>所需工具</p>
<ul>
<li>python 3.6</li>
<li>mitmproxy 5.0.1</li>
<li>Burpsuite</li>
</ul>
</li>
<li><p>参考文章推荐</p>
<ul>
<li><a href="https://www.freebuf.com/articles/web/243370.html" target="_blank" rel="noopener">Burpsuite+Mitmproxy+Python 解决 Web 渗透测试过程中遇到的自定义 JS 加密防护</a></li>
<li><a href="https://www.cnblogs.com/linlang781/p/8868496.html" target="_blank" rel="noopener">python 调用 JS 方法</a></li>
</ul>
</li>
</ul>
<h4 id="2、实现过程"><a href="#2、实现过程" class="headerlink" title="2、实现过程"></a>2、实现过程</h4><ul>
<li>js 文件的模板函数导出,方便外部的调用</li>
</ul>
<figure class="highlight javascript"><table><tr><td class="code"><pre><span class="line"><span class="built_in">module</span>.exports.enc = <span class="function"><span class="keyword">function</span> (<span class="params">data</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(i.encrypt(data, i.key))</span><br><span class="line">}</span><br><span class="line"><span class="built_in">module</span>.exports.dec = <span class="function"><span class="keyword">function</span> (<span class="params">data</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(i.decrypt(data, i.key))</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<ul>
<li>加解密函数的编写<ul>
<li>cmd 为要执行的命令,使用 node 的-e 参数,require 调用模块以及模块里面的参数</li>
<li>pipeline 获得 os.popen 后的内容</li>
<li>最后返回 result</li>
</ul>
</li>
</ul>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">enc</span><span class="params">(data)</span>:</span></span><br><span class="line"> cmd = <span class="string">'node -e "require(\\"./ase.js\\").enc(\'%s\')"'</span> % (data)</span><br><span class="line"> pipeline = os.popen(cmd)</span><br><span class="line"> result = pipeline.read()</span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">dec</span><span class="params">(data)</span>:</span></span><br><span class="line"> cmd = <span class="string">'node -e "require(\\"./ase.js\\").dec(\'%s\')"'</span> % (data)</span><br><span class="line"> pipeline = os.popen(cmd)</span><br><span class="line"> result = pipeline.read()</span><br><span class="line"> <span class="keyword">return</span> result</span><br></pre></td></tr></table></figure>
<ul>
<li><p>mitm 第一层代理的编写</p>
<ul>
<li><p>需要接受来自客户端的加密请求,可以通过<code>mitmdump -p 8081</code>去监听端口,客户端设置 8081 端口进行代理流量</p>
</li>
<li><p>接收来自客户端的加密数据,进行解密,然后发送给 Burpsuite</p>
</li>
</ul>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">request</span><span class="params">(self, flow: http.HTTPFlow)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">enc</span><span class="params">(data)</span>:</span></span><br><span class="line"> cmd = <span class="string">'node -e "require(\\"./ase.js\\").enc(\'%s\')"'</span> % (data)</span><br><span class="line"> pipeline = os.popen(cmd)</span><br><span class="line"> result = pipeline.read()</span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">dec</span><span class="params">(data)</span>:</span></span><br><span class="line"> cmd = <span class="string">'node -e "require(\\"./ase.js\\").dec(\'%s\')"'</span> % (data)</span><br><span class="line"> pipeline = os.popen(cmd)</span><br><span class="line"> result = pipeline.read()</span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"> req_data = flow.request.get_text()</span><br><span class="line"> <span class="keyword">if</span> req_data:</span><br><span class="line"> print(<span class="string">"req:"</span>+req_data)</span><br><span class="line"> print(<span class="string">"解密:"</span>+dec(req_data))</span><br><span class="line"> flow.request.set_text(dec(req_data))</span><br></pre></td></tr></table></figure>
<ul>
<li>发送来自 Burpsuite 的解密数据,进行加密,然后发送给客户端</li>
</ul>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">response</span><span class="params">(self, flow: http.HTTPFlow)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">enc</span><span class="params">(data)</span>:</span></span><br><span class="line"> cmd = <span class="string">'node -e "require(\\"./ase.js\\").enc(\'%s\')"'</span> % (data)</span><br><span class="line"> print(cmd)</span><br><span class="line"> pipeline = os.popen(cmd)</span><br><span class="line"> result = pipeline.buffer.read().decode(encoding=<span class="string">"utf-8"</span>) <span class="comment"># 因为中文编码问题会报错,这里需要进行utf-8编码</span></span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">dec</span><span class="params">(data)</span>:</span></span><br><span class="line"> cmd = <span class="string">'node -e "require(\\"./ase.js\\").dec(\'%s\')"'</span> % (data)</span><br><span class="line"> pipeline = os.popen(cmd)</span><br><span class="line"> result = pipeline.buffer.read().decode(encoding=<span class="string">"utf-8"</span>) <span class="comment"># 因为中文编码问题会报错,这里需要进行utf-8编码</span></span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"> resp_data = flow.response.get_text()</span><br><span class="line"> <span class="keyword">if</span> resp_data:</span><br><span class="line"> print(resp_data.strip(<span class="string">'\n'</span>))</span><br><span class="line"> flow.response.set_text(dec(resp_data.strip(<span class="string">'\n'</span>)))</span><br></pre></td></tr></table></figure>
<ul>
<li><p>设置上游代理为 Burpsuite,进行数据包的转发<code>mitmdump -p 8081 -m upstream:http://127.0.0.1:8080 -s min.py -k</code></p>
<ul>
<li>-m 为指定上游代理模块,这里为 Burpsuite 监听的端口</li>
<li>-k 为忽略证书的错误,同时也需要在客户端中安装 mitm 的证书(安装 mitm 的证书在设置代理的情况下访问<a href="https://mitm.it下载即可)" target="_blank" rel="noopener">https://mitm.it下载即可)</a></li>
<li>-s 为指定使用的脚本</li>
</ul>
<p><img src="/images/js/image-20201208100558530.png" alt="image-20201208100558530"></p>
</li>
<li><p>发现已经可以正常的对请求报进行解密</p>
</li>
</ul>
<p><img src="/images/js/image-20201208100941327.png" alt="image-20201208100941327"></p>
</li>
<li><p>Burpsuite 的设置</p>
<ul>
<li>监听 8080 端口,接收来自 mitm 第一层代理的数据</li>
<li>设置上层代理为 mitm 第三层代理,进行数据包的转发</li>
</ul>
</li>
</ul>
<p><img src="/images/js/image-20201208101410378.png" alt="image-20201208101410378"></p>
<ul>
<li><p>mitm 第三层代理的编写</p>
<ul>
<li>接收来自 Burpsuite 的解密后的数据,可以通过<code>mitmdump -p 8088</code>去监听端口</li>
<li>接收来自 Burpsuite 的解密数据,进行加密,然后发送给服务端</li>
</ul>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">request</span><span class="params">(self, flow: http.HTTPFlow)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">enc</span><span class="params">(data)</span>:</span></span><br><span class="line"> cmd = <span class="string">'node -e "require(\\"./ase.js\\").enc(\'%s\')"'</span> % (data.strip(<span class="string">'\n'</span>))</span><br><span class="line"> print(cmd)</span><br><span class="line"> pipeline = os.popen(cmd)</span><br><span class="line"> result = pipeline.buffer.read().decode(encoding=<span class="string">"utf-8"</span>)<span class="comment"># 因为中文编码问题会报错,这里需要进行utf-8编码</span></span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">dec</span><span class="params">(data)</span>:</span></span><br><span class="line"> cmd = <span class="string">'node -e "require(\\"./ase.js\\").dec(\'%s\')"'</span> % (data)</span><br><span class="line"> pipeline = os.popen(cmd)</span><br><span class="line"> result = pipeline.buffer.read().decode(encoding=<span class="string">"utf-8"</span>)<span class="comment"># 因为中文编码问题会报错,这里需要进行utf-8编码</span></span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"> req_data = flow.request.get_text()</span><br><span class="line"> <span class="keyword">if</span> req_data:</span><br><span class="line"> print(req_data)</span><br><span class="line"> print(<span class="string">"sdasdasdasa"</span>)</span><br><span class="line"> req_data = req_data.replace(<span class="string">'"'</span>,<span class="string">'\\"'</span>)</span><br><span class="line"> print(<span class="string">"req:"</span>+req_data)</span><br><span class="line"> print(<span class="string">"加密:"</span>+enc(req_data))</span><br><span class="line"> flow.request.set_text(enc(req_data))</span><br></pre></td></tr></table></figure>
<ul>
<li>发送来自服务端的加密数据,进行解密,然后发送给 Burpsuite</li>
</ul>
<figure class="highlight python"><table><tr><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">response</span><span class="params">(self, flow: http.HTTPFlow)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">enc</span><span class="params">(data)</span>:</span></span><br><span class="line"> cmd = <span class="string">'node -e "require(\\"./ase.js\\").enc(\'%s\')"'</span> % (data)</span><br><span class="line"> print(cmd)</span><br><span class="line"> pipeline = os.popen(cmd)</span><br><span class="line"> result = pipeline.buffer.read().decode(encoding=<span class="string">"utf-8"</span>)<span class="comment"># 因为中文编码问题会报错,这里需要进行utf-8编码</span></span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">dec</span><span class="params">(data)</span>:</span></span><br><span class="line"> cmd = <span class="string">'node -e "require(\\"./ase.js\\").dec(\'%s\')"'</span> % (data)</span><br><span class="line"> pipeline = os.popen(cmd)</span><br><span class="line"> result = pipeline.buffer.read().decode(encoding=<span class="string">"utf-8"</span>)<span class="comment"># 因为中文编码问题会报错,这里需要进行utf-8编码</span></span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"> resp_data = flow.response.get_text()</span><br><span class="line"> <span class="keyword">if</span> resp_data:</span><br><span class="line"> print(<span class="string">"req:"</span>+resp_data)</span><br><span class="line"> print(<span class="string">"解密:"</span>+dec(resp_data))</span><br><span class="line"> print(resp_data.strip(<span class="string">'\n'</span>))</span><br><span class="line"> flow.response.set_text(dec(resp_data.strip(<span class="string">'\n'</span>)))</span><br></pre></td></tr></table></figure>
<ul>
<li>设置转发给服务器,进行数据包的转发<code>mitmdump -p 8088 -s min.py -k</code></li>
</ul>
<p><img src="/images/js/image-20201208103439259.png" alt="image-20201208103439259"></p>
<ul>
<li>使用 Burpsuite 的 Repeater 模块进行测试,发现已经可以正常加解密了</li>
</ul>
<p><img src="/images/js/image-20201208103721232.png" alt="image-20201208103721232"></p>
<p><img src="/images/js/image-20201208104630280.png" alt="image-20201208104630280"></p>
</li>
</ul>
<h3 id="0X02-总结"><a href="#0X02-总结" class="headerlink" title="0X02 总结"></a>0X02 总结</h3><p> 这次的过程中也存在着很多问题,请各位路过的大哥大姐大佬等不吝指导,后续想集成一个 Burpsuite 插件,可以自定义需要加解密的目标地址方便渗透测试加解密,只需要导入加密的 js 文件即可,各个论坛网站上也有各个大佬开发的插件脚本,想后续继续深入学习</p>
]]></content>
<categories>
<category>javascript</category>
</categories>
</entry>
<entry>
<title>汇总一下konga的代码审计流程</title>
<url>/2024/02/10/konga_audit/</url>
<content><![CDATA[<p>▶️ 代码是javascript写的,基于Sails进行部署开发,所以也是我第一次意义上的审计javascript后端项目</p>
<p>项目地址:<a href="https://github.com/pantsel/konga" target="_blank" rel="noopener">GitHub - pantsel/konga: More than just another GUI to Kong Admin API</a></p>
<h5 id="先上一下历史ISSUE以及PR中提到的问题"><a href="#先上一下历史ISSUE以及PR中提到的问题" class="headerlink" title="先上一下历史ISSUE以及PR中提到的问题"></a>先上一下历史ISSUE以及PR中提到的问题</h5><p>1、privilege escalation: <a href="https://github.com/pantsel/konga/commit/af43bee30f69cd6628d53c37a48724686af2849b" target="_blank" rel="noopener">Fix priviledged escalation · pantsel/konga@af43bee · GitHub</a></p>
<p>2、xss vuln: <a href="https://github.com/pantsel/konga/commit/16e36e8bc855b2cd01e34bab4f0e001fd477d22d" target="_blank" rel="noopener">Merge branch ‘fix/xss-vuln’ into next · pantsel/konga@16e36e8 · GitHub</a></p>
<p>3、multiple registed: <a href="https://github.com/pantsel/konga/commit/37fce1c72b5edefff10ef61aaeb3c860708ca114" target="_blank" rel="noopener">Prevent admin users to be registered multiple times via the /register… · pantsel/konga@37fce1c · GitHub</a></p>
<p>上述三个为公开的漏洞,但是没有CVE编码,外网公开的还有一个Secret的问题,但是其实出现的概率很多,只有没有设置TOKEN_SECRET的时候才会出现密钥泄漏,最后导致可自定义构造JWT进行任意用户登陆,但是感觉用处也比较少</p>
<h5 id="后台nodemailer组件-配置修改-gt-RCE"><a href="#后台nodemailer组件-配置修改-gt-RCE" class="headerlink" title="后台nodemailer组件+配置修改->RCE"></a>后台nodemailer组件+配置修改->RCE</h5><p>这一步有点运气,主要是看到dependency-check那边报了组件问题nodemailer在send()函数存在可命令执行的地方,前提是需要覆盖两个参数或者进行原型污染</p>
<p>可以参考来自这篇文章:<a href="https://bycsec.top/2021/03/06/D%5E3CTF-8-bit-pub/" target="_blank" rel="noopener">D^3CTF 8-bit-pub - byc_404’s blog</a></p>
<p>问题主要是以下代码处:lib/sendmail-transport/index.js,在SendmailTransport类中的send()方法,在发送之前会调用<code>this._spoawn(this.path, args)</code>,其中<code>const spawn = require('child_process').spawn;</code>,所以会进行命令执行</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111.png" alt=""></p>
<p>this.path以及args是在初始化(new SendmailTransport)的时候进行赋值,也就是说,只要控制了this.path以及args,就可以达成命令执行</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-1.png" alt=""></p>
<p>可以来看下konga中怎么实现的,有三个关键的文件如下,这三个文件都会调用到邮件来进行发送,三个文件的导出函数都一样,所以这里用其中的一个来讲即可</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">konga-0.13.0/api/events/node-health-checks.js</span><br><span class="line">konga-0.13.0/api/events/api-health-checks.js</span><br><span class="line">konga-0.13.0/api/events/user-events.js</span><br></pre></td></tr></table></figure>
<p>其中关注点为导出函数createTransporter以及notify</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-2.png" alt=""><br>createTransporter为创建一个transport,也就是邮件发送的方式,其中transport为可控,也就是我们传进去的参数</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-3.png" alt=""></p>
<p>可以看到下面的图,当options.sendmail为true的时候,会new一个SendmailTransport,我们这里可以构造transport.settings其中一个参数的值为:<code>sendmail:true</code>,即可以进入到SendmailTransport的构造方法</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-4.png" alt=""></p>
<p>其实我们也不难发现,options参数,也就是transport.settings参数也会被带入到SendmailTransport中,也就以为着参数中存在path以及args即可以造成RCE,此处完整payload如下</p>
<p><code>"settings":{"sendmail":"true","path":"/bin/bash","args":["-c","echo 1 > /tmp/44.txt"]}</code></p>
<p>当创建好了SendmailTransport的时候,就需要用到发送的函数,在konga中是notify,在notify中会直接调用sendmail函数,也就是在发送邮件的时候会造成RCE</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-6.png" alt=""></p>
<p>mailer.sendMail()会继续调用到this.transporter.send(),而this.transporter.send()为SendmailTransport.send()</p>
<p><img src="/images/konga_auditsources/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-26.png" alt=""></p>
<p>数据包为如下:</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-5.png" alt=""></p>
<p>当default_transport为smtp或者mailgun的时候,即可以造成RCE,这里有一个比较可惜的一个点,这个default_transport的设置需要管理员,不然普通用户通过api的接口也可以实现RCE</p>
<figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">这里发送邮件有三种方式,当一个node或者api下线或者掉线的时候会发送邮件(node及时发生,api需要经过15分钟),或者当一个用户singup的时候,也会发送邮件,其中api下线或者掉线都可以通过普通用户权限来实现</span><br></pre></td></tr></table></figure>
<p>最后给以下完整的流程</p>
<p>先开启其中一个</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-27.png" alt=""></p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-8.png" alt=""></p>
<p>接着配置邮件</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-9.png" alt=""></p>
<p>可以抓到包,替换一下payload,替换的是data字段</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-10.png" alt=""></p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-11.png" alt=""></p>
<p>数据库也被成功写入</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-12.png" alt=""></p>
<p>设置api或者node下线或者掉线又或者用户注册的时候,即可以实现RCE</p>
<p>下图为成功进行用户注册</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-20.png" alt=""></p>
<p>成功写入文件</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-19.png" alt=""></p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-21.png" alt=""></p>
<p>这里要提一下,之前有人提过nodemailer的这个问题,不过是注入邮件,来自如下链接:<a href="https://security.snyk.io/vuln/SNYK-JS-NODEMAILER-1038834" target="_blank" rel="noopener">Command Injection in nodemailer | CVE-2020-7769 | Snyk</a></p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-15.png" alt=""></p>
<p>官方的修复手法是添加校验发送地址以及接收地址是否存在,所以我更愿意觉得这个spawn()是nodemailer的一个特性,最新一版依旧可以利用</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-16.png" alt=""></p>
<p>▶️ 思考:是否可以通过原型污染的方式来覆盖<code>settings[0].data.default_transport</code>的方式来实现低权限用户RCE?</p>
<h5 id="signup接口的crash服务"><a href="#signup接口的crash服务" class="headerlink" title="signup接口的crash服务"></a>signup接口的crash服务</h5><p>漏洞原理很简单,也是无意间测试出来的,路径:konga-0.13.0/api/controllers/AuthController.js</p>
<p>在注册的时候会对protocol进行赋值</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-17.png" alt=""></p>
<p>而protocol的参数又是必须的,路径:konga-0.13.0/api/models/Passport.js</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-18.png" alt=""></p>
<p>所以会导致当注册的时候不存在参数passports.protocol的时候,会直接带出异常,又因为是在赋值的是时候抛出的异常,还没进入到create()函数中,所以没有进行异常处理,最后导致服务crash掉,直接引用GPT的解释</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-25.png" alt=""></p>
<p>正常的注册包</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-22.png" alt=""></p>
<p>删除参数后的注册包</p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-23.png" alt=""></p>
<p><img src="/images/konga_audit/%E6%B1%87%E6%80%BB%E4%B8%80%E4%B8%8Bkonga%E7%9A%84%E4%BB%A3%E7%A0%81%E5%AE%A1%E8%AE%A1%E8%BF%87%E7%A8%8B-20240111-24.png" alt=""></p>
<h5 id="贴一下konga和kong的部署"><a href="#贴一下konga和kong的部署" class="headerlink" title="贴一下konga和kong的部署"></a>贴一下konga和kong的部署</h5><figure class="highlight plain"><table><tr><td class="code"><pre><span class="line">docker run -d --name kong-database \</span><br><span class="line"> -p 5432:5432 \</span><br><span class="line"> -e "POSTGRES_USER=kong" \</span><br><span class="line"> -e "POSTGRES_DB=kong" \</span><br><span class="line"> -e "POSTGRES_PASSWORD=kongpass" \</span><br><span class="line"> postgres:9.6</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">docker run --rm \</span><br><span class="line"> -e "KONG_DATABASE=postgres" \</span><br><span class="line"> -e "KONG_PG_HOST=10.211.55.115" \</span><br><span class="line"> -e "KONG_PG_USER=kong" \</span><br><span class="line"> -e "KONG_PG_PASSWORD=kongpass" \</span><br><span class="line">rjshrjndrn/kong:0.14.1 kong migrations up</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">docker run -d --name kong \</span><br><span class="line"> -e "KONG_DATABASE=postgres" \</span><br><span class="line"> -e "KONG_PG_HOST=10.211.55.115" \</span><br><span class="line"> -e "KONG_PG_USER=kong" \</span><br><span class="line"> -e "KONG_PG_PASSWORD=kongpass" \</span><br><span class="line"> -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \</span><br><span class="line"> -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \</span><br><span class="line"> -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \</span><br><span class="line"> -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \</span><br><span class="line"> -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \</span><br><span class="line"> -e "KONG_ADMIN_GUI_URL=http://localhost:8002" \</span><br><span class="line"> -e KONG_LICENSE_DATA \</span><br><span class="line"> -p 8000:8000 \</span><br><span class="line"> -p 8443:8443 \</span><br><span class="line"> -p 8001:8001 \</span><br><span class="line"> -p 8444:8444 \</span><br><span class="line"> -p 8002:8002 \</span><br><span class="line"> -p 8445:8445 \</span><br><span class="line"> -p 8003:8003 \</span><br><span class="line"> -p 8004:8004 \</span><br><span class="line"> rjshrjndrn/kong:0.14.1</span><br><span class="line"></span><br><span class="line">curl -i -X GET --url http://10.211.55.115:8001/services</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">sudo docker pull pantsel/konga:0.13.0</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">docker run --rm pantsel/konga:0.13.0 -c prepare -a postgres -u postgres://kong:[email protected]:5432/konga</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">docker run -p 1337:1337 --name konga \</span><br><span class="line"> -e "TOKEN_SECRET=@Aa@123456" \</span><br><span class="line"> -e "DB_ADAPTER=postgres" \</span><br><span class="line"> -e "DB_HOST=10.211.55.115" \</span><br><span class="line"> -e "DB_PORT=5432" \</span><br><span class="line"> -e "DB_USER=kong" \</span><br><span class="line"> -e "DB_PASSWORD=kongpass" \</span><br><span class="line"> -e "DB_DATABASE=konga" \</span><br><span class="line"> -e "NODE_ENV=production" \</span><br><span class="line"> pantsel/konga:0.13.0</span><br></pre></td></tr></table></figure>
]]></content>
<categories>
<category>javascript</category>
</categories>
</entry>
<entry>
<title>2023年年度总结</title>
<url>/2024/02/10/2023_final/</url>
<content><![CDATA[<h3 id="论"><a href="#论" class="headerlink" title="论"></a><strong>论</strong></h3><p>2023年年度总结,第一次写年度总结,脑子有很多想说的,但是如同今年自己的目标、工作以及生活一样混乱。</p>
<h3 id="叙"><a href="#叙" class="headerlink" title="叙"></a><strong>叙</strong></h3><h5 id="爱情里"><a href="#爱情里" class="headerlink" title="爱情里"></a>爱情里</h5><p>重庆三次,广西两次,深圳广州三次,一年平均下来八次,还远远达不到之前预想的一个月一次见面,今年受到下述工作上的不平衡,下一年势必要进行调整(PS: 朋友圈还有好多我跟女朋友的照片哈哈哈)</p>
<p><img src="/images/2023_final/2023%E5%B9%B4%E5%B9%B4%E5%BA%A6%E6%80%BB%E7%BB%93-20240209-1.jpg" alt="2023年年度总结-20240209-1.jpg"></p>
<h5 id="工作上"><a href="#工作上" class="headerlink" title="工作上"></a>工作上</h5><p>Q1的期望、Q2Q3攻防的忙碌、Q4的迷茫与转变。</p>
<p>说实话,Q1也忘的差不多了,只觉得没什么特殊的事情,也可能是公司组织架构刚开始调整,也觉得新刚开始的第一年,期望很大,这里的期望就不说了,懂得都懂。</p>
<p>接下来就是Q2Q3,对于我来说,是忙碌的两个季度,也是身体奔溃的两个季度。攻击与防守的无缝衔接,导致我身体直接垮了。印象最深的一次,去完华大基因回来后,三天内都在发高烧,最后去了三趟医院吊了抗生素后依旧高烧,医生都建议我住院,说今晚抗的过去就没事了,这也直接导致了Q4我的迷茫。</p>
<p>Q4来了,项目开始收尾,开始不忙碌了,但是也开始不知道干啥了,学啥时间都不够,学啥进度都太慢,也啥都想学</p>
<p><img src="/images/2023_final/2023%E5%B9%B4%E5%B9%B4%E5%BA%A6%E6%80%BB%E7%BB%93-20240209.jpg" alt="2023年年度总结-20240209.jpg"></p>
<h5 id="生活中"><a href="#生活中" class="headerlink" title="生活中"></a>生活中</h5><p>一塌糊涂,毫无生活,这一年是狠狠糟蹋自己的一年,也是最不爱自己的一年,具体原因就是工作上时间的极度不平衡导致的,具体见工作上</p>
<h3 id="转"><a href="#转" class="headerlink" title="转"></a><strong>转</strong></h3><h5 id="2023工作重心开始在攻防上,关注点也逐渐在内网、打点以及代码审计上。"><a href="#2023工作重心开始在攻防上,关注点也逐渐在内网、打点以及代码审计上。" class="headerlink" title="2023工作重心开始在攻防上,关注点也逐渐在内网、打点以及代码审计上。"></a>2023工作重心开始在攻防上,关注点也逐渐在内网、打点以及代码审计上。</h5><p>Q3开始去Dji做代码审计,我也开始转换自己方向为代码审计,开始关注各个语言的相关漏洞以及各个语言的Web漏洞,自我感觉良好的的一个体现是审计konga(在之前的文章中),也跟公司的大哥聊了下,后续可能会更多关注组件特性方面的东西吧,这玩意才是真有意识。</p>
<p>工具开发以及二开方面,关注在asm框架(一个基于k8s的信息收集框架)以及我心心念念的IaC平台;后续想搞一堆tg的机器人,将现有的一些简易工具以及功能先做个简单接入(比如这一年开发的一个爬虫文章保存工具);如果还有的话,可能就Bp的插件了吧(后续有想到什么其他的再慢慢添加吧,先把想做的做完),毕竟岗位摆在这里,就是一个做渗透测试的安服仔</p>
<p>云原生方向的,第一次接触云原生是在华为的面试上,接着就是RJ跟我说的IaC,再接着也是Dji的项目(花了两个星期的云原生渗透+代码审计GUI平台),后续除了基本云原生的渗透之外,可能饭重心在容器上吧,感觉容器逃逸也是一个很不错很有意思的话题</p>
<h5 id="2023生活重心开始转移在多个兴趣上,给自己列了一个清单"><a href="#2023生活重心开始转移在多个兴趣上,给自己列了一个清单" class="headerlink" title="2023生活重心开始转移在多个兴趣上,给自己列了一个清单"></a>2023生活重心开始转移在多个兴趣上,给自己列了一个清单</h5><p>讲粤语在于我能听得懂,但是说出来很怪,所以要练。学英语在于文献还是得国外足,经过一两个月强制英语阅读,现在水平渐渐上去了,看英语没那么痛苦了,自己也给自己制定了一个日常英语训练,现在读写都尽量使用英文了,这样子才能用熟用会</p>
<p>看书集中王阳明的心学上,我开始接触王阳明的传习录,开始接触心学以及理学相关的,当然也开始接触命理学相关的东西,断断续续的看,虽然看的不全,但还是在坚持着。后续可能接触一下孔孟之说,感觉中国传承了这几千年的学说还是挺有意思的,再后续可能就关注一下西方哲学,相互对比,那都是后话了</p>
<p>插花买了云南斗南花市的花还是学习种植修剪哈哈哈,总的来说开始养花陶冶情操,等后续养活了就发朋友圈(养死两批了哈哈哈哈)</p>
<p>CISSP还在等Rj、E神以及DC带带,希望24年能都搞完</p>
<p>中医食疗做饭以及运动锻炼还卡在路上,不过开始关注自己的饮食问题了….</p>
<p>▶️ Note:开始关心自己的身体、自己的生活、更加专注陪在自己身边的人,比如最最最可爱的女朋友!!!</p>
<p><img src="/images/2023_final/2023%E5%B9%B4%E5%B9%B4%E5%BA%A6%E6%80%BB%E7%BB%93-20240209.png" alt="2023年年度总结-20240209.png"></p>
<h3 id="结"><a href="#结" class="headerlink" title="结"></a><strong>结</strong></h3><p>新的一年没啥目标,就是希望自己好好生活好好工作。硬要说的话,就是工作专心在代码审计、工具开发以及云原生上;生活就继续扩展兴趣,去突破自己的交际圈,充实自己</p>
<p><img src="/images/2023_final/2023%E5%B9%B4%E5%B9%B4%E5%BA%A6%E6%80%BB%E7%BB%93-20240209-1.png" alt="2023年年度总结-20240209-1.png"></p>
]]></content>
<categories>
<category>javascript</category>
</categories>
</entry>
</search>