浅析PHP变量解析复杂规则语法

阅读量312476

|

发布时间 : 2019-04-15 15:30:17

 

前言

翻了好久前写过的关于php复杂语法变量解析的文章,发现很多地方存在问题。因此又查阅文档重新理解了一遍该语法,谈谈个人的理解,并记录在此。

 

题目简析

一道很早之前的题目,代码(简化):

$str= @(string)$_GET['str'];
eval('$str="'.addslashes($str).'";');

通过eval执行php代码获得flag,addslashes函数将字符串中的特殊字符转义,“{}”在双引号中可以标记变量边界来解析,利用该方式来达到代码执行的目的。

eg:

通过payload:${assert($_GET[cmd])}}即可获取shell,也可以利用system函数来执行命令读取flag等。

 

变量解析之复杂语法

当字符串用双引号或heredoc结构定义时,其中的变量将会被解析。共有两种语法规则,一种简单规则,一种复杂规则,这里讨论复杂规则。

复杂规则语法的显著标记是用花括号包围的表达式。任何具有string表达的标量变量,数组单元或对象属性都可使用此语法,表达方式{$var_name}或${var_name}。

根据php官方文档,这里提示在PHP5以后可以使用{$}来调用函数、方法等。看下面的例子:

不难理解,{${getname()}} => {$s1ye},以函数返回值命名变量。这里我在函数中加入了echo "s1ye";,可以发现先执行了getname函数并输出了“s1ye”,接着才执行了echo(优先级)。

为了方便理解payload,利用以下代码进行测试:

构造了一个类似phpinfo的简化函数,利用变量解析在双引号中的复杂语法,先执行了test函数输出了“just for test”并返回true,可以看到,返回一条警告并且变量a的值是空的。

为什么Notice为”Undefined variable: 1”呢?返回TRUE,变量应该为$TRUE的。前面官方文档说过了,$ + string的变量会被解析,而TRUE是bool类型,并且是个常量,当返回TRUE并命名变量时php解析器将TRUE转换为了string类型。

由于没有该变量导致赋值给a变量时返回为空(并不能用数字开头来命名变量)。

 

理解payload

直接利用payload{${phpinfo()}}或者${${phpinfo()}}会返回phpinfo信息,但都会报错。

上面已经讲过了报错的原因,这里就很好理解了。接下来逐步的来分析payload成功执行的过程:

eval函数将字符串当作php代码执行,因此,通过图中代码清晰可见相当于定义了str变量,赋值为一个字符串”{${phpinfo()}}”。

$str = "{${phpinfo()}}",花括号定义了变量的边界,因此该条语句先执行括号中内容,获取函数返回值,并以返回值的string命名变量再赋值给str变量(同上面分析的test函数一样)。

到了这里只要修改”{${?}}”中的?为其他php代码就可以达到写文件读文件或者getshell等操作了,只需要注意addslashes函数即可。

 

思考

先看一下原题代码

eval('$str="'.addslashes($str).'";');

在双引号中可以利用花括号定义变量边界,调用函数等,如果修改为单引号包裹addslashes函数,还能执行代码了吗。

$str = @(string)$_GET['str'];
eval("$str='".addslashes($str)."';");

很容易就发现虽然addslashes函数部分内容被单引号包裹,但是变量str却变成了双引号包裹。这说明还是可以被利用的,直接尝试上面的payload:

发现报错,变量同样被双引号包裹(其实并没有被双引号包裹),这里却报错了。但是payload2${${phpinfo()}}却可以正常执行。

其实这里只要稍微思考一下就可以理解了,用两个例子来解释:

可以看到payload1不能执行成功的原因就是并没有被双引号包裹,所以外层标记变量边界的花括号无用。而payload${phpinfo()}/${${phpinfo()}}(无论加几个”${}”都无差,只不过报错更多而已)相当于$a=’string’,a==(phpinfo()的返回值string形式),即执行函数后利用返回值定义变量并赋值,因此可以执行成功。

 

总结

整体看下来感觉还是很绕的,总结就是遇到问题除了百度谷歌,要多认真读官方文档, 其实文档已经写得很清楚了。

本文由撕夜原创发布

转载,请参考转载声明,注明出处: https://www.anquanke.com/post/id/176331

安全客 - 有思想的安全新媒体

分享到:微信
+16赞
收藏
撕夜
分享到:微信

发表评论

撕夜

我就是啥都不会的s1ye,

  • 文章
  • 4
  • 粉丝
  • 6

TA的文章

热门推荐

内容需知
  • 投稿须知
  • 转载须知
  • 官网QQ群8:819797106
  • 官网QQ群3:830462644(已满)
  • 官网QQ群2:814450983(已满)
  • 官网QQ群1:702511263(已满)
合作单位
  • 安全客
  • 安全客
Copyright © 北京奇虎科技有限公司 360网络攻防实验室 安全客 All Rights Reserved 京ICP备08010314号-66