### 简要描述: 继 http://wooyun.org/bugs/wooyun-2014-079938 后第二发,依旧是直接注入非盲注,绝不鸡肋。 看看乌云的奖励怎么样,好的话还有第三发。 ### 详细说明: 一个比较有意思的点,因为安全策略造成的注入。 就拿齐博整站系统为例。 看到/member/userinfo.php,112到114行: ``` //过滤不健康的字 $truename=replace_bad_word($truename); $introduce=replace_bad_word($introduce); $address=replace_bad_word($address); ``` 这几句过滤代码,意思是想过滤一些“不和谐”的词语。那我们看看这个replace_bad_word函数。 ``` function replace_bad_word($str){ global $Limitword; @include_once(ROOT_PATH."data/limitword.php"); foreach( $Limitword AS $old=>$new){ strlen($old)>2 && $str=str_replace($old,trim($new),$str); } return $str; } ``` 实际上是一个str_replace,将旧的“不和谐”词语替换成新的“和谐”词语。那么替换列表从哪来?看看data/limitword.php: ``` <?php $Limitword['造反']='造**'; $Limitword['法轮功']='法**功'; ``` 就这两个,$Limitword并没有初值。而且include之前有global $Limitword。齐博cms是将GET和POST变量注册成全局变量了,所以global取到的可以是$_POST[Limitword]或$_GET[Limitword]。也就是说$Limitword是我们可以控制的。 也就是说,我们可以控制str_replace函数的三个参数。不知道还有没有人记得ecshop曾经的一个注入漏洞(http://zone.wooyun.org/content/2700),原理相同,我再说一遍。...
### 简要描述: 继 http://wooyun.org/bugs/wooyun-2014-079938 后第二发,依旧是直接注入非盲注,绝不鸡肋。 看看乌云的奖励怎么样,好的话还有第三发。 ### 详细说明: 一个比较有意思的点,因为安全策略造成的注入。 就拿齐博整站系统为例。 看到/member/userinfo.php,112到114行: ``` //过滤不健康的字 $truename=replace_bad_word($truename); $introduce=replace_bad_word($introduce); $address=replace_bad_word($address); ``` 这几句过滤代码,意思是想过滤一些“不和谐”的词语。那我们看看这个replace_bad_word函数。 ``` function replace_bad_word($str){ global $Limitword; @include_once(ROOT_PATH."data/limitword.php"); foreach( $Limitword AS $old=>$new){ strlen($old)>2 && $str=str_replace($old,trim($new),$str); } return $str; } ``` 实际上是一个str_replace,将旧的“不和谐”词语替换成新的“和谐”词语。那么替换列表从哪来?看看data/limitword.php: ``` <?php $Limitword['造反']='造**'; $Limitword['法轮功']='法**功'; ``` 就这两个,$Limitword并没有初值。而且include之前有global $Limitword。齐博cms是将GET和POST变量注册成全局变量了,所以global取到的可以是$_POST[Limitword]或$_GET[Limitword]。也就是说$Limitword是我们可以控制的。 也就是说,我们可以控制str_replace函数的三个参数。不知道还有没有人记得ecshop曾经的一个注入漏洞(http://zone.wooyun.org/content/2700),原理相同,我再说一遍。 某变量$str全局做过转义,导致%00转义成了\0.我们能够控制str_replace的前两个参数,则str_replace('0', '', $str),再将0转换成空,则留下了\,这个\可以转义其后的\’,使之变成\\’,导致单引号逃逸出转义符的限制,造成注入。 这里的原理是一样的,只不过齐博cms之前对一些变量做了过滤: ``` $truename=filtrate($truename); $idcard=filtrate($idcard); $telephone=filtrate($telephone); $address=filtrate($address); $introduce=filtrate($introduce); $homepage=filtrate($homepage); function filtrate($msg){ //$msg = str_replace('&','&',$msg); //$msg = str_replace(' ',' ',$msg); $msg = str_replace('"','"',$msg); $msg = str_replace("'",''',$msg); $msg = str_replace("<","<",$msg); $msg = str_replace(">",">",$msg); $msg = str_replace("\t"," ",$msg); //$msg = str_replace("\r","",$msg); $msg = str_replace(" "," ",$msg); return $msg; } ``` 将’等敏感字符过滤了。就算有一个\可以转义一个',但是这里连'都引入不了。 没关系,这个文件是更新用户信息用的,执行的语句类似update table set a='111',b='222' where uid=1,我们引入一个\在111的最后,转义掉111后面的引号,这样222就逃逸出了限制,我们的sql注入语句就可以放在222的位置执行了。这个和之前discuz7.2的faq.php那个注入类似: [WooYun: Discuz7存在一处SQL注射漏洞(无需登录即可触发)](http://www.wooyun.org/bugs/wooyun-2014-066095) 所以,完美构造了一个SQL注入。 ### 漏洞证明: 先注册一个用户: [<img src="https://images.seebug.org/upload/201410/211552026898636fd6011732148069ed76794b47.jpg" alt="04.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201410/211552026898636fd6011732148069ed76794b47.jpg) 记下自己的uid,以便一会更新数据: [<img src="https://images.seebug.org/upload/201410/211552186daca730913860ca1f3c2be322eb7c7d.jpg" alt="05.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201410/211552186daca730913860ca1f3c2be322eb7c7d.jpg) 可以先测试一下是否存在注入: [<img src="https://images.seebug.org/upload/201410/21155337d4108fb46ca53bd7d57a08358a5d94e6.jpg" alt="07.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201410/21155337d4108fb46ca53bd7d57a08358a5d94e6.jpg) 报错了,说明注入是存在的。 简单构造一下,向http://localhost/qibov7/member/userinfo.php?job=edit&step=2发送数据包: truename=xxxx%0000&Limitword[000]=&email=123@qq.com&provinceid=,address=(select user()) where uid=38%23 [<img src="https://images.seebug.org/upload/201410/211552371e4148a225fdaf68fe752d2547e6ee08.jpg" alt="06.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201410/211552371e4148a225fdaf68fe752d2547e6ee08.jpg) 将address注入成为user()。Where后面加上uid=2,防止把其他人的address也注入了。 查看个人注入的地址,即可见注入获得的结果: [<img src="https://images.seebug.org/upload/201410/211554120c2fa5bac227d29b386201d524e53d68.jpg" alt="08.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201410/211554120c2fa5bac227d29b386201d524e53d68.jpg) 这个洞是通杀齐博所有系统的,经测试齐博整站系统、齐博地方门户都可以中招,没试其他一些系统了,我估计很多都得中招。