前言

根据红日安全写的文章,学习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. 关于 spring security 对用户名和密码的校验过程

    1.执行 AuthenticationManager 认证方法 authenticate(UsernamePasswordAuthenticationToken) 2.ProviderManager ...

  2. XOR性质

    异或XOR的性质: 1. 交换律 2. 结合律 3. x^x = 0 -> 偶数个异或为0 4. x^0 = x -> 奇数个异或为本身 5. 自反性:a^b^b = a^0 =a

  3. 网骗欺诈?网络裸奔?都是因为 HTTP?

    先跟大家讲个故事,我初恋是在初中时谈的,我的后桌的后桌.那个时候没有手机这类的沟通工具,上课交流有三宝,脚踢屁股.笔戳后背以及传纸条,当然我只能是那个屁股和后背,还不是能让初恋踢到的后背. 但是说实话 ...

  4. JVM 堆中对象分配、布局和访问

    本文摘自深入理解 Java 虚拟机第三版 对象的创建 Java 是一门面向对象的语言,Java 程序运行过程中无时无刻都有对象被创建出来.从语言层面看,创建对象只是一个 new 关键字而已,而在虚拟机 ...

  5. LeetCode 042 Trapping Rain Water

    题目要求:Trapping Rain Water Given n non-negative integers representing an elevation map where the width ...

  6. Canal Admin

    一.Canal Admin 安装与配置 1.1 下载 wget https://github.com/alibaba/canal/releases/download/canal-1.1.4/canal ...

  7. day8(使用celery异步发送短信)

    1.1在celery_task/mian.py中添加发送短信函数 # celery项目中的所有导包地址, 都是以CELERY_BASE_DIR为基准设定. # 执行celery命令时, 也需要进入CE ...

  8. 学JAVA的艰难之路

    周五回家了,这两天也没有更新代码系列,很抱歉,之后会补上.今天刚到宿舍,写了会代码,想用一个数组的从键盘输入,再也弄不好了,最终在我不断的翻之前写的代码,终于是找到了一个例子,真的不容易,编程这东西, ...

  9. 手写mini版MVC框架

    目录 1, Springmvc基本原理流程 2,注解开发 编写测试代码: 目录结构: 3,编写自定义DispatcherServlet中的初始化流程: 3.1 加载配置文件 3.2 扫描相关的类,扫描 ...

  10. 赶紧收藏!王者级别的Java多线程技术笔记,我java小菜鸡愿奉你为地表最强!

    Java多线程技术概述 介绍多线程之前要介绍线程,介绍线程则离不开进程. 首先 , 进程 :是一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元: 线程:就 ...