Nmap最强大,最灵活的功能之一NSE脚本引擎
它允许用户自己编写脚本来执行自动化的操作或者扩展Nmap的功能,使用lua语言
基本使用
NSE默认就提供了丰富的脚本库,可以为我们提供诸多Nmap的扩展使用,它的设计初衷主要考虑了一下几个方面:
网络发现
版本侦察
漏洞侦察
后门侦察
漏洞利用
nmap脚本主要分为以下几类,在扫描时可根据需要设置--script=类别这种方式及进行比较笼统的扫描
auth: 负责处理鉴权证书(绕开鉴权)的脚本
broadcast: 在局域网内探查更多服务开启状况,如dhcp/dns/sqlserver等服务
brute: 提供暴力破解方式,针对常见的应用如http/snmp等
default: 使用-sC或-A选项扫描时候默认的脚本,提供基本脚本扫描能力
discovery: 对网络进行更多的信息,如SMB枚举、SNMP查询等
dos: 用于进行拒绝服务攻击
exploit: 利用已知的漏洞入侵系统
external: 利用第三方的数据库或资源,例如进行whois解析
fuzzer: 模糊测试的脚本,发送异常的包到目标机,探测出潜在漏洞 intrusive: 入侵性的脚本,此类脚本可能引发对方的IDS/IPS的记录或屏蔽
malware: 探测目标机是否感染了病毒、开启了后门等信息
safe: 此类与intrusive相反,属于安全性脚本
version: 负责增强服务与版本扫描(Version Detection)功能的脚本
vuln: 负责检查目标机是否有常见的漏洞(Vulnerability),如是否有MS08_067
基本命令行使用
default类别为使用默认脚本扫描,我们可以使用命令行--script=default或者使用-sC来应用默认扫描脚本,像下面这样:
nmap -Pn -sC 47.106.80.112
因为NSE脚本是平行执行的,所以我们还可以多参数同时进行扫描,使用英文状态下的逗号,进行分割
nmap -Pn --script=default,fuzzer,vuln 47.106.80.112
也可以直接是lua脚本的文件名或者表达式之类的值,一样的都用逗号进行分割
多参数同时进行扫描时,基于表达式>分类>文件名/文件夹名这样的优先级排序,进行脚本扫描
NSE表达式
NSE的表达式要由双引号包裹,为了避免与shell冲突
比如说这样四条命令:
nmap --script "http-*" #可以与开头为 http- 的脚本匹配,例如 http-auth / http-open-proxy
nmap --script "not brute" # 可以与不是 brute 分类下的脚本进行匹配
nmap --script "safe or default" # 等价于 nmap --script safe,default
nmap --script "(default or safe or intrusive) and not http-*" # 与 default/safe/intrusive 匹配但是不匹配任何 http- 开头的脚本
可以看到,NSE脚本中的表达式也可以使用逻辑运算符号(not/or/and)和小括号,通过小括号来改变优先级
* 可以作为通配符来使用,比如说not http-* 不匹配任何http-开头的脚本
脚本参数使用
还可以通过--script-args将参数传递给NSE脚本。参数的结构为:name=value,以,分割多个参数对。name和value中都不应该包含以下符号:{ } , =
举一个参数使用的例子:
nmap -sC --script-args'user = foo,pass =“,{} = bar”,paths = {/ admin,/ cgi-bin},xmpp-info.server_name = localhost'
脚本参数用单引号包裹起来,上述命令将会生成以下Lua表
nmap.registry.args = {
user=“ foo”,
pass=“,{} = bar”,
paths= {
“ / admin”,
“ / cgi-bin”
},
xmpp-info.server_name =“ localhost”
}
一些完整的使用实例像以下这样:
nmap -sC example.com #使用默认脚本集进行简单的脚本扫描
nmap -sn -sC example.com #没有端口扫描的脚本扫描;只有主机脚本才运行扫描
nmap -Pn -sn -sC example.com #默认所有主机都存活,并且只有主机脚本才运行扫描
nmap --script smb-os-discovery --script-trace example.com #通过脚本跟踪执行特定的脚本
nmap --script snmp-sysdescr --script-args creds.snmp = admin example.com #运行带有脚本参数的单个脚本
更多关于脚本的用法实例,大家可以深入研究以下官方文档
脚本用法与示例:https://nmap.org/book/nse-usage.html#nse-args
常见服务
我们以FTP服务以实例展开讲讲,第一个脚本ftp-anon:FTP 匿名登录
该脚本有一个可设置的参数,为maxlist。用于列出扫到开放ftp端口时最多列出的文件列表的数量。
maxlist默认值为20,如果更改为负数则可以取消参数限制;改为0的话则为不列出文件
使用范例演示,此处我以一台专门开放了ftp服务的主机作为了演示,大家可以在本地设置开放端口进行练习
nmap -sV --script ftp-anon --script-args ftp-anon.maxlist=20 example.com
可以看到当扫到目标开放ftp开放端口时,输出样例如下:
ftp-anon: Anonymous FTP login allowed (FTP code 230)
drwx------ 1 user group 0 Dec 03 09:26 .vscode
drwx------ 1 user group 0 Dec 03 09:26 client_body_temp
drwx------ 1 user group 0 Dec 03 09:11 conf
drwx------ 1 user group 0 Dec 03 09:26 fastcgi_temp
drwx------ 1 user group 0 Dec 03 09:26 logs
drwx------ 1 user group 0 Dec 24 14:40 lua
drwx------ 1 user group 0 Dec 03 09:26 proxy_temp
drwx------ 1 user group 0 Dec 03 09:26 scgi_temp
drwx------ 1 user group 0 Dec 03 09:26 uwsgi_temp
当成功扫到目标服务后,就会输出可以访问的文件列表。相当于你就已经扫到了敏感信息啦~
再来看看第二个,ftp-bounce:ftp跳转攻击。这个脚本可以检查http服务器是否允许FTP跳转攻击
同样的,该脚本也有几个需要设置的参数:
ftp-bounce.password ftp服务器登录密码,默认为IEUser@
ftp-bounce.username ftp服务器登录用户名,默认为anonymous
ftp-bounce.checkhost PORT命令连接的主机,默认为scanme.nmap.org
nmap -sV --script ftp-bounce --script-args ftp-bounce.password=IEUser@,ftp.username=anonymous example.com
当输出以下内容时代表获得反馈:
成功:
ORT STATE SERVICE
21/tcp open ftp
|_ftp-bounce: bounce working!
失败:
PORT STATE SERVICE
21/tcp open ftp
|_ftp-bounce: server forbids bouncing to low ports <1025
失败:
PORT STATE SERVICE
21/tcp open ftp
|_ftp-bounce: no banner
来学习第三个脚本 ftp-brute:爆破ftp服务器认证。可用于爆破服务器认证信息
脚本参数有以下几个:
ftp-brute.timeout 每一socket连接的最长等待时间,默认为5秒
passdb 密码字典,默认为nselib/data/passwords.lst
userdb 用户名字典,默认为nselib/data/usernames.lst
unpwdb.passlimit / unpwdb.userlimit 用户/密码最大尝试数(默认都为无限制)
不常用参数 :creds 与 brute 两个库(暂略)
使用范例:
nmap --script ftp-brute -p 21 example.com --script-args passdb=密码文档.txt
输出内容为:PORT STATE SERVICE
21/tcp open ftp
| ftp-brute:
| Accounts
| root:root - Valid credentials
| Statistics
| Performed 510 guesses in 610 seconds, average tps: 0
第四个脚本:ftp-libopie:CVE-2010-1938 扫描 检查FTP是否存在CVE-2010-1938。有两个模块:vuln和instrusive
该脚本有可选参数:vulns.short和vulns.showall两个,对应vulns模块,这两个参数都是非必选项,默认即可
使用范例:
nmap -sV -Pn --script ftp-libopie example.com
一般扫描成功后,将会输出类似于以下的内容:
PORT STATE SERVICE
21/tcp open ftp
| ftp-libopie:
| VULNERABLE:
| OPIE off-by-one stack overflow
| State: LIKELY VULNERABLE
| IDs: CVE:CVE-2010-1938 OSVDB:64949
| Risk factor: High CVSSv2: 9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)
| Description:
| An off-by-one error in OPIE library 2.4.1-test1 and earlier, allows remote
| attackers to cause a denial of service or possibly execute arbitrary code
| via a long username.
| Disclosure date: 2010-05-27
| References:
| http://osvdb.org/64949
| http://site.pi3.com.pl/adv/libopie-adv.txt
| http://security.freebsd.org/advisories/FreeBSD-SA-10:05.opie.asc
|_ http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-1938
第五个脚本:ftp-proftpd-backdoor:OSVDB-ID 69562,主要用于检查ProFTPD 1.3.3c中的后门漏洞
参数有:ftp-proftpd-backdoor.cmd,如果扫描成功,就执行命令语句,默认为 id
使用范例:
nmap --script ftp-proftpd-backdoor -p 21 example.com
输出内容参考一下:
PORT STATE SERVICE
21/tcp open ftp
| ftp-proftpd-backdoor:
| This installation has been backdoored.
| Command: id
| Results: uid=0(root) gid=0(wheel) groups=0(wheel)
|_
前面为大家展示了一些常见脚本的具体使用方法,还有很多针对不同服务的扫描脚本,大家可以根据自己的需要进行选择:
HTTP相关常见脚本
备份文件:http-backup-finder
WAF类扫描:
http-waf-fingerprint
http-waf-detect
Wordpress 相关:
http-wordpress-enum
http-wordpress-users
http-wordpress-brute
CVE漏洞扫描(通配表达式):
nmap --script "http-vuln-cve*" 127.0.0.1
代理扫描:
http-open-proxy 扫描开放 HTTP 代理
http-proxy-brute
socks-open-proxy 扫描开放 socks 开放代理
socks-brute
socks-auth-info
其他参见官方文档
常见漏洞类扫描:
ftp-heartbleed:SSL 心脏出血漏洞检测
smb-vuln-*:SMB 服务相关漏洞
dns-zone-transfer:检查 DNS 域传送漏洞
banner:banner 收集