首页 > 编程语言 >PHP代码审计——Day 8-Candle

PHP代码审计——Day 8-Candle

时间:2024-04-10 19:11:38浏览次数:21  
标签:匹配 pattern preg phpinfo replace Candle PHP Day

漏洞解析

header("Content-Type: text/plain");

function complexStrtolower($regex, $value) {
    return preg_replace(
        '/(' . $regex . ')/ei',
        'strtolower("\\1")',
        $value
    );
}

foreach ($_GET as $regex => $value) {
    echo complexStrtolower($regex, $value) . "\n";
}

考察点:代码执行

preg_replace:(PHP 5.5)

  • 功能 : 函数执行一个正则表达式的搜索和替换
  • 定义 : mixed preg_replace ( mixed $pattern , mixed $replacement , mixed $subject [, int $limit = -1 [, int &$count ]] )

搜索 subject 中匹配 pattern 的部分, 如果匹配成功以 replacement 进行替换,如果没找到匹配项,则返回原始字符串。

$pattern 存在/e模式修正符,允许代码执行

/e 模式修正符,是preg_replace()将 $replacement 当做php代码来执行

/e 是一个已经被废弃的模式修正符,它在 PHP 5.5.0 版本中已经被移除。

传入的GET参数在complexStrtolower函数中调用,可控制preg_replace的第一个和第三个参数,第二个参数固定为'strtolower("\\1")',此处涉及到正则表达式反向引用的知识,即此处的 \\1\\1表示正则匹配到的第一个内容,然后用strtolower函数转成小写字母。

反向引用
对一个正则表达式模式或部分模式两边添加圆括号,将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。
缓冲区编号从 1 开始,最多可存储 99 个捕获的子表达式。每个缓冲区都可以使用 '\n' 访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。这对于查找重复的模式或者匹配配对的字符串非常有用。
反向引用使用 \加数字来表示。其中 \1 表示第一个捕获组的内容,\2 表示第二个捕获组的内容,以此类推。
举例来说,

$string = "hello hello";
$pattern = "/(\w+)\s\1/";
if (preg_match($pattern, $string, $matches)) {
    echo "找到重复的单词: " . $matches[0]; // 输出: "找到重复的单词: hello hello"
} else {
    echo "未找到重复的单词";
}

在这个例子中,正则表达式 (\w+)\s\1 匹配一个单词后跟一个空格,然后再次匹配相同的单词。\1 是对第一个捕获组 (\w+) 的反向引用,表示要匹配与第一个捕获组相同的内容。

继续说回有问题的代码。

想要执行phpinfo()函数,需要匹配到{${phpinfo()}} 或者${phpinfo()},原因在于php可变变量,也就是$$

坑一:
在PHP中双引号包裹的字符串中可以解析变量,而单引号则不行。 ${phpinfo()}中的phpinfo()会被当做变量先执行,执行后,即变成${1}(phpinfo()成功执行返回true)。

坑二:
正则参数使用.*来匹配任何字符是最方便的选择,但是这里通过GET传入后发现没有匹配到任何字符,因为我们传上去的.*变成了_*,这是由于在PHP中,对于传入的非法的 $_GET数组参数名,会将其转换成下划线,这就导致我们正则匹配失效。那么可以换用\S*来达到相同的效果。(\S:用于匹配除单个空格符之外的所有字符)

当非法字符为首字母时,只有点号会被替换成下划线。

构造payload:\S*=${phpinfo()}

参考文章

https://xz.aliyun.com/t/2557

https://lanvnal.com/2020/02/19/rips-php-security-calendar-2017-xue-xi-ji-lu/#toc-heading-2

https://github.com/hongriSec/PHP-Audit-Labs/blob/master/Part1/Day8/files/README.md

标签:匹配,pattern,preg,phpinfo,replace,Candle,PHP,Day
From: https://www.cnblogs.com/smile2333/p/18127187

相关文章

  • 01 Php学习:导学篇
    Php是什么?PHP是服务器端脚本语言。PHP(HypertextPreprocessor)是一种通用开源脚本语言,主要用于服务器端开发。PHP脚本在服务器端执行,生成动态网页内容或执行服务器端任务。PHP可以嵌入到HTML中,也可以与各种数据库结合使用,常用于开发Web应用程序。PHP文件可包含文本、HT......
  • 03 Php学习:echo 、 print 、EOF
    echo和print在PHP中有两个基本的输出方式:echo和print。echo和print区别:echo-可以输出一个或多个字符串print-只允许输出一个字符串,返回值总为1注意:echo输出的速度比print快,echo没有返回值,print有返回值1。echo详解和举例在PHP中,echo语句用于将......
  • C语言学习笔记day18
    1.指针基本概念    1.地址:用来区分内存中不同字节的编号   2.指针:地址就是指针,指针就是地址   3.指针变量:存储指针的变量,有时去掉变量,称为指针2.指针运算符   1.&:      1.获得一个变量在内存空间中的首地址      2.让表达式类......
  • php中date() 函数
    实例格式化本地日期和时间,并返回格式化的日期字符串:<?php//Printsthedayechodate("l")."<br>";//Printstheday,date,month,year,time,AMorPMechodate("ljSofFYh:i:sA");?>定义和用法date()函数格式化本地日期和时间,并返回格式化的日期字符串。......
  • PHP中yield关键字的作用和示例
     php中的yield关键字是在php5.5版本引入的一个关键字,它在函数内部可以用来创建一个生成器(generator)。生成器可以用来遍历一个大数据集,而不需要一次性将整个数据集加载到内存中。yield关键字的作用是将当前函数变成一个生成器函数。在生成器函数内部,我们可以使用yield语句将......
  • JAVA语言学习-Day7
    概述计算机网络:将地理位置不同的具有独立功能的多台计算机及其外部设备,通过线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。网络编程的目的:传播交流信息,数据交换。通信想达到这个效果需要什么:通过ip地址及端口,定......
  • [算法刷题打卡]Day11
    1、Leetcode-面试经典150题目20- 14.最长公共前缀思路:1、首先对于空的情况判断,直接返回“”2、对于多个即两个以上的字符串找公共前缀,其实就是先两个两个找公共前缀。道理很简单,ans(S1,S2,S3,S4)= ans(S4,ans(S3,ans(S1,S2)))classSolution{public:string......
  • JavaWeb开发:day01
    目录Web开发模式前后端分离开发混合开发网页本质HTML/CSS学习目录官方文档:w3school.com.cn首页选择HTML5--参考书HTML快速入门案例:实践:创建一个自己网页2024/4/10Web开发模式前后端分离开发混合开发网页本质HTML负责网页结构(元素和内容);CSS控制页面样式和表现;JS控......
  • JavaWeb开发:day01
    JavaWeb--01Web开发模式前后端分离开发混合开发网页本质HTML/CSS学习目录官方文档:[w3school.com.cn](http://www.w3school.com.cn/)首页选择HTML5--参考书HTML快速入门案例:实践:创建一个自己网页总结2024/4/10Web开发模式前后端分离开发混合开发网页本......
  • php常见的输出语句及相互之间的区别
    常见的输出语句echo(): 可以一次输出多个值,多个值之间用逗号分隔。echo是语言结构(languageconstruct),而并不是真正的函数,因此不能作为表达式的一部分使用。print(): 函数print()打印一个值(它的参数),如果字符串成功显示则返回true,否则返回false。print_r(): 可以把字符串......