前言

根据红日安全写的文章,学习PHP代码审计审计的第二节内容,题目均来自PHP SECURITY CALENDAR 2017,讲完这个题目,会有一道CTF题目来进行巩固,外加一个实例来深入分析,想了解上一篇的内容,可以点击这里:PHP代码审计01之in_array()函数缺陷

下面我们开始分析。

漏洞分析

下面来看第一题,代码如下:

<?php
require 'vendor/autoload.php'; class Template{
private $twig; public function __construct()
{ //这里是第一次过滤
$indexTemplate = 'img'.'src="https://loremflickr.com/320/240">'.
'<a href="{{link|escape}}">Next slide &raquo;</a>'; $loader = new Twig\Loader\ArrayLoader([
'index.html'=>$indexTemplate
]);
$this->twig = new Twig\Environment($loader);
} public function getNexSlideUrl(){
$nexSlide = $_GET['nexSlide'];
//这里是第二次过滤
return filter_var($nexSlide,FILTER_VALIDATE_URL);
} public function render(){
echo $this->twig->render(
'index.html',
['link'=>$this->getNexSlideUrl()]
);
}
}
(new Template())->render();
?>

这一关用的是PHP的一个模板引擎Twig,考察的是XSS漏洞,也就是跨站脚本攻击。虽然程序使用了escape和filter_var()两个过滤方法,但是。还是可以被绕过的。下面我们看第一处过滤,在上面代码的第10行,使用Twig模板引擎定义的escape过滤器来过滤link。而escape过滤器默认情况下,它使用HTML转义策略,也就是escape将PHP本机htmlspecialchars函数用于HTML转义策略,现在我们看一下PHP手册,htmlspecialchars函数是如何定义的。



其实就是把一些预定义字符转换成HTML实体。具体看下表:



下面我们来看第二处过滤,是在上面代码第20行,是用filter_var()来进行过滤,下面我们来看看PHP手册对这个函数的定义:



具体参数设置如下表:



上面代码是用了FILTER_VALIDATE_URL,把值作为 URL 来验证。这个函数过滤其他的参数设置说明,如下:

  • FILTER_CALLBACK:调用用户自定义函数来过滤数据。
  • FILTER_SANITIZE_STRING:去除标签,去除或编码特殊字符。
  • FILTER_SANITIZE_STRIPPED:”string” 过滤器的别名。
  • FILTER_SANITIZE_ENCODED:URL-encode 字符串,去除或编码特殊字符。
  • FILTER_SANITIZE_SPECIAL_CHARS:HTML 转义字符 ‘”<>& 以及 ASCII 值小于 32 的字符。
  • FILTER_SANITIZE_EMAIL:删除所有字符,除了字母、数字以及 !#$%&’*+-/=?^_{|}~@.[]
  • FILTER_SANITIZE_URL:删除所有字符,除了字母、数字以及 $-_.+!*'(),{}|\^~[]<>#%”;/?&=
  • FILTER_SANITIZE_NUMBER_INT:删除所有字符,除了数字和 +-
  • FILTER_SANITIZE_NUMBER_FLOAT:删除所有字符,除了数字、+- 以及 .,eE。
  • FILTER_SANITIZE_MAGIC_QUOTES:应用 addslashes()。
  • FILTER_UNSAFE_RAW:不进行任何过滤,去除或编码特殊字符。
  • FILTER_VALIDATE_INT:在指定的范围以整数验证值。
  • FILTER_VALIDATE_BOOLEAN:如果是 “1”, “true”, “on” 以及 “yes”,则返回 true,如果是 “0”, “false”, “off”, “no” 以及 “”,则返回 false。否则返回 NULL。
  • FILTER_VALIDATE_FLOAT:以浮点数验证值。
  • FILTER_VALIDATE_REGEXP:根据 regexp,兼容 Perl 的正则表达式来验证值。
  • FILTER_VALIDATE_URL:把值作为 URL 来验证。
  • FILTER_VALIDATE_EMAIL:把值作为 e-mail 来验证。
  • FILTER_VALIDATE_IP:把值作为 IP 地址来验证。

通过对两个过滤器的了解,我们想想该如何绕过呢?,其实,这里可以通过JavaScript伪协议来绕过,为了更好的理解,这里写一小段简单的代码。

$url = filter_var($_GET['url'],FILTER_VALIDATE_URL);
var_dump($url);
$url = htmlspecialchars($url);
var_dump($url);
echo "<a href='$url'>测试一下</a>";

下面我们构造payload,用JavaScript伪协议来绕过,payload为:javascript://test%250aalert(1),然后执行如下图:



