漏洞扫描 --编写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. AsyncTask使用须知

    AsyncTask的实现原理就是封装了的线程池,详细见AsyncTask实现原理. 在1.5中初始引入的时候, AsyncTask 运行( AsyncTask.execute() )起来是顺序的,当同 ...

  2. c,assert 宏的实现

    预备知识:#define _VAL(x) #x //#x的作用就是把x表达式变成一个字符串.(注意 : 不带换行符'\n' , 换行符ascii==10).如:_STR(i<100)printf ...

  3. 第四届蓝桥杯 c/c++真题

    第四届蓝桥杯 c/c++真题 <1>高斯日记 问题 大数学家高斯有个好习惯:无论如何都要记日记. 他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210 后来人们 ...

  4. 动态规划之一ones

    n给一个整数n,要你找一个值为n的表达式,这个表达式只有1 + * ( ) 够成.并且1不能连续,比如11+1就不合法. n输入n,(1<=n<=10000) n输出最少需要多少个1才能构 ...

  5. js判断IP js判断域名

    <html> <head> <script language="javascript" type="text/javascript" ...

  6. SignalR系列教程:SignalR快速入门

    ---恢复内容开始--- 本篇是SignalR系列教程的第一篇,本篇内容介绍了如何创建SignalR应用,如何利用SignalR搭建简易的聊天室等,本篇内容参考自:http://www.asp.net ...

  7. Struts2 学习笔记17 I18N国际化

    讲解一下国际化的内容,比如书有些大的网站可以一键切换语言,例如中英切换,这时候就会用到国际化.但是由于struts2大多数是用来写后台,国际化并不是十分重要,而且用国际化开发会减慢开发的速度,大家只要 ...

  8. Learning Web

    1.UDACITY https://www.udacity.com/course/cs258

  9. C#多线程的死锁演示

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...

  10. perl 类里的函数调用其他类的函数

    perl 类里的函数调用其他类的函数: package Horse; use base qw(Critter); sub new { my $invocant = shift; my $class = ...