在CTF中有些时候
GET
、POST
等方法传参中参数名可能存在一些非法字符导致传参问题。下面讲述的也算是CTF比赛中常见的一种Trick
注意:这种Trick只能在PHP版本小于8时有效,当PHP版本大于等于8并不会出现这种转换错误
在PHP官方文档中有解释当变量名中出现点
和空格
时,PHP的处理方式
https://www.php.net/manual/zh/language.variables.external.php
这里的参数名为:$_REQUEST['mo chu.']
参数名中含有空格
和点
,可以看到当我们传入?mo chu.=xxx
时,传入的参数名中点.
和空格
都被替换为了下划线_
,这样的参数名确实无法传参
$var = $_REQUEST['mo_chu.7'];
这里就有条件可以利用一个PHP8
被修复的转换错误进行传参:https://github.com/php/php-src/commit//fc4d462e947828fdbeac6020ac8f34704a218834?branch=fc4d462e947828fdbeac6020ac8f34704a218834&diff=unified
当PHP版本小于8
时,如果参数中出现中括号[
,中括号会被转换成下划线_
,但是会出现转换错误导致接下来如果该参数名中还有非法字符
并不会继续转换成下划线_
,也就是说如果中括号[
出现在前面,那么中括号[
还是会被转换成下划线_
,但是因为出错导致接下来的非法字符并不会被转换成下划线_
Payload如下:
?mo[chu.7=xxx
利用了如果传入的参数名出现了中括号[
只替换一次的原理,使得传入的参数为:mo_chu.7
多做几组测试来验证参数名从左到右如果先出现中括号[
会导致之后的非法字符无法替换为下划线_
接下来看看PHP8
是否修复了这个转换错误
很明显在PHP8中这种转换错误被修复了,传入的参数名中非法字符一律全部转换为了下划线