SSH协议解析及wireshark抓包分析

ssh中文名称叫安全外壳协议,是一种加密的网络传输协议。SSH 在 TCP 和 UDP 中都被分配了端口 22。 但是,由于需要可靠的通信、正确的数据包排序等,该协议主要在 TCP 上运行。

为什么需要SSH?

SSH 和 telnet 之间的主要区别在于 SSH 提供完全加密和经过身份验证的会话。而telnet缺少安全的认证方式,而且传输过程采用TCP进行明文传输,存在很大的安全隐患。单纯提供telnet服务容易招致DoS、主机IP地址欺骗、路由欺骗等。所以在远程登陆上SSH替代telnet,提供更安全可靠的服务。

如何实现数据的安全呢?

我们肯定会想,对于数据,我使用加密就行啦,没错。对于加密机制,主要有两种:

对称密钥加密
非对称密钥加密

广义地说,根据使用的密钥,如果加密与解密使用相同的密钥,则称为对称密钥加密,如果加密与解密使用不同的密钥我们称为非对称密钥加密。

对于对称密钥加密和非对称密钥加密。实际应用过程中会面临一个问题:我们如何确保安全的保存密钥呢?或者说Client端如何保证接受到的公钥就是目标Server端的?下面我们接着讲。

Client端如何保证接受到的公钥就是目标Server端的?
《SSH协议解析及wireshark抓包分析》图片来源网上,如果一个攻击者中途拦截Client的登录请求,向其发送自己的公钥。而中间人用自己的假公钥替换掉server的真公钥,这就窃取了Client的登录信息了。这就是中间人攻击。

认证:私钥加密公钥解密;

主要用于身份验证,判断某个身份的真实性。使用私钥加密之后,用对应的公钥解密从而验证身份真实性。

A要验证B是否是真实用户

1、B将自己公钥给A
2、B将文件用自己私钥加密传送给A
3、A根据B的公钥解密,如果成功则为真实身份用户

识别数据发送者和接收者身份客户端验证SSH服务端的身份:防止攻击者仿冒SSH服务端身份,避免中间人攻击和重定向请求的攻击。

OpenSSH 通过在 know-hosts 中存储主机名和 host key 对服务端身份进行认证。

《SSH协议解析及wireshark抓包分析》

authorized_keys:保存已授权的客户端公钥
id_rsa:保存私钥
id_rsa.pub:保存公钥
known_hosts:保存已认证的远程主机ID

聊一聊SSH的基本框架

SSH协议框架中最主要的部分是三个协议:

  • 传输层协议:提供服务器认证,数据机密性,信息完整性等的支持;
  • 用户认证协议: 则为服务器提供客户端的身份鉴别;有两种方式,方式一:口令(密码);方式二:证书(公钥)。建立在传输层协议(SSH-TRANS)基础之上。
  • 连接协议:连接协议将加密的信息隧道复用成若干个逻辑通道,提供给更高层的应用协议使用。它建立在用户认证协议之上。

下面我们先通过wireshire抓包分析SSH协议。

wireshire抓包分析SSH协议

分析SSH协议上述三个流程,先上个图来瞅一瞅。

《SSH协议解析及wireshark抓包分析》

TCP三次握手

所有基于TCP的通信都需要从两台主机的握手开始,这样=个握手过程主要希望达到的这样一些目的。

  • 保证传输主机可以确定目的主机在线并且进行通信。
  • 让传输主机确定目标主机在监听传输主机试图连接的端口。
  • 允许传输主机向目标主机发送它的起始序列号,使得两台主机可以将这一个会话保存得井然有序。

《SSH协议解析及wireshark抓包分析》
《SSH协议解析及wireshark抓包分析》

主动向通信的设备向目标发送一个TCP数据包,这个数据包的TCP头设置了SYN标志。主机B向这个数据包回复一个类似的SYN和ACK标志以及包含的它的初始序列号的数据包。

最后,主机A向主机B发送最后一个设置ACK标志的数据包,这样就具备所需要正常通信所需的信息。

这个过程属于传输阶段。

SSH版本协商

《SSH协议解析及wireshark抓包分析》
《SSH协议解析及wireshark抓包分析》

服务器将自己的SSH协议版本发送到客户端。客户端将自己的SSH协议版本发送到服务器,这些协议是以 ASCII 字符串表示。