其实上面payload中,//后面的内容全是注释的内容,那为什么还是会被执行呢?因为在上面的payload用了%0a,%进行了编码,成了%25,这是换行符,所以执行了咱们的弹窗。

CTF练习

通过上面的分析,是不是对filter_var()函数有了一定的了解呢,让咱们用一道CTF的题目来巩固一下吧。这道题也是因为filter_var被绕过,导致命令执行。看下面代码。

<?php
$url = $_GET['url'];
//检查是否是合法的URL
if (isset($url)&&filter_var($url,FILTER_VALIDATE_URL)) {
$site_info = parse_url($url);
//正则判断
if (preg_match('/test.com$/', $site_info['host'])) {
exec('curl "' . $site_info['host'] . '"', $result);
echo "<center><h1>You have curl {$site_info['host']}
successfully!</h1></center>
<center><textarea rows ='20' cols='90'>";
echo implode(' ', $result);
} else {
die("<center><h1>Error: Host not allowed</h1></center>");
}
}
else{
echo "<center><h1>Just curl test.com.com!</h1></center><br>
         <center><h3>For example:?url=http://test.com.com</h3></center>";
}
?>

现在分析上面的代码,GET接收url参数,然后用filter_var检查是否为合法的URL,接着走到下面的代码,正则判断结尾必须还有test.com。

然后用了exec函数,看到它我们嘴就有了笑容,因为只要我们绕过上面两处检查,我们就可以为所欲为,命令执行了。而上面我们分析了,可以使用伪协议来绕过filter_var的检查,至于正则判断,只要我们结尾包含test.com,就绕过了正则检查。

现在我们设置payload:javascript://123";ls;"test.com

伪协议绕过了filter_var检查。结尾绕过了正则判断,当与exec函数拼接后就形成了三条命令

  • curl "javascript://123"
  • ls
  • "test.com"

    这就成功命令执行,第一条和第三条不会被执行,当第二条被执行后,就可以查看到当前目录,发现flag.php,然后用cat命令来查看文件,拿到flag,这里需要注意的是,如果直接使用cat是会包含空格的,这样无法绕过filter_var()函数的过滤,所以用<代替空格。最后的flag为:javascript://";cat<flag.php;"test.com

    如果是Windows机器,换一下语法就可以了,比如要查看目录:
