第一次在 Kali 里跑 nuclei,我盯着屏幕看了二十秒,一行结果都没有。
命令是这条:
nuclei -u http://192.168.207.130
目标明明是通的,ping 也回了包,扫完却干干净净。我当时的第一反应是靶机太新、没漏洞,差点就去翻别的教程了。后来才发现是模板库空的,nuclei 手里一条规则都没有,自然不会报任何东西。
装完 nuclei 之后要先跑一次 nuclei -update-templates。这一步不做,它就是个空壳。
一、它和传统扫描器的区别
nuclei 是 ProjectDiscovery 做的模板化扫描器。它自己不带多少检测逻辑,真正干活的是模板,一个模板一个 YAML 文件,里面写清楚两件事:往目标发什么请求,看到什么回应算命中。
模板由社区维护,官方仓库 nuclei-templates 现在是上万条的规模。我本机 v3.8.0 上跑 nuclei -tl,列出来 13687 条,CVE、默认口令、暴露的配置文件、错误配置都在里面。
所以它的强弱很直白。某个漏洞已经有人写好模板,你就能扫;没人写,它就看不见。你拿它当"自动化的初步侦察"很合适,拿它当"什么都能查出来"会失望。
用之前先说一句:这东西只在自己搭的靶机、公司给了书面授权的主机上跑。它本身不算攻击工具,但往别人的服务器上打,性质就变了。练手用 Metasploitable 2、DVWA、VulnHub 的镜像,或者 TryHackMe 这类授权靶场。
二、装
Kali 上最省事:
sudo apt update && sudo apt install -y nuclei
源里的包就叫 nuclei,装完直接用,版本可能比官方 release 旧一点,我本机是 v3.8.0。
不是 Kali 的话用 Go:
go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest
前提是有 Go 1.21 以上,装完二进制在 ~/go/bin/,记得加进 PATH。
想要最新版就去 GitHub 的 Releases 页下 Linux AMD64 的 zip:
unzip nuclei_3.8.0_linux_amd64.zip
sudo mv nuclei /usr/local/bin/
文件名里的版本号得按你实际看到的改。这篇写的 3.8.0,过一阵可能就变了。
装完先确认:
nuclei –version
三、模板库,第一次必须更新
nuclei -update-templates
模板默认落在 ~/.local/nuclei-templates/,配置文件在 ~/.config/nuclei/。v3.8.0 上就是这个路径,早期版本有过别的目录,找不到就 find 一下。
更新完再验一次:
nuclei -tl
能列出一堆模板名,说明就绪了。这一步没做,就是你扫完什么也看不到的原因,我上面就栽在这儿。
模板是活的,隔段时间重跑一次这条命令。跑完想知道这次新增了什么,用 -nt 只跑新模板:
nuclei -nt -u http://192.168.207.130
刚披露的漏洞想第一时间验证,这是最快的路子。
四、目标怎么写,覆盖面差很多
同一个靶机,-u 后面写不写协议,效果不一样。
写 IP 不带协议:
nuclei -u 192.168.207.130
所有协议类型的模板都会往上打,HTTP、TCP、UDP 都试,覆盖面最全。
写成 http://192.168.207.130:
nuclei -u http://192.168.207.130
HTTP 类的模板拿这个 URL 当基准,但那些自带固定端口的 TCP 模板,比如 21 端口的 FTP、5432 端口的 PostgreSQL,照样会主动去连。所以带协议也不是只管 80。这篇下面的实战就是这种写法,FTP 和 PG 的问题照样扫出来了。
新手先写全 URL,等熟了再决定要不要放开。
五、扫一台靶机
先确认通不通:
ping -c 2 192.168.207.130
回了包再往下走。不通的话,后面的扫描全是白等。
然后是这条:
nuclei -u http://192.168.207.130 -rl 150 -c 15 -timeout 5 -o ~/nuclei_result.txt
四个参数各管一件事。-rl 150 限制每秒最多 150 个请求,-c 15 是同时跑 15 个模板,-timeout 5 是单请求 5 秒超时,-o 把结果落盘。
限速这个参数别省。模板库里有大量弱口令模板,它们本身就带爆破行为,对着老靶机不限速很可能直接把它打停,后面就什么都扫不出来了。
靶机是 Metasploitable 2 那种 2010 年前后的系统,这一发两分钟跑完,最后打印:
INF Scan completed in 2m. 71 matches found.
六、输出怎么读
结果文件一行一条,格式固定成这样:
[模板名] [协议] [严重程度] 目标 [附带数据]
实战里的几行原文,加上我的理解:
| [CVE-2012-1823] [http] [high] http://192.168.207.130/index.php?… | PHP-CGI 远程代码执行,高危,模板里带能直接打的 payload |
| [CVE-2011-2523] [tcp] [high] 192.168.207.130:21 | vsftpd 2.3.4 后门,就是那个 6200 端口的后门 |
| [vnc-default-login] [javascript] [high] 192.168.207.130:5900 [passwords="password"] | VNC 用了默认密码 password |
| [pgsql-empty-password] [javascript] [critical] 192.168.207.130:5432 | PostgreSQL 空密码能连,Critical |
| [ftp-weak-credentials] [tcp] [high] 192.168.207.130:21 [password="toor",username="ftp"] | FTP 弱口令,账号密码一并打出来了 |
| [http-trace:trace-request] [http] [low] http://192.168.207.130 | TRACE 方法开着,低危泄露 |
| [http-missing-security-headers:x-frame-options] [http] [info] | 响应缺安全头,Info,属于加固建议 |
中间那条 [javascript] 值得说一句。它不是说目标上跑了 JavaScript,指的是这条模板用 JS 协议写的,能连原始 socket 自己做交互,所以才能去试 VNC 密码、去连空密码的 PG。协议那列看着像目标属性,其实是模板属性。
判读上我自己的顺序是这样。
先按严重程度过滤,critical 和 high 排前面看。info 和 low 大多是加固建议,攒着最后统一改,别一上来就陷进去。
再看模板名。CVE-xxxx-xxxx 直接去搜编号,xxx-default-login 是默认口令,xxx-empty-password 是空密码,xxx-eol 说的是软件过期了,xxx-detect 只是识别出你用了什么,没证明有洞。这几个前缀认熟,一眼就能分类。
想只看高危,扫完再筛一遍就行:
grep -E '\\[(high|critical)\\]' ~/nuclei_result.txt
有一件事得记住:没报出来不等于没有。模板没覆盖到、端口不通、请求超时,这些情况在结果里都表现为"一片安静",和"确实没问题"看起来一模一样。写报告的时候,这两种要分开写。
七、几条常用的组合
# 只扫高危和严重,限速,不带进度日志
nuclei -u http://192.168.207.130 -s high,critical -rl 100 -silent
# 只扫 FTP 相关模板
nuclei -u 192.168.207.130 -tags ftp
# 只跑 HTTP 类模板,跳过 tcp 的口令爆破,快也安全
nuclei -u http://192.168.207.130 -pt http
-pt http 这条我挺常用。口令爆破类的模板慢,还容易把目标搞出状况,先只看 HTTP 面的问题,心里有个数,再决定要不要往深里打。
目标多的时候写进文件,一行一个:
nuclei -l targets.txt -rl 200 -o all_results.txt
要拿结果去做二次处理,输出成 JSONL:
nuclei -u http://192.168.207.130 -j -o result.jsonl
JSON 里带原始请求和响应,写报告要溯源的时候能直接贴。
八、参数按用途记
参数表不建议硬背,按"我在解决哪个问题"分组,记起来顺得多。
目标相关的就三个:
| -u | 单个目标 |
| -l | 目标清单文件 |
| -nt | 只跑最近一次更新新增的模板 |
挑模板的:
| -t | 指定模板文件或目录,比如 -t http/cves/ |
| -tags | 按标签筛,-tags cve,ftp |
| -s | 按严重程度筛,-s critical,high |
| -pt | 按协议筛,-pt http |
| -etags | 排除标签,-etags dos |
| -tl | 只列模板,不扫 |
控速和输出的:
| -c | 并发跑多少个模板,默认 25 |
| -rl | 每秒请求上限 |
| -timeout | 单请求超时秒数 |
| -o | 结果写文件 |
| -silent | 只输出命中,去掉进度日志 |
| -nc | 关掉彩色,重定向到文件时用 |
| -j | 输出 JSONL |
-c 和 -rl 容易搞混。-c 是同时开几个模板,-rl 是每秒总共发多少请求。前者调大更吃本机,后者调大更吃目标。打老靶机的时候,卡住的是 -rl。
九、新手常遇到的情况
扫完什么都没输出。先跑 -update-templates,再 -tl 看能不能列出模板。这一步九成的问题都能解决。
控制台一直刷 Skipped xxx as found unresponsive。意思是那个端口探测过去没反应,nuclei 跳过了。这不算故障,端口本来就没开,或者被防火墙挡了。
-u 带协议还是不带,前面说过,会影响到哪些模板能跑,选之前想清楚要覆盖多大范围。
结果太多不知道从哪看起。先 grep critical,再 high,info 全部当加固建议收着。
有人问过它能不能代替 nmap。不能。nmap 先把有哪些门开着摸清楚,nuclei 是拿着规则挨个去敲。顺序上一般先 nmap 再看 nuclei,反过来也能跑,只是白花时间在没开的端口上。
十、靶机从哪来
上面扫的那台是 Metasploitable 2,Rapid7 官方做的"故意装满漏洞"的 Ubuntu 虚机,本来就是为了给人练手。
压缩包大概 865 MB,解压出来是 .vmdk 虚拟磁盘,不是 ISO,直接导进 VMware 或者 VirtualBox 就能开机。
下载有三个地方:
| SourceForge 官方发布页 | https://sourceforge.net/projects/metasploitable/files/Metasploitable2/ |
| Rapid7 官方入口 | https://information.rapid7.com/metasploitable-download.html |
| VulnHub 备用镜像 | https://download.vulnhub.com/metasploitable/metasploitable-linux-2.0.0.zip |
SourceForge 那个文件叫 metasploitable-linux-2.0.0.zip,是 Rapid7 官方账号维护的。VulnHub 的镜像在 SourceForge 慢的时候可以换。
默认账号密码 msfadmin:msfadmin。这个账号本身就是个漏洞,官方 README 里就这么写的。
它的网络设置成 NAT 或 Host-only。这东西出厂不带任何防护,挂到公网或者宿舍的共享网络里,等于把一台任人进出的机器放在那儿。做实验之前先拍个快照,玩坏了还原。
上面扫出来的 PG 空密码、VNC 弱口令、vsftpd 后门,都是它自带的,不是你操作失误。
最后
我现在的流程大概是:装好,-update-templates,ping 一下,然后 nuclei -u <目标> -rl 100 -c 15 -o 结果文件,跑完 grep 一遍 high 和 critical,剩下的按前缀分类。
一条命令摸清一台靶机的 21、5432、80 三个端口有后门、空密码和 RCE,这是 nuclei 用模板换来的速度。代价也在这套模板上:规则里没写的,它不会替你想。
扫描结果始终带"可能"两个字。没报出东西可能是真干净,也可能是模板没覆盖到。读的时候把这一层一起读进去,比记住所有参数有用。


