nc(netcat) 被譽為網絡安全界的‘瑞士軍刀’,可以用於完成幾乎涉及TCP、UDP或者Unix域套接字的任何事。它可以打開TCP連接,發送UDP報文,在任意的TCP和UDP端口監聽,進行端口掃描,支持ipv6。不象telnet,nc能夠更好地支持腳本,能夠將錯誤消息分離到標准錯誤,而不是標准輸出。nc有四種典型應用:
一、C/S模型
用nc能夠非常簡單地建立一個基本的C/S模型。
打開控制台,在某個端口上啟動nc監聽,等待連接。例如,nc在端口1234上啟動監聽,等待連接:
$ nc -l 1234
在另外一個控制台上(或另外一台機器上),連接該機器上監聽的端口
$ nc 127.0.0.1 1234
現在,端口之間的連接就建立了。連接建立之后,nc並不區分誰是server,誰是client。在任何一端的輸入都會發送到另一端。通過發送EOF(^D’)中斷連接。
Linux中的nc沒有-c或-e選項(可能是安全因素),但是,你仍然能夠通過重定向文件描述符在建立連接之后執行命令。注意,打開一個端口,讓任何人連接並在你的機器上執行任意命令是危險的。如果你需要這樣做,下面有個例子:
在server端:
$ rm -f /tmp/f; mkfifo /tmp/f
$ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
在client端:
$ nc host.example.com 1234
$ (shell prompt from host.example.com)
通過創建一個FIFO文件/tmp/f,讓nc在server端127.0.0.1的端口1234上監聽,當一個client成功連接之后,/bin/sh在服務端執行,但執行反饋傳送給client端。
當連接中斷后,nc也退出。如果要保持連接,使用-k選項,但是如果命令退出,這個選項也不會重啟它或保持nc運行。如果不再需要,不要忘記刪除該文件描述符。
$ rm -f /tmp/f
二、數據傳輸
上面的例子可以擴展來建立一個基本的數據傳輸模型。在連接的一端輸入的任何信息將輸出到另一端,輸入和輸出能夠很容易被捕捉來模擬文件傳輸。
nc在一個端口上啟動監聽,並將輸出重定向到一個文件中:
$ nc -l 1234 > filename.out
在另一台機器上,連接nc運行的機器和監聽端口,將要傳輸的文件作為輸入:
$ nc host.example.com 1234 < filename.in
當文件傳輸完畢后,連接自動關閉。
三、和服務器通訊
在解決故障和調試中,有時候手動和服務器通信很有用,而不是通過一個用戶界面。比如,當需要驗證一個服務器對於client發送的命令有什么響應時。例如,獲得一個Web站點的主頁:
$ printf "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80
注意,上述命令也會顯示Web服務器發送的頁面頭部。可以根據需要用sed等工具過濾返回的信息。
可以建立更復雜的例子,當用戶知道服務器端要求的請求格式。例如,一封email可以提交給SMTP郵件發送服務器:
$ nc [-C] localhost 25 << EOF
HELO host.example.com
MAIL FROM:<user@host.example.com>
RCPT TO:<user2@host.example.com>
DATA
Body of email.
.
QUIT
EOF
四、端口掃描
有時候需要知道目標機器上哪些端口開放和運行了那些服務。nc可以利用-z標志來獲取開放的端口。通常和-v標志一起用來向標准錯誤輸出詳細信息。例如:
$ nc -zv host.example.com 20-30
Connection to host.example.com 22 port [tcp/ssh] succeeded!
Connection to host.example.com 25 port [tcp/smtp] succeeded!
指定搜索的端口范圍為20-30,並且按升序進行掃描。你也可以指定一個端口列表來掃描, 端口按給定的順序進行掃描。例如:
$ nc -zv host.example.com 80 20 22
nc: connect to host.example.com 80 (tcp) failed: Connection refused
nc: connect to host.example.com 20 (tcp) failed: Connection refused
Connection to host.example.com port [tcp/ssh] succeeded!
有時候需要了解哪些服務軟件以及什么版本正在運行。這些信息通常包含在問候標語(greeting banner)中。為了取得這些信息,首先需要建立一個連接,然后當問候標語獲得之后再斷開連接。這能夠通過用-w標志指定一個短暫的超時時間來實現,或者也許能通過發送一個“QUIT”命令給服務器。
$ echo "QUIT" | nc host.example.com 20-30
SSH-1.99-OpenSSH_3.6.1p2
Protocol mismatch.
220 host.example.com IMS SMTP Receiver Version 0.84 Ready
五、例子
1、建立到主機host.example.com端口42的TCP連接,本地源端口為31337,超時時間為5秒
$ nc -p 31337 -w 5 host.example.com 42
2、建立到主機host.example.com端口53的UDP連接
$ nc -u host.example.com 53
3、建立到主機host.example.com端口42的TCP連接,本地源IP地址為10.1.2.3
$ nc -s 10.1.2.3 host.example.com 42
4、建立和監聽一個UNIX域的流套接字
$ nc -lU /var/tmp/dsocket
5、通過HTPP代理10.2.3.4的8080端口連接主機host.example.com的42號端口。這個例子也可以被ssh用到,查詢ssh_config的ProxyCommand命令獲取更多信息
$ nc -x10.2.3.4:8080 -Xconnect host.example.com 42
6、同樣的例子,該例子使能了代理認證,如果代理需要,使用了用戶名'ruser'
$ nc -x10.2.3.4:8080 -Xconnect -Pruser host.example.com 42
六、遠程監控案例
案例說明:
1、服務器IP地址:23.65.55.252,服務器上運行了一個服務,該服務會將訪問該服務器http服務(80端口)的用戶IP寫到一個文本文件中,文件名為http_rec.txt
2、用戶想看每天有哪些IP地址訪問,需要用ssh登陸到服務器上,查看文件http_rec.txt增加了哪些IP,比較麻煩
3、需求:用戶在客戶端能夠實時監控遠程服務器上文件http_rec.txt的改變
實現步驟:
1、服務器端
$tail -f http_rec.txt | nc 23.65.55.251 5901
2、客戶端在5901端口啟動監聽,一旦有新的IP地址訪問服務器,會顯示在客戶端終端上
$nc -l 23.65.55.251 5901 //23.65.55.251為本機IP地址,不能寫localhost
也可以將監控內容寫入客戶端某個文件
$nc -l 23.65.55.251 5901 > ~/tmp/http_rec.txt &
搞定。