ncat
ncat
コマンドを利用すると、簡易的な TCP/UDP クライアントの操作をコマンドラインから行うことができます。
$ nc example.com 80 <<EOF
GET / HTTP/1.1
Host: example.com
Connection: close
EOF
実行例
$ nc example.com 80 <<EOF
GET / HTTP/1.1
Host: example.com
Connection: close
EOF
HTTP/1.1 200 OK
Accept-Ranges: bytes
Age: 469158
Cache-Control: max-age=604800
Content-Type: text/html; charset=UTF-8
Date: Mon, 21 Oct 2024 13:03:13 GMT
Etag: "3147526947"
Expires: Mon, 28 Oct 2024 13:03:13 GMT
Last-Modified: Thu, 17 Oct 2019 07:18:26 GMT
Server: ECAcc (lac/55C3)
Vary: Accept-Encoding
X-Cache: HIT
Content-Length: 1256
Connection: close
<!doctype html>
<html>
<head>
...
</head>
<body>
<div>
<h1>Example Domain</h1>
<p>This domain is for use in illustrative examples in documents. You may use this
domain in literature without prior coordination or asking for permission.</p>
<p><a href="https://www.iana.org/domains/example">More information...</a></p>
</div>
</body>
</html>
また、サーバとして実行することもできます。
# nc --listen 0.0.0.0 8080
この状態で 8080 ポートにブラウザアクセスすると接続があった旨が表示されるので、以下を入力します。
HTTP/1.0 200 OK
<html>
<body>
<h1>Hello, world!</h1>
</body>
</html>
最後は改行を入れてください。ブラウザに「Hello, world!」と表示されます。
クローズは ^D
です。
161/udp への接続
nc
を用いて 161/udp の疎通確認ができます。これは非常に有用だと思います。
$ echo | nc -u -v 127.0.0.1 161
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 127.0.0.1:161.
Ncat: 1 bytes sent, 0 bytes received in 0.02 seconds.
snmpd が停止していたりする (ポートが開いていない) と、「Connection Refused」となります。
$ systemctl stop snmpd
$ echo | nc -u -v 127.0.0.1 161
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 127.0.0.1:161.
Ncat: Connection refused.
snmpget のリクエストをシミュレート
結論から言うとうまくいきませんでした。以下のような結果となりました。
$ cat ./byte.bin | nc -u -v 127.0.0.1 161
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 127.0.0.1:161.
Ncat: 43 bytes sent, 0 bytes received in 0.14 seconds.
「0 bytes received」となってしまい、応答が返ってきませんでした。
試したこと1
tcpdump
コマンドによって pcap ファイルを作成
$ tcpdump -i lo udp port 161 -w snmp_request.pcap
$ snmpget -v 2c -c public 127.0.0.1 1.3.6.1.2.1.1.1.0
取得したパケットキャプチャファイルを Wireshark で開き、 「Export Packet Bytes...」でファイルに出力。
cat で標準出力に渡す形で実行。
$ cat ./byte.bin | nc -u -v 127.0.0.1 161
試したこと2
「copy as C String」という形で Wireshark から C言語形式でデータを取得。 ncat
コマンドに流し込み。
$ printf "0)\x02\x01\x0x04\x06public\xa0\x1c\x02\x04$h\x95\xf8\x02\x01\x00\x02\x01\x000\x\x06\x01\x02\x01\x01\x01\x00\x05\x00" | nc -u -v 127.0.0.1 161
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 127.0.0.1:161.
Ncat: 43 bytes sent, 0 bytes received in 0.01 seconds.
試したこと3
「試したこと2」で取得したバイナリデータを c 言語で出力するようにし、その出力を ncat
に流し込み。
$ gcc -std=c99 -o out out.c; ./out | nc -v -u 127.0.0.1 161
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 127.0.0.1:161.
Ncat: 37 bytes sent, 0 bytes received in 0.07 seconds.
#include <stdio.h>
int main() {
// Define the raw SNMP packet as a byte array
unsigned char snmp_packet[] = {
0x30, 0x02, 0x01, 0x00, 0x04, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63,
0xa0, 0x1c, 0x02, 0x04, 0x24, 0x68, 0x95, 0xf8, 0x02, 0x01, 0x00, 0x02,
0x01, 0x00, 0x30, 0x0a, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00, 0x05, 0x00
};
int length = sizeof(snmp_packet) / sizeof(snmp_packet[0]);
// Write the binary data to standard output
fwrite(snmp_packet, sizeof(unsigned char), length, stdout);
return 0;
}