网盾网络安全培训学校,培养技术精英
全国免费咨询电话: 18696195380/18672920250

位置:首页 > 渗透测试

渗透&&探测 (之SSH密码暴破)

2021-07-29 15:16:59 来源: CSDN博主
简介渗透&&探测 (之SSH密码暴破)

什么是SSH?

  简单说,SSH是一种 网络协议,用于计算机之间的 加密登录

  如果一个用户从本地计算机,使用SSH协议 登录 另一台远程计算机,我们就可以认为,这种登录是 安全 的,即使 被中途截获,密码也 不会泄露

  最早的时候,互联网通信都是 明文通信,一旦被截获,内容就 暴露无疑。1995年,芬兰学者Tatu Ylonen设计了SSH协议,将登录信息 全部加密,成为互联网安全的一个 基本解决方案,迅速在全世界获得推广,目前已经成为Linux系统的 标准配置

  需要指出的是,SSH只是一种 协议,存在 多种实现,既有 商业实现,也有 开源实现。本文针对的实现是OpenSSH,它是 自由软件,应用非常广泛。

  此外,本文只讨论SSHLinux Shell中的用法。如果要在Windows系统中使用SSH,会用到另一种软件PuTTY,本文不做介绍。

SSH如何工作

  该协议在 客户端-服务器 模型中工作,这意味着连接是由连接到SSH服务器的SSH客户端建立的。

  SSH 客户端驱动连接设置过程并使用公钥加密来验证SSH服务器的身份。在设置阶段之后,SSH协议使用 强对称加密和散列算法 来确保 客户端 和 服务器 之间交换的数据的 隐私性 和 完整性

  下图显示了安全 shell 连接的简化设置流程。

 

最基本的用法

  SSH 主要用于 远程登录。假定你要以用户名user,登录远程主机host,只要一条简单命令就可以了。


 
  1.   $ ssh user@host
  2. 复制代码

  如果 本地用户名 与 远程用户名 一致,登录时可以 省略 用户名。


 
  1.   $ ssh host
  2. 复制代码

  SSH 的默认端口是22,也就是说,你的登录请求会送进远程主机的22端口。使用p参数,可以修改这个端口。


 
  1.   $ ssh -p 2222 user@host
  2. 复制代码

  上面这条命令表示,ssh直接连接远程主机的2222端口。

中间人攻击

  SSH 之所以能够 保证安全,原因在于它采用了 公钥加密

  整个过程是这样的:

  1. 远程主机收到用户的 登录请求,把 自己的公钥 发给用户。

  2. 用户使用这个公钥,将 登录密码加密后,发送给远程主机。

  3. 远程主机用自己的 私钥解密 登录密码,如果 密码正确,就 同意用户 登录。

  这个过程本身是 安全 的,但是实施的时候存在 一个风险

  如果有人 截获 了 登录请求,然后 冒充远程主机,将 伪造 的 公钥 发给用户,那么用户 很难辨别真伪

  因为不像https协议,SSH协议的 公钥 是没有证书中心(CA)公证的,也就是说,都是 自己签发 的。

  可以设想,如果 攻击者 插在 用户与远程主机 之间(比如在 公共的wifi区域),用 伪造的公钥,获取用户的 登录密码

  再用这个密码 登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的 中间人攻击Man-in-the-middle attack)。

  SSH 协议是如何应对的呢?

口令登录

  如果你是 第一次 登录对方主机,系统会出现下面的提示:


 
  1.   $ ssh user@host
  2.  
  3.   The authenticity of host host (12.18.429.21) cant be established.
  4.  
  5.   RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
  6.  
  7.   Are you sure you want to continue connecting (yes/no)?
  8. 复制代码

  这段话的意思是,无法确认host主机的真实性,只知道它的 公钥指纹,问你还想 继续连接吗

  所谓 公钥指纹,是指 公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。上例中是98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,再进行比较,就容易多了。

  很自然的 一个问题 就是,用户怎么知道 远程主机 的 公钥指纹 应该是多少?回答是 没有好办法远程主机 必须在自己的 网站上 贴出 公钥指纹,以便用户 自行核对

  假定经过风险衡量以后,用户 决定接受 这个远程主机的 公钥


 
  1.   Are you sure you want to continue connecting (yes/no)? yes
  2. 复制代码

  系统会出现一句提示,表示host主机已经得到认可。


 
  1.   Warning: Permanently added host,12.18.429.21 (RSA) to the list of known hosts.
  2. 复制代码

  然后,会要求输入 密码

Password: (enter password)

  如果密码 正确,就可以登录了。

  当远程主机的公钥被接受以后,它就会被保存在本地主机文件 $HOME/.ssh/known_hosts 之中。

  下次 再连接 这台主机,系统就会认出它的 公钥 已经保存在本地了,从而跳过警告部分,直接提示输入密码

  每个SSH用户都有自己的known_hosts文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts,保存一些对 所有用户 都可信赖的远程主机的公钥。

