无参RCE 就是没有参数的函数来进行RCE ,一般代码都会限制成这样。
<?php
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {
eval($_GET['code']);
}
?>
这段代码,就是我们传入code参数 进行正则匹配,如果传入的值 是a-z的字符串 + () ,那么 这个字符串+() 就会替换为 空。 如果替换后的值为; 那么 我们传入的code 就会被eval 执行。如果我们传入一个phpinfo(); 那么 phpinfo() 就会被替换为空。只剩下一个 ; 那么 phpinfo就会被eval函数所执行。
总结一下 无参 RCE 的几种姿势,方便以后自己看:
1 、 getallheaders () 也就是apache_request_headers
包含当前请求所有头信息的数组,失败返回
FALSE
。。但是 他返回的是一个数组。 而exp 得传入的是字符串才会替换为空。
知道这些后 我们还需要一个把数组替换为字符串的函数。
百度了一下 impload可以把 数组替换成字符串。。
在本地测试一下是否
成功返回http头信息组。
抓包修改信息头,试着在最后随意添加一个头header,插入我们的恶意代码并且将后面的内容注释掉。
成功显示在信息头前面
我们构造pyload
eval(imlode(getallheaders()));
这里的意思执行 字符串中的消息头内容。 里面有我们的恶意代码。并且将多余的消息头信息屏蔽掉了。
我代码没法实现,可能 环境有问题。
2、 get_defined_vars()
这个和第一个差不多。
该函数的作用是获取所有的已定义变量,返回值也是数组。不过这个函数返回的是一个二维数组,所以不能与implode结合起来用。 echo不能实现用var_dump()就可以了。
var_dump(get_defined_vars());
看到 通过GET方式传入的参数会在第一个数组里。 这里再利用另一个函数。
这个函数可以返回数组中的第一个单元。 因为GET传入的参数就在第一个数组里,所以我们能够通过这个函数 把参数取出来。
所以我们get传入:
1.php?a=111
本地测试下:
php源代码
<?php
var_dump(current(get_defined_vars()));
?>
取出来了
因为我们在做题的时候,也是通过get传入。 一般的话 插入的恶意的代码一般都在最后面。
比如这样:
后面才是我们要执行的代码。
所以这里还要利用到另一个函数。
我们可以用这个函数取出来,还可以过滤掉其他的值。
<?php
var_dump(end(current(get_defined_vars())));
?>
成功RCE了。
这里的代码意思就是 把已定义的函数数组,取第一个数组的最后一个函数出来执行,也就是我们输入的code=phpinfo();
3、利用session_id 命令执行。
session_id 顾名思义,就是会话id,其作用就是获取当前会话id,也就是cookie 中的phpsession,可以通过抓包修改插入恶意代码,也可以利用火狐的插件进行修改。但是session中只允许出现a-z A-Z 0-9 等字符。所以并不能直接插入恶意代码,但是我们可以先进行16进制编码 再插入。
代码:
<?php
echo hex2bin(session_id(session_start()));
?>
这里要利用session_start();才会生成你的id
字符串转16进制_16进制转换、十六进制转换_汇享在线工具箱 (huixiang360.com)
利用 cookie插件 插入到 session里
在本地环境下测试:
php 文件代码:
<?php
if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['exp'])) {
eval($_GET['exp']);
}
?>
成功RCE
session rce总结: 利用无参代码 使session_id的值为 16进制后的 恶意代码,然后再进行eval执行
至于localeconv(),array_rand(),scandir(),array_flip(),pos() 就不一一介绍利用了