PHP代码审计05之正则使用不当
前言
根据红日安全写的文章,学习PHP代码审计的第五节内容,题目均来自PHP SECURITY CALENDAR 2017,讲完题目会用一道CTF的题目和实例来加深巩固。这是之前写的,有兴趣可以去看看:
PHP代码审计01之in_array()函数缺陷
PHP代码审计02之filter_var()函数缺陷
PHP代码审计03之实例化任意对象漏洞
PHP代码审计04之strpos函数使用不当
漏洞分析
下面看题目,代码如下:

题目漏洞是正则使用不严谨导致任意文件删除的漏洞,现在来具体分析,引起漏洞的地方在上面代码的21行,这里用到了preg_replace()函数,我们打开PHP手册来看看对这个函数的定义如下:

了解了函数的用法,看上面代码,[^a-z.-_] 表示匹配除了 a 字符到 z 字符和. 字符到 _ 字符之间的所有字符,但是没有考虑到目录路径字符。这就直接可以任意删除文件,例如构造如下参数:
action=delete&data=../../config.php
将删除config.php文件。
CTF练习
通过上面的讲解,来用一道CTF题目来练习一下,也是关于正则的问题,先看代码:
//index.php
<?php
include 'flag.php';
if ("POST" == $_SERVER['REQUEST_METHOD'])
{
$password = $_POST['password'];
if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password))
{
echo 'Wrong Format';
exit;
}
while (TRUE)
{
$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
if (6 > preg_match_all($reg, $password, $arr))
break;
$c = 0;
$ps = array('punct', 'digit', 'upper', 'lower');
foreach ($ps as $pt)
{
if (preg_match("/[[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;
if ("42" == $password) echo $flag;
else echo 'Wrong password';
exit;
}
}
highlight_file(__FILE__);
?>
//flag.php
<?php $flag = "HRCTF{Pr3g_R3plac3_1s_Int3r3sting}";?>
这道题目考察了是否熟悉PHP正则表达的字符类,大体是下面这个表格:
| alnum 字母和数字 | header |
|---|---|
| alpha 字母 | |
| ascii 0 - 127的ascii字符 | |
| blank 空格和水平制表符 | |
| cntrl 控制字符 | |
| digit 十进制数(same as \d) | |
| graph 打印字符, 不包括空格 | |
| lower 小写字母 | |
| print 打印字符,包含空格 | |
| punct 打印字符, 不包括字母和数字 | |
| space 空白字符 (比\s多垂直制表符) | |
| upper 大写字母 | |
| word 单词字符(same as \w) | |
| xdigit 十六进制数字 |
想要更加详细的了解,建议翻阅PHP手册,了解了字符类,下面来分析代码,上面一共三处正则表达,第一处如下:
if (0 >= preg_match('/[1]{12,}$/', $password))
它表示的含义是匹配到可打印字符12往上包含12,^表示必须某类字符开头,$表示必须某类字符结尾。
第二处正则如下:
$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
if (6 > preg_match_all($reg, $password, $arr))
break;
它表示的含义是,把连续的字符,数字,大写,小写作为一段,最少分成六段,比如Test+0He 会分为T est + 0 H e六段。
下面看第三处正则:
$ps = array('punct', 'digit', 'upper', 'lower');
foreach ($ps as $pt)
{
if (preg_match("/[[:$pt:]]+/", $password))
$c += 1;
}
if ($c < 3) break;
if ("42" == $password) echo $flag;
这里的含义是输入的字符必须包含字符,数字,大写,小写其中的三种往上。最后与42进行弱类型比较,都符合就输出flag,现在都解读清楚了,让咱们构造payload结果如下:
实例分析
通过例题和CTF题目的讲解,是不是感觉棒棒的,现在咱们来分析实例吧,实例是LvyeCMS3.1,是基于ThinkPHP3.2.3框架。这个实例存在的漏洞也是函数使用不规范被绕过,导致任意文件删除。下面来具体分析:
先查看入口文件index.php

可以看到公共目录,应用目录等一些信息。接下来再看看目录结构:

而漏洞在Application/Template/Controller/StyleController.class.php文件中,具体如下:

看代码第117行,这里是获取目录路径,参数也是我们可以控制的,再向后看,用到了str_replace()函数,它是个字符串替换函数,具体说明如下:

再这里起到的作用就是将'..\', '../', './', '.\'替换为空。但是这里是可以绕过的,如果我们输入.....///呢,会发生什么?是不是正好构造成了../,举个小例子会更清楚,如下:

构造出../我们就可以穿越目录了,现在访问install.php文件会提示已安装,如下图:

然后尝试删除lvyecms/Application/Install/目录下的 install.lock 文件,构造payload如下:
http://www.xxx.com/index.php?g=Template&m=Style&a=delete&dir=.....///Application/Install/&file=install.lock
现在访问install.php,发现确实删除了,如下图:
小结
通过这篇文章的学习与讲解,是不是对PHP的正则了解的更多了呢,下一篇文章会对parse_str函数缺陷进行学习和讲解。一起加油吧!
[:graph:] ︎
PHP代码审计05之正则使用不当的更多相关文章
- ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi
// where子单元分析 protected function parseWhereItem($key,$val) { $whereStr = ''; if(is_array($val)) { if ...
- 【python正则】工作中常用的python正则代码
工作中常用的一些正则代码: 01.用户名正则 import re # 4到16位(字母,数字,下划线,减号)if re.match(r'^[a-zA-Z0-9_-]{4,16}$', "ab ...
- PHP代码审计分段讲解(3)
05 ereg正则%00截断 放上源代码 <?php $flag = "flag"; if (isset ($_GET['password'])) { if (ereg (& ...
- 航遇项目react踩坑
1.iconfont应用: a.正常用法如下 <span className='iconfont' > iconfont的代码,例如: </span> b.react不能动态 ...
- JS正则表达式完整教程
JS正则表达式完整教程(略长) 引言 亲爱的读者朋友,如果你点开了这篇文章,说明你对正则很感兴趣. 想必你也了解正则的重要性,在我看来正则表达式是衡量程序员水平的一个侧面标准. 关于正则表达式的教程, ...
- CTF-WEB-XTCTF-Web_php_unserialize
题目来源 XTCTF-Web_php_unserialize 题目考点:PHP代码审计.PHP正则.PHP序列化与反序列化 解题思路 题目源码 <?php class Demo { privat ...
- MySQL Crash Course #05# Chapter 9. 10. 11. 12 正则.函数. API
索引 正则表达式:MySQL only supports a small subset of what is supported in most regular expression implemen ...
- 代码审计-ereg正则%00截断
<?php $flag = "xxx"; if (isset ($_GET['password'])) { if (ereg ("^[a-zA-Z0-9]+$&qu ...
- PHP代码审计04之strpos函数使用不当
前言 根据红日安全写的文章,学习PHP代码审计的第四节内容,题目均来自PHP SECURITY CALENDAR 2017,讲完题目会用一个实例来加深巩固,这是之前写的,有兴趣可以去看看: PHP代码 ...
随机推荐
- 2020.11最新JAVA环境安装配置
Windows10下java环境配置 更新:2020年11月25日 电脑环境: windows10 64位 一.下载jdk 首先到Oracle网站下载对应操作系统的jdk安装包. https://ww ...
- 【MySQL篇】Navicat导入SQL文件报错终极解决方案
面对大数据库文件(一般50M以上),使用Navicat导入的时候容易出现[ERR]2006等报错问题,此文提供了几种办法,包括修改MySQL的配置参数在网上也有很多详细教程介绍过,但此文精彩处在于前面 ...
- 保姆级别的RabbitMQ教程!包括Java和Golang两种客户端
目录 什么是AMQP 和 JMS? 常见的MQ产品 安装RabbitMQ 启动RabbitMQ 什么是Authentication(认证) 指定RabbitMQ的启动配置文件 如何让guest用户远程 ...
- moviepy音视频剪辑:与大小相关的视频变换函数详解
☞ ░ 前往老猿Python博文目录 ░ 一.引言 在<moviepy音视频剪辑:moviepy中的剪辑基类Clip详解>介绍了剪辑基类的fl.fl_time.fx方法,在<movi ...
- Python使用property函数定义的属性名与其他实例变量重名会怎么样?
首先如果定义的属性名与该属性对应的操作方法操作的实例对象同名就会触发无穷的递归调用,相关部分请参考<Python案例详解:使用property函数定义与实例变量同名的属性会怎样?> 但如果 ...
- 第8.30节 重写Python __setattr__方法实现属性修改捕获
一. 引言 在<第8.26节 重写Python类中的__getattribute__方法实现实例属性访问捕获>章节介绍了__getattribute__方法,可以通过重写该方法,截获所有通 ...
- sails框架结合mocha
sails框架(testing&model and orm): http://sailsjs.org/documentation/concepts/testing orm(对象关系映射): h ...
- linux服务器性能分析只需1分钟
背景: 现在的互联网公司,大多数时候应用服务都是部署在linux服务器上,那么当你的服务运行过程中出现了一些响应慢,资源瓶颈等疑似性能问题时,给你60秒,如何快速完成初步检测? 肯定有人会说用工具,公 ...
- MySQL事务(一)认识事务
简单来说,事务就是要保证一组数据库操作,要么全部完成,要么全部失败. 为什么要有事务 数据库中的数据是共享资源,因此数据库系统通常要支持多个用户的或不同应用程序的访问,会出现并发存取数据的现象. 数据 ...
- MySQL增强半同步的搭建实验,和一些参数的个人理解
关于参数理解,已补充实验,可以查看: rpl_semi_sync_master_wait_no_slave 参数研究实验 环境信息 role ip port hostname master 192.1 ...