公钥登录

  使用 密码登录,每次都 必须输入密码,非常麻烦。好在SSH还提供了 公钥登录,可以 省去输入密码 的步骤。

  所谓 公钥登录,原理很 简单,就是用户将自己的 公钥 储存在 远程主机上

  登录的时候,远程主机会向用户 发送一段随机字符串,用户用自己的 私钥加密后,再发回来。

  远程主机用事先储存的 公钥 进行 解密,如果成功,就证明用户是 可信的,直接允许登录shell不再要求密码。

  这种方法要求用户必须 提供自己的公钥。如果 没有 现成的,可以直接用ssh-keygen 生成一个:


 
  1.   $ ssh-keygen
  2. 复制代码

  运行 上面的命令 以后,系统会出现 一系列提示,可以 一路回车

  其中有一个问题是,要不要对 私钥设置口令(passphrase),如果担心 私钥的安全,这里可以 设置一个

  运行结束以后,在$HOME/.ssh/目录下,会新生成两个文件:id_rsa.pubid_rsa

  前者 是你的 公钥后者 是你的 私钥

  这时再输入下面的命令,将公钥传送到远程主机host上面:


 
  1.   $ ssh-copy-id user@host
  2. 复制代码

  好了,从此你再登录,就不需要输入密码了。

  如果 还是不行,就打开远程主机的/etc/ssh/sshd_config这个文件,检查下面几行前面 # 注释是否取掉。


 
  1.   RSAAuthentication yes
  2.   PubkeyAuthentication yes
  3.   AuthorizedKeysFile .ssh/authorized_keys
  4. 复制代码

  然后,重启远程主机 的ssh服务。


 
  1.   # ubuntu系统
  2.   service ssh restart
  3.  
  4.   # debian系统
  5.   /etc/init.d/ssh restart
  6. 复制代码

authorized_keys文件

  远程主机 将 用户 的 公钥,保存在 登录后的用户主目录 的$HOME/.ssh/authorized_keys文件中。

  公钥 就是 一段字符串,只要把它追加在authorized_keys文件的 末尾 就行了。

  这里不使用上面的ssh-copy-id命令,改用下面的命令,解释公钥的保存过程:


 
  1. &emsp;&emsp;$ ssh user@host 'mkdir -p .ssh && cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub
  2. 复制代码

  我们来分析一下这条命令:

  1. $ ssh user@host
    表示登录远程主机;

  2. 单引号中的mkdir -p .ssh && cat >> .ssh/authorized_keys
    表示登录后在远程shell上执行的命令

  3. $ mkdir -p .ssh 如果用户主目录中的.ssh目录不存在,就创建一个;

  4. cat >> .ssh/authorized_keys' < ~/.ssh/id_rsa.pub
    作用是,将本地的公钥文件~/.ssh/id_rsa.pub,重定向追加到远程文件authorized_keys的末尾。

  写入authorized_keys文件后,公钥登录的设置就完成了。

SSH密码暴力破解

  我们明白了SSH的登录原理,那么我们就可以来制作工作来暴力破解SSH密码啦。当然,所有的暴力破解都需要 破解字典 的支持

  对于 应用层 以下的协议,scapy是绝对的 神器,但是对于应用层,它就有点吃力啦。。。

  现在又要给大家安利一个SSHPython神器啦,paramiko

  • 安装

 
  1. pip3 install paramio
  2. 复制代码
  • 建立ssh连接

 
  1. import paramiko
  2. ssh_client=paramiko.SSHClient()
  3. ssh_client.connect(hostname=’hostname’,username='username',password=’mypassword’)
  4. 复制代码

如果不出意料,即使 用户名 和 密码 都正确
还是会报错:


 
  1. Raises BadHostKeyException,AuthenticationException,
  2. SSHException,socket error
  3. 复制代码

我们回顾一下上面我们讲到的,当2台机器第一次进行SSH连接时候, 远程主机要需要 用户 确认是否信任远程主机的 指纹


 
  1. The authenticity of host hostname cant be established.
  2. RSA key fingerprint is key. Are you sure you want to
  3. continue connecting (yes/no)?
  4. 复制代码

用户可以手动选择  时,就可以远程连接。  

Paramiko 同样要求验证用户对机器的信任。

我们通过调用SSHClient上的set_missing_host_key_policy()并传递在访问新远程计算机时要实现的策略来处理此验证。   

默认 情况下,paramiko.SSHclient将策略设置为RejectPolicy

如上所述,该政策拒绝连接而未经验证。

然而,Paramiko确实为您提供了一种 信任所有 关键策略AutoAddPolicy的方法。

AutoAddPolicy的实例解析为set_missing_host_key_policy()会将其更改为允许任何主机。

那么代码就如下:

 

  • 我们在connect方法中加入了cmd可以在登录成功后执行相关 命令

  • 执行命令的输入,输出都传入到一个元组保存

  • 如果登录成功,返回密码以及执行命令的结果;

  • 如果失败,就以另外的code提示

  • 使用 字典 爆破

    1. 准备一个爆破字典,互联网可以找到很多
    2. 使用爆破字典的密码进行爆破  

    相关代码如下:

     

    使用爆破测试一下:

     我们 爆破 出了远程主机的密码,并且通过远程 执行命令,发现了对方的 操作系统版本。。

     

    但是,实际运用中,这种技术还是 不靠谱的。很大程度上依赖于字典的作用,而且对于 复杂密码,相当 费时

    所以就有了另外的攻击方式,钓鱼攻击 ,之后笔者会与大家分享。