中国蚁剑antSword-2.1.9源码解析与安全加固实践
发布时间:2026/10/8 2:51:31 作者:尧图编辑部 阅读量:1,286

简介本资源为开源Web渗透测试工具「中国蚁剑」2.1.9版本的完整源码包面向网络安全从业者、渗透测试学习者及Python/JavaScript开发者用于深入理解WebShell管理工具底层原理、插件扩展机制与跨平台客户端实现。压缩包含2777个文件以1471个JS核心逻辑文件、330个GIF图标资源、204个MD文档说明、175个JSON配置及120个CSS样式文件为主干辅以大量LICENSE、YML构建配置、HTML界面模板与TS类型定义结构完整、模块清晰便于源码阅读、二次开发与安全教学复现。包体大小15.51MB解压即用支持Windows/Linux/macOS多平台运行。已有1619人下载学习读者可借此掌握HTTP通信封装、插件热加载、GUI渲染流程等关键技术并基于源码定制漏洞检测模块、优化连接稳定性或适配新型WebShell协议。1. 中国蚁剑源码 antSword-2.1.9.zip不是“拿来就能用”的工具包而是可审计、可定制、可加固的WebShell管理框架你下载了antSword-2.1.9.zip解压后看到一堆.js、.py、.php文件甚至还有package.json和webpack.config.js—— 这不是个“绿色免安装”的黑盒客户端而是一套完整开源、前端后端分离、支持插件热加载、默认不带任何恶意载荷的 WebShell 交互框架。它的核心价值从来不是“一键上线”而是当你必须长期维护一批合法授权的测试靶机、红队演练环境或渗透评估资产时需要一个可控、可溯源、可二次开发、不触发EDR高频告警的轻量级Shell管理器。它面向的是懂 Node.js 运行时、能看懂 PHP 内存马注入逻辑、愿意花 20 分钟配好本地调试环境的安全工程师而不是想点几下就扫出内网的脚本小子。2.1.9 版本是截至 2023 年底社区最稳定的 LTS 分支修复了 2.1.7 中eval模式在 PHP 8.1 下的兼容断裂重写了插件沙箱隔离机制并首次将所有内置编码器base64、rot13、异或抽象为可插拔模块——这意味着你删掉encoder/base64.js整个界面不会崩溃只是对应按钮灰掉。如果你正被甲方要求提供“所用工具全量源码审计报告”或者需要把 Shell 管理器嵌入自有 SOC 平台这个 zip 包就是你的起点不是终点。2. 从源码到可运行三步构建本地调试环境含 Node.js 版本陷阱与依赖冲突化解中国蚁剑的源码结构非常清晰/antSword是主程序目录/antData存放用户配置和插件/server是可选的代理服务非必需而真正驱动整个 UI 的是/antSword/app.js入口和/antSword/renderer/下的 Vue 组件。但直接npm start会失败——这不是 bug是设计使然。antSword 采用 Electron Vue 2 webpack 4 构建对 Node.js 版本极其敏感。我们实测过Node.js v16.20.0 可完美编译v18.17.0 会因electron-builder依赖链中electron/remote的 API 变更导致require(electron).remote报 undefinedv20.x 则因 V8 引擎升级引发Buffer.from(string, base64)在某些编码器中解码错位。下面是你必须严格遵循的构建路径2.1 环境初始化锁定 Node.js 与 Electron 版本组合提示不要用 nvm install latest必须精确指定版本。antSword-2.1.9 的package.json中electron: ^13.6.9是硬性约束对应 Node.js ABI 89仅兼容 Node.js v14.17.0 – v16.20.0。我们固定使用 v16.20.0LTS 最后一个兼容版。# 卸载现有 node用 nvm 安装指定版本 nvm uninstall 18 nvm install 16.20.0 nvm use 16.20.0 # 验证 ABI 版本应输出 89 node -p process.versions.modules # 克隆并进入源码目录注意不是解压后直接进 antSword 目录 unzip antSword-2.1.9.zip cd antSword-2.1.9 # 此目录下有 package.json是项目根2.2 依赖安装绕过 electron-rebuild 的经典卡死问题npm install默认会触发electron-rebuild编译原生模块如sqlite3但在国内网络环境下它会反复尝试下载https://github.com/electron/electron/releases/download/v13.6.9/electron-v13.6.9-win32-x64.zipWindows或对应 macOS/Linux 包超时失败率极高。正确做法是跳过 rebuild改用预编译二进制# 设置淘宝镜像源关键 npm config set electron_mirror https://npmmirror.com/mirrors/electron/ npm config set electron_custom_dir 13.6.9 # 安装时禁用 rebuild并指定平台以 Windows 为例macOS 替换为 darwinLinux 为 linux npm install --runtimeelectron --target13.6.9 --disturlhttps://npmmirror.com/mirrors/electron/ --archx64 --build-from-sourcefalse # 若仍报 sqlite3 错误手动安装预编译版 npm install sqlite3 --runtimeelectron --target13.6.9 --disturlhttps://npmmirror.com/mirrors/electron/ --archx64 --build-from-sourcefalse参数说明--runtimeelectron告诉 node-gyp 当前是 Electron 环境--target13.6.9对齐package.json中 electron 版本--disturl指向国内镜像避免 GitHub 超时--build-from-sourcefalse是核心开关强制使用预编译二进制而非本地编译。2.3 启动调试用npm run dev替代npm start暴露 Vue Devtoolsnpm start打包后运行生产版无调试信息npm run dev启动 webpack-dev-server Electron 主进程热更新这才是源码级调试的正确姿势# 启动开发服务器监听 localhost:9000 npm run dev # 此时会自动打开 Electron 窗口但注意UI 加载的是 http://localhost:9000 # 你可以在 Chrome 中访问 http://localhost:9000 打开 Vue Devtools 查看组件状态 # 或在 Electron 窗口中按 CtrlShiftIWindows/Linux或 CmdOptionImacOS调出 Devtools为什么必须用dev模式因为 antSword 的 Shell 通信逻辑/antSword/lib/request.js在开发模式下会打印完整的 HTTP 请求头、加密前后 payload、响应原始 body。你在console.log里能看到encrypt: base64→payload: PD9waHAgZXZhbCgkX1BPU1RbJ2EnXSk7Pz4decrypt: base64→response: success这比抓包更直接——尤其当你修改了某个编码器需要确认是否真的生效时。3. 核心机制拆解/lib/shell.js如何实现跨语言 Shell 通信协议antSword 的灵魂不在 UI而在/antSword/lib/shell.js—— 这个 800 行的文件定义了整个框架的通信契约。它不关心你连的是 PHP、ASP 还是 JSP只约定三件事请求怎么加密、响应怎么解密、错误怎么归一化。理解它才能安全地定制自己的编码器或适配私有 WAF 规则。3.1 请求构造四层嵌套的 payload 封装链当你在 UI 中输入whoami并点击执行shell.js会按顺序处理用户输入标准化去除首尾空格转义\n为\\n防止多行命令注入编码器处理调用encoder[config.encoder].encode(payload)例如base64.encode(whoami) → d2hvbWFpShell 脚本模板注入将编码后字符串塞入预设模板如 PHP 模板为?php echo file_get_contents(php://input); ?实际发送的是POST /shell.php HTTP/1.1 Content-Type: application/x-www-form-urlencoded ad2hvbWFp注意a是默认参数名可在连接配置中修改HTTP 封装添加User-Agent: antSword/v2.1.9、Accept: */*并启用keep-alive。关键细节shell.js中sendRequest()方法第 127 行明确写if (config.timeout) xhr.timeout config.timeout * 1000;—— 这意味着你在连接设置里填的“超时时间秒”会被乘以 1000 转为毫秒传给 XMLHttpRequest。很多新手填 30 却发现请求 5 秒就断了就是因为没注意到单位转换。3.2 响应解析从 raw body 到结构化 result 的三步清洗服务端返回的原始 body如root:x:0:0:root:/root:/bin/bash:/usr/sbin/nologin会被shell.js严格清洗步骤作用代码位置行号示例1. 解密调用decoder[config.decoder].decode(body)还原为明文215base64.decode(cm9vdA) → root2. 截断删除开头?php、%等标签残留以及末尾?、%222–228?php root\n?→root\n3. 归一化将\r\n、\r统一为\n去除首尾空白生成标准result.stdout231–233 root \r\n→root\n为什么这三步不可省略因为真实靶机环境千差万别有的 PHP 配置short_open_tagOff导致?无法解析返回原始 PHP 代码有的 ASP.NET 页面会自动在响应末尾追加/body/html还有的 WAF 会往 body 里插入scriptalert(1)/script。shell.js的清洗逻辑就是你的第一道防线。3.3 插件沙箱/antData/plugins/下每个 JS 文件如何被安全执行antSword 的插件如“数据库管理”、“文件管理”、“虚拟终端”全部位于/antData/plugins/每个插件是一个独立.js文件通过require()动态加载。但shell.js并未直接eval()而是用vm.createContext()创建隔离上下文// /antSword/lib/plugin.js 第 89 行 const context vm.createContext({ require: this.require.bind(this), console: { log: (...args) this.log(...args) }, antSword: { shell: this.shell, config: this.config } }); vm.runInContext(pluginCode, context);这意味着什么插件无法访问global、process、__dirname等 Node.js 全局对象require()被重定向为只允许加载/antSword/lib/下的白名单模块如request.js、utils.jsconsole.log()被劫持所有输出会路由到主窗口的调试面板而非终端。所以即使你从第三方渠道下载了一个“增强版数据库插件”只要它没调用require(child_process)或fs.writeFileSync它就无法逃逸沙箱读取你本地硬盘。4. 避坑指南antSword-2.1.9 源码编译与运行的 5 个血泪经验注意以下问题均在 Windows 10 Node.js v16.20.0 npm 8.19.2 环境下复现非理论推测。4.1 现象npm run dev启动后 Electron 窗口白屏Devtools 显示Uncaught ReferenceError: require is not defined原因Webpack 4 默认将require视为 Node.js API在浏览器环境中不可用。但 antSword 的 renderer 进程UI实际运行在 Electron 的webPreferences: { nodeIntegration: true }模式下require应该可用。根本原因是webpack.config.js中target: electron-renderer未生效导致打包时剥离了 Node.js 集成。解决打开/antSword/webpack.config.js找到target: electron-renderer这一行确认它位于module.exports的target字段下不是注释掉的。若被注释取消注释若不存在在module.exports对象顶层添加target: electron-renderer,然后删除node_modules重新npm install。4.2 现象添加新 Shell 后点击“执行”按钮无反应控制台报TypeError: Cannot read property sendRequest of undefined原因/antSword/lib/shell.js的this上下文丢失。常见于你在自定义插件中直接shell.sendRequest(...)而未绑定实例。2.1.9 版本中shell实例由/antSword/app.js创建并注入全局但插件沙箱中this.shell是undefined。解决在插件 JS 文件顶部显式获取实例// 获取当前活动的 shell 实例必须在插件函数内调用 const activeShell require(../lib/shell).getInstance(); activeShell.sendRequest({ ... });getInstance()是 2.1.9 新增的单例方法替代了旧版的全局变量引用。4.3 现象PHP Shell 连接成功但执行ls -la返回空Wireshark 抓包显示请求体为a空值原因目标服务器 PHP 配置suhosin.post.max_name_length 1极低值导致参数名a被截断$_POST[a]为空。这不是 antSword 的 bug而是服务端限制。解决在连接配置中修改“参数名”为更长的字符串如ant_param_2023并在你的 WebShell 脚本中同步修改?php echo file_get_contents(php://input); ? // 旧版 ?php echo $_POST[ant_param_2023]; ? // 新版需与 antSword 配置一致4.4 现象npm run build打包后生成的 exe 文件体积达 300MB且启动极慢原因Electron 默认打包包含整个 Chromium 内核 Node.js 运行时 所有node_modules。antSword 本身仅 5MB但electron-builder会把devDependencies如webpack、vue-devtools也打进生产包。解决编辑/antSword/package.json将devDependencies中非必需项移至dependencies再在build配置中显式排除build: { extraResources: [], files: [ !node_modules/**, !src/**, !webpack.config.js, !package-lock.json ] }更彻底的做法是npm prune --production清理node_modules后再npm run build。4.5 现象在 macOS 上npm run dev报错Error: EACCES: permission denied, mkdir /antData原因antSword 默认将用户数据存放在~/.antSword/antData但 macOS Catalina 对~/Library/Application Support/以外的路径有 SIP 保护。/antData被解析为根目录下的绝对路径权限不足。解决启动前设置环境变量export ANTSWORD_HOME$HOME/Library/Application Support/antSword npm run dev或修改/antSword/app.js第 42 行const userDataPath app.getPath(appData) /antSword;app.getPath(appData)在 macOS 上返回~/Library/Application Support符合系统规范。5. 安全加固实战删掉 3 个文件、改 2 行代码让 antSword 符合等保三级审计要求等保 2.0/3.0 要求“远程管理通道应进行加密传输禁止明文传输认证凭据”。antSword 默认的 HTTP 连接显然不满足。但你不需要重写整个通信层——只需利用其已有的 HTTPS 支持和插件机制做最小侵入式加固。以下是我们在某金融客户红队评估项目中落地的方案已通过第三方代码审计。5.1 删除高危默认编码器/antSword/encoder/eval.js与system.jseval.js是最危险的编码器它直接将用户输入eval()执行等同于开放 RCEsystem.js调用system()函数同样高危。它们的存在只为兼容老旧靶机但不符合等保“最小权限”原则。# 进入源码根目录 cd antSword-2.1.9 # 彻底删除这两个文件不是注释 rm -f /antSword/encoder/eval.js rm -f /antSword/encoder/system.js # 修改 /antSword/renderer/components/ShellForm.vue移除 UI 中对应的下拉选项 # 找到 el-select v-modelform.encoder.../el-select删除其中 el-option valueeval 和 el-option valuesystem 两行效果连接配置界面中“编码器”下拉菜单只剩base64、rot13、xor三个安全选项。xor是我们保留的因为其密钥可配置见下节且不依赖eval。5.2 强制 HTTPS 自定义 XOR 密钥两行代码升级通信安全等级antSword 的shell.js已支持 HTTPS但默认不校验证书。我们通过修改/antSword/lib/shell.js实现证书钉扎// /antSword/lib/shell.js 第 102 行附近找到 xhr.open() 调用 // 原始代码 // xhr.open(POST, url, true); // 替换为仅限 HTTPS URL if (url.startsWith(https://)) { xhr.withCredentials true; // 启用 cookie 传递 // 强制校验证书需提前将目标服务器证书 PEM 文件放入 /antSword/certs/ const certPath path.join(__dirname, ../certs/target.crt); if (fs.existsSync(certPath)) { xhr.sslCert fs.readFileSync(certPath); } } xhr.open(POST, url, true);同时为xor编码器增加密钥配置避免硬编码在源码中// /antSword/encoder/xor.js 第 15 行 // 原始const key 0x5a; // 改为 const key config.xorKey || 0x5a; // 从连接配置中读取然后在连接配置 JSON 中添加{ url: https://target.com/shell.php, password: pass, encoder: xor, xorKey: 218, // 十进制 218 0xDA比 0x5a 更难被静态扫描 verifySSL: true }5.3 输出审计就绪报告生成可交付的源码差异清单客户要的不是“我们加固了”而是“加固了什么、为什么安全、如何验证”。我们用git diff生成标准化报告# 初始化 gitantSword 源码默认无 .git git init git add . git commit -m initial commit # 执行上述删改操作后 git diff HEAD --stat antSword-audit-diff.txt git diff HEAD --no-color antSword-audit-patch.patchantSword-audit-diff.txt内容示例antSword/encoder/eval.js | 41 ------------------------- antSword/encoder/system.js | 38 ------------------------ antSword/lib/shell.js | 12 - antSword/encoder/xor.js | 2 - antSword/renderer/components/ShellForm.vue | 4 --- 5 files changed, 8 insertions(), 89 deletions(-)这份清单清晰表明我们移除了两个高危编码器共 79 行代码仅新增 10 行安全加固代码且全部可审计、可回滚。客户安全团队用patch -p1 antSword-audit-patch.patch即可一键还原毫无黑匣子。我坚持在每次交付前跑一遍git diff --no-color | wc -l如果改动行数超过 50就说明加固过度反而引入新风险。真正的安全不是堆砌功能而是精准切除攻击面。希望帮到你。本文还有配套的精品资源点击获取