//查看目录
javascript://";dir;"test.com
![](https://img2020.cnblogs.com/blog/1996712/202010/1996712-20201001112330129-253033111.png)
//查看文件
javascript://";type=flag.php;"test.com

实例分析

通过上面的题目和CTF练习,是不是感觉正到劲头了,下面咱们分析实例,是Anchor 0.9.2版本,在这个版本中,当用户访问一个不存在的url时,程序会调用404模板,而这个模板存在XSS漏洞。现在咱们来仔细分析。下面看代码:



现在我们打开themes\default\404.php文件,看第六行,标签中的current_url()函数,接下来我们搜索这个函数,发现它在anchor\functions\helpers.php文件中,并看到current_url是由Uri类的current方法实现的,如下图:



下面我们跟进Uri类,是在system\Uri.php文件中,如下图:



发现这里调用了static::detect()方法,( static:: 是在PHP5.3版本之后引入的延迟静态绑定写法)

detect()方法就在下方,具体代码如下图:



detect()方法会获取$_SERVER数组中的REQUEST_URI, PATH_INFO, ORIG_PATH_INFO键值,如果存在其中一个键,并且符合filter_var($uri, FILTER_SANITIZE_URL)和parse_url($uri, PHP_URL_PATH)则直接将$uri传入format()方法中。现在我们跟进这个方法。就在下边,如图:



发现程序过滤了三次,看截图130行到136行。但是没有对XSS进行过滤。下面我们来构造payload。

漏洞利用

现在我们构造payload:localhost/anchor/index.php/<script>alert("XSS")</script>

现在结合上面的讲解来分析,当我们访问这个不存在的url时,程序会调用404模板页面,然后调用current_url()函数来获取当前文件名,也就是咱们构造的<script>alert("XSS")</script>,嵌入了标签中,找成XSS攻击。效果如下图:

小结

通过上面的分析,是不是对filter_var()函数理解更深了呢?下一篇文章会对实例化任意对象漏洞进行学习和分析,一起努力吧!

PHP代码审计02之filter_var()函数缺陷的更多相关文章

  1. PHP代码审计01之in_array()函数缺陷

    前言 从今天起,结合红日安全写的文章,开始学习代码审计,题目均来自PHP SECURITY CALENDAR 2017,讲完这个题目,会再用一道有相同问题的CTF题来进行巩固.下面开始分析. 漏洞分析 ...

  2. [代码审计Day2] filter_var函数缺陷代码审计

    简介 // composer require "twig/twig" require 'vendor/autoload.php'; class Template { private ...

  3. PHP-Audit-Labs-Day2 - filter_var函数缺陷

    目录 分析 示例 payload 修复建议 Day02-CTF题解 参考链接 分析 先看源码 // composer require "twig/twig" require 've ...

  4. PHP代码审计04之strpos函数使用不当

    前言 根据红日安全写的文章,学习PHP代码审计的第四节内容,题目均来自PHP SECURITY CALENDAR 2017,讲完题目会用一个实例来加深巩固,这是之前写的,有兴趣可以去看看: PHP代码 ...

  5. filter_var()函数

    我们使用 payload :?url=javascript://comment%250aalert(1) ,可以执行 alert 函数: 实际上,这里的 // 在JavaScript中表示单行注释,所 ...

  6. 代码审计学习01-in_array() 函数缺陷

    一.开始代码审计之旅 01 从今天起,学习代码审计了,这篇文章就叫代码审计01吧,题目来自 PHP SECURITY CALENDAR 2017 的第一题,结合 红日安全 写的文章,开始吧. 二.先看 ...

  7. PHP filter_var 函数用法

    先介绍下PHP Filter PHP手册地址:http://php.net/manual/zh/ref.filter.php PHP 过滤器用于对来自非安全来源的数据(比如用户输入)进行验证和过滤. ...

  8. 学习笔记:filter_var()函数

    PHP 过滤器用于对来自非安全来源的数据(比如用户输入)进行验证和过滤 filter_var() 函数通过指定的过滤器过滤变量. 如果成功,则返回已过滤的数据,如果失败,则返回 false. 语法 f ...

  9. 漏洞:阿里云盾phpMyAdmin <=4.8.1 后台checkPageValidity函数缺陷可导致GETSHELL

    阿里云盾提示phpMyAdmin <=4.8.1会出现漏洞有被SHELL风险,具体漏洞提醒: 标题 phpMyAdmin <=4.8.1 后台checkPageValidity函数缺陷可导 ...

随机推荐

  1. 学习seo赚钱一定要有超前的思路和眼光

    http://www.wocaoseo.com/thread-100-1-1.html        日子过的真是快,一天又一天,一年又一年,虽然过年的脚步将近,火车票的问题还是没有解决,昨天忙活了半 ...

  2. 使用【QQ五笔的码表】转成【百度手机自定义码表】

    使用[QQ五笔码表]转成[百度手机自定义码表] QQ五笔码表先转成多多格式. 这里选用极点>>多多. 然后去掉空格. 转成GB.去掉没的字. 百度要的是这种格式. 现再用点讯工具转成 de ...

  3. ABP VNext实践之搭建可用于生产的IdentityServer4

    一.前言 用了半年多的abp vnext,在开发的效果还是非常的好,可以说节省了很多时间,像事件总线.模块化开发.动态API进行远程调用.自动API控制器等等,一整套的规范,让开发人员更方便的集成,提 ...

  4. 【JAVA】生成一个32位的随机数。防止重复,保留唯一性

    作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985, QQ986945193 微博:http://weibo.com/mcxiaobing import ...

  5. 初学WebGL引擎-BabylonJS:第6篇-碰撞交错与挑选

    [playground]-collisions(碰撞) 先贴官方源码(机器翻译版本) var createScene = function () { var scene = new BABYLON.S ...

  6. PyCharm切换解释器版本

    Mac PyCharm > Preferences... > Project Interpreter > Python Interpreters Windows File->D ...

  7. 持续部署入门:基于 Kubernetes 实现滚动发布

    前言 软件世界比以往任何时候都更快.为了保持竞争力,需要尽快推出新的软件版本,而不会中断活跃用户访问,影响用户体验.越来越多企业已将其应用迁移到 Kubernetes. 在 Kubernetes 中有 ...

  8. CentOS+Phpstudy安装Sqli-Labs

    CentOS+Phpstudy安装Sqli-Labs 安装环境 CentOS 7.5 vmware fusion phpstudy 安装步骤 1. 下载sqli-labs 2. 将sqli-labs ...

  9. JQuery的Ajax实现注册检测用户名

    Ajax(无需等待直接向服务器发起请求) (Asynchronous Javascript And Xml) :异步的 Google创新的一种js技术 实现方法一:比较原始没有封装的方法: //核对用 ...

  10. python基础:面向对象

    一.定义 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类:一个种类,一个模型. 对象:指具体的东西,模型造出来的东西叫做对象. 实例:实例和对象是一样的. 实例化:实例化就 ...