#!/usr/bin/env python3 """ 修复 /home/ta0/key 的 magic bytes 并输出可用的 SSH 私钥。 原理: OpenSSH 私钥格式 (cipher="none", kdf="none"): ┌──────────────────┬──────┬─────────┬──────┬──────────────┬───────────────────────────────┐ │ "openssh-key-v1\0"│cipher│cipherlen│ kdf │ kdf_options │ num_keys(4) pubkey privkey │ │ 15 bytes │4+len │ "none" │4+len │ (0 bytes) │ ... │ └──────────────────┴──────┴─────────┴──────┴──────────────┴───────────────────────────────┘ 偏移0 偏移19 偏移31 本文件 cipher="none" 且 kdf="none",即私钥未加密,可直接用 hex 阅读器确认 offset 19-22 = "none", offset 27-30 = "none", offset 43 = "ssh-rsa"。 但前 15 字节 (magic) 被故意损坏——只有前两个字节 "op" 正确。 因为整段数据未加密,直接把损坏的 magic 替换为标准值即可恢复。 """ import base64 import os import sys # ── 配置 ────────────────────────────────────── TOKEN = "sMZfeCxJpMbEX0fLAAAADlN1YmxhcmdlQFZhdWx0AQIDBA==" KEY_PATH = "ta0_key_clean.txt" # 从靶机获取的干净密钥文件 OUTPUT_PATH = "sublarge_id_ed25519" # 修复后输出的私钥 CORRECT_MAGIC = b'openssh-key-v1\x00' assert len(CORRECT_MAGIC) == 15 def load_key(path: str) -> bytes: """读取密钥文件, 提取 base64 + token 拼接后的二进制数据.""" with open(path) as f: lines = f.read().strip().split('\n') header = lines[0] footer = lines[-1] print(f"[*] Header: {header}") print(f"[*] Footer: {footer}") # 收集红acted行之前的全部 base64 行 b64_lines = [] for line in lines[1:-1]: stripped = line.strip() if '***' in stripped: print(f"[*] 发现红acted行: {stripped[:50]}...") print(f"[*] Token 长度: {len(TOKEN)} chars") break if stripped and not stripped.startswith('#'): b64_lines.append(stripped) b64_prefix = ''.join(b64_lines) print(f"[*] 红acted行之前 base64: {len(b64_prefix)} chars") b64_combined = b64_prefix + TOKEN print(f"[*] 拼接后 base64: {len(b64_combined)} chars") raw = base64.b64decode(b64_combined) print(f"[*] 解码后: {len(raw)} bytes") return raw, header, footer def analyze(raw: bytes): """分析解码数据的关键字段.""" print("\n─── 解码数据分析 ───") # 前 40 字节 hex dump print(" hex dump (前 40 bytes):") for i in range(0, min(40, len(raw)), 16): hex_str = ' '.join(f'{b:02x}' for b in raw[i:i+16]) ascii_str = ''.join(chr(b) if 32 <= b < 127 else '.' for b in raw[i:i+16]) print(f" {i:04x}: {hex_str:<48} {ascii_str}") print() # 检查 magic (偏移 0-14) actual_magic = raw[:15] print(f" offset 0-14 magic (实际): {actual_magic.hex()} -> {actual_magic}") print(f" offset 0-14 magic (期望): {CORRECT_MAGIC.hex()} -> {CORRECT_MAGIC}") match = actual_magic == CORRECT_MAGIC print(f" magic 匹配: {'✓' if match else '✗ (需修复)'}") # 检查 cipher (偏移 19) import struct offset = 15 cipher_len = struct.unpack('>I', raw[offset:offset+4])[0] cipher = raw[offset+4:offset+4+cipher_len] print(f" offset {offset+4} cipher: {cipher.decode()}") # 检查 kdf (偏移 15+4+4+cipher_len) offset = 19 + cipher_len kdf_len = struct.unpack('>I', raw[offset:offset+4])[0] kdf = raw[offset+4:offset+4+kdf_len] print(f" offset {offset+4} kdf: {kdf.decode()}") # 检查 key type offset = 19 + cipher_len + 4 + kdf_len + 4 + 4 # skip kdf_options(0) + num_keys(4) pubkey_len = struct.unpack('>I', raw[offset:offset+4])[0] pubkey_data = raw[offset+4:offset+4+pubkey_len] # 公钥内部: keytype_len(4) + keytype + ... kt_len = struct.unpack('>I', pubkey_data[0:4])[0] keytype = pubkey_data[4:4+kt_len].decode() print(f" public key type: {keytype}") def fix_and_save(raw: bytes, header: str, footer: str) -> str: """替换 magic bytes, 重新 base64 编码并写入文件.""" fixed_raw = CORRECT_MAGIC + raw[15:] # 验证固定后的结构 import struct cipher_len = struct.unpack('>I', fixed_raw[15:19])[0] cipher = fixed_raw[19:19+cipher_len] kdf_len = struct.unpack('>I', fixed_raw[19+cipher_len:23+cipher_len])[0] kdf = fixed_raw[23+cipher_len:23+cipher_len+kdf_len] print(f"\n─── 修复后验证 ───") print(f" magic: {fixed_raw[:15]} -> ✓") print(f" cipher: {cipher.decode()}") print(f" kdf: {kdf.decode()}") fixed_b64 = base64.b64encode(fixed_raw).decode() # 写入 PEM 格式 # 注意: 原文件 footer 是 -----END RSA PRIVATE KEY-----, # 但 OpenSSH 格式要求 -----END OPENSSH PRIVATE KEY-----,统一修正。 openssh_header = "-----BEGIN OPENSSH PRIVATE KEY-----" openssh_footer = "-----END OPENSSH PRIVATE KEY-----" with open(OUTPUT_PATH, 'w') as f: f.write(openssh_header + '\n') for i in range(0, len(fixed_b64), 70): f.write(fixed_b64[i:i+70] + '\n') f.write(openssh_footer + '\n') os.chmod(OUTPUT_PATH, 0o600) print(f"\n[+] 密钥已保存: {OUTPUT_PATH}") print(f"[+] 权限: 0600") print(f"[+] 使用: ssh -i {OUTPUT_PATH} Sublarge@192.168.1.247") return OUTPUT_PATH def main(): if not os.path.exists(KEY_PATH): print(f"[-] 未找到密钥文件: {KEY_PATH}") print(f" 请先从靶机获取: ssh ta0@192.168.1.247 'cat /home/ta0/key' > {KEY_PATH}") sys.exit(1) raw, header, footer = load_key(KEY_PATH) analyze(raw) fix_and_save(raw, header, footer) if __name__ == '__main__': main()