如果一个只使用 SSH-1 的客户端连接到一个只使用 SSH-2 的服务器上,那么客户端就会断开连接并打印一条错误消息。

密钥交换

《SSH协议解析及wireshark抓包分析》《SSH协议解析及wireshark抓包分析》

密钥协商过程从客户端和服务器相互发出Key Exchange Init请求开始,主要是告诉对方自己支持的相关加密算法列表、MAC算法列表等。

《SSH协议解析及wireshark抓包分析》

客户端发送D-H公钥,服务端与客户端使用D-H算法生成会话密钥key。服务端回复,服务端与客户端使用D-H算法生成会话密码key

《SSH协议解析及wireshark抓包分析》

DH回复包:

  • 一个服务端的公钥,即证书,客户端会将该公钥与本地公钥对比,看是否是被信任的服务器,如过是第一次访问则会询问用户是否信任这样的公钥。
  • 服务端回复的D-H公钥
  • 签名

这个时候,服务端端还会回复一个new Key包 用于表明服务端可以使用会话密码key加密消息了。

《SSH协议解析及wireshark抓包分析》客户端要回复服务端的new key包

《SSH协议解析及wireshark抓包分析》
以表明双方构建了一个加密通道,可以使用会话密码key加密来传输信息了。

《SSH协议解析及wireshark抓包分析》
这个时候服务器就有了会话密码。接下来就是加密后的数据了,我们无法从中看出任何有用信息。

ssh协议的复杂度也是远超于此的,这里就讲到这里。我们写个代码识别一下SSH协议。

static int ssh_dissect_protocol(u_char *ssh_data,int offset,unsigned int *version,
bool *need_desegmentation,int PayloadLen)
{ 
    int    protolen = 0;

	int line1 = PayloadLen-1;
	int line2 = PayloadLen-2;

	if (ssh_data[line2] == 0x0d && ssh_data[line1] == 0x0a)
		protolen = PayloadLen - 2;
	else
		protolen = PayloadLen - 1;

    if (strstr((const char *)ssh_data, "SSH-")  == NULL){ 
		
		printf( "Encrypted packet (len=%d)\n", PayloadLen);
		offset += PayloadLen;
        return offset;
    }

	if (strstr((const char *)ssh_data, "SSH-2.") == 0) 
	{ 
		*version = SSH_VERSION_2;
	} 
	else if (strstr((const char *)ssh_data,"SSH-1.99-") == 0) 
	{ 
		*version = SSH_VERSION_2;
	} 
	else if (strstr((const char *)ssh_data, "SSH-1.") == 0) 
	{ 
		*version = SSH_VERSION_1;
	}

	g_version = *version;

	char *Proto = (char*)malloc(protolen);
	if (Proto == NULL)
	{ 
		printf("Failed to apply for memory\n");
		return -1;
	}
	
	memcpy(Proto, ssh_data + offset,protolen);
	Proto[protolen] = '\0';
    printf("Protocol (%s)\n",Proto);


    offset += protolen;
    return offset;
}


void dissect_ssh(u_char *ssh_data,int PayloadLen)
{ 
	int offset = 0;
	int i  = 0;
	unsigned int  version = 0;
	bool   need_desegmentation = false;

	
	if (PayloadLen <= 0)
		return;

	if (strstr((const char *)ssh_data, "SSH-") != NULL)
	{ 
		offset = ssh_dissect_protocol(ssh_data,
                    offset,&version, &need_desegmentation,PayloadLen);

	}
	else
	{ 
		printf("g_version: %d\n",g_version);
		
		
		 switch(g_version) 
		 { 

            case SSH_VERSION_UNKNOWN:
                printf("Encrypted packet (len=%d)\n", PayloadLen);
                break;

            case SSH_VERSION_1:
                
                break;

            case SSH_VERSION_2:
                
                break;
            }
		
	}
}

编译运行:
《SSH协议解析及wireshark抓包分析》

总结

我在使用SSH登录服务器的时候,即使被中途截获,密码也不会泄露。SSH实现的目的是实现安全远程登录以及其它安全网络服务。对SSH感兴趣的朋友结合SSH协议RFC文档研究。

欢迎关注微信公众号【程序猿编码】,需要SSH源码报文的添加本人微信号(17865354792)

参考密码学与网络安全

    原文作者:程序猿编码
    原文地址: https://blog.csdn.net/chen1415886044/article/details/118650286
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