- 网络安全
- 渗透测试
- 桌面应用
【免费下载链接】antSword
中国蚁剑是一款跨平台的开源网站管理工具。AntSword is a cross-platform website management toolkit.
本文以 source/core/custom/README.md 为骨架,结合 source/core/custom 目录下的完整源码与 source/modules 中各业务模块的调用实现,系统梳理 AntSword CUSTOM 自定义脚本类型的 API 协议:包括基础信息、文件管理、命令执行、数据库四大类 21 个功能码的参数约定、底层模板映射与客户端调用方式。读完本文,你将能够理解 CUSTOM 类型 WebShell 的通信协议设计,并据此开发或调试自定义脚本与配套的编码器、解码器、数据库驱动。
一、CUSTOM 类型在 AntSword 中的定位
AntSword(中国蚁剑)的脚本类型(core_types)由 source/app.entry.js 在启动时自动扫描source/core目录下的子目录生成,CUSTOM 即是其中之一。与 php、jsp、aspx 等内置类型不同,CUSTOM 的核心特征在于协议完全由使用者定义:客户端通过固定的Code(功能码,即 A~Z 的字母)与Param(参数名,如z1、z2)组合,与服务端自定义脚本约定的行为一一对应。
从 source/core/custom/index.js 可以看到,CUSTOM 类继承自Base(见 source/core/base.js),并在构造函数中依次解析以下模板:
[ 'base', 'command', 'filemanager', 'database/sqlserver', 'database/mysql', 'database/oracle' ].map((_) => { this.parseTemplate(`./custom/template/${_}`); });也就是说,CUSTOM 客户端侧由**模板(template)定义功能码映射、由编码器(encoder)负责请求参数包装、由解码器(decoder)**负责响应数据还原,三者共同构成了完整的通信链路。
二、CUSTOM API 协议总览
source/core/custom/README.md 将 API 划分为 Base、FileManager、Command、Database 四大类。下表为完整协议清单:
2.1 Base(基础信息)
| Code | Function | Param |
|---|---|---|
| A | info | {} |
| Z | probedb | {} |
对应模板见 source/core/custom/template/base.js,其中注释明确标注:info用于获取当前路径、磁盘列表,probedb用于检测数据库函数支持。
2.2 FileManager(文件管理)
| Code | Function | Param |
|---|---|---|
| B | dir | {"z1": "path"} |
| C | read_file | {"z1": "path"} |
| D | creat_file | {"z1": "path", "z2": "content"} |
| E | delete | {"z1": "path"} |
| F | download_file | {"z1": "path"} |
| H | copy | {"z1": "path", "z2": "target"} |
| I | rename | {"z1": "path", "z2": "name"} |
| K | retime | {"z1": "path", "z2": "time"} |
| J | mkdir | {"z1": "path"} |
| L | wget | {"z1": "url", "z2": "path"} |
| U | upload_file | {"z1": "path", "z2": "buffer::content"} |
| G | filehash | {"z1": "path"} |
2.3 Command(命令执行)
| Code | Function | Param |
|---|---|---|
| M | exec | {"z1": "bin", "z2": "cmd", "z3": "env"} |
| Y | listcmd | {"z1": "binarr"} |
2.4 Database(数据库)
| Code | Function | Param |
|---|---|---|
| N | show_databases | {"z0": "encode", "z1": "conn"} |
| O | show_tables | {"z0": "encode", "z1": "conn", "z2": "db"} |
| P | show_columns | {"z0": "encode", "z1": "conn", "z2": "db", "z3": "table"} |
| Q | query | {"z0": "encode", "z1": "conn", "z2": "sql"} |
三、功能码的参数与语义详解
从 source/core/custom/template 目录下的模板文件可以还原每个功能码的完整参数占位符,占位符采用#{arg}形式,由基类Base.parseTemplate()在运行时替换(见 source/core/base.js)。
3.1 基础信息(A / Z)
模板文件 source/core/custom/template/base.js 定义了:
module.exports = () => ({ info: 'A', probedb: 'Z', // 检测数据库函数支持 })A(info):无参数,用于探测当前工作目录、磁盘盘符等基础信息,通常在连接测试时调用;Z(probedb):无参数,用于检测服务端是否具备数据库函数支持,是数据库模块可用性的前置探测。
在客户端,core.base.info()的调用入口为this.core.request(this.core.base.info()),请求返回的文本与字节流会经过所选解码器处理(见 source/core/base.js)。
3.2 文件管理(B / C / D / E / F / H / I / K / J / L / U / G)
source/core/custom/template/filemanager.js 给出了全部 12 个文件管理功能码的完整模板,摘录核心结构如下:
dir: { _: 'B', 'z1': '#{path}' } read_file: { _: 'C', 'z1': '#{path}' } create_file:{ _: 'D', 'z1': '#{path}', 'z2': '#{content}' } delete: { _: 'E', 'z1': '#{path}' } download_file: { _: 'F', 'z1': '#{path}' } copy: { _: 'H', 'z1': '#{path}', 'z2': '#{target}' } rename: { _: 'I', 'z1': '#{path}', 'z2': '#{name}' } retime: { _: 'K', 'z1': '#{path}', 'z2': '#{time}' } mkdir: { _: 'J', 'z1': '#{path}' } wget: { _: 'L', 'z1': '#{url}', 'z2': '#{path}' } upload_file:{ _: 'U', 'z1': '#{path}', 'z2': '#{buffer::content}' } filehash: { _: 'G', 'z1': '#{path}' }各功能码语义如下:
- B(dir):列出
z1指定路径下的目录内容; - C(read_file):读取
z1指定文件内容; - D(creat_file):在
z1路径创建文件,内容为z2。客户端 source/modules/filemanager/index.js 调用时为create_file({ path, content }),并根据返回文本判断结果——返回'1'视为成功、'0'视为失败(见同文件 L450-L455); - E(delete):删除
z1路径的文件或目录; - F(download_file):下载
z1路径的文件(配合download专用接口与分块回调使用,见 source/core/base.js); - H(copy):将
z1复制到z2; - I(rename):将
z1重命名为z2; - K(retime):修改
z1的修改时间戳为z2; - J(mkdir):在
z1创建目录; - L(wget):从
z1(URL)下载文件到z2(本地路径); - U(upload_file):将
z2内容(buffer::前缀标识二进制缓冲)写入z1路径; - G(filehash):计算
z1文件的哈希值。客户端在 source/modules/filemanager/index.js 中调用后按\n分行解析Algorithm,Hash列表,并以ERROR://前缀作为错误标记。
3.3 命令执行(M / Y)
source/core/custom/template/command.js 定义了:
exec: { _: 'M', 'z1': '#{bin}', 'z2': '#{cmd}', 'z3': '#{env}' } listcmd: { _: 'Y', 'z1': '#{binarr}' }- M(exec):执行命令,
z1为解释器/可执行文件(bin),z2为命令内容(cmd),z3为环境变量(env); - Y(listcmd):传入
z1(binarr,命令候选数组),由服务端返回可用的命令列表,用于在目标机上探测可用命令。
3.4 数据库(N / O / P / Q)
source/core/custom/template/database/default.js 的头部注释明确了四个占位符参数的含义:
// @params // :encode SHELL编码 // :conn 数据库连接字符串 // :sql 执行SQL语句 // :db 数据库名 // :table 表名- N(show_databases):
z0为 SHELL 编码、z1为数据库连接字符串(conn),返回数据库列表; - O(show_tables):在
z0编码、z1连接串基础上,追加z2(db 数据库名),返回表名列表; - P(show_columns):追加
z2(db)、z3(table),返回字段列表; - Q(query):携带
z0编码、z1连接串与z2(sql 语句)执行查询。
客户端 source/modules/database/custom/index.js 是对应数据库驱动:其getTables()通过this.core[database_${conf['type']}].show_tables({ conn, encode, db })发起请求,并对返回值按\t分割生成树节点(见 L586-L613);getColumns()调用show_columns后同样按\t解析字段(见 L643-L678);execSQL()则调用query,若返回文本包含ERROR://即判定为错误(见 L713-L726)。这也从实现侧印证了 README 中z0(encode)与z1(conn)两个参数的设计用途。
四、编码器与解码器:请求如何被包装、响应如何被还原
CUSTOM 类型内置 2 个编码器与 4 个解码器,声明于 source/core/custom/index.js:
get encoders() { return ['base64', 'hex']; } get decoders() { return ['default', 'base64', 'hex', 'hex_base64']; }编码器决定请求参数的包装方式:
base64(source/core/custom/encoder/base64.js):将除_主变量(即连接密码字段)外的所有参数逐一Buffer.from(...).toString('base64')编码,最终把主代码data['_']挂到密码名下;hex(source/core/custom/encoder/hex.js):同上,但编码方式为 16 进制。
该处理发生在基类
encodeComplete()中(见 source/core/base.js),由this.__encoder__[this.__opts__['encoder']](pwd, data, ext)完成。解码器负责还原服务端响应:
default(source/core/custom/decoder/default.js):decode_buff原样返回;base64(source/core/custom/decoder/base64.js):Buffer.from(data.toString(), 'base64')解码;hex(source/core/custom/decoder/hex.js):按 16 进制解码;hex_base64(source/core/custom/decoder/hex_base64.js):先 16 进制还原、再 base64 还原,对应"服务端先将明文 base64 编码再转 hex"的复合编码场景。
解码结果随后交由 source/core/base.js 中的detectEncoding自动识别编码并还原文本。
五、自定义数据分割符(Custom DataTag)
CUSTOM 的complete()方法(source/core/custom/index.js)支持自定义请求数据的起始与结束分割符:
if (this.__opts__['otherConf']['use-custom-datatag'] == 1 && ...) { tag_s = this.__opts__['otherConf']['custom-datatag-tags']; } else { tag_s = "->|"; // 默认开始标记 } // tag_e 默认 "|<-",即结束标记对应配置项定义于 source/modules/shellmanager/list/form.js:
'use-custom-datatag': 0, 'custom-datatag-tags': '', 'custom-datatag-tage': ''在"其他设置"面板中,该功能以"数据分割符"分组呈现(source/language/zh.js),包含"开启自定义数据分割符""开始标记""结束标记"三个选项,内置的候选标记为:
- 开始标记:
->|、~~>|、__}| - 结束标记:
|<-、|<~~、|{~~
界面提示明确要求"数据分割符请避免和页面中其它不相关的字符相同",且"开始标记与结束标记不能相同"(校验逻辑见 source/modules/shellmanager/list/form.js 与 L871-L878)。这一机制用于适配那些在页面输出中混入干扰字符的 WebShell 场景,通过自定义前后标记精确截取有效数据。
六、数据库连接串与驱动约定
CUSTOM 数据库驱动在 source/modules/database/custom/index.js 中预置了三类 JDBC 连接串模板,与 source/core/custom/template/database 下的模板一一对应:
| 类型 | 模板文件 | JDBC Driver / 连接串示例 |
|---|---|---|
| mysql | mysql.js | com.mysql.jdbc.Driver/jdbc:mysql://localhost/test?user=root&password=123456 |
| sqlserver | sqlserver.js | com.microsoft.sqlserver.jdbc.SQLServerDriver/jdbc:sqlserver://127.0.0.1:1433;databaseName=test;user=sa;password=123456 |
| oracle | oracle.js | oracle.jdbc.driver.OracleDriver/jdbc:oracle:thin:user/password@127.0.0.1:1521/test |
上述连接串中的<T>XDB</T>/<X>...</X>注释块用于向使用者标识该模板对应的数据库类型。用户也可以在驱动面板中自行编辑conn字段(含 Driver 与 JDBC 地址两行),新增任意 JDBC 可连接的数据库类型——这正是 README 中z1: conn参数开放设计的意义所在。
七、模板解析机制:从#{arg}到实际请求
理解 CUSTOM API 的底层执行,需要了解基类Base.parseTemplate()的模板替换逻辑(source/core/base.js):
- 每个模板函数返回形如
{ _: 'B', 'z1': '#{path}' }的对象,_字段是主代码(功能码); - 运行时将
#{path}、#{content}等占位符替换为实际传入的实参; - 支持
#{格式函数::参数}语法,例如#{hex::str}会先调用格式化函数hex处理参数再替换;Base.format()(同文件 L140-L198)提供了base64、newbase64、buffer、hex等格式化工具; - 替换完成后,
data['_']中的#randomPrefix#标记还会按otherConf["random-Prefix"]配置替换(L247)。
可见 README 中的Param列({"z1": "path"}等)正是模板占位符的"参数名 → 模板变量"约定:同一个功能码对应服务端脚本中的一个分支,参数名z1/z2/z3是约定好的键,值则为客户端填入的实际数据。服务端自定义脚本只需按 Code 分发、按参数名取数即可实现完整对接。
八、实践要点小结
- 对接约定:开发 CUSTOM 类型 WebShell 时,服务端脚本需实现 README 所列的 A~Z 功能码分支,并正确处理对应
z*参数;客户端侧则通过 source/core/custom/template 下的模板文件统一维护映射,无需修改 source/core/custom/index.js 即可扩展。 - 请求与响应:请求数据经所选编码器(base64 / hex)包装后随功能码发送;响应数据经对应解码器还原,错误约定以
ERROR://前缀返回(数据库、文件哈希等模块均按此约定判断)。 - 数据库接入:在数据库面板新建连接时,
conn字段填写"JDBC Driver 类名 + 换行 + JDBC 连接串",CUSTOM 驱动会通过N/O/P/Q四个功能码完成库、表、字段遍历与 SQL 查询。 - 流量特征控制:可通过"数据分割符"自定义
->|/|<-之外的起止标记,降低流量特征被规则匹配的风险,但需保证前后标记不同且不与页面其他字符冲突。 - 进一步阅读:完整的协议清单可回看 source/core/custom/README.md;模板实现位于 source/core/custom/template;客户端驱动实现位于 source/modules/database/custom/index.js 与 source/modules/filemanager/index.js。
- 网络安全
- 渗透测试
- 桌面应用
【免费下载链接】antSword
中国蚁剑是一款跨平台的开源网站管理工具。AntSword is a cross-platform website management toolkit.
相关推荐
中国蚁剑AntSword核心源码解读:从启动到功能实现的完整指南
中国蚁剑AntSword核心源码解读:从启动到功能实现的完整指南 中国蚁剑(AntSword)是一款跨平台的开源网站管理工具,通过模块化架构实现灵活的功能扩展。
网络安全渗透测试桌面应用AntSword 中国蚁剑 Custom 模式服务端脚本全解析:PHP / JSP / JSPX / Python 示例脚本与源码原理
AntSword 中国蚁剑 Custom 模式服务端脚本全解析:PHP / JSP / JSPX / Python 示例脚本与源码原理 本文以 webshell
网络安全渗透测试中国蚁剑AntSword终极指南:10个自定义模板与编码器开发技巧
中国蚁剑AntSword终极指南:10个自定义模板与编码器开发技巧 中国蚁剑AntSword是一款功能强大的开源网站管理工具,作为渗透测试和安全研究人员的必备利
网络安全渗透测试桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考