前言

根据红日安全写的文章,学习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函数缺陷进行学习和讲解。一起加油吧!


  1. [:graph:]

PHP代码审计05之正则使用不当的更多相关文章

  1. ThinkPHP 3.1,3.2中对IN和BETWEEN正则匹配不当导致的一个SQLi

    // where子单元分析 protected function parseWhereItem($key,$val) { $whereStr = ''; if(is_array($val)) { if ...

  2. 【python正则】工作中常用的python正则代码

    工作中常用的一些正则代码: 01.用户名正则 import re # 4到16位(字母,数字,下划线,减号)if re.match(r'^[a-zA-Z0-9_-]{4,16}$', "ab ...

  3. PHP代码审计分段讲解(3)

    05 ereg正则%00截断 放上源代码 <?php $flag = "flag"; if (isset ($_GET['password'])) { if (ereg (& ...

  4. 航遇项目react踩坑

    1.iconfont应用: a.正常用法如下 <span className='iconfont' > iconfont的代码,例如: </span> b.react不能动态 ...

  5. JS正则表达式完整教程

    JS正则表达式完整教程(略长) 引言 亲爱的读者朋友,如果你点开了这篇文章,说明你对正则很感兴趣. 想必你也了解正则的重要性,在我看来正则表达式是衡量程序员水平的一个侧面标准. 关于正则表达式的教程, ...

  6. CTF-WEB-XTCTF-Web_php_unserialize

    题目来源 XTCTF-Web_php_unserialize 题目考点:PHP代码审计.PHP正则.PHP序列化与反序列化 解题思路 题目源码 <?php class Demo { privat ...

  7. 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 ...

  8. 代码审计-ereg正则%00截断

    <?php $flag = "xxx"; if (isset ($_GET['password'])) { if (ereg ("^[a-zA-Z0-9]+$&qu ...

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

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

随机推荐

  1. LeetCode 038 Count and Say

    题目要求:Count and Say The count-and-say sequence is the sequence of integers beginning as follows:1, 11 ...

  2. 03_Service的绑定

    Start Service启动的Service,Application退出,Service也不会退出: Bind Service启动的Service,Application退出,Service就会退出 ...

  3. python下载三方库源地址修改

    临时使用 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package 默认使用 windows系统使用cmd快速设置 pi ...

  4. Spring Boot 使用 XXL-JOB

    一.配置部署调度中心 1.1 下载源码 https://github.com/xuxueli/xxl-job 1.2 数据库初始化 执行 /xxl-job/doc/db/tables_xxl_job. ...

  5. 赶紧收藏吧!MyBatis-Plus万字长文图解笔记,错过了这个村可就没这个店了

    简介 MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生 愿景 我们的愿景是成为 MyBatis 最好的搭档 ...

  6. 第3.6节 Python字符串基础知识

    一. 引言 前面第二章已经接单介绍了字符串,本来计划讲完列表解析和字典解析再来精讲字符串的内容,但发现要讲列表解析和字典解析需要介绍迭代器和生成器,这个概念比较复杂,老猿还需要复习和验证一下才能完全掌 ...

  7. PyQt(Python+Qt)学习随笔:model/view架构中QTableView视图的标题显示不正常问题

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 在进行QTableView展示数据时,使用了QStandardItemModel的model,并在将 ...

  8. 第12.3节 Python math模块导览

    math 模块提供对浮点数学的底层C库函数的访问,常用的成员包括: math.ceil(x):返回 x 的上限,即大于或者等于 x 的最小整数 math.floor(x):返回 x 的向下取整,小于或 ...

  9. PyQt(Python+Qt)学习随笔:Qt Designer组件属性编辑界面中对话窗QDialog的modal属性

    modal属性表示窗口执行show()操作时是以模态窗口还是非模态窗口形式展示,缺省为False,设置该值与QWidget.windowModality的值设置为 Qt.ApplicationModa ...

  10. PyQt(Python+Qt)学习随笔:toolButton的popupMode属性

    属性介绍 toolButton的popupMode属性为设有菜单集或Action列表的toolButton指定菜单弹出模式,类型为枚举类型ToolButtonPopupMode,有如下三种模式: 1. ...