什麼是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,只要一條簡單命令就可以了。

$ ssh user@host

如果 本地用戶名 與 遠程用戶名 一致,登錄時可以 省略 用戶名。

$ ssh host

SSH 的默認埠是22,也就是說,你的登錄請求會送進遠程主機的22埠。使用p參數,可以修改這個埠。

$ ssh -p 2222 user@host

上面這條命令表示,ssh直接連接遠程主機的2222埠。 中間人攻擊 SSH 之所以能夠 保證安全,原因在於它採用了 公鑰加密。

整個過程是這樣的:

  1. 遠程主機收到用戶的 登錄請求,把 自己的公鑰 發給用戶。
  2. 用戶使用這個公鑰,將 登錄密碼加密後,發送給遠程主機。
  3. 遠程主機用自己的 私鑰解密 登錄密碼,如果 密碼正確,就 同意用戶 登錄。

這個過程本身是 安全 的,但是實施的時候存在 一個風險

如果有人 截獲登錄請求,然後 冒充遠程主機,將 偽造公鑰 發給用戶,那麼用戶 很難辨別真偽。 因為不像https協議,SSH協議的 公鑰 是沒有證書中心(CA)公證的,也就是說,都是 自己簽發 的。 可以設想,如果 攻擊者 插在 用戶與遠程主機 之間(比如在 公共的wifi區域),用 偽造的公鑰,獲取用戶的 登錄密碼。 再用這個密碼 登錄遠程主機,那麼SSH的安全機制就蕩然無存了。這種風險就是著名的 中間人攻擊Man-in-the-middle attack)。

SSH 協議是如何應對的呢?

口令登錄 如果你是 第一次 登錄對方主機,系統會出現下面的提示:

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

這段話的意思是,無法確認host主機的真實性,只知道它的 公鑰指紋,問你還想 繼續連接嗎? 所謂 公鑰指紋,是指 公鑰長度較長(這裡採用RSA演算法,長達1024位),很難比對,所以對其進行MD5計算,將它變成一個128位的指紋。上例中是98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d,再進行比較,就容易多了。 很自然的 一個問題 就是,用戶怎麼知道 遠程主機公鑰指紋 應該是多少?回答是 沒有好辦法遠程主機 必須在自己的 網站上 貼出 公鑰指紋,以便用戶 自行核對。 假定經過風險衡量以後,用戶 決定接受 這個遠程主機的 公鑰

Are you sure you want to continue connecting (yes/no)? yes

系統會出現一句提示,表示host主機已經得到認可。

Warning: Permanently added host,12.18.429.21 (RSA) to the list of known hosts.

然後,會要求輸入 密碼Password: (enter password) 如果密碼 正確,就可以登錄了。 當遠程主機的公鑰被接受以後,它就會被保存在本地主機文件 $HOME/.ssh/known_hosts 之中。

下次 再連接 這臺主機,系統就會認出它的 公鑰 已經保存在本地了,從而跳過警告部分,直接提示輸入密碼

每個SSH用戶都有自己的known_hosts文件,此外系統也有一個這樣的文件,通常是/etc/ssh/ssh_known_hosts,保存一些對 所有用戶 都可信賴的遠程主機的公鑰。 公鑰登錄 使用 密碼登錄,每次都 必須輸入密碼,非常麻煩。好在SSH還提供了 公鑰登錄,可以 省去輸入密碼 的步驟。 所謂 公鑰登錄,原理很 簡單,就是用戶將自己的 公鑰 儲存在 遠程主機上。 登錄的時候,遠程主機會向用戶 發送一段隨機字元串,用戶用自己的 私鑰加密後,再發回來。 遠程主機用事先儲存的 公鑰 進行 解密,如果成功,就證明用戶是 可信的,直接允許登錄shell不再要求密碼。 這種方法要求用戶必須 提供自己的公鑰。如果 沒有 現成的,可以直接用ssh-keygen 生成一個: $ ssh-keygen 運行 上面的命令 以後,系統會出現 一系列提示,可以 一路回車

