漏洞扫描 --编写Nmap脚本

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

挑战

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

实现

Nmap 引擎脚本,由Lua编程语言、NmapAPI、系列强大的NSE库实现。为了达到本文的目的,现如果某个应用中存在一个叫ArcticFission漏洞。

与更多的web应用程序类似。能够通过探測特定的文件。如果这个文件就是/arcticfission.html。用正則表達式提取文件内容中的版本。与有漏洞的值进行对照.听起来好像非常easy,让我们開始吧
!

框架代码

基于传统的语言标准。我们写一个脚本,作用:遇到开放的HTTPport。就返回”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

该部分定义脚本逻辑。

此处案例中,检測到开放80port。则打印“HelloWorld”。脚本的输出内容。会在nmap运行期间显示出来。

root@security:/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

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

root@security:/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页面。

root@security:/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

上述输出表明,两个serverport不存在相应页面”arcticfission.html”。注意'http'库会自己主动在http与httpsport切换。因此你不须要考虑去实现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的页面内容。

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

漏洞探測

很多时候。能够通过一个简单的服务版本。探測漏洞。这样的情况。假象的server会返回一个包括版本的标识。

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库,以便获取页面头。

offensive@security:~/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

測试结果例如以下:

offensive@security:~/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

加入隐藏属性

使用第三方的库时,測试脚本的运行流程非常重要。

offensive@security:~/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。可使用以下方法.

offensive@security:~/nmap_nse$ nmap -p 80,443 --script /home/offensive/nmap_nse/http-vuln-check_openssl.nse --script-args="http.useragent='Mozilla/5.0 (compatible [offensive@security])'" --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 nsive@security])

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

扫描结果例如以下:

offensive@security:~/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

nmap -- write a nmap script的更多相关文章

  1. nmap学习之nmap -sP 【目标】

    一.通过arp包判断局域网内的主机状态 二.对于局域网外的主机通过向主机 1)发送普通ICMP请求包[类型字段为8,代码字段为0]: 2)发送时间戳ICMP请求包[类型字段为13,代码字段为0]: 3 ...

  2. ★Kali信息收集★8.Nmap :端口扫描

    ★Kali信息收集~ 0.Httrack 网站复制机 http://www.cnblogs.com/dunitian/p/5061954.html ★Kali信息收集~ 1.Google Hackin ...

  3. 转-Nmap扫描原理与用法

    1     Nmap介绍 操作系统与设备类型等信息. Nmap的优点: 1.      灵活.支持数十种不同的扫描方式,支持多种目标对象的扫描. 2.      强大.Nmap可以用于扫描互联网上大规 ...

  4. nmap脚本扫描使用总结

    nmap的脚本默认目录为:/usr/share/nmap/scripts/ Nmap提供的命令行参数如下 -sC: 等价于--script=default,使用默认类别的脚本进行扫描 可更换其他类别 ...

  5. Nmap扫描手册

    By:WHILE扫描类-sTTCP connect()扫描,完整的通话连接,容易被检测,会被记录日志.-sSTCP同步扫描,不完整的通话连接,很少有系统会记入日志.-sUUDP扫描-sAACK扫描用来 ...

  6. Nmap备忘单:从探索到漏洞利用(Part 5)

    这是备忘单的最后一部分,在这里主要讲述漏洞评估和渗透测试. 数据库审计 列出数据库名称 nmap -sV --script=mysql-databases 192.168.195.130 上图并没有显 ...

  7. Nmap备忘单:从探索到漏洞利用(Part3)

    众所周知NMAP是经常用来进行端口发现.端口识别.除此之外我们还可以通过NMAP的NSE脚本做很多事情,比如邮件指纹识别,检索WHOIS记录,使用UDP服务等. 发现地理位置 Gorjan Petro ...

  8. Nmap备忘单:从探索到漏洞利用 Part1

    在侦查过程中,信息收集的初始阶段是扫描. 侦查是什么? 侦查是尽可能多的收集目标网络的信息.从黑客的角度来看,信息收集对攻击非常有帮助,一般来说可以收集到以下信息: 电子邮件.端口号.操作系统.运行的 ...

  9. Top 30 Nmap Command Examples For Sys/Network Admins

    Nmap is short for Network Mapper. It is an open source security tool for network exploration, securi ...

随机推荐

  1. JS多维数组转一维

    题目: var array = [1, [2, [3, 4], [5, 6]], 7, 8]; 写一个方法 flatArray(),得到数组 [1, 2, 3, 4, 5, 6, 7, 8] 解答: ...

  2. [转]CentOS_yum的详细使用方法

    yum 是什么yum = Yellow dog Updater, Modified主要功能是更方便的添加/删除/更新RPM包.它能自动解决包的倚赖性问题.它能便于管理大量系统的更新问题 yum特点可以 ...

  3. 新浪微博中tableview中头部信息

    摘自http://www.cnblogs.com/gcb999/p/3151665.html #import <UIKit/UIKit.h> @class User; @protocol ...

  4. Qt实现QQ好友下拉列表(用QListView实现,所以还得定义它的Model)

    偶然发现Qt有个控件可以实现下拉列表,所以就试着实现一下类似QQ面板的下拉列表,这里主要实现几个功能: 1.可以删除列表中图标 2.可以像qq一样的,把某个分组下的图标转移到另外的分组 3.添加分组 ...

  5. Convert SVG to PNG in Python - Stack Overflow

    Convert SVG to PNG in Python - Stack Overflow Convert SVG to PNG in Python

  6. JQuery Datatable Ajax请求两次问题的解决

    最近一个项目中使用JQuery Datatable,用起来比较方便,但在测试过程中,发现当条件改变时,有时查询结果中的数据不正确. 使用FireBug跟踪时,发现在使用Ajax请求时,点击一次搜索按钮 ...

  7. perl $d = encode_utf8($r); $f = decode_json($d)

    [root@dr-mysql01 ~]# cat a1.pl my $url="http://192.168.32.101:3000/api/getcode?env=zj&phone ...

  8. boost操作xml 5分钟官方教程

    Five Minute Tutorial This tutorial uses XML. Note that the library is not specifically bound to XML, ...

  9. inner join、left join、right join中where和and的作用

    inner join.left join.right join中where和and的作用 .内连接(自然连接): 只有两个表相匹配的行才能在结果集中出现 2.外连接: 包括  (1)左外连接 (左边的 ...

  10. 在windows下如何配置RTT开发环境?

    之前一直使用MDK查看和编译RTT的源码,这几天无聊想起RTT官方提供使用scons工具编译RTT,因此想试试这种方法,做下此笔记,以供入门者参考. 注 1 下载安装Python2.7 论坛中很多人说 ...