什么是SSH?

SSH 为 Secure Shell 的缩写,由 IETF 的网络工作小组(Network Working Group)所制定;SSH 为建立在应用层和传输层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。S S H最初是U N I X系统上的一个程序,后来又迅速扩展到其他操作平台。S S H在正确使用时可弥补网络中的漏洞。S S H客户端适用于多种平台。几乎所有U N I X平台—包括H P - U X、L i n u x、A I X、S o l a r i s、Digital UNIX、I r i x,以及其他平台—都可运行S S H。

为什么要引入SSH?

一言以蔽之,就是因为网络的不安全性,传统的网络通信方式,如telnet,rlogin,FTP,http 都是以明文方式传送用户名和密码进行身份验证的,这是十分危险的。在共享网络环境下,只要用一些嗅探工具(如大名顶顶的sniffer portable 和wireshark)就很容易捕获到登录者的用户名和密码,进而控制远程的主机,而合法用户却毫无察觉。有人会说之所以能够捕获到用户名和密码,是因为共享式(典型的代表就是集线器)网络工作原理带来的不安全性(集线器的工作原理就是机械的将收到的数据包向每一哥集线器端口发送),才使得嗅探工具有用武之地,如果使用交换式网络(交换式网络工作原理是以目的MAC地址进行转发,而不是进行泛洪发送到每一个端口),就能够避免明文密码被嗅探到。其实对于交换网络也是可以进行密码嗅探的,只不过手段要稍显复杂一点,我们知道每一个交换机都有一张MAC地址表,记录着相应端口和MAC地址的对应,交换机就是依据这个MAC地址表将数据包发送到正确的端口对应的机器。交换机的MAC地址表是交换机动态学习得到的,而且容量是一定的,当MAC地址表容量满了,就是溢出了,对于新收到的数据包就无法进行动态学习并加入到MAC地址表中。这是因为这样,给了攻击者可乘之机,MacFlooding就是利用这个原理进行攻击,攻击者持续不断发送大量源地址伪造的数据包,交换机傻傻的不断学习(心学习道德会替换旧的数据),不一会MAC地址表就被假的数据撑爆了,当合法的数据包发送至交换机时候,交换机是无法进行学习并从MAC地址表中找到相应正确端口,这时交换机就启用共享工作模式,变成了一个集线器,向每一个端口发送收到的数据包,于是嗅探工具又可以工作了。当然这只是针对交换式网络攻击的一种,还有如MAC地址欺骗攻击(就是声称自己的MAC地址就是被攻击主机,数据包便会发送至攻击者啦,sniffer就乐了,哈哈又来啦)、ARP欺骗攻击(这样说吧,有A B C三台主机,C是攻击者,C向A发送ARP应答,说B的ip对应的MAC地址是我的MAC地址,然后C再向B发送ARP应答,说A的IP地址对应的MAC地址是我的MAC地址,这样A B都被C骗了,修改了自己的ARP表,将数据发送给了C,C充当了A B 中间传递着,这种攻击也可称作中间人攻击,值得注意的是这种存在缺陷就是ARP不能跨网段),由此我们知道交换式网络也是不安全的,虽然我们还是可以做点什么以加强交换网络的安全性,如端口安全(事先将合法MAC地址与相应端口绑定,这样MacFloding ,MAC地址欺骗就不太管用啦)、arp静态绑定(抵制arp欺骗攻击)。但是让明文数据在网络上传播终究让人不太放心,于是就有必要引入SSH啦,SSH会加密传输的数据,通过使用SSH,你可以把所有传输的数据进行加密,这样"中间人"这种攻击方式就不可能实现了,而且也能够防止DNS欺骗和IP欺骗。使用SSH,还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。SSH有很多功能,它既可以代替Telnet,又可以为FTP、PoP、甚至为PPP提供一个安全的"通道"。

SSH协议的主要构成

