漏洞扫描 -- 编写Nmap脚本

漏洞扫描 --
编写Nmap脚本

2006年12月份,Nmap4.21 ALPHA1版加入脚本引擎,并将其作为主线代码的一部分。NSE脚本库如今已经有400多个脚本,覆盖了各种不同的网络机制(从SMB漏洞检测到Stuxnet探测,及中间的一些内容)。NSE的强大,依赖它强大的功能库,这些库可以非常容易的与主流的网络服务和协议,进行交互。

挑战

我们经常会扫描网络环境中的主机是否存在某种新漏洞,而扫描器引擎中没有新漏洞的检测方法,这时候我们可能需要自己开发扫描工具。
你可能已经熟悉了某种脚本(例如:Python,Perl,etc.),并可以快速写出检测漏洞的程序。但是,如果面临许多主机时,
针对两三个主机的检测方法,可能并不奏效。
Nmap 解救你 !使用内嵌的Lua语言和强大的集合库,你可以结合nmap高效的主机和端口扫描引擎,开发出针对多数主机的检测方法。

实现

Nmap 引擎脚本,由Lua编程语言、NmapAPI、系列强大的NSE库实现。为了达到本文的目的,现假设某个应用中存在一个叫ArcticFission漏洞。与许多其他的web应用程序类似,可以通过探测特定的文件,假设这个文件就是/arcticfission.html,用正则表达式提取文件内容中的版本号,与有漏洞的值进行对比.
听起来好像很简单,让我们开始吧 !

框架代码

基于传统的语言标准,我们写一个脚本,作用:遇到开放的HTTP端口,就返回”Hello World”。

-- The Head Section --

-- The Rule Section --

portrule = function(host, port)

return port.protocol == "tcp" and port.number == 80 and port.state == "open"

end

-- The Action Section --

action = function(host, port)

return "Hello world !"

end

注意:以--起始的行表示注释。

NSE脚本主要由三部分组成:


The Head Section

该部分包含一些元数据,主要描述脚本的功能,作者,影响力,类别及其他。


The Rule Section

该部分定义脚本执行的必要条件。至少包含下面列表中的一个函数:

portrule

hostrule

prerule

postrule

此案例中,重点介绍portrule。portrule能够在执行操作前,检查host和port属性。portrule会利用nmap的API检查TCP80端口。


The Action Section

该部分定义脚本逻辑。此处案例中,检测到开放80端口,则打印“HelloWorld”。脚本的输出内容,会在nmap执行期间显示出来。


[email protected]:/home/offensive/nmap_nse# nmap -sS -p 22,80,443 --script /home/offensive/nmap_nse/http-vuln-check.nse www.exploit-db.com

