
問題
有些舊WS_FTP伺服器Windows 更新後在工作中停止啟動。相應的管理員早已不存在。我所掌握的唯一資訊是:
- 文件結構
- 使用者名稱
- 每個用戶的未加鹽 SHA256 雜湊值
這些哈希值之一是:
5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8
對應於"password"
.我可以檢查:echo -n password | sha256sum
。
我甚至不知道 FTP 客戶端在哪裡。其中一些是我無法訪問的遠端感測器。他們仍在發送數據,直到伺服器停止。這些數據不是機密,但對我們來說仍然很重要。
嘗試
我嘗試跑步開膛手約翰在哈希值上。它在 30 個密碼中找到了 4 個。
我試圖找到一個使用無鹽 SHA256 哈希值的 Linux FTP 伺服器。我認為它太不安全了,所以沒有伺服器提出它,至少不是預設的
一些伺服器(例如VSFTPD) 委託給 htpasswd。不過,我找不到儲存未加鹽的 SHA256 雜湊值的方法。
問題
是否可以htpasswd
使用 SHA256 創建哈希,不加鹽,僅一輪?最小似乎是 8 位元組鹽和 1000 輪mkpasswd
。
是否有另一個 Linux FTP 伺服器可以配置為使用這些哈希值?
我不太關心安全性,我只想設定一個 FTP 伺服器來接受來自感測器的傳入連線。
答案1
@Broco建議使用pyftpdlib,這非常適合我的需求!
步驟如下:
- 安裝Linux伺服器
- 安裝蟒蛇
- 安裝pyftpdlib
- 建立一個包含使用者名稱、雜湊值和資料夾的字典的 json 文件
- 為 FTP 伺服器建立一個 pyftpdlib 腳本,用於比較 SHA256 雜湊值
- 重定向連接埠 21 到連接埠 8021
- 將其作為系統單元作為非特權用戶
- 重新啟動自動FTP伺服器如果json檔案被修改。
這是 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。