netcatについて
はじめまして、今年4月に入社したN.Tと申します。
今回はLinuC-1にも登場するnetcatコマンドについて解説していこうと思います。
netcatとは
netcatは、TCPやUDP接続を用いて、指定したホスト名の特定ポートに対して
データの送受信を行えるツールです。
この機能だけではtelnetと何ら変わりがないように思えますが、
netcatは指定したポートで待ち受けることも可能なのです。
この他にも非常に多くの機能を備えていますので、紹介していきます。
今回はグローバルネットワークに接続しているnc-test1サーバとローカル環境のnc-test2サーバの
2つの検証サーバで進めていきます。
任意ポートに対する接続
基本機能です。ホストとポート番号を指定して接続できます。
世界一有名なサイトに直接80ポートで接続して、HTTPリクエストを送ってみましょう。
[root@nc-test1 ~]# nc -v google.com 80
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Connected to 142.251.42.174:80.
HEAD / HTTP/1.1
HTTP/1.1 200 OK
Content-Type: text/html; charset=ISO-8859-1
Content-Security-Policy-Report-Only: object-src 'none';base-uri 'self';script-src 'nonce-xd1dvHakE5kspm7AF5YpsQ' 'strict-dynamic' 'report-sample' 'unsafe-eval' 'unsafe-inline' https: http:;report-uri https://csp.withgoogle.com/csp/gws/other-hp
P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
Date: Wed, 18 Oct 2023 05:49:25 GMT
Server: gws
X-XSS-Protection: 0
X-Frame-Options: SAMEORIGIN
Transfer-Encoding: chunked
Expires: Wed, 18 Oct 2023 05:49:25 GMT
Cache-Control: private
Set-Cookie: 1P_JAR=2023-10-18-05; expires=Fri, 17-Nov-2023 05:49:25 GMT; path=/; domain=.google.com; Secure
Set-Cookie: AEC=Ackid1TXYP8_NfAcIZM205Cj2Rh_I7hn8ZjD0hQF7seYsRjKMDnOoZN3ZA; expires=Mon, 15-Apr-2024 05:49:25 GMT; path=/; domain=.google.com; Secure; HttpOnly; SameSite=lax
Set-Cookie: NID=511=gHd2aZ7owBU4yBLk2gstofUJt1LeHSWGpLLXpYk4VlKoHPw8o9KfywkTXEMiUhSP5ZYjW6zps0K_lwsX_j-Csyjb1j8X666kaQM8pc-DDQda1Ffy3vg6uyxOIAHknzNGuGXYwZAE7BafdO7ZINtpmJ-EOJCWS2Iy6Pf-CvD1UZ0; expires=Thu, 18-Apr-2024 05:49:25 GMT; path=/; domain=.google.com; HttpOnly
このようにステータスコードとHTTPレスポンスを受け取ることができました。
ですが、この機能はtelnetやcurlとは何も変わりないですね。
任意ポートでの待ち受け
なんと、「-l」オプションを用いると、任意ポートで待ち受けることもできます。
netcatはサーバとしても機能することができるんですね。
1000ポートで待ち受けているtest2サーバに接続すると…
[root@nc-test2 ~]# nc -lk 1000
hello
I am test1
[root@nc-test1 ~]# nc 172.31.29.174 1000
hello
I am test1
チャット機能のように、テキストの送受信が行えます。
また、他にもWebサーバのように動作させることもできるので、
8080ポートで”Hello World”を返すように待ち受けていると…
[root@nc-test2 ~]# ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | nc -l 8080;
[root@nc-test1 ~]# nc 172.31.29.174 8080
HTTP/1.0 200 Ok
Hello World
このように”Hello World”と返してくれて、簡易Webサーバのように機能しました。
バックドア
「-e」オプションは接続後に実行するプログラムを指定できます。
なのでシェルに接続した状態で待ち受けていると…
[root@nc-test2 ~]# nc -l 1000 -e /bin/bash
[root@nc-test1 ~]# nc 172.31.29.174 1000
uname -n
nc-test2
pwd
/root
telnetのように対象サーバでコマンドを入力することが可能となります。
当然ですが何も認証機能が存在しないので裏でこっそりnetcatが実行されていると
簡単にバックドアとして機能してしまいます。
ポートスキャン機能
対象ホストに対し、ポートスキャンを行い、待ち受けているポートを確認することが出来ます。
test2の事前に待ち受けているポートを確認し、
[root@nc-test2 ~]# ss -nltp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=922,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=922,fd=4))
[root@nc-test2 ~]#
22ポートとそれ以外のポートスキャンを試みると
[root@nc-test1 ~]# nc -zv 172.31.29.174 22
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Connected to 172.31.29.174:22.
Ncat: 0 bytes sent, 0 bytes received in 0.04 seconds.
[root@nc-test1 ~]# nc -zv 172.31.29.174 25
Ncat: Version 7.91 ( https://nmap.org/ncat )
Ncat: Connection refused.
[root@nc-test1 ~]#
このように外部から簡単に確認できます。
プロキシサーバ機能
プロキシサーバとは、クライアントとサーバ間で、通信を中継するサーバのことです。
[root@nc-test1 ~]# nc -l 8080 --proxy-type http
このようにhttpのプロキシサーバ機能を持たせることが出来ます。
なので、グローバルネットワークに接続していないtest2サーバでも….
[root@nc-test2 ~]# curl -m 2 -I https://www.netassist.ne.jp
curl: (28) Connection timed out after 2000 milliseconds
[root@nc-test2 ~]#
test1サーバの8080ポートを経由することで、Web接続ができます。
[root@nc-test2 ~]# curl -x 172.31.27.200:8080 -I https://www.netassist.ne.jp
HTTP/1.0 200 OK
HTTP/2 200
date: Wed, 18 Oct 2023 07:22:07 GMT
server: Apache
link: <https://www.netassist.ne.jp/wp-json/>; rel="https://api.w.org/", <https://www.netassist.ne.jp/wp-json/wp/v2/pages/2836>; rel="alternate"; type="application/json", <https://www.netassist.ne.jp/>; rel=shortlink
strict-transport-security: max-age=15724800
content-security-policy: upgrade-insecure-requests
content-type: text/html; charset=UTF-8
[root@nc-test2 ~]#
最後にここまで紹介した機能を組み合わせて、
test1をプロキシサーバ、test2をWebサーバとして動作させて、
簡単な冗長化を持たせたwebサーバ構成を実現しましょう。
まずは、test2でhtmlコンテンツを返すWebサーバを動作させて….
[root@nc-test2 ~]# while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; cat index.html; } | nc -l 8080; done
そしてtest1は外部からの通信をtest2サーバに受け渡しするようなプロキシサーバを動作させると、
[root@nc-test1 ~]# while true; do [[ -p fifo ]] || mkfifo fifo && nc -l 80 < fifo | nc 172.31.29.174 8080 > fifo; done
クライアント → test1(プロキシ) → test2(Web) の順番で接続できるので…
このようにローカル環境下のWebページを表示することが出来ました。
おわりに
今回はnetcatの機能を一部紹介いたしましたが、まだまだ機能がありますので
皆様も触ってもらえたらなと思います。
次の機会があれば、さらなるnetcat深さを紹介できればなと思います。