最近看一些开源蜜罐的源码,其中涉及到网络协议相关的蜜罐需要对协议进行模拟。就有这篇对SSH、Telnet、FTP、TFTP、Mysql、Redis协议抓包分析的记录。需要和另一篇蜜罐文章《从Hfish看蜜罐开发思路》搭配着看,是对开发涉及的协议的一些补充。
SSH协议
Secure Shell Protocol,维基百科的定义是用于在不安全的网络上安全地进行网络服务。简单一点其实就是提供了一个加密的通道,用于客户端和服务器之间通信。
SSH创建的起因是早年间,攻击者可以通过密码嗅探攻击(password sniffing attack)在网络上获取用户的明文密码。例如,在用户的设备上运行嗅探工具(如Wireshark、tcpdump、dsniff等),捕获网络流量,对特定协议的数据包(如Telnet、HTTP、FTP等)过滤出包含用户名密码的数据包。Ps:HTTP、FTP这些后来也发展成了加密协议SFTP、HTTPS。然后芬兰科学家Tatu Ylönen就设计了SSH对网络上的数据进行加密传输。初始版本SSH-1,后来发现也存在点问题就发展出了SSH-2
SSH使用非对称加密技术,通信的两端使用公钥-私钥来加密网络连接,使用密码验证用户身份。拥有公钥的人可以加密消息,拥有私钥的人可以解密消息。比如在Linux系统中,SSH可以用于登录远程主机。主要有两种方式:1. 用户名+密码 2. 免密登录(公私钥)
解释一下公私钥的登录方式。用户在本地现生成一对密钥(公钥+私钥)。将公钥内容添加到文件/.ssh/authorized_keys
中。SSH登录时服务器检查该文件中是否存在对应的公钥,如果匹配到了就生成一个随机数并用公钥加密。客户端收到这个加密的挑战后使用私钥解密,并将解密后的内容返回服务器。服务器检查解密内容正确就通过了认证。
SSH是运行在TCP协议上的。TCP负责连接和传输。SSH负责加密和认证,默认SSH使用TCP的22端口。
a. 建立TCP连接:
用户的SSH客户端通过TCP向服务器的22号端口发送SYN包,开始三次握手过程。确认双方做好通信准备
b. SSH认证:
建立TCP连接后,SSH客户端和服务器之间开始SSH协议的握手过程,包括版本交换、密钥交换和用户认证。
c. 加密通信:
认证成功后,SSH客户端和服务器之间建立一个加密的通信通道来传输数据
Telnet
Telnet(teletype network)提供对远程主机上的命令行界面的访问。但上面提到因为不安全,已经被SSH代替。所以现在系统上默认不装Telnet。先在远程服务器上安装telnet-server。
sudo yum install telnet-server xinetd
sudo vi /etc/xinetd.d/telnet
sudo systemctl start xinetd
telnet添加内容
service telnet
{
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/sbin/in.telnetd
log_on_failure += USERID
disable = no
}
然后在本机Mac上安装Telnet,https://www.cnblogs.com/rxbook/p/17310156.html。本机用telnet命令尝试连接远程服务器进行测试,效果如下。的确可以在wireshark抓包的流量中看到我尝试输入的明文
整个telnet协议同样是先进行TCP三次握手,然后客户端向服务器发送了这个如下的包
客户端和服务器在三次握手建立连接后,会进行一系列的选项协商。通常以“Will”、“Do”、“Wont”、“Dont”作为前缀,表示请求、允许、拒绝等操作。
协商过程使用了特定的控制字符。首先是0xFF
(十进制255)表示IAC (Interpret as Command):表示接下来的字节是一个命令而不是数据。而命令通常以“Will”(0xFB
,251)、“Do”(0xDO
,253)、“Wont”(0xFC
,252)、“Dont”(0xFE
, 254)作为前缀,表示请求、允许、拒绝等操作。WILL和WONT都是发送方愿意和拒绝做的事。DO和DONT是发送方希望对方做的事。0x18
(十进制24),在 Telnet 协议中对应 TERMINAL-TYPE 选项,即终端类型。那么0xFF 0xFB 0x18
就代表发送方愿意报告其终端类型。经过几步协商,发送方发送自己的终端类型XTERM-256COLOR
(表示支持 256 色的 xterm 终端仿真)。然后进入到登录提示和密码交互阶段,认证成功后进入终端交互。
这也是Telnet协议的意义,能实施会话管理(用户名、密码、登录提示等)、命令执行、终端仿真等功能。
FTP
FTP(File Transfer Protocol)文件传输协议是在计算机网络的客户端和服务器间传输文件的应用层协议。传送文件(file transfer)和访问文件(file access)之间的区别在于:前者由FTP提供,后者由NFS等应用系统提供
同样搭环境抓个包看看。在Linux服务器上搭建ftp服务器。环境搭建:https://www.alibabacloud.com/help/zh/ecs/use-cases/manually-build-an-ftp-site-on-a-centos-7-instance#a3a93120065zt
如果要测试ls
,get
等命令,需要在ftp命令行输入passive
开启被动模式。简单来说,主动适用于无防火墙或 NAT 的网络环境,被动则相反。因为主动模式是服务器主动连接客户端的数据端口(一般是20,但客户端往往有防火墙等,可能连接失败)。被动模式是客户端主动连接服务器的指定数据端口。
主动模式
控制连接:
客户端从任意非特权端口(N>1023)连接到服务器的 FTP 命令端口(默认是端口 21)。
客户端发送 PORT 命令,告知服务器客户端的 IP 地址和监听数据连接的端口号(N+1)。
数据连接:
服务器从它的 FTP 数据端口(默认是端口 20)连接到客户端之前通过 PORT 命令指定的端口(N+1)。
数据传输通过这个连接进行。
被动模式
控制连接:
客户端从任意非特权端口(N>1023)连接到服务器的 FTP 命令端口(默认是端口 21)。
客户端发送 PASV 命令,要求服务器准备接收数据连接。
数据连接:
服务器打开一个任意非特权端口(P>1023),并通过响应 PASV 命令告诉客户端该端口号。
客户端从它的任意非特权端口(N+1)连接到服务器的指定端口(P)。
本机尝试连接远程ftp服务器,并开启被动模式,过程如下
对应的抓包内容如下。同样是三次握手,然后以明文传输
TFTP
TFTP(Trivial File Transfer Protocol),基于UDP的69端口。TFTP和FTP的对比如下
安装sudo yum install tftp-server
TFTP服务器,编辑文件/etc/xinetd.d/tftp
,将 disable 选项改为 no
Mysql
在远程mysql服务器上执行如下命令,允许远程主机访问此mysql服务。
mysql> CREATE USER 'root'@'%' IDENTIFIED BY 'PASSWORD';
mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;
另外,wireshark查看mysql协议流量,需要先在Preferences中勾选"show SQL Query string in INFO column"
mysql抓取流量的时候需要注意,加上--ssl-mode=DISABLED
,否则登录mysql后的流量都是TLS协议的加密流量。
mysql -h ip -P 3306 -u root -p --ssl-mode=DISABLED
TCP三次握手之后,服务器向客户端发送Greeting,包含mysql服务器的版本,分配的线程ID等信息。
然后客户端输入用户名密码,及客户端具有的能力信息发送给服务端。服务端认证成功返回一个OK。然后就可以开始执行sql请求。图中的Request Query
执行的是show tables
操作,每个Request Show Fields
都回显了一个table。
Redis
Redis作为内存数据库,是攻击中常见的一个突破点。环境安装很简单
yum -y install redis
sudo systemctl start redis
如果要远程服务需要修改vi /etc/redis.conf
,将bind 127.0.0.1
改为bind 0.0.0.0
。如果要设置密码,可以修改这行#requirepass xxx
客户端访问Redis服务器
redis-cli -h ip -p 6379 -a "密码"
但是这样抓到的报文都是TCP的,可以用wireshark的Redis插件来查看具体的内容。高版本wireshark是默认开启了对lua的支持,所以只需要找到/Applications/Wireshark.app/Contents/Resources/share/wireshark/init.lua
在其中加入一行引入文件
dofile("./redis-wireshark.lua")
然后在init.lua
的同目录下放入redis的lua插件。下载地址:https://github.com/jzwinck/redis-wireshark
然后wireshark中按ctrl+shift+L
就可以加载lua了。
可以从图中看到,先是TCP三次握手,然后客户端向服务器发送Redis的认证密码
客户端向服务器发送INFO SERVER,服务器返回如下内容。