news 2026/10/15 2:10:15

中国蚁剑 AntSword CUSTOM 自定义脚本类型 API 协议全解析:从功能码到模板实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
中国蚁剑 AntSword CUSTOM 自定义脚本类型 API 协议全解析:从功能码到模板实现
  • 网络安全
  • 渗透测试
  • 桌面应用

【免费下载链接】antSword

中国蚁剑是一款跨平台的开源网站管理工具。AntSword is a cross-platform website management toolkit.

项目地址:https://gitcode.com/gh_mirrors/an/antSword
点击查看免费下载

本文以 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(基础信息)

CodeFunctionParam
Ainfo{}
Zprobedb{}

对应模板见 source/core/custom/template/base.js,其中注释明确标注:info用于获取当前路径、磁盘列表,probedb用于检测数据库函数支持。

2.2 FileManager(文件管理)

CodeFunctionParam
Bdir{"z1": "path"}
Cread_file{"z1": "path"}
Dcreat_file{"z1": "path", "z2": "content"}
Edelete{"z1": "path"}
Fdownload_file{"z1": "path"}
Hcopy{"z1": "path", "z2": "target"}
Irename{"z1": "path", "z2": "name"}
Kretime{"z1": "path", "z2": "time"}
Jmkdir{"z1": "path"}
Lwget{"z1": "url", "z2": "path"}
Uupload_file{"z1": "path", "z2": "buffer::content"}
Gfilehash{"z1": "path"}

2.3 Command(命令执行)

CodeFunctionParam
Mexec{"z1": "bin", "z2": "cmd", "z3": "env"}
Ylistcmd{"z1": "binarr"}

2.4 Database(数据库)

CodeFunctionParam
Nshow_databases{"z0": "encode", "z1": "conn"}
Oshow_tables{"z0": "encode", "z1": "conn", "z2": "db"}
Pshow_columns{"z0": "encode", "z1": "conn", "z2": "db", "z3": "table"}
Qquery{"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 / 连接串示例
mysqlmysql.jscom.mysql.jdbc.Driver/jdbc:mysql://localhost/test?user=root&password=123456
sqlserversqlserver.jscom.microsoft.sqlserver.jdbc.SQLServerDriver/jdbc:sqlserver://127.0.0.1:1433;databaseName=test;user=sa;password=123456
oracleoracle.jsoracle.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):

  1. 每个模板函数返回形如{ _: 'B', 'z1': '#{path}' }的对象,_字段是主代码(功能码);
  2. 运行时将#{path}、#{content}等占位符替换为实际传入的实参;
  3. 支持#{格式函数::参数}语法,例如#{hex::str}会先调用格式化函数hex处理参数再替换;Base.format()(同文件 L140-L198)提供了base64、newbase64、buffer、hex等格式化工具;
  4. 替换完成后,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.

项目地址:https://gitcode.com/gh_mirrors/an/antSword
点击查看免费下载

相关推荐

上一篇:fx_cast白名单系统:安全策略与网站权限管理最佳实践
下一篇:钉钉位置模拟实战:Xposed钉钉助手从零到能用的保姆级教程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/15 2:05:53

双11业务风控与反欺诈实战总结:构筑全链路抗黑产纵深防御长城

大促前夕的攻防对抗从来都不是偶发的试探&#xff0c;而是一场组织严密、分工明确的立体消耗战。黑灰产依托分布式代理池、群控设备农场、自研逆向破解框架以及高度自动化的脚本工具&#xff0c;在毫秒之间向核心结算、领券、加购与详情接口发起海量伪造请求。如果防御体系仅仅…

作者头像 李华
网站建设 2026/10/15 2:04:35

嵌套 ESXi 里的 VM 拿不到 DHCP?一篇讲透 vSwitch 混杂模式 + 实战配置

本文适用场景:vSphere 实验室 / NSX 试验环境 / vSphere with Kubernetes / VCF 演示 涉及版本:物理 ESXi 7.0/8.0/9.0,嵌套 ESXi 6.7/7.0/8.0 阅读时长:约 7 分钟一、排错日记:今天又踩了一遍这个坑今天下午在搭 vSphere with Kubernetes 实验环境,在物理 ESXi 8.0 上装了一台…

作者头像 李华
网站建设 2026/10/15 2:03:07

MFC多视频界面空壳程序设计与稳定性验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/15 2:02:38

SpringBoot+Vue旅游小程序开发与AI技术融合实践

1. 项目概述这个毕业设计项目是一个结合了前后端技术的旅游攻略小程序&#xff0c;采用SpringBoot作为后端框架&#xff0c;Vue.js作为前端框架&#xff0c;并融入了AI技术来增强用户体验。这类项目在当前旅游信息化浪潮中具有典型意义——随着移动互联网的普及&#xff0c;传统…

作者头像 李华