SSH 主要有三部分组成: 传输层协议 [SSH-TRANS]
提供了服务器认证,保密性及完整性。此外它有时还提供压缩功能。 SSH-TRANS 通常运行在 TCP/IP连接上,也可能用于其它可靠数据流上。 SSH-TRANS 提供了强力的加密技术、密码主机认证及完整性保护。该协议中的认证基于主机,并且该协议不执行用户认证。更高层的用户认证协议可以设计为在此协议之上。
用户认证协议 [SSH-USERAUTH]
用于向服务器提供客户端用户鉴别功能。它运行在传输层协议 SSH-TRANS 上面。当SSH-USERAUTH 开始后,它从低层协议那里接收会话标识符(从第一次密钥交换中的交换哈希H )。会话标识符唯一标识此会话并且适用于标记以证明私钥的所有权。 SSH-USERAUTH 也需要知道低层协议是否提供保密性保护。
连接协议 [SSH-CONNECT]
将多个加密隧道分成逻辑通道。它运行在用户认证协议上。它提供了交互式登录话路、远程命令执行、转发 TCP/IP 连接和转发 X11 连接。


SSH的结构

SSH是由客户端和服务端的软件组成的,有两个不兼容的版本分别是:1.x和2.x。 用SSH 2.x的客户程序是不能连接到SSH 1.x的服务程序上去的。OpenSSH 2.x同时支持SSH 1.x和2.x。
服务端是一个守护进程(demon),他在后台运行并响应来自客户端的连接请求。服务端一般是sshd进程,提供了对远程连接的处理,一般包括公共密钥认证、密钥交换、对称密钥加密和非安全连接。
客户端包含ssh程序以及像scp(远程拷贝)、slogin(远程登陆)、sftp(安全文件传输)等其他的应用程序。
他们的工作机制大致是本地的客户端发送一个连接请求到远程的服务端,服务端检查申请的包和IP地址再发送密钥给SSH的客户端,本地再将密钥发回给服务端,自此连接建立。SSH 1.x和SSH 2.x在连接协议上有一些差异。
一旦建立一个安全传输层连接,客户机就发送一个服务请求。当用户认证完成之后,会发送第二个服务请求。这样就允许新定义的协议可以与上述协议共存。连接协议提供了用途广泛的各种通道,有标准的方法用于建立安全交互式会话外壳和转发(“隧道技术”)专有 TCP/IP 端口和 X11 连接。
SSH被设计成为工作于自己的基础之上而不利用超级服务器(inetd),虽然可以通过inetd上的tcpd来运行SSH进程,但是这完全没有必要。启动SSH服务器后,sshd运行起来并在默认的22端口进行监听(你可以用 # ps -waux | grep sshd 来查看sshd是否已经被正确的运行了)如果不是通过inetd启动的SSH,那么SSH就将一直等待连接请求。当请求到来的时候SSH守护进程会产生一个子进程,该子进程进行这次的连接处理。


SSH两个主要版本特点与区别


上面已经提到,SSH协议主要存在两个版本SSH1和SSH2,而且这两个版本是不兼容的,这就是说,使用SSH1协议的客户端是不能登录SSH2协议的服务器。

SSH1又分为1.3和1.5两个版本。SSH1采用DES、3DES、Blowfish和RC4等对称加密算法保护数据安全传输,而对称加密算法的密钥是通过非对称加密算法(RSA)来完成交换的。SSH1使用循环冗余校验码(CRC)来保证数据的完整性,但是后来发现这种方法有缺陷。

SSH2避免了RSA的专利问题,并修补了CRC的缺陷。SSH2用数字签名算法(DSA)和Diffie-Hellman(DH)算法代替RSA来完成对称密钥的交换,用消息证实代码(HMAC)来代替CRC。同时SSH2增加了AES和Twofish等对称加密算法。


SSH两种认证方式的特点

从客户端来看,SSH提供两种级别的安全验证。

第一种级别(基于口令的安全验证)
只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密, 但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器, 也就是受到“中间人”这种方式的攻击。

  例子: 如何以中间人攻击的方式攻击SSH1

简单地说,SSH1的通信过程是这样的:

                服务器                             客户

握手阶段
                                 SYN
                      <---------------------------
                              SYN ACK
                      --------------------------->
                                 ACK
                      <---------------------------

协议协商阶段
                              版本信息
                      --------------------------->
                              版本信息
                      <---------------------------
交换密钥阶段
                           明码传输的服务器公钥
                      --------------------------->
                          服务器公钥加密的会话密钥
                      <---------------------------
认证阶段
                               确认信息
                      <---------------------------
                          会话密钥加密的用户名
                      <---------------------------
                               应答信息
                      --------------------------->
                          会话密钥加密的口令信息
                      <---------------------------
                               应答信息
                      --------------------------->
数据通信阶段
                      ............................

这个过程中,由于监听者处于中间人的地位,它可以在交换密钥的阶段从截获的数据流中取出服务器的公钥,保存起来,然后用自己生成的一对密钥中的公钥替换数据包中的公钥,发送给客户。这样,当客户生成会话密钥的时候就会用我们的公钥加密。当我们收到客户发送的会话密钥的时候,可以用我们所掌握的私钥解密,得到会话密钥,然后再用保存下来的服务器公钥加密,发送给服务器。此时,服务器、客户和监听者都有了同一个会话密钥,以后的通信对于监听者来说就如同明文了。


第二种级别(基于密匙的安全验证)
需要依靠密匙,也就是你必须为自己创建一对密匙,并把公用密匙放在需要访问的服务器上。 如果你要连接到SSH服务器上,客户端软件就会向服务器发出请求,请求用你的密匙进行安全验证。服务器收到请求之后, 先在该服务器上你的主目录下寻找你的公用密匙,然后把它和你发送过来的公用密匙进行比较。如果两个密匙一致, 服务器就用公用密匙加密“质询”(challenge)并把它发送给客户端软件。 客户端软件收到“质询”之后就可以用你的私人密匙解密再把它发送给服务器。
用这种方式,你必须知道自己密匙的口令。但是,与第一种级别相比,第二种级别不需要在网络上传送口令。
第二种级别不仅加密所有传送的数据,而且“中间人”这种攻击方式也是不可能的(因为他没有你的私人密匙)。 但是整个登录的过程可能需要10秒。


SSH另类应用:用ssh做socks5代理

1. 下载MyEntunnel
2.下载PuTTY,解压到MyEntunnel程序的目录下。
3.运行MyEntunnel.exe,设置:SSH Server里头填上ssh ftp的地址或IP,填好用户名和密码,点Connect,系统栏里面的小锁变成绿色就连接成功了。
4.设置浏览器。IE是不支持socks代理的,用firefox好了,打开firefox的代理设置页,在socks主机处填上127.0.0.1端口填原先设置的,默认7070。


SSH相关实验。

一、抓包观察ssh协议流程:

由上图可知ssh协议主要经历握手->协商->密钥交换->加密数据传输这么几个阶段

 

二、ssh公钥验证登录实验

使用ssh公钥验证登陆不仅可以省去每一登录时输入密码的烦扰,而且更为安全,下面就开始实验吧:

1、使用putty产生密钥对并进行登录

使用puttygen制作密钥
启动puttygen工具,为兼容OpenSSH密钥,选择“SSH2 RSA”

 

单击 Generate 按钮,并使用鼠标在“key”框内移动,以获得足够的随机数据供生成密钥使用:

 

期间,你会看到进度条上面有个提示“Please generate some radomness by moving the mouse over the blank area.”,意思就是让你用鼠标在空白区域随机移动。随着鼠标在空白区域的移动,进度条会一直走下去。停止移动鼠标,进度条也就停止了。所以,那我们要移动鼠标,直到进度条走满为止。
完成后的窗口如下:

其中:

Key comment:是注释,不会影响密钥的有效性,但可作为自己用于区别其他密钥的参考;
Key passphrase 和 Confirm passphrase :用于保护私钥,如果不输入该信息,那么任何人只要拿到该私钥,即可无密码登陆系统,非常危险;通常情况下,我是建议大家输入的,但这里为了方便说明,暂时留空.

随后,点击“Save private key”保留私钥。
如果没有输入Key passphrase信息,会有警告,这里点击yes保存私钥

输入私钥的文件名:

公钥信息可以不用保留在本地的,puttygen可以从私钥得到它,验证时也不会用到。

修改openssh配置
修改/etc/ssh/sshd_config:

ChallengeResponseAuthentication no  #关闭挑战应答方式
UsePAM no  #不使用PAM认证

PubkeyAuthentication yes
AuthorizedKeysFile      %h/.ssh/authorized_keys

 

然后重启sshd服务

拷贝公钥信息
上面密钥信息窗口的“Key”框最后生成的就是公钥信息(最好直接复制框中的公钥信息然后粘贴到目标的authroized_keys文件中,因为这样不会导致refuse key等错误信息):

需要把该信息拷贝到Linux服务器的特定文件中:~/.ssh/authroized_keys
其中,“~”表示对应用户的主目录,以root为例。
若.ssh目录不存在,请创建它,并把公钥信息写入文件中:

# mkdir ~/.ssh
# chmod 700 ~/.ssh
# vi ~/.ssh/authorized_keys
# chmod 644 ~/.ssh/authorized_keys

请务必留意:文件和目录的权限问题,用户必须是将要进行认证的用户,而权限必须是0644,也就是禁止其他人对该文件写入信息。(否则,某些有心人把自己的公钥写入这里,他也可以无密码进来了)
因为,通常umask是0022或0002的,所以请使用chown和chmod修改为对应的权限咯。

 

使用putty使用密钥登陆
对putty进行一些简单配置,即可使用密钥登陆Linux服务器。

打开putty 输入目标ssh 服务器的ip地址,并选择端口号:


选择Connection-SSH-Auth,在“Private key file for authentication”输入密钥的路径:

然后在Connection->data ->Auth-login username”(不同版本的putty会有所不同)输入登陆的用户名,例如root:

然后点击Open即可:

2、linux作为客户端产生密钥对并进行登录

打开终端输入以下命令

ssh-genkey -t rsa

-t表示公钥算法为rsa

# ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):  <-密钥路径
Enter passphrase (empty for no passphrase): <-密钥保护密码
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa. <-私钥
Your public key has been saved in /root/.ssh/id_rsa.pub. <-公钥

将产生的密钥传输到远程ssh server

root@bt #scp /root/.ssh/id_rsa.pub root@192.168.88.29:/root/.ssh/authorized_keys

公钥无密码登录

root@bt #ssh 192.168.88.29

ok

 

PS:

由于SSH的标准中,并没有固定密钥文件的格式。而Putty使用的私钥格式和OpenSSH生成的有点不同,使用时需要转换一下。
a)把id_rsa传到Windows机器上
b)使用puttygen的“Load”读取id_rsa文件