其中有一個問題是,要不要對 私鑰設置口令(passphrase),如果擔心 私鑰的安全,這裡可以 設置一個

運行結束以後,在$HOME/.ssh/目錄下,會新生成兩個文件:id_rsa.pubid_rsa前者 是你的 公鑰後者 是你的 私鑰。 這時再輸入下面的命令,將公鑰傳送到遠程主機host上面:   $ ssh-copy-id user@host 複製代碼 好了,從此你再登錄,就不需要輸入密碼了。 如果 還是不行,就打開遠程主機的/etc/ssh/sshd_config這個文件,檢查下面幾行前面 # 注釋是否取掉。

RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys

然後,重啟遠程主機ssh服務。

# ubuntu系統
service ssh restart
# debian系統
/etc/init.d/ssh restart

authorized_keys文件

遠程主機用戶公鑰,保存在 登錄後的用戶主目錄$HOME/.ssh/authorized_keys文件中。 公鑰 就是 一段字元串,只要把它追加在authorized_keys文件的 末尾 就行了。 這裡不使用上面的ssh-copy-id命令,改用下面的命令,解釋公鑰的保存過程:

$ ssh user@host mkdir -p .ssh && cat >> .ssh/authorized_keys < ~/.ssh/id_rsa.pub

我們來分析一下這條命令:

  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
  • 安裝

pip3 install paramio

  • 建立ssh連接

import paramiko
ssh_client=paramiko.SSHClient() ssh_client.connect(hostname=』hostname』,username=username,password=』mypassword』)

如果不出意料,即使 用戶名密碼 都正確還是會報錯: Raises BadHostKeyException,AuthenticationException, SSHException,socket error 我們回顧一下上面我們講到的,當2臺機器第一次進行SSH連接時候, 遠程主機要需要 用戶 確認是否信任遠程主機的 指紋: The authenticity of host hostname cant be established. RSA key fingerprint is key. Are you sure you want to continue connecting (yes/no)? 複製代碼用戶可以手動選擇 時,就可以遠程連接。 Paramiko 同樣要求驗證用戶對機器的信任。 我們通過調用SSHClient上的set_missing_host_key_policy()並傳遞在訪問新遠程計算機時要實現的策略來處理此驗證。 默認 情況下,paramiko.SSHclient將策略設置為RejectPolicy。 如上所述,該政策拒絕連接而未經驗證。 然而,Paramiko確實為您提供了一種 信任所有 關鍵策略AutoAddPolicy的方法。 將AutoAddPolicy的實例解析為set_missing_host_key_policy()會將其更改為允許任何主機。 那麼代碼就如下:

  • 我們在connect方法中加入了cmd可以在登錄成功後執行相關 命令
  • 執行命令的輸入,輸出都傳入到一個元組保存
  • 如果登錄成功,返回密碼以及執行命令的結果;
  • 如果失敗,就以另外的code提示
  • 使用 字典 爆破
  1. 準備一個爆破字典,互聯網可以找到很多
  2. 使用爆破字典的密碼進行爆破

相關代碼如下:

使用爆破測試一下:

我們 爆破 出了遠程主機的密碼,並且通過遠程 執行命令,發現了對方的 操作系統版本。。

但是,實際運用中,這種技術還是 不靠譜的。很大程度上依賴於字典的作用,而且對於 複雜密碼,相當 費時。 所以就有了另外的攻擊方式,釣魚攻擊 ,之後筆者會與大家分享。

關注筆者公眾賬號[mindev],並回復 ssh,就能得到 ssh爆破源碼 喲~~

願意與大家分享交流各種技術,個人公眾賬號[mindev],以及 知識星球[ 極客世界 ]

歡迎訂閱公眾賬號,日更喲~~~
推薦閱讀:
相關文章