SED による gnmap フィールドのパターン マッチング

SED による gnmap フィールドのパターン マッチング

Splunk を使用して nmap のフィールド抽出を作成するために必要な正規表現をテストしていますが、近い結果になると思います...

完全な行の例:

Host: 10.0.0.1 (host)   Ports: 21/open|filtered/tcp//ftp///, 22/open/tcp//ssh//OpenSSH 5.9p1 Debian 5ubuntu1 (protocol 2.0)/, 23/closed/tcp//telnet///, 80/open/tcp//http//Apache httpd 2.2.22 ((Ubuntu))/,  10000/closed/tcp//snet-sensor-mgmt///  OS: Linux 2.6.32 - 3.2  Seq Index: 257  IP ID Seq: All zeros

読みやすくなるように、区切り文字としてアンダースコア「_」を使用しました。

root@host:/# sed -n -e 's_\([0-9]\{1,5\}\/[^/]*\/[^/]*\/\/[^/]*\/\/[^/]*\/.\)_\n\1_pg' filename

エスケープ文字を削除した同じ正規表現:

root@host:/# sed -n -e 's_\([0-9]\{1,5\}/[^/]*/[^/]*//[^/]*//[^/]*/.\)_\n\1_pg' filename

出力:

... ... ...
Host: 10.0.0.1 (host)   Ports: 
21/open|filtered/tcp//ftp///, 
22/open/tcp//ssh//OpenSSH 2.0p1 Debian 2ubuntu1 (protocol 2.0)/, 
23/closed/tcp//telnet///, 
80/open/tcp//http//Apache httpd 5.4.32 ((Ubuntu))/, 
10000/closed/tcp//snet-sensor-mgmt///   OS: Linux 9.8.76 - 7.3  Seq Index: 257 IPID Seq: All zeros
... ... ...

ご覧のとおり、パターン マッチングは機能しているようですが、次のことはできません。

1 - 行末 (カンマ、および空白/タブスペース) の両方のパターンに一致します。最後の行には不要なテキスト (この場合は、OS と TCP タイミング情報) が含まれています。2 つの文字 (カンマと空白) のブール「OR」は一致しないようです。

...(\,|\s)

そして

2 - 不要なデータを削除します。つまり、一致するパターンのみを印刷します。実際には行全体を印刷しています。sed -n フラグを削除すると、残りのファイルの内容も印刷されます。一致した正規表現のみを印刷する方法が見つからないようです。

つまり、明示的に出力しないように指示したのに、なぜ sed はこれらの行を出力するのでしょうか? =>

Host: 10.0.0.1 (host) Ports:

そして

OS: Linux 2.6.32 - 3.2  Seq Index: 257  IP ID Seq: All zeros

sed と regex については初心者なので、助けやアドバイスをいただければ幸いです。

答え1

まず、Nmap の XML 出力 ( フラグで利用可能-oX) を確認することをお勧めします。これは、公式にサポートされている機械可読出力形式です。Grepp 可能な (-oGまたは.gnmap) 出力は非推奨であるため、traceroute や NSE スクリプトなどの Nmap の新機能からの役立つ情報は含まれていません。

ご質問に直接お答えしますと、

  1. カンマまたはスペースのいずれかに一致させると、|カンマではなく交替パイプ文字 ( ) をエスケープする必要があるため、エラーが発生します。また、おそらく常に空白文字に一致させたいが、カンマに一致させたい場合もあるでしょう。これは私がそれを行う方法です:

    ,\?\s
    

交替 (「または」パイプ) がないので、グループ化は使用していません。

  1. sed不要な「行」を印刷するのではなく、パターン スペースを印刷します。sed 情報ページsed の動作を説明しており、sed スクリプトを作成するための優れたリファレンスです。基本的に 2 つのスペースを使用して作業し、sed コマンドを使用すると、パターン スペースの内容全体が出力されますp

これを実行する方法の例として、ファイルからポート情報だけを出力する sed スクリプトを次に示します.gnmap

#!/usr/bin/sed -n 

#First, strip the beginning (Host and Ports labels) off
s/.*Ports: //

#Now match a port entry, consuming the optional comma and whitespace
#The comma and whitespace are replaced with a newline
s_\([0-9]\{1,5\}/[^/]*/[^/]*/[^/]*/[^/]*/[^/]*/[^/]*/\),\?\s_\1\n_

#If we made a successful substitution, jump to :matched, 
t matched
#otherwise skip to the next input line
d

:matched
#Print the pattern space up to the first newline
P
#Then delete up to the first newline and start over with what's left
D

すべてを 1 行にまとめると、次のようになります。

sed -n -e 's/.*Ports: //;s_\([0-9]\{1,5\}/[^/]*/[^/]*/[^/]*/[^/]*/[^/]*/[^/]*/\),\?\s_\1\n_;t matched;d;:matched;P;D' file.gnmap

また、ポート仕様の一部のフィールドが常に空であるとは限らないことにも注意してください。たとえば、RPC サービスでバージョン検出が行われた場合、SunRPC 情報フィールドに値が設定されます。

関連情報