这里也可以从图中的公钥信息,与id_rsa.pub对比一下,应该是一致的。
c)点击“Save private key”保留私钥。
d)putty使用该新的私钥登陆服务器即可。


三、ftp telnet http 明文传输验证实验


FTP 明文传输验证实验

实验环境:

BT5充当FTP登录客户端并进行抓包,win7充当ftp服务器

抓包工具wireshark

实验过程如下:

打开wireshark,依次执行capture->options->Filter

在Filter右边的输入框中输入捕获过滤表达式(详见 《简明使用wireshark教程》一文),这里为简单期间,输入TCP即可,点击start进行捕获:

 

 

停止捕获,在Filter右边的输入框中输入显示过滤表达式(详见 《简明使用wireshark教程》一文)FTP,点击apply,捕获结果如下:

 

 

由上图可见ftp明文密码被轻松捕获到,用户名为ajian密码为123

 

 

telnet明文传输验证实验:

实验环境大体与上面ftp一样,只不过有ftp server 换成了telnet server

开始实验:

打开wireshark,依次执行capture->options->Filter

在Filter右边的输入框中输入捕获过滤表达式(详见 《简明使用wireshark教程》一文),这里为简单期间,输入TCP port 23即可,点击start进行捕获:

 

停止捕获,在Filter右边的输入框中输入显示过滤表达式(详见 《简明使用wireshark教程》一文)telnet,点击apply,捕获结果如下:

 

选择第一个条目,右键选择 Follow Tcp Stream :

 

由上图清晰可见用户名和密码

 

Http明文传输验证实验:

实验环境:

BT5进行http server 登录并抓包,GNS3+cisco3725模拟要求验证的http server

抓包工具dsniffer (该工具据说善于抓取敏感数据包,拭目以待啦)

开始监听:

dsniffer -i eth1

 

由上图可见 cisco路由器的名字叫R1 enable密码是123