【代码审计】QYKCMS_v4.3.2 前台存储型XSS跨站脚本漏洞分析

时间:2021-11-21 07:11:13

 

0x00 环境准备

QYKCMS官网:http://www.qykcms.com/

网站源码版本:QYKCMS_v4.3.2(企业站主题)

程序源码下载:http://bbs.qingyunke.com/thread-13.htm

测试网站首页:

 【代码审计】QYKCMS_v4.3.2 前台存储型XSS跨站脚本漏洞分析

0x01 代码分析

1、漏洞文件位置:/include/lib_post.php 第153-200行:

  1. case 'feedback':  
  2.     $fromurl=$_SERVER["HTTP_REFERER"];  
  3.     if(!strstr($fromurl,setup_weburl))ajaxreturn(3,'未知的URL来源,请刷新重新提交或联系工作人员');  
  4.     $lang=strtolower(arg('lang','post','url'));  
  5.     $name=arg('name','post','txt');  
  6.     $email=arg('email','post','url');  
  7.     $phone=arg('phone','post','url');  
  8.     $content=arg('content','post','txt');  
  9.     $attachment=arg('attach称ment','post','url');  
  10. 10.     checkstr($name,'none',1,50,'您的呼');  
  11. 11.     if($email!='')checkstr($email,'email',1,200,'电子邮箱');  
  12. 12.     if($phone!='')checkstr($phone,'none',1,20,'联系电话');  
  13. 13.     checkstr($content,'none',1,1000,'留言内容');  
  14. 14.     if(setup_feedback_cn){  
  15. 15.         if(!preg_match("/[\x7f-\xff]/",$content)){  
  16. 16.             $errtip=getlang('send','notcn');  
  17. 17.             ajaxreturn(1,$errtip);  
  18. 18.             }  
  19. 19.         }  
  20. 20.     if(setup_errkey!=''){  
  21. 21.         if(!checkerrkey($content)){  
  22. 22.             $errtip=getlang('send','errkey');  
  23. 23.             ajaxreturn(1,$errtip);  
  24. 24.             }  
  25. 25.         }  
  26. 26.     $user_ip=getip();  
  27. 27.     if(setup_feedback_limit){  
  28. 28.         $ltime=time()-setup_feedback_limit;  
  29. 29.         $ftime=db_count('feedback','webid='.$web['id'].' and time_add>'.$ltime.' and user_ip="'.$user_ip.'"');  
  30. 30.         if($ftime){  
  31. 31.             $errtip=sprintf(getlang('comment','limiterr'),setup_feedback_limit);  
  32. 32.             ajaxreturn(1,$errtip);  
  33. 33.             }  
  34. 34.         }  
  35. 35.     require_once('include/class_ip.php');  
  36. 36.     $ipdata=new IpLocation();  
  37. 37.     $add=$ipdata->getlocation($user_ip);  
  38. 38.     $user_iptext=$add['country'];  
  39. 39.     $attachment_new='';  
  40. 40.     if($attachment!=''){  
  41. 41.         $attachment_new='feedback/'.$attachment;  
  42. 42.         @rename(setup_upfolder.$web['id'].'/'.setup_uptemp.$attachment,setup_upfolder.$web['id'].'/'.$attachment_new);  
  43. 43.         }  
  44. 44.     $content1=nl2br($content);  
  45. 45.     $content2=str_replace('<br>','{br}',$content1);  
  46. 46.     $tab='webid,dataid,languages,name,email,phone,user_ip,user_iptext,content,attachment,time_add';  
  47. 47.     $val=$web['id'].',0,"'.$lang.'","'.$name.'","'.$email.'","'.$phone.'","'.$user_ip.'","'.$user_iptext.'","'.$content2.'","'.$attachment_new.'",'.time();  
  48. 48.     db_intoshow('feedback',$tab,$val);  

这段代码对游客提交的留言进行处理,然后写入数据库进行查看,在留言提交的几个参数$lang,$email,$phone,$attachment,其中$lang的参数是url,但是$email,$phone有格式检测不能利用,发现把ip也写入了数据库,我们进一步查看程序中如何获取ip的?

文件位置:/admin_system/include/lib/login.php 第447-453行:

  1. function getip(){  
  2.   if(!empty($_SERVER["HTTP_CLIENT_IP"]))$cip = $_SERVER["HTTP_CLIENT_IP"];  
  3.   else if(!empty($_SERVER["HTTP_X_FORWARDED_FOR"]))$cip = $_SERVER["HTTP_X_FORWARDED_FOR"];  
  4.   else if(!empty($_SERVER["REMOTE_ADDR"]))$cip = $_SERVER["REMOTE_ADDR"];  
  5.   else $cip = "127.0.0.1";  
  6.   return $cip;  
  7. }  

可以发现程序先从客户端获取IP,这是可以伪造的,伪造IP将XSS Payload写入数据库,后台数据库查询出来展示的时候,便会触发XSS,导致程序在实现上存在存储型XSS跨站脚本漏洞,攻击者通过该漏洞可在页面中插入恶意js代码,获得用户cookie等信息,导致用户被劫持。

0x02 漏洞利用

1、在首页点击在线留言—填写数据—抓包—修改X-Forwarded-For头部信息:

 【代码审计】QYKCMS_v4.3.2 前台存储型XSS跨站脚本漏洞分析

2、前台留言成功,当管理员后台查看留言的时候,成功触发XSS语句。

 【代码审计】QYKCMS_v4.3.2 前台存储型XSS跨站脚本漏洞分析

0x03 修复建议

建议对参数做html转义过滤(要过滤的字符包括:单引号、双引号、大于号、小于号,&符号),防止脚本执行。在变量输出时进行HTML ENCODE处理。

最后

欢迎关注个人微信公众号:Bypass--,每周原创一篇技术干货。 

【代码审计】QYKCMS_v4.3.2 前台存储型XSS跨站脚本漏洞分析