Starting Nmap 6.47 ( http://nmap.org ) at 2014-09-29 10:39 EDT

Nmap scan report for www.exploit-db.com (192.99.12.218)

Host is up (0.47s latency).

Other addresses for www.exploit-db.com (not scanned): 198.58.102.135

rDNS record for 192.99.12.218: cloudproxy71.sucuri.net

PORT    STATE    SERVICE

22/tcp  filtered ssh

80/tcp  open     http

|_http-vuln-check: Hello world !

443/tcp open     https

调用脚本库

优秀的库集合,促使其变的强大。例如,可调用现有库中的函数,针对http端口创建portrule。此处用到了shortport.

local shortport = require "shortport"

-- The Rule Section --

portrule = shortport.http

-- The Action Section --

action = function(host, port)

return "Hello world!"

end


同样的扫描,产生了不同的结果

[email protected]:/home/offensive/nmap_nse# nmap -sS -p 22,80,443 --script /home/offensive/nmap_nse/http-vuln-check_shortport.nse www.exploit-db.com

Starting Nmap 6.47 ( http://nmap.org ) at 2014-09-29 10:36 EDT

Nmap scan report for www.exploit-db.com (192.99.12.218)

Host is up (0.46s latency).

Other addresses for www.exploit-db.com (not scanned): 198.58.102.135

rDNS record for 192.99.12.218: cloudproxy71.sucuri.net

PORT    STATE    SERVICE

22/tcp  filtered ssh

80/tcp  open     http

|_http-vuln-check_shortport: Hello world!

443/tcp open     https

|_http-vuln-check_shortport: Hello world!

Nmap done: 1 IP address (1 host up) scanned in 6.32 seconds


该脚本对443执行了类似80端口的操作。主要是因为shortport.http表示类似HTTP的端口(80,443,631,7080,8080,8088,5800,3872,8180,8000),也就是说,nmap会探测服务http、https、ipp、http-alt、vnc-http、oem-agent、soap、http-proxy非标准端口,如果想要获取更多的信息,请查阅shortport的文档.

服务探测


让我们把注意力放到action
部分的逻辑上。上述漏洞的检测,首先需要探测页面”/arcticfission.html”

local shortport = require "shortport"

local http = require "http"

-- The Rule Section --

portrule = shortport.http

-- The Action Section --

action = function(host, port)

local uri = "/arcticfission.html"

local response = http.get(host, port, uri)

return response.status

end


上述代码用到了库http处理web页面,

[email protected]:/home/offensive/nmap_nse# nmap -sS -p 22,80,443 --script /home/offensive/nmap_nse/http-vuln-check_shortport2.nse www.exploit-db.com

Starting Nmap 6.47 ( http://nmap.org ) at 2014-09-29 11:16 EDT

Nmap scan report for www.exploit-db.com (192.99.12.218)

Host is up (0.48s latency).

Other addresses for www.exploit-db.com (not scanned): 198.58.102.135

rDNS record for 192.99.12.218: cloudproxy71.sucuri.net

PORT    STATE    SERVICE

22/tcp  filtered ssh

80/tcp  open     http

|_http-vuln-check_shortport2: 403

443/tcp open     https

|_http-vuln-check_shortport2: 400


上述输出表明,两个服务器端口不存在对应页面”arcticfission.html”,注意‘http‘
库会自动在http与https端口切换,因此你不需要考虑去实现TLS/SSL。


如果只想输出存在该页面的web应用,可以如下操作:

local shortport = require "shortport"

local http = require "http"

-- The Rule Section --

portrule = shortport.http

-- The Action Section --

action = function(host, port)

local uri = "/arcticfission.html"

local response = http.get(host, port, uri)

if (response.status == 200) then

return response.body

end

end


上述代码,返回状态码为200的页面内容。


注意:如果没有数据返回或返回数据为空,将导致无输出显示.

漏洞探测


许多时候,可以通过一个简单的服务版本号,探测漏洞。这种情况,假象的服务器会返回一个包含版本号的标识。

local shortport = require "shortport"

local http = require "http"

local string = require "string"

-- The Rule Section --

portrule = shortport.http

-- The Action Section --

action = function(host, port)

local uri = "/arcticfission.html"

local response = http.get(host, port, uri)

if ( response.status == 200 ) then

local title = string.match(response.body, "<[Tt][Ii][Tt][Ll][Ee][^>]*>ArcticFission ([^<]*)</[Tt][Ii][Tt][Ll][Ee]>")

return title

end

end


上述代码,用到了
string库,以便获取页面头。

[email protected]:~/nmap_nse$ nmap -p 80,443 --script /home/offensive/nmap_nse/http-vuln-check_shortport4.nse 192.168.1.105

Starting Nmap 6.47 ( http://nmap.org ) at 2014-09-30 03:49 EDT

Nmap scan report for localhost (192.168.1.105)

Host is up (0.00053s latency).

PORT    STATE  SERVICE

80/tcp  open   http

|_http-vuln-check_shortport4: 1.0

443/tcp closed https

Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds


正如上面描述的那样,现在需要将获取的值与漏洞值比较, 确认是否存在漏洞。

local shortport = require "shortport"

local http = require "http"

local string = require "string"

-- The Rule Section --

portrule = shortport.http

-- The Action Section --

action = function(host, port)

local uri = "/arcticfission.html"

local response = http.get(host, port, uri)

if ( response.status == 200 ) then

local title = string.match(response.body, "<[Tt][Ii][Tt][Ll][Ee][^>]*>ArcticFission ([^<]*)</[Tt][Ii][Tt][Ll][Ee]>")

if ( title == "1.0" ) then

return "Vnlnerable"

else

return "Not Vulnerable"

end

end

end


测试结果如下:

[email protected]:~/nmap_nse$ nmap -p 80,443 --script /home/offensive/nmap_nse/http-vuln-check_shortport5.nse 192.168.1.105

Starting Nmap 6.47 ( http://nmap.org ) at 2014-09-30 04:05 EDT

Nmap scan report for localhost (192.168.1.105)

Host is up (0.00045s latency).

PORT    STATE  SERVICE

80/tcp  open   http

|_http-vuln-check_shortport5: Vnlnerable

443/tcp closed https


版本检测的另一种方法,生成Hash与有漏洞的页面对比。为了实现此效果,此处调用了openssl库。

local shortport = require "shortport"

local http = require "http"

local stdnse = require "stdnse"

local openssl = require "openssl"

-- The Rule Section --

portrule = shortport.http

-- The Action Section --

action = function(host, port)

local uri = "/arcticfission.html"

local response = http.get(host, port, uri)

if (response.status == 200) then

local vulnsha1 = "398ffad678f17a4f16ccd00b1914ca986d0b9258"

local sha1 = string.lower(stdnse.tohex(openssl.sha1(response.body)))

if ( sha1 == vulnsha1 ) then

return "Vulnerable"

else

return "Not Vulnerable"

end

end

end

添加隐藏属性


使用第三方的库时,测试脚本的执行流程很重要。

[email protected]:~/nmap_nse$ nmap -p 80,443 --script /home/offensive/nmap_nse/http-vuln-check_openssl.nse --script-trace 192.168.1.105

Starting Nmap 6.47 ( http://nmap.org ) at 2014-09-30 05:38 EDT

NSOCK INFO [0.0600s] nsi_new2(): nsi_new (IOD #1)

NSOCK INFO [0.0610s] nsock_connect_tcp(): TCP connection requested to 192.168.1.105:80 (IOD #1) EID 8

NSOCK INFO [0.0610s] nsock_trace_handler_callback(): Callback: CONNECT SUCCESS for EID 8 [192.168.1.105:80]

NSE: TCP 192.168.1.106:59791 > 192.168.1.105:80 | CONNECT

NSE: TCP 192.168.1.106:59791 > 192.168.1.105:80 | 00000000: 47 45 54 20 2f 61 72 63 74 69 63 66 69 73 73 69 GET /arcticfissi

00000010: 6f 6e 2e 68 74 6d 6c 20 48 54 54 50 2f 31 2e 31 on.html HTTP/1.1

00000020: 0d 0a 48 6f 73 74 3a 20 6c 6f 63 61 6c 68 6f 73   Host: localhos

00000030: 74 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 t  Connection: c

00000040: 6c 6f 73 65 0d 0a 55 73 65 72 2d 41 67 65 6e 74 lose  User-Agent

00000050: 3a 20 4d 6f 7a 69 6c 6c 61 2f 35 2e 30 20 28 63 : Mozilla/5.0 (c

00000060: 6f 6d 70 61 74 69 62 6c 65 3b 20 4e 6d 61 70 20 ompatible; Nmap

00000070: 53 63 72 69 70 74 69 6e 67 20 45 6e 67 69 6e 65 Scripting Engine

00000080: 3b 20 68 74 74 70 3a 2f 2f 6e 6d 61 70 2e 6f 72 ; http://nmap.or

00000090: 67 2f 62 6f 6f 6b 2f 6e 73 65 2e 68 74 6d 6c 29 g/book/nse.html)

000000a0: 0d 0a 0d 0a

NSOCK INFO [0.0620s] nsock_trace_handler_callback(): Callback: WRITE SUCCESS for EID 19 [192.168.1.105:80]

NSE: TCP 192.168.1.106:59791 > 192.168.1.105:80 | SEND

NSOCK INFO [0.0620s] nsock_read(): Read request from IOD #1 [192.168.1.105:80] (timeout: 8000ms) EID 26

NSOCK INFO [0.0640s] nsock_trace_handler_callback(): Callback: READ SUCCESS for EID 26 [192.168.1.105:80] (392 bytes)

NSE: TCP 192.168.1.106:59791 < 192.168.1.105:80 | 00000000: 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d HTTP/1.1 200 OK

00000010: 0a 44 61 74 65 3a 20 54 75 65 2c 20 33 30 20 53  Date: Tue, 30 S

00000020: 65 70 20 32 30 31 34 20 30 39 3a 33 38 3a 34 39 ep 2014 09:38:49

00000030: 20 47 4d 54 0d 0a 53 65 72 76 65 72 3a 20 41 70  GMT  Server: Ap

00000040: 61 63 68 65 2f 32 2e 32 2e 32 32 20 28 44 65 62 ache/2.2.22 (Deb

00000050: 69 61 6e 29 0d 0a 4c 61 73 74 2d 4d 6f 64 69 66 ian)  Last-Modif

00000060: 69 65 64 3a 20 54 75 65 2c 20 33 30 20 53 65 70 ied: Tue, 30 Sep

00000070: 20 32 30 31 34 20 30 37 3a 33 30 3a 33 33 20 47  2014 07:30:33 G

00000080: 4d 54 0d 0a 45 54 61 67 3a 20 22 65 31 31 38 31 MT  ETag: "e1181

00000090: 2d 37 34 2d 35 30 34 34 33 35 62 64 38 36 62 30 -74-504435bd86b0

000000a0: 32 22 0d 0a 41 63 63 65 70 74 2d 52 61 6e 67 65 2"  Accept-Range

000000b0: 73 3a 20 62 79 74 65 73 0d 0a 43 6f 6e 74 65 6e s: bytes  Conten

000000c0: 74 2d 4c 65 6e 67 74 68 3a 20 31 31 36 0d 0a 56 t-Length: 116  V

000000d0: 61 72 79 3a 20 41 63 63 65 70 74 2d 45 6e 63 6f ary: Accept-Enco

000000e0: 64 69 6e 67 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e ding  Connection

000000f0: 3a 20 63 6c 6f 73 65 0d 0a 43 6f 6e 74 65 6e 74 : close  Content

00000100: 2d 54 79 70 65 3a 20 74 65 78 74 2f 68 74 6d 6c -Type: text/html

00000110: 0d 0a 0d 0a 3c 68 74 6d 6c 3e 0a 3c 68 65 61 64     <html> <head

00000120: 3e 0a 3c 74 69 74 6c 65 3e 41 72 63 74 69 63 46 > <title>ArcticF

00000130: 69 73 73 69 6f 6e 20 31 2e 30 3c 2f 74 69 74 6c ission 1.0</titl

00000140: 65 3e 0a 3c 2f 68 65 61 64 3e 0a 3c 62 6f 64 79 e> </head> <body

00000150: 3e 0a 3c 68 31 3e 57 65 6c 63 6f 6d 65 20 74 6f > <h1>Welcome to

00000160: 20 41 72 63 74 69 63 46 69 73 73 69 6f 6e 20 31  ArcticFission 1

00000170: 2e 30 3c 2f 68 31 3e 0a 3c 2f 62 6f 64 79 3e 0a .0</h1> </body>

00000180: 3c 2f 68 74 6d 6c 3e 0a                         </html>

NSE: TCP 192.168.1.106:59791 > 192.168.1.105:80 | CLOSE

NSOCK INFO [0.0640s] nsi_delete(): nsi_delete (IOD #1)

Nmap scan report for localhost (192.168.1.105)

Host is up (0.00064s latency).

PORT    STATE  SERVICE

80/tcp  open   http

|_http-vuln-check_openssl: Vulnerable

443/tcp closed https

Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds


从上面的跟踪看,NSE的‘http‘库使用的默认User-Agent是“Mozilla/5.0(compatible;
Nmap Scripting Engine;http://nmap.org/book/nse.html)”. 可能由于某些安全原因,你需要更改user-agent,可使用下面方法.

[email protected]:~/nmap_nse$ nmap -p 80,443 --script /home/offensive/nmap_nse/http-vuln-check_openssl.nse --script-args="http.useragent=‘Mozilla/5.0 (compatible [[email protected]])‘" --script-trace 192.168.1.105

Starting Nmap 6.47 ( http://nmap.org ) at 2014-09-30 06:08 EDT

NSOCK INFO [0.2590s] nsi_new2(): nsi_new (IOD #1)

NSOCK INFO [0.2600s] nsock_connect_tcp(): TCP connection requested to 192.168.1.105:80 (IOD #1) EID 8

NSOCK INFO [0.2610s] nsock_trace_handler_callback(): Callback: CONNECT SUCCESS for EID 8 [192.168.1.105:80]

NSE: TCP 192.168.1.106:59923 > 192.168.1.105:80 | CONNECT

NSE: TCP 192.168.1.106:59923 > 192.168.1.105:80 | 00000000: 47 45 54 20 2f 61 72 63 74 69 63 66 69 73 73 69 GET /arcticfissi

00000010: 6f 6e 2e 68 74 6d 6c 20 48 54 54 50 2f 31 2e 31 on.html HTTP/1.1

00000020: 0d 0a 48 6f 73 74 3a 20 31 39 32 2e 31 36 38 2e   Host: 192.168.

00000030: 31 2e 31 30 35 0d 0a 55 73 65 72 2d 41 67 65 6e 1.105  User-Agen

00000040: 74 3a 20 4d 6f 7a 69 6c 6c 61 2f 35 2e 30 20 28 t: Mozilla/5.0 (

00000050: 63 6f 6d 70 61 74 69 62 6c 65 20 5b 6f 66 66 65 compatible [offe

00000060: 6e 73 69 76 65 40 73 65 63 75 72 69 74 79 5d 29 [email protected]])

00000070: 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 6c   Connection: cl

00000080: 6f 73 65 0d 0a 0d 0a                            ose

NSOCK INFO [0.2610s] nsock_trace_handler_callback(): Callback: WRITE SUCCESS for EID 19 [192.168.1.105:80]

NSE: TCP 192.168.1.106:59923 > 192.168.1.105:80 | SEND

NSOCK INFO [0.2610s] nsock_read(): Read request from IOD #1 [192.168.1.105:80] (timeout: 8000ms) EID 26

NSOCK INFO [0.2640s] nsock_trace_handler_callback(): Callback: READ SUCCESS for EID 26 [192.168.1.105:80] (392 bytes)

NSE: TCP 192.168.1.106:59923 < 192.168.1.105:80 | 00000000: 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 0d HTTP/1.1 200 OK

00000010: 0a 44 61 74 65 3a 20 54 75 65 2c 20 33 30 20 53  Date: Tue, 30 S

00000020: 65 70 20 32 30 31 34 20 31 30 3a 30 38 3a 32 34 ep 2014 10:08:24

00000030: 20 47 4d 54 0d 0a 53 65 72 76 65 72 3a 20 41 70  GMT  Server: Ap

00000040: 61 63 68 65 2f 32 2e 32 2e 32 32 20 28 44 65 62 ache/2.2.22 (Deb

00000050: 69 61 6e 29 0d 0a 4c 61 73 74 2d 4d 6f 64 69 66 ian)  Last-Modif

00000060: 69 65 64 3a 20 54 75 65 2c 20 33 30 20 53 65 70 ied: Tue, 30 Sep

00000070: 20 32 30 31 34 20 30 37 3a 33 30 3a 33 33 20 47  2014 07:30:33 G

00000080: 4d 54 0d 0a 45 54 61 67 3a 20 22 65 31 31 38 31 MT  ETag: "e1181

00000090: 2d 37 34 2d 35 30 34 34 33 35 62 64 38 36 62 30 -74-504435bd86b0

000000a0: 32 22 0d 0a 41 63 63 65 70 74 2d 52 61 6e 67 65 2"  Accept-Range

000000b0: 73 3a 20 62 79 74 65 73 0d 0a 43 6f 6e 74 65 6e s: bytes  Conten

000000c0: 74 2d 4c 65 6e 67 74 68 3a 20 31 31 36 0d 0a 56 t-Length: 116  V

000000d0: 61 72 79 3a 20 41 63 63 65 70 74 2d 45 6e 63 6f ary: Accept-Enco

000000e0: 64 69 6e 67 0d 0a 43 6f 6e 6e 65 63 74 69 6f 6e ding  Connection

000000f0: 3a 20 63 6c 6f 73 65 0d 0a 43 6f 6e 74 65 6e 74 : close  Content

00000100: 2d 54 79 70 65 3a 20 74 65 78 74 2f 68 74 6d 6c -Type: text/html

00000110: 0d 0a 0d 0a 3c 68 74 6d 6c 3e 0a 3c 68 65 61 64     <html> <head

00000120: 3e 0a 3c 74 69 74 6c 65 3e 41 72 63 74 69 63 46 > <title>ArcticF

00000130: 69 73 73 69 6f 6e 20 31 2e 30 3c 2f 74 69 74 6c ission 1.0</titl

00000140: 65 3e 0a 3c 2f 68 65 61 64 3e 0a 3c 62 6f 64 79 e> </head> <body

00000150: 3e 0a 3c 68 31 3e 57 65 6c 63 6f 6d 65 20 74 6f > <h1>Welcome to

00000160: 20 41 72 63 74 69 63 46 69 73 73 69 6f 6e 20 31  ArcticFission 1

00000170: 2e 30 3c 2f 68 31 3e 0a 3c 2f 62 6f 64 79 3e 0a .0</h1> </body>

00000180: 3c 2f 68 74 6d 6c 3e 0a                         </html>

NSE: TCP 192.168.1.106:59923 > 192.168.1.105:80 | CLOSE

NSOCK INFO [0.2660s] nsi_delete(): nsi_delete (IOD #1)

Nmap scan report for 192.168.1.105

Host is up (0.00053s latency).

PORT    STATE  SERVICE

80/tcp  open   http

|_http-vuln-check_openssl: Vulnerable

443/tcp closed https

Nmap done: 1 IP address (1 host up) scanned in 0.27 seconds

local shortport = require "shortport"

local http = require "http"

local stdnse = require "stdnse"

local string = require "string"

-- The Rule Section --

portrule = shortport.http

-- The Action Section --

action = function(host, port)

local uri = "/arcticfission.html"

local options = {headers={}}

options[‘headers‘][‘User-Agent‘] = "Mozilla/5.0 (compatible; ArcticFission)"

local response = http.get(host, port, uri, options)

if ( response.status == 200 ) then

local title = string.match(response.body, "<[Tt][Ii][Tt][Ll][Ee][^>]*>ArcticFission ([^<]*)</[Tt][Ii][Tt][Ll][Ee]>")

if ( title == "1.0" ) then

return "Vulnerable"

else

return "Not Vulnerable"

end

end

end

包装脚本


如果你想要发布脚本,有些重要的元数据需要提供,例如:描述、作者信息、证书,以便理解脚本的功能与影响力.

-- The Head Section --

description = [[Sample script to detect a fictional vulnerability in a fictional ArcticFission 1.0 web server]]

author = "iphelix"

license = "Same as Nmap -- See http://nmap.org/book/man-legal.html"

categories = {"default", "safe"}

local shortport = require "shortport"

local http = require "http"

local stdnse = require "stdnse"

local string = require "string"

-- The Rule Section --

portrule = shortport.http

-- The Action Section --

action = function(host, port)

local uri = "/arcticfission.html"

local options = {header={}}

options[‘header‘][‘User-Agent‘] = "Mozilla/5.0 (compatible; ArcticFission)"

local response = http.get(host, port, uri, options)

if ( response.status == 200) then

local title = string.match(response.body, "<[Tt][Ii][Tt][Ll][Ee]>ArcticFission ([^<]*)</[Tt][Ii][Tt][Ll][Ee]>")

if ( title == "1.0" ) then

return "Vulnerable"

else

return "Not Vulnerable"

end

end

end


你现在可能想写入一些NSE文档格式的说明。脚本文档可能包含一些可能会被文档系统处理的特殊标识。(例如@output表示脚本输出,@args表示脚本参数,@usage表示简单的命令行参数,等)

-- The Head Section --

description = [[Sample script to detect a fictional vulnerability in a fictional ArcticFission 1.0 web server]]

---

-- @usage

-- nmap --script http-vuln-check <target>

-- @output

-- PORT    STATE  SERVICE

-- 80/tcp  open   http

-- |_http-vuln-check_packaging: Vulnerable

author = "iphelix"

license = "Same as Nmap -- See http://nmap.org/book/man-legal.html"

categories = {"default", "safe"}

local shortport = require "shortport"

local http = require "http"

local stdnse = require "stdnse"

local string = require "string"

-- The Rule Section --

portrule = shortport.http

-- The Action Section --

action = function(host, port)

local uri = "/arcticfission.html"

local options = {header={}}

options[‘header‘][‘User-Agent‘] = "Mozilla/5.0 (compatible; ArcticFission)"

local response = http.get(host, port, uri, options)

if ( response.status == 200) then

local title = string.match(response.body, "<[Tt][Ii][Tt][Ll][Ee]>ArcticFission ([^<]*)</[Tt][Ii][Tt][Ll][Ee]>")

if ( title == "1.0" ) then

return "Vulnerable"

else

return "Not Vulnerable"

end

end

end

解析输出


使用自定义的脚本检测完成后,我们还需要解析产生的结果,以易理解的方式输出报告。不幸的是,‘gnamp‘输出格式不支持脚本输出,所以我们选择解析‘xml‘格式的输出。

#!/usr/bin/env python

# nmap-xml-parse by iphelix

import sys

from xml.dom.minidom import parse

def main():

if len(sys.argv) != 2:

print "Usage: %s nmap_output.xml" % sys.argv[0]

sys.exit(1)

nmap = parse(sys.argv[1])

for host in nmap.getElementsByTagName("host"):

addresses = [addr.getAttribute("addr")

for addr in host.getElementsByTagName("address")]

for port in host.getElementsByTagName("port"):

portid = port.getAttribute("portid")

for script in port.getElementsByTagName("script"):

if script.getAttribute("id") == "http-vuln-check_packaging":

output = script.getAttribute("output")

for address in addresses:

print "%s,%s,%s" % (address, portid, output)

if __name__ == "__main__":

main()

漏洞管理


上述漏洞发现脚本有些问题。首先,它没有漏洞相关的描述信息,其次,完成扫描后,你需要编写脚本解析整个扫描结果。上面的这些,可以用Nmap的库‘vulns‘进行处理。


NSE漏洞库


NSE漏洞库由DjalalHarouni和HenriDoreau开发,目的是标准化呈现与管理漏洞。

-- The Head Section --

description = [[Sample script to detect a fictional vulnerability in a fictional ArcticFission 1.0 web server]]

---

-- @usage

-- nmap --script http-vuln-check <target>

-- @output

-- PORT    STATE  SERVICE

-- 80/tcp  open   http

-- |_http-vuln-check_packaging: Vulnerable

-- |   VULNERABLE

-- |   ArcticFission 1.0 Vulnerability

-- |     State: VULNERABLE

-- |     IDs: CVE:CVE-XXXX-XX

-- |     References:

-- |_      http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-XXXX-XX

author = "iphelix"

license = "Same as Nmap -- See http://nmap.org/book/man-legal.html"

categories = {"default", "safe"}

local shortport = require "shortport"

local http = require "http"

local stdnse = require "stdnse"

local string = require "string"

local vulns = require "vulns"

-- The Rule Section --

portrule = shortport.http

-- The Action Section --

action = function(host, port)

-- The Vuln Definition Section --

local vuln = {

title = "ArcticFission 1.0 Vulnerability",

state = vulns.STATE.NOT_VULN,

IDS = { CVE = ‘CVE-XXXX-XXX‘ }

}

local report = vulns.Report:new(SCRIPT_NAME, host, port)

local uri = "/arcticfission.html"

local options = {header={}}

options[‘header‘][‘User-Agent‘] = "Mozilla/5.0 (compatible; ArcticFission)"

local response = http.get(host, port, uri, options)

if ( response.status == 200) then

local title = string.match(response.body, "<[Tt][Ii][Tt][Ll][Ee]>ArcticFission ([^<]*)</[Tt][Ii][Tt][Ll][Ee]>")

if ( title == "1.0" ) then

vuln.state = vulns.STATE.VULN

else

vuln.state = vulns.STATE.NOT_VULN

end

end

return report:make_output(vuln)

end


扫描结果如下:

[email protected]:~/nmap_nse$ nmap -p 80,443 --script /home/offensive/nmap_nse/http-vuln-check_packaging.nse  192.168.1.105

Starting Nmap 6.47 ( http://nmap.org ) at 2014-09-30 10:22 EDT

Nmap scan report for localhost (192.168.1.105)

Host is up (0.00053s latency).

PORT    STATE  SERVICE

80/tcp  open   http

| http-vuln-check_packaging:

|   VULNERABLE:

|   ArcticFission 1.0 Vulnerability

|     State: VULNERABLE

|     IDs:  CVE:CVE-XXXX-XXX

|     References:

|_      http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-XXXX-XXX

443/tcp closed https

Nmap done: 1 IP address (1 host up) scanned in 0.07 seconds

从这里获取了什么


我希望你能够对上面我提到的Nmap脚本感到兴奋。最好的办法就是学习库相关的文档,并编写一些复杂的脚本,不局限于http。Nmap是一款强大的工具,强大的脚本库及开源的社区支持,会促使其变成一款强大的漏洞扫描器。感谢,Fyodor和所有的Nmap开发者。

参考链接


NmapNetwork Scanning

Lua

NmapAPI

NSELibraries

pwnmaps

NSEVulnerability Library

ListTCP and UDP port

[原始链接]writingnse
scripts for vulnerability scanning

时间: 2024-10-20 04:21:12

漏洞扫描 -- 编写Nmap脚本的相关文章

Nmap漏洞扫描

Nmap网络安全审计(七) 漏洞审计 Nmap中的漏洞扫描功能 做过安服的可能知道经常用的一些漏扫工具,像Nessus.Open Vas等.在NSE的加持下,Nmap也可以成为一款漏扫工具,这些漏扫的脚本在vuln分类下. NSE漏洞扫描的优势: 可以使用Nmap API来完成对扫描过程中收集信息的处理 NSE脚本可以在执行过程中和其他脚本共享获得的信息 NSE中提供了大量网络协议库的组件 NSE中提供了漏洞库文件,利用漏洞库文件可以创建一份优秀的漏洞报告 NSE中提供了强大的并发机制和错误处理

Nessus漏洞扫描教程之使用Nmap工具扫描识别指纹

Nessus漏洞扫描教程之使用Nmap工具扫描识别指纹 Nmap工具的准备工作 当用户对Nessus工具有清晰的认识后,即可使用该工具实施扫描.但是,在扫描之前需要做一些准备工作,如探测网络中活动的主机.主机中运行的服务及主机的操作系统等.当用户对一个主机比较熟悉后,进行扫描也就非常容易了.因为对于Nessus工具,针对不同的系统.漏洞都提供了相应的插件.如果用户对目标主机很了解的话,使用Nessus工具扫描目标就不会像个无头苍蝇似的瞎扫描.而且,可以更容易获取到非常有价值的信息了.本章将介绍实

Nmap脚本引擎原理

Nmap脚本引擎原理 一.NSE介绍 虽然Nmap内嵌的服务于版本探测已足够强大,但是在某些情况下我们需要多伦次的交互才能够探测到服务器的信息,这时候就需要自己编写NSE插件实现这个功能.NSE插件能够完成网络发现.复杂版本探测.脆弱性探测.简单漏洞利用等功能. 转载请注明出处:http://www.cnblogs.com/liun1994/ 在文章   "Nmap脚本文件分析(AMQP协议为例)"   中会将版本探测,NSE脚本原理联系起来,具体分析Nmap探测的执行过程. 在文章 

Kali Linux渗透基础知识整理(二)漏洞扫描

Kali Linux渗透基础知识整理系列文章回顾 漏洞扫描 网络流量 Nmap Hping3 Nessus whatweb DirBuster joomscan WPScan 网络流量 网络流量就是网络上传输的数据量. TCP协议 TCP是因特网中的传输层协议,使用三次握手协议建立连接.当主动方发出SYN连接请求后,等待对方回答SYN+ACK ,并最终对对方的 SYN 执行 ACK 确认.这种建立连接的方法可以防止产生错误的连接,TCP使用的流量控制协议是可变大小的滑动窗口协议. 连接建立 TC

Nmap脚本引擎NSE

Nmap网络安全审计(六) Nmap脚本引擎NSE NSE中的脚本采用Lua语言编写.NSE设计出来是为了提供Nmap的灵活性,式版的NSE包含14个大类的脚本,总数达500多个,这些脚本的功能包括对各种网络口令强度的审计,对各种服务器安全性配置的审计,对各种服务器漏洞的审计等. NSE脚本的运行 我们使用NSE脚本测试一台主机,我们来看一下这条指令使用的参数,-O进行操作系统检测,-sV对目标系统的服务进行检测,这里我们没有使用脚本的参数所有使用的是默认脚本,默认脚本会使用-sC参数.默认脚本

nmap脚本使用总结

0x00 前言: nmap的基本介绍和基本使用方法,在乌云知识库中已经有人提交过,讲的比较详细,在此文中就不再讲述. 具体链接:http://drops.wooyun.org/tips/2002 本文主要讲解nmap的众多脚本的使用,在内网渗透的时候尤其好用. 0x01 nmap按脚本分类扫描 nmap脚本主要分为以下几类,在扫描时可根据需要设置--script=类别这种方式进行比较笼统的扫描: auth: 负责处理鉴权证书(绕开鉴权)的脚本   broadcast: 在局域网内探查更多服务开启

LVS集群的基本原理、LVS/NAT模式的配置、LVS/DR模式的配置、编写自动脚本检查LVS上realserver健康性

Linux 虚拟服务器(LVS)由章文嵩在国防科技大学就读博士期间创建利用LVS可以实现高可用的.可伸缩的Web.Mail.Cache和Media等网络服务,已经被集成到linux内核里了. 1.什么是集群? 使用一组服务器提供相同的服务2.使用集群的目的? 增强可靠性   降低成本   提高可扩展性   提高性能3.集群分类? HPC 高性能计算集群    (气象   航天   航空)    LB    负载均衡集群 (平均地分摊处理)    * LVS    hproxy HA    高可用

网络扫描利器-----NMAP

一.主机发现  -A: 全面扫描,扫描指定的IP或域名的所有端口 -sP: ping扫描 -PN: 无ping扫描,不使用默认的探测检查,而是对目录进行一个完整的端口扫描.此对扫描有防火墙 保护而封锁ping探针主机的时间非常有用: -PS:TCP SYN ping 扫描,该选项发送一个设置了SYN标志位的空TCP报文. 默认目的端口为80 (可以通过改变nmap.h) 文件中的DEFAULT_TCP_PROBE_PORT值进行配置,但不同的端口也可以作为选项指定. -PA:TCP ACK pi

Nmap脚本使用总结(转乌云) 下

nmap脚本使用总结 clzzy · 2014/06/08 11:24 <:SECTION class="entry-content ng-binding" ng-bind-html="postContentTrustedHtml"> 0x00 前言: nmap的基本介绍和基本使用方法,在乌云知识库中已经有人提交过,讲的比较详细,在此文中就不再讲述. 具体链接:http://drops.wooyun.org/tips/2002 本文主要讲解nmap的众多