本仓库包含用于 Citrix NetScaler 设备的分类排查脚本:
iocitrix.py —— 一个用于对 Citrix NetScaler 镜像/目标进行排查的 Dissect 脚本。scan-citrix-netscaler-version.py —— 通过 HTTP(s) 扫描并识别 NetScaler 设备的版本。你可以使用此脚本通过 HTTP(s) 扫描并确定 Citrix NetScaler 设备的版本。 它还会根据版本判断该 NetScaler 是否易受特定 CVE 影响。
scan-citrix-netscaler-version.py如果你使用 pip,请按以下步骤操作:
如果使用 uv,你可以直接运行该脚本:
用法示例:
$ python3 scan-citrix-netscaler-version.py 192.168.1.10 192.168.1.12
192.168.1.10 (*.local.domain) is running Citrix NetScaler version 13.1-51.15 (VULNERABLE)
192.168.1.12 (*.local.domain) is running Citrix NetScaler version 12.1-55.330 (NOT VULNERABLE)
或者以 JSON 格式获取结果:
$ python3 scan-citrix-netscaler-version.py https://192.168.1.11 --json | jq
{
"scanned_at": "2025-09-03T23:11:36.864228+00:00",
"target": "https://192.168.1.11",
"tls_names": "my-first-netscaler.local",
"rdx_en_stamp": 1702886392,
"rdx_en_dt": "2023-12-18T07:59:52+00:00",
"version": "12.1-55.302",
"error": null,
"vulnerable": {
"CVE-2025-5349": true,
"CVE-2025-5777": true,
"CVE-2025-6543": false,
"CVE-2025-7775": true,
"CVE-2025-7776": true,
"CVE-2025-8424": true
},
"is_vulnerable": true
}
也可以使用 --cve 标志将漏洞状态检查限制为特定的 CVE:
$ python3 scan-citrix-netscaler-version.py https://192.168.1.11 --cve CVE-2025-6543 --json | jq
{
"scanned_at": "2025-09-03T23:16:36.573016+00:00",
"target": "https://192.168.1.11",
"tls_names": "my-first-netscaler.local",
"rdx_en_stamp": 1702886392,
"rdx_en_dt": "2023-12-18T07:59:52+00:00",
"version": "12.1-55.302",
"error": null,
"vulnerable": {
"CVE-2025-6543": false
},
"is_vulnerable": false
}
若要以 CSV 格式获取结果,只需使用 --csv 标志。
更多选项请参见 --help。
你可以使用 iocitrix.py 在 NetScaler Dissect 目标上检查已知的入侵指标(Indicators of Compromise)。它会检查以下内容:
请注意,此脚本旨在对 Citrix NetScaler 设备的取证磁盘镜像运行,而不是在设备本身上运行。 另请参阅创建 Citrix NetScaler 磁盘镜像一节,了解如何创建 Citrix NetScaler 的取证磁盘镜像。
请确保你使用的是最新版本的 Dissect,对 Citrix NetScaler 的支持是在此 PR 中添加的:https://github.com/fox-it/dissect.target/pull/357
免责声明:尽管此工具力求准确,但仍可能产生误报或漏报。建议用户交叉核对结果,并在根据此工具的输出做出任何决定之前自行判断。
iocitrix.py请按以下步骤操作:
请注意,第 4 步会打印以下错误,但你可以忽略它:
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
然后你可以运行 iocitrix.py <TARGETS> 对一个或多个取证镜像启动 IOC 检查。该脚本接受 dissect 能作为 Target 读取的任何输入,例如 .VMDK 或原始磁盘镜像。下面提供了一些示例。
python3 iocitrix.py image.vmx
python3 iocitrix.py image.vmdk
如果你还创建了 RAM 磁盘的取证镜像,你可以利用 iocitrix.py 将易失性数据纳入其排查中,如下所示:
python3 iocitrix.py md0.img+image.vmx
python3 iocitrix.py md0.img+image.vmdk
python3 iocitrix.py md0.img+da0.img
+(加号)会将两个磁盘镜像加载为单个 Dissect Target。
Citrix NetScaler 暴露了两个重要的块设备,可对其制作镜像以进行离线取证分析。这些块设备文件位于以下路径:
/dev/md0:保存根(/)目录的磁盘。这是一个 RAM 磁盘/dev/da0 或 /dev/ada0:保存 /var 和 /flash 目录的磁盘。这是一个持久性磁盘。Citrix NetScaler 的根目录(/)是一个 RAM 磁盘,这意味着它是一个易失性磁盘。当 NetScaler 开机并运行时,该磁盘位于 /dev/md0,当 NetScaler 关机时则不可用。/var 和 /flash 目录作为两个独立分区位于 /dev/da0 或 /dev/ada0 磁盘上,并且是持久性的。
以下命令可在本地 Linux 机器上通过 SSH 为你的 NetScaler 创建磁盘副本。如果你使用 Windows,可以使用 WSL(wsl.exe)或 Git Bash(git-bash.exe)来使用相同的命令。请避免使用原生 PowerShell 命令,因为 PowerShell 无法正确处理通过 SSH 流式传输的原始二进制数据。
这将显示可用的磁盘,包括你的持久性磁盘是 /dev/da0 还是 /dev/ada0。
然后检查确切大小:
local ~ $ ssh nsroot@<YOUR-NETSCALER-IP> shell diskinfo /dev/da0
local ~ $ ssh nsroot@<YOUR-NETSCALER-IP> shell diskinfo /dev/ada0
对于 RAM 磁盘:
local ~ $ ssh nsroot@<YOUR-NETSCALER-IP> shell diskinfo /dev/md0
生成的 da0.img 或 ada0.img 大小约为相应设备的大小,而 md0.img 约为 /dev/md0 的大小。
local ~ $ df -h .
确保有足够的可用空间来容纳磁盘镜像文件,其文件大小已在上一步中计算得出。
/dev/da0 或 /dev/ada0 磁盘的镜像创建到你的本地机器根据你的磁盘名称,执行以下命令之一
local ~ $ ssh nsroot@<YOUR-NETSCALER-IP> shell dd if=/dev/da0 bs=10M | tail -c +7 | head -c -6 > da0.img
或
local ~ $ ssh nsroot@<YOUR-NETSCALER-IP> shell dd if=/dev/ada0 bs=10M | tail -c +7 | head -c -6 > ada0.img
请注意,这可能需要一些时间才能完成。使用 dd 时不会显示进度。
建议等到你重新获得对提示符的控制权。这表明 dd 已完成。
tail 和 head 命令用于从字节流中剥离 NetScaler SSH 横幅。请注意,NetScaler SSH 横幅可能会随时间变化,在这种情况下,你应手动编辑该命令。
/dev/md0 磁盘的镜像创建到你的本地机器此步骤可以跳过,但这可能导致 iocitrix.py 遗漏某些入侵指标。因此,建议同时创建 /dev/md0 和 /dev/da0 或 /dev/ada0 的磁盘镜像。
local ~ $ ssh nsroot@<YOUR-NETSCALER-IP> shell dd if=/dev/md0 bs=10M | tail -c +7 | head -c -6 > md0.img
iocitrix.py在本地机器上执行前面的命令后,da0.img 或 ada0.img 以及 md0.img 文件将存在。你可以将 iocitrix 指向这些文件以开始排查你的镜像。使用以下命令执行此操作:
local ~ $ python3 iocitrix.py md0.img+da0.img
或
local ~ $ python3 iocitrix.py md0.img+ada0.img
示例输出:
(venv) user@dissect:/data/netscaler/image$ python3 iocitrix.py md0.img+da0.img
<Target md0.img+da0.img>
Disks
- <RawContainer size=555745286 vs=None>
- <RawContainer size=21474836486 vs=<DissectVolumeSystem serial=None>>
Volumes
- <Volume name=None size=555745286 fs=<FfsFilesystem>>
- <Volume name='part_00000000' size=1717567488 fs=<FfsFilesystem>>
- <Volume name='part_66600000' size=4401922048 fs=<FfsFilesystem>>
- <Volume name='part_16cc00000' size=2097152 fs=<FfsFilesystem>>
- <Volume name='part_16ce00000' size=15353200128 fs=<FfsFilesystem>>
Hostname : None
Domain : None
IPs : 10.164.0.39, 10.164.0.10
OS family : citrix-netscaler (CitrixBsdPlugin)
OS version : NetScaler 13.1 build 30 (ns-13.1-30.52)
Architecture : x86_64-citrix-netscaler
Language(s) :
Timezone : None
Install date : 2023-08-08 13:59:38.228043+00:00
Last activity : 2023-08-11 08:51:13.979536+00:00
*** Checking for webshells ***
<ioc/hit type='php-file-permission' alert='Suspicious php permission 0o644' confidence='high' path='/var/netscaler/logon/LogonPoint/uiareas/linux/adminupevents.php'>
<ioc/hit type='php-file-contents' alert="Suspicious PHP code 'b'array_filter(''" confidence='high' path='/var/netscaler/logon/LogonPoint/uiareas/linux/adminupevents.php'>
<ioc/hit type='php-file-permission' alert='Suspicious php permission 0o644' confidence='high' path='/var/vpn/config.php'>
<ioc/hit type='php-file-contents' alert="Suspicious PHP code 'b'array_filter(''" confidence='high' path='/var/vpn/config.php'>
<ioc/hit type='php-file-permission' alert='Suspicious php permission 0o644' confidence='high' path='/var/vpn/themes/config.php'>
*** Checking for timestomped files ***
*** Checking for suspicious cronjobs ***
*** Checking for SUID Binaries (this takes a while) ***
<ioc/hit type='binary/suid' alert='Binary with SUID bit set Observed' confidence='medium' path='/tmp/python/bash'>