遇到这一类题目:
1 | $username = isset($_POST['a_b.c']) ? $_POST['a_b.c'] : die("please input something"); |
首先我们知道正常post传入一个 a_b.c
的话它实际会被解析为 a_b_c
也就是无法正常传入 $_['a_b.c']
。
解决办法
我们只需要将第一个_
改为 [
就可以了。也就是post一个 a[b.c = 123
就可绕过了。
解析
我们看看底层的处理方式:(main/php_variables.c)
这里我是直接拿的别人的图,我太菜了找不到这文件。
从图片中我们可以看到当出现 [
时我们的参数名指针值会变为 0 ,并且 break 。就是说我们[
后面如果出现 空格 或者点 也不会被替换为 下划线了。但是这里的 [
也不是我们想要的样子呀?
我们看看 https://bugs.php.net/bug.php?id=78236 这个链接。这里指出 [
会被替换为 _
同时我们可以顺带了解到 只会替换第一个[
1 | “ [”只会被替换一次吗? |
那么这样我们就达到了绕过效果。
补充知识点
参照: https://www.php.net/manual/en/language.variables.external.php
这里指出 如果外部变量名称以有效的数组语法开头,则尾部字符将被静默忽略。例如, 变为$_REQUEST[‘foo’][‘bar’]。
测试代码:
1 | <?php |
我们输入:
1 | ?foo[bar]az=123213123123 |