3way-handshakeからnmapのステルススキャンを理解する

#3way-handshakeとnmapステルススキャン

[以前の記事](https://qiita.com/rui-watanabe/items/5ac828d29c6c5915c0a1)でpWnOS:2.0という脆弱性サーバーに、Kali Linuxを使ってroot権限を取得しました。

そのKali Linuxで**ポートスキャンを行うに使ったnmapというツール**は、対象サーバーにログを残さない**ステルススキャン**を行うことができました。

今回はこのnmapのステルススキャンを実現している、**TCPプロトコルの3way-handshake**についてまとめていきたいと思います。

#3way-handshakeとは?

3way-handshakeとは通信の信頼性を確保するための接続で、**TCPヘッダ情報のフラグを利用した通信方法**です。

この3way-handshakeが終了したことでTCPコネクションが確立したということを示し、上位レイヤーでHTTP通信などが行われます。

#3way-handshakeを実現するTCPコネクション

次に、3way-handshakeを実現するTCPコネクションについてまとめていきます。

そもそもTCPはヘッダに、6つのフラグ情報というものを持っています。

そして、各フラグにはTCPコネクションを行うためのフラグ情報が1ビット(0か1)で管理されています。

3way-handshakeでは6つのフラグのうち、通信を確立するための**SYN(Synchronize)フラグ**、通信可能を確認できたことを示す**ACK(Acknowledge)フラグ**、通信を強制的に切断する**RST(Reset)フラグ**が使われています。

クライアントサーバー間のパケットで、このフラグを設定することで通信が可能か、通信が不可能かということを判断するのです。

具体的に通信手順は、以下のようになります。

※パケット（TCPセグメント）とは、TCPのヘッダとTCPペイロード（データ）から構成される。
※シーケンス番号とはTCPヘッダに記載されている、パケットにつけられる通し番号のことである。

##3way-handshakeの通信例

①クライアント側は、シーケンス番号が10000、SYNフラグが1の**SYNパケットをサーバー側に送る**。

②サーバー側は通信可能な場合、ACKフラグを1、シーケンス番号を送られてきたSYNパケットに1を足10001にした、**ACKパケットをクライアント側に返す**。
またクライアント側からどのシーケンス番号を起点とし通信するか決めるため、新たにシーケンス番号30000の**SYNパケットをクライアント側に返す**。

③クライアント側は送られてきたSYNパケットのシーケンス番号に1を足した30001に設定し、**ACKパケットをサーバー側に返す**ことで通信が確立される。(このSYNパケットはサーバの対する応答の意味しかないので、SYNフラグは0に設定されている）

通信が不可能な時は②で**RSTフラグが1のパケットが返ってくる**ので、通信が強制終了されます。

#nmapのTCPフルコネクトスキャン

ここで、3way-handshakeを使ったnmapの通信方法について紹介したいと思います。

nmapではスキャンタイプを**-sT**とすることで、TCPフルコネクトスキャンが可能になります。

このTCPフルコネクトスキャンが、先ほど説明した**3way-handshakeのTCPコネクションが実践されている接続方法**になります。

```
root@kali:~# nmap -sT 対象IPアドレス
```

![demo](https://gyazo.com/57565c49a409c434aa8316aebad922b3/raw)


#nmapのTCPハーフコネクトスキャン

TCPフルコネクトスキャンに対して、-sSオプションは、TCPハーフコネクトスキャンと呼ばれます。

TCPハーフコネクトスキャンでは、通信が成功しても先ほどの手順③の際に、**SYNパケットを送りません**。

サーバー側から返ってきたパケットが**SYN/ACKかRSTか**で、ポートが空いているか（通信が可能か）判断するため、サーバー側にログを残さずにその確認が可能となります。

```
root@kali:~# nmap -sS 対象IPアドレス
```

![demo](https://gyazo.com/fd80c8b86a26badfa24803409a597892/raw)


#Wiresharkで3way-handshakeを確認

実際に**Wireshark**という、パケットの流れをみれるKali Linuxのツールを使って、nmapによる3way-handshakeがどのような通信になっているか確認します。

ここではpWnOS:2.0で設定したIPアドレスと同じで、クライアント側のIPが10.10.10.10、サーバー側のIPが10.10.10.100に設定されています。

まずKali Linuxを開いて、wiresharkコマンドを打ちます。

```
root@kali:~# wireshark
```

無事Wiresharkが立ち上がりeth0を選択します。

次に別のタブでターミナルを開き、nmapコマンドでポート80番に対しステルススキャンを行います。

```
root@kali:~# nmap -sS -p 80 10.10.10.100
```

nmapコマンドを打ったら、パケットの情報がでてきているのでWIRESHARKを開きます。

Sourceが通信元サーバー、Destinationが通信先サーバーとなっています。

![demo](https://gyazo.com/fbe57c3ea2d8baaeef9abbbdaa20d2b9/raw)

このようにNo12でクライアント側からサーバー側にSYNパケットを送り、No13でサーバー側からSYN/ACKパケットが返ってきて、No13でRSTパケットにより接続を終了していることがわかります。

このようにWiresharkを使うことで、nmapを使った3way-handshakeのTCP通信の流れを見ることができました、



#参考URL
https://resources.infosecinstitute.com/nmap/#gref
https://www.atmarkit.co.jp/ait/articles/0801/08/news127_2.html
http://www.yk.rim.or.jp/~shikap/security/vul_text/attack1.html
http://www.yk.rim.or.jp/~shikap/security/vul_text/TCPIP1.html
http://www.yk.rim.or.jp/~shikap/security/vul_text/TCPIP2.html
http://www.yk.rim.or.jp/~shikap/security/use_nmap.html
https://ascii.jp/elem/000/000/619/619702/
https://milestone-of-se.nesuke.com/nw-basic/tcp-udp/tcp-connection/
https://qiita.com/55momotara55/items/2081312e1dd14521c0a1
https://www.infraexpert.com/study/tcpip8.html