👁️

Nmapの基本的な使い方〜CTFの基本のキ〜

2024/01/20に公開

はじめに

今年から本格的にCTFに取り組んでいこうと言うことでまず手始めにTry Hack Me(通称THM)に取り組み始めました。
THMはとても優良なセキュリティ学習コンテンツなのですが、英語であるのが唯一の悲しいところ。そこで今回はペネトレーションテストの基本であるnmapについてTHMのNmapルームで学んだことを覚書としてまとめようと思います。
最初に言っておきおます。「悪用ダメ!絶対!」

Nmap(Network Mapper)とは

一言で言うと、「nmapはポートスキャンを行うツール」です。
つまり、Nmapを用いることによってターゲットホストがどのようなサービスやプロトコル、OSやそれらのバージョン使っているのかを知ることができます。
これはコマンドあるあるですが、オプションが沢山あり、それらをどのように使うかによってポートスキャンの効率性、さらにはそれによるCTFの成績が向上します。
そのため以降のセクションでは、nmapの仕組みをまとめながらオプションについてまとめていきます。

Scan Type

nmapを用いる際にスキャンタイプをオプションによって選択することができます。選択できる基本的なスキャンタイプは以下の3つです。

  • TCPスキャン(-sT
  • SYN "Half-open"スキャン(-sS
  • UDPスキャン(-sU

この他にもTHMでは以下の3つが紹介されています。

  • TCP Nullスキャン(-sN
  • TCP FINスキャン(-sF
  • TCP Xmas スキャン(-sX

正味、最初の3つのスキャン方法だけ覚えておけば大丈夫そうです。
それでは次にそれぞれ詳しくまとめていきます。

TCPスキャン

TCPスキャンはその名の通り、3-wayハンドシェイクを用いたスキャン方法です。
Nmapをすることによって各TCPポートに接続を試みて、それらの応答によってポートが開いているか否かを判断します。
たとえばポートが閉じている場合、ターゲットサーバーはRST(Reset)フラグを応答として返してきます。RSTフラグが返ってくると、Nmapはそのポートは閉じている(closed)であると判断します。
逆にポートが開いている場合、ターゲットサーバーはSYN/ACKフラグを応答として返してきます。このフラグによってNmapはポートが開いている(open)であると判断します。

それでは、ファイアウォールがあった場合はどうなるか。
ファイアウォールがあった場合は、パケットがファイアウォールによって通れず捨てられるので、ターゲットサーバーからの応答が返ってきません。そのため、この場合nmapはそのポートはファイアウォールが設定されている(filtered)と判断します。

SYNスキャン(デフォルト)

SYNスキャンもTCPスキャンと同様にTCPポートで用いられるスキャン方式です。
しかし、TCPスキャンとはわずかに違うところがあります。
TCPスキャンはターゲットサーバーに対して3-wayハンドシェイクを一通り行う方式ですが、SYNスキャンは最初にNmap側からSYNを送ったのちに、SYN/ACKフラグが返ってきたらターゲットサーバーにRSTパケットを送り返します。
これによる有益な点は

  • 仮にターゲットホストが古い侵入検知システムを用いている場合、完全な3-wayハンドシェイクを監視しているため、Half-openなSYNスキャンは回避することができる(今はそんな侵入検知システム使ってるところはそうそうないらしい)
  • SYNスキャンはRSTを返しているので、openポートとして認識されず、openポートのみをリッスンしているアプリケーションではログに記録されないことが多い
  • Half-openであるため、TCPスキャンよりも高速化することができる。

一方で、弱みとしては、

  • Linuxにおいては、実行にsudo権限がいる(rawパケットを作る必要があるため)
  • 不安定なサービスの場合、SYNスキャンによってダウンしてしまうことがある

このようにSYNスキャンはTCPスキャンよりも一般的に優れているため、Nmapのデフォルトでは、SYNスキャンが用いられます。
ただ前述の通り、SYNスキャンの実行にはsudo権限が必要なので、Nmapをするときにsudo権限で行えば、SYNスキャン、なしであればTCPスキャンになります。

UDPスキャン

UDPスキャンはその名の通り、openしているUDPポートにパケットを送るスキャン方法です。
もし、パケットを送り、応答がなければNmapはそのポートがopenまたはfilteredと見なします。もし、応答がない場合は一応確認のために再度パケットを送り、最終判断を下します。逆にポートが閉じている場合、ターゲットサーバーからunreachableであることを伝えるICMPパケットが送られてくるので、これによってclosedであることを判断することができます。
前述の通り、UDPスキャンは応答がない場合、ダブルチェックを行うので、TCPスキャンに比べ速度が落ちます。そのため、よく--top-ports <number>が用いられます。この指定をすることでターゲットサーバーのよく使われているnumber個のポートをスキャンすることができ、時間を短縮することができます。

NULLスキャン

NULLスキャンは何もフラグを送らないTCPリクエストです。
ターゲットサーバーが閉じている場合、ターゲットサーバーはRSTで応答する必要があります。

FINスキャン

FINスキャンは完全に空のパケットを送る代わりに、FINフラグをつけたリクエストを送ります。
ポートが閉じている場合、RSTフラグが応答として返ってきます。

Xmasスキャン

Xmasスキャンは変わったTCPパケットを送信します。
もしポートが閉じていればRSTが応答として返ってきます。名前はどうやらWireSharkでパケットキャプチャを見た時に設定するフラグが点滅するクリスマスツリーのように見えることから名付けられているようです。

NSE Scripts

NmapにはNSE(Nmap Scripting Engine)というものが存在し、Luaという言語で書かれています。
NSE Scriptsは多くのカテゴリが存在し、有名なものは以下のようなものになります。

  • safe:ターゲットに影響を及ぼさない
  • intrusive:ターゲットに影響を及ぼす
  • vuln:脆弱性をスキャンする
  • exploit:脆弱性の攻撃を試みる
  • auth:サービスの認証の突破を試みる
  • brute:サービスに対して総当たり攻撃を試みる
  • discovery:サービスのより詳しい情報の取得を試みる

この他のものはこちらを参考にしてください。

NSE Scriptsの使い方

NSE Scriptsを実行する際は、オプションとして--script=<category>を付加します。
vulnを実行するとすると--script=vulnとなります。
特定のスクリプトを実行したい時は、--script=<script-name>とします。
複数のscriptを実行したい場合は、,区切りで複数指定することができます。
引数を必要とする場合は、script-argsの後に引数を入力するか、<script-name>.<argument>のように.で区切って渡すこともできます。
スクリプトについて困ったらnmap --script-help <script-name>で聞いてみましょう。
教えてくれます。

どんなNSE Scriptsを見るには、nmapのMan Pageを参照するか、自身の/usr/share/nmap/scriptsにスクリプトが格納されているためそちらを参照してください。また、インストールされているscriptは/usr/share/nmap/scripts/script.dbに格納されているのでそちらを参照することによっても確認することができます。
もしインストールされていないスクリプトを使いたい場合は、sudo wget -O /usr/share/nmap/scripts/<script-name>.nse https://svn.nmap.org/nmap/scripts/<script-name>.nseを用いることによってインストールすることもできます。インストール後はnmap --script-updatedbを実行してdbを更新します。

最後に

今回は、Nmapの基本的な使い方をまとめました。
かなり端折ったので、今後追記するかもしれません。詳しくは、ぜひTHMをやってみてください。
自分自身、まだ本格的に勉強し始めたところなので、是非アドバイスや訂正等あればコメントで教えてください!
最後にもう一度言っておきます。悪用ダメ!絶対!
それでは良いTHMライフを!

参考

Discussion