JCS-Pro · Joomla 组件漏洞扫描器(Java 汉化重写版)

JCS-Pro · Joomla 组件漏洞扫描器(Java 汉化重写版)

原版 JCS(Joomla Component Scanner)由 TheM4hd1 用 C# / WinForms 编写;
本项目是它的 Java 重写 + 汉化 + 功能扩展版:命令行、单 jar、零第三方依赖(JDK 17+)。


1. 它解决的问题

Joomla 站点的攻击面大量来自 第三方组件(com_xxx)。
一个组件是否安装、是否带已知漏洞,往往比核心版本更关键。
JCS-Pro 做的事情是:

  1. 确认目标是不是 Joomla(多特征指纹打分)
  2. 识别 Joomla 核心版本(6 种方法交叉验证)
  3. 探测组件是否存在(内置字典 + 页面自动发现,多线程)
  4. 按版本与组件匹配已知漏洞,并对可无授权验证的漏洞实际发请求验证
  5. 输出中文报告(HTML / JSON / TXT),可直接贴进漏洞报告

2. 相对原版的变化

维度 原版 JCS (C#) JCS-Pro (Java)
运行形态 WinForms 图形界面,需 Visual Studio 编译 Swing 图形界面 + 命令行,run.bat 双击可用(单 jar,仅 MySQL 驱动/JBCrypt 两个可选依赖)
语言/界面 英文 全中文(帮助、进度、报告、漏洞描述)
版本识别 4 种 6 种(新增 language/*/langmetadata.xml、administrator/language/...)
组件库 需手工维护 database.txt 内置 136 条 + 支持 data/components.csv 追加
组件发现 正则爬虫抓链接 首页/index.php 抓 option=com_xxx + 链接正则,且页面发现的组件强制探测
漏洞模块 仅列 ExploitDB 链接 12 个可执行 POC 模块(见第 5 节),能给出实锤回显
报告 HTML HTML + JSON + TXT,含请求数、指纹得分、证据片段
副作用控制 无 危险模块默认不执行,必须 --force-exp
工程性 无重试、无代理鉴权细节 连接失败自动重试、随机 UA、代理、Cookie、限速、gzip

3. 构建与运行

:: 构建(需要 JDK 17+,会自动找 JAVA_HOME / PATH / Program Files 下的 JDK)
build.bat

:: 查看全部漏洞模块
run.bat --list-exp

:: 扫描单个目标(默认 all:指纹 + 版本 + 组件 + 漏洞)
run.bat -u http://target.com

:: 批量扫描
run.bat -f targets.txt -t 30 --delay 80 -o reports

:: 只跑指定漏洞模块,并允许有副作用的利用
run.bat -u http://target.com -m exp --only cve-2023-23752-config,cve-2017-8917-com_fields

:: 导出组件字典,按需补充后放回 data/components.csv
run.bat --dump-db

产物:reports/jcs-<host>-<时间>.html|.json|.txt,reports/loot/ 存放泄露到的配置、用户列表等证据。


3.1 图形界面(默认启动)

run.bat                 :: 直接进图形界面
run.bat --gui           :: 同上
run.bat --gui http://192.168.1.10   :: 带目标进图形界面

界面分四页:

页 内容
运行日志 实时日志(指纹得分、版本与来源、组件发现、漏洞命中、报告路径)、进度条、底部汇总
组件 命中的组件 / 说明 / HTTP 状态 / 判定证据;双击看完整证据
漏洞 等级(严重=红、高危=橙、中危=黄、信息=灰)、名称、CVE、是否命中、详情;未命中也会列出原因(版本不在区间 / 需 --force-exp / 未发现接口)
数据库 / 后台 见 5.1:拿到数据库口令后一键建管理员并回显账号口令

要点:

  • 顶部三个按钮:开始扫描 / 停止(可中途取消,已发出的请求不回收)/ 打开报告目录;
  • 线程、超时、模式(全量 / 只识别版本 / 只扫组件 / 只跑漏洞)在第二行;
  • 扫描过程中「数据库 / 后台」页会自动填入从 configuration.php~ 或 CVE-2023-23752 拿到的凭据;
  • 窗口尺寸按 DPI 换算成逻辑像素再居中,150% 缩放下不会被切到屏幕外。

3.2 参数说明

参数 说明
-u, --url <URL> 目标地址,可重复或空格分隔多个
-f, --file <文件> 从文件读目标,每行一个,# 注释
-m, --mode <all\|detect\|scan\|exp> 默认 all
--only <id,id> 只跑指定漏洞模块
--force-exp 允许执行有副作用的利用(注册管理员、上传、爆破等)
--no-crawl 不从页面抓取组件名
--strict-version 只探测版本区间相符的组件(原版行为,请求更少、可能漏)
-t, --threads <N> 并发线程,默认 20
--delay <ms> 每次请求前间隔,默认 0(绕过 WAF 限速时用)
--timeout <ms> 单请求超时,默认 12000
--proxy <host:port> HTTP 代理
--ua <UA> 固定 User-Agent(默认随机)
-H "K: V" 追加请求头,可重复
--cookie <串> 手工 Cookie
-o, --out <目录> 报告目录,默认 ./reports
--list-exp 列出全部漏洞模块后退出
--dump-db 导出 data/components.csv 后退出
--no-color 关闭 ANSI 彩色

5. 漏洞模块(12 个)

ID 等级 说明 影响版本
core-cve-map 信息 核心版本 → 已知 CVE 映射表 全部
cve-2023-23752-config 严重 /api/index.php/v1/config/application?public=true 未授权读数据库账号口令、站点配置 4.0.0-4.2.7
cve-2023-23752-users 高危 /api/index.php/v1/users?public=true 枚举用户名/邮箱/注册时间 4.0.0-4.2.7
cve-2017-8917-com_fields 严重 com_fields list[fullordering] 报错注入,回显 database() 3.7.0
cve-2015-7857-contenthistory 高危 com_contenthistory list[select] 注入 2.5.0-3.4.4
cve-2015-8562-ua-rce 严重 User-Agent 反序列化 RCE(版本命中即报,附 gadget 构造要点) 1.5.0-3.4.5
cve-2016-8869-com_users 严重 注册接口提权,可注册管理员(需 --force-exp) 3.4.4-3.6.3
backup-leak 高危 configuration.php~/.bak/.save/.old/.txt/.orig、com_akeeba 备份、joomla.sql 等 14 条路径,命中即解析 $host/$user/$password/$db 全部
admin-panel 信息 后台入口与登录字段指纹 全部
com_jckman-upload 中危 com_jckman 历史版本任意文件上传点探测 1.0-2.0
com_fabrik-check 中危 读 fabrik.xml 取版本,标注 SQLi/上传面 3.0-3.9
com_ajax-info 信息 com_ajax 是否启用及返回结构 3.0-4.2

说明:模块只做「最小必要验证」——能回显就取回显(库名、账号、口令),
不能回显就只报版本与利用面,不猜测、不伪造成功。


5.1 数据库 / 后台:拿到库口令直接建管理员

界面第四页,或命令行看到 [+] 泄露数据库凭据: user@host:port/db 前缀 jos_ 之后使用。

流程:扫描命中 → 凭据自动进下拉框 → 使用选中凭据 → 测试连接 → 一键创建管理员。

它到底写了什么(Joomla 官方表结构):

表 写入内容
#__users name / username / email / password / block=0 / sendEmail=1 / registerDate=now / params='',按目标实际存在的列动态拼 INSERT(1.5 老库缺列也不会报错)
#__user_usergroup_map (user_id, group_id=8) —— 8 即 Super Users(超级用户组,后台最高权限)
老结构 1.5.x 若无映射表但有 gid 列,则 UPDATE #__users SET gid=25(超级管理员)

口令方案自动判别(决定能不能登录成功的关键):

  • 读站点既有账号的 password 字段判断:$2y$/$2a$/$2b$ → bcrypt;含 : → md5(password+salt):salt;
  • 判不出来时按版本推断:≥4.0 或 ≥3.2 用 bcrypt,更早用 md5+salt;
  • bcrypt 用 JBCrypt gensalt(10) 生成后把 $2a$ 改写成 Joomla 认的 $2y$;
  • 用户名已存在则重置口令而不是重复插入,最后回读校验 id|username|email|block|hash。

账号口令回显:底部绿色大字 后台: http://目标/administrator/ 账号: jcsadmin 口令: xxxx,复制账号口令 一键进剪贴板,可直接拿去登录后台。

MySQL 严格模式的坑(已修):Joomla 建表时 lastvisitDate / registerDate 的默认值是
'0000-00-00 00:00:00',而 MySQL 5.7+ 默认 sql_mode 含 NO_ZERO_DATE,INSERT 时省略这两列会直接失败:

MysqlDataTruncation: Data truncation: Incorrect datetime value: '0000-00-00 00:00:00'
for column 'lastvisitDate' at row 1        (MySQL 侧为 ERROR 1292 22007)

现在的处理是双保险:

  1. 连接后执行 SET SESSION sql_mode=''(会话级,不影响其他连接);
  2. 更关键的一条:INSERT 前按 information_schema.columns 逐列检查,凡是没写、且默认值是零日期/NULL 的 NOT NULL 列,一律显式补合法值
    —— 日期列给 NOW(),整数列给 0,字符列给 '';自增列与生成列跳过。
    日志里会打印 [i] 将写入列: ...,方便核对到底写了哪些字段。

所以即使目标库的账号没有权限改 sql_mode,也能正常建号。生成 SQL 输出的语句同样把
registerDate/lastvisitDate/lastResetTime 写成 NOW()(resetCount=0),粘进 phpMyAdmin 不会再报 1292。

同一族的另一个坑:Column 'lastResetTime' cannot be null

MySQLIntegrityConstraintViolationException: Column 'lastResetTime' cannot be null

不同 Joomla 版本的 #__users 里,lastResetTime 有的是可空 NULL,有的是
datetime NOT NULL DEFAULT '0000-00-00 00:00:00'(MySQL 5.7 常见)。早期版本里我们把它固定写成
NULL,碰上后者就会报这句。现在的规则是按 information_schema.columns 的真实可空性走:

列类型 可空 写入值
datetime / timestamp 是 NULL
datetime / timestamp 否 NOW()
int / bit / tinyint — 0
其它(char/varchar/text) — ''

[i] 将写入列: ... 里能看到 lastResetTime 排在哪一列,回读结果会给出它的实际值。

数据库只允许 localhost 怎么办(很常见,例如 phpStudy 的 root 仅 127.0.0.1):
点 生成 SQL,工具会输出两套可直接粘进 phpMyAdmin 的语句(bcrypt 与 md5+salt),
执行后同样得到超级管理员;也可以在目标上做端口转发后再用直连。


5.2 识别原理

指纹(每命中 +分,≥4 判定为 Joomla):/administrator/、/components/、
/templates/system/css/system.css、/media/system/js/core.js、
<meta name="generator" content="Joomla!">、/language/en-GB/en-GB.xml。

版本(6 法,按可靠性排序):

  1. /administrator/manifests/files/joomla.xml → <version>
  2. /language/en-GB/langmetadata.xml → <version>
  3. /administrator/language/en-GB/en-GB.xml → <version>
  4. /README.txt → Joomla! x.y.z
  5. /plugins/editors/tinymce/tinymce.xml → TinyMCE 版本 → 反查 Joomla 版本(内置 21 条映射表)
  6. /components/com_contact/metadata.xml → 时间戳特征(仅 1.5.x)

组件存在判定:/components/<com_x>

  • 200 且命中 Joomla 空页特征(<html><body bgcolor="#FFFFFF"></body></html> 等)→ 存在
  • 200 正常内容 → 存在
  • 403 → 目录存在但禁止访问
  • 404/302/连接失败 → 不存在

7. 扩展组件字典

--dump-db 导出 data/components.csv,格式:

name,title,range,vuln,link
com_fabrik,Fabrik 表单,3.0-3.9,SQL 注入 / 任意文件上传,https://cxsecurity.com/ascii/WLB-2017120085
  • range 写成 1.5-3.4.5,留空表示全版本
  • 放回 data/components.csv 后启动会自动合并(同名字段以文件为准)

8. 已知限制

  • 版本区间是经验值,只用于排序与提示,不代表必然可利用;
  • cve-2015-8562 需要构造 PHP gadget chain(JDatabaseDriverMysqli),工具只判定版本并给出构造要点,不内置通用链;
  • 需要登录的利用(模板写入、com_media 上传、插件安装)只标注位置,需拿后台凭据后手工执行;
  • 目标若挂在 CDN/WAF 后,403 与 200 空页 的判定可能失真,建议配合 --delay 与 -H 自定义头;
  • 建管理员依赖 MySQL 允许远程连接:root@localhost 这类配置下直连会报
    Access denied for user 'root'@'<本机>',此时请用 生成 SQL 走 phpMyAdmin(见 5.1);
  • 建管理员会在目标库留下一个真实账号,请在授权测试范围内使用、并在结束后自行清理。

9. 参考来源


10. 免责声明

仅用于已获授权的安全测试、教学与自家资产检查。
使用者对自己发出的每一个请求负责。

JCS-Pro · Joomla 组件漏洞扫描器(Java 汉化重写版)-棉花糖网络安全资源站
JCS-Pro · Joomla 组件漏洞扫描器(Java 汉化重写版)
此内容为付费资源,请付费后查看
20积分
付费资源
© 版权声明
THE END
喜欢就支持一下吧
点赞64 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容