2013-11-26 54 views
1

我使用NMAP,我在大型網絡上運行掃描以查看打開的端口。輸出文件是2MB,但我想用全部關閉的端口過濾掉所有的IP地址。使用grep,awk或sed過濾nmap輸出

Nmap scan report for 10.x.x.x 
Host is up (0.048s latency). 
Not shown: 998 closed ports 
PORT STATE SERVICE 
22/tcp open ssh 
23/tcp open telnet 

Nmap scan report for 10.x.x.x 
Host is up (0.046s latency). 
All 1000 scanned ports on 10.x.x.x are closed 

Nmap scan report for 10.x.x.x 
Host is up (0.045s latency). 
All 1000 scanned ports on 10.x.x.x are closed 

應該輸出只輸出到:

Nmap scan report for 10.x.x.x 
Host is up (0.048s latency). 
Not shown: 998 closed ports 
PORT STATE SERVICE 
22/tcp open ssh 
23/tcp open telnet 

編輯

的結果是一樣

Nmap scan report for 10.x.x.x 
Host is up (0.048s latency). 
Not shown: 998 closed ports 
PORT STATE SERVICE 
22/tcp open ssh 
23/tcp open telnet 
Nmap scan report for 10.x.x.x 
Host is up (0.046s latency). 
All 1000 scanned ports on 10.x.x.x are closed 
Nmap scan report for 10.x.x.x 
Host is up (0.045s latency). 
All 1000 scanned ports on 10.x.x.x are closed 

有跡象表明,沒有拷貝過來的換行符正確地

編輯 謝謝大家。我看到awk非常棒,容易操作。

+0

我只知道簡單的grep。像「cat nmap,out | grep open」。但是它僅列出了已打開的端口,而不是其他詳細信息,例如IP地址 – user3037023

+0

請提供您正在使用的nmap命令行,以便我們可以複製輸出以測試解決方案。 – ghoti

+0

nmap 10.10.0.0/16 – user3037023

回答

1

你可以嘗試

awk -f filter.awk input.txt 

其中input.txtnmap的輸出中和filter.awk是:

/^Nmap/ { 
    if (block) 
     if (!match(block,/are closed/)) 
      print block 
    block=$0 
    next 
} 

{ 
    if (block) 
     block=block RS $0 
    else 
     block=$0 
} 
+0

真棒!謝謝。它的工作雖然我修改了一點點,以擺脫一些其他的東西。 > if(!match(block,/ closed)/)&&!match(block,/ is filtered /)) – user3037023

+0

@ user3037023太好了:) –

4

在我看來,你想一些智能過濾應用到您的NMAP輸出,而不僅僅是一個簡單的「grep」。

由於您的nmap命令(根據您的意見而不是您的問題)指向子網而不是單個主機,因此您需要單獨解釋輸出的每個部分。但是這種解釋對於正則表達式來說太複雜了。 (使用PREG可能會出現這種情況,但編寫起來非常困難,而且幾乎不可能讀取。)像awk這樣的工具對於這項任務來說是一個更好的選擇。

例如:

nmap 10.10.0.0/16 | awk ' 
    /^Nmap scan report for/ { 
    if (open) { 
     print output; 
    } 
    output=""; 
    open=0; 
    } 

    { 
    output=output $0 "\n"; 
    } 

    $2 == "open" { 
    open=1; 
    } 

    END { 
    if (open) { 
     print output; 
    } 
    } 
' 

AWK是很容易閱讀,但你應該知道,它通過對匹配看起來像condition { action }表情輸入的每一行操作。如果條件評估爲真,則執行該操作。所以第一個有一個條件是一個正則表達式來查找主機節的開始,並且這些動作被封裝在大括號中。第二個條件不存在,所以假定所有行都是「真實的」。最後一個條件在所有行輸入都被處理後匹配,並且在最後掃描的主機包含開放端口的情況下是必要的。

這種事情可以表達得更密集,但我已經寫了很長時間,以便您可以更容易地看到邏輯的工作原理。更嚴格的代碼將伴隨練習而來。

請注意,您可以將awk腳本放入單獨的文件中,您可以使用awk的-f選項參考該文件。有關詳細信息,請閱讀the man page

如果您不想將awk部分保留在自己的文件中,您也可以將這整個事件放到它自己的shell腳本中。你應該能夠找到那些看起來很容易的例子 - 無論如何,它已經超出了這個問題的範圍。

+0

+1對概念的很好的解釋.. –

+0

謝謝你,先生! – user3037023

+0

如果問題是「複雜的文本處理」,答案几乎總是'awk'(除非它是'perl' ...)。好答案。 – Floris

0

雖然看起來你有答案,但我會從Nmap方面解決這個問題。 Nmap有很多不同的output options,所以事先仔細的規劃可以使這類問題簡單地處理。

首先,如果您只想要帶有開放端口的主機,您可以使用--open運行掃描,這將會隱藏所有關閉和過濾的端口以及沒有開放端口的主機。這意味着您的輸出將完全是您想要的,而無需過濾。缺點是你失去了一些信息;有時知道主機是否在場,即使他們沒有服務也是很重要的。

接下來,Nmap有幾種輸出格式。正常輸出(-oN)主要是您在屏幕上看到的內容。滾動瀏覽很不錯,但正如你所看到的那樣,對於文本處理或使用grep,sed,awk等進行過濾是非常糟糕的。我發現最有用的輸出選項是-oA,它可以保存3個不同的文件:一個正常的.nmap文件,一個「greppable」.gnmap文件,以及所有格式的母版,.xml文件。

Greppable format很適合快速查詢,比如「哪些IP有端口22打開?」它每個主機有一行,並有嚴格的分隔符。缺點是不推薦使用:Nmap的任何新功能都不會被集成到可格式化格式中。以下列出了-oG中缺少的一些內容:NSE腳本輸出,traceroute信息,多個主機名,端口狀態原因,ttls。你的問題可以用greppable格式如下回答:

grep '[0-9]/open' myscan.gnmap 

XML output是最完整的格式,包括甚至不適合正常的輸出信息。它也是由於是XML而能夠在命令行上處理。下面是一個使用xmlstarlet的示例查詢(雖然有很多其他工具可以完成這項工作):

xmlstarlet sel -t -m "//host[ports/port/state/@state='open']" -v "address[@addrtype='ipv4']/@addr" -n myscan.xml