Ftp

可以使用無鹽 SHA256 雜湊的 Linux FTP 伺服器?

  • April 4, 2018

問題

一些舊的WS_FTP 伺服器在 Windows 更新後停止啟動。相應的管理員早已不復存在。我擁有的唯一資訊是:

  • 文件結構
  • 使用者名
  • 每個使用者的無鹽 SHA256 雜湊

這些雜湊之一是:

5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8

對應於"password"。我可以檢查:echo -n password | sha256sum

我什至不知道 FTP 客戶端在哪裡。其中一些是我無法訪問的遠端感測器。他們仍在發送數據,直到伺服器停止。這些數據不是機密的,但對我們很重要。

嘗試

  • 我嘗試在雜湊上執行john the ripper 。它在 30 個密碼中找到了 4 個密碼。
  • 我試圖找到一個使用無鹽 SHA256 雜湊的 Linux FTP 伺服器。我認為它太不安全了,所以沒有伺服器建議它,至少不是預設的
  • 一些伺服器(例如vsftpd)委託給 htpasswd。不過,我找不到保存未加鹽 SHA256 雜湊的方法。

問題

是否可以使用 SHA256 創建一個htpasswd沒有鹽且只有一輪的雜湊?最小值似乎是 8 字節鹽和 1000 輪mkpasswd.

是否有另一個可以配置為使用這些雜湊的 linux FTP 伺服器?

我不太關心安全性,我只想設置一個接受來自感測器的傳入連接的 FTP 伺服器。

@Broco 建議使用pyftpdlib,它非常適合我的需求!

以下是步驟:

  • 安裝 Linux 伺服器
  • 安裝Anaconda
  • 安裝pyftpdlib
  • 使用使用者名、雜湊和文件夾的字典創建一個 json 文件
  • 為比較 SHA256 雜湊的 FTP 伺服器創建一個 pyftpdlib 腳本
  • 將埠 21重定向到埠 8021
  • 以非特權使用者身份作為systemd 單元執行
  • 如果修改了 json 文件,會自動重啟ftp 伺服器。

這是 json 文件的模板:

{
   "user1": {
       "folder": "users/user1",
       "sha256": "DFB0CE07EDF923F1F40BA56CC9BA9C396B53E3399E3164D60E35050BAA2BE9C9"
   },
   "user2": {
       "folder": "users/user2",
       "sha256": "5E884898DA28047151D0E56F8DC6292773603D0D6AABBDD62A11EF721D1542D8"
   }
}

這是腳本:

#!/opt/anaconda3/bin/python -u
#encoding: UTF-8
import re
import os
import hashlib
import json
from pathlib import Path
from pyftpdlib.authorizers import DummyAuthorizer, AuthenticationFailed
from pyftpdlib.handlers import FTPHandler
from pyftpdlib.servers import FTPServer
from pyftpdlib.filesystems import AbstractedFS

FTP_FOLDER = Path("/media/ftp_data")

with open('input/ftp_users.json') as users_json:
   USERS = json.loads(users_json.read())

current_folder = Path.cwd().resolve()


def login_dump(username, password, success):
   if success:
       subfolder = 'logins'
       attr = 'w'
   else:
       subfolder = 'logins/failed'
       attr = 'a'
   logins_folder = current_folder.joinpath(subfolder)
   logins_folder.mkdir(parents=True, exist_ok=True)
   with open(str(logins_folder.joinpath(username)), attr) as user_file:
       # NOTE: Could write better hash directly, e.g. with `mkpasswd -m sha-512`
       user_file.write(password + "\n")


class SHA256Authorizer(DummyAuthorizer):
   def validate_authentication(self, username, password, handler):
       sha256_hash = hashlib.sha256(password.encode('ascii')).hexdigest().upper()
       try:
           # NOTE: Case sensitive!
           if self.user_table[username]['pwd'] != sha256_hash:
               login_dump(username, password, False)
               raise AuthenticationFailed
       except KeyError:
           login_dump(username, password, False)
           raise AuthenticationFailed
       login_dump(username, password, True)


authorizer = SHA256Authorizer()

for user, params in USERS.items():
   print("Adding user %r" % user)
   folder = FTP_FOLDER.joinpath(params['folder'])
   folder.mkdir(parents=True, exist_ok=True)
   authorizer.add_user(user,
                       params['sha256'].upper(),
                       str(folder),
                       perm="elradfmw",
                       msg_login="Welcome, %s!" % user)
handler = FTPHandler
handler.authorizer = authorizer
handler.banner = "FTP server"


class WindowsOrUnixPathFS(AbstractedFS):
   def ftpnorm(self, ftppath):
       # NOTE: Some old clients still think they talk to a Windows Server
       return super().ftpnorm(ftppath.replace("\\", "/"))


handler.abstracted_fs = WindowsOrUnixPathFS

handler.passive_ports = range(40000, 40500)
# NOTE: Port forwarding is needed because this script shouldn't be run as root.
# See https://serverfault.com/a/238565/442344
server = FTPServer((IP_ADDRESS, 8021), handler)
server.serve_forever()

該腳本以純文字形式記錄密碼,這是可以接受的,因為數據不是機密的。幾個月後,我將切換到 vsftpd。

引用自:https://serverfault.com/questions/903533