2026软件安全赛华东赛区线下赛-pth_attcak题解wp

administrator::pc:cd0a6722277096c9:3fa965e4d9af9a92bde5cefcdd309acb:010100000000000022a2d32cbc72dc01ff545caf96411c670000000002000a0044004500310041005900010004005000430004001200640065003100610079002e0063006f006d0003001800500043002e00640065003100610079002e0063006f006d0005001200640065003100610079002e0063006f006d000700080022a2d32cbc72dc010600040002000000080030003000000000000000000000000030000026544cc05c735b21ae876ab6adeaf35030fb649315896d1d685326c99ddb5f6b0a001000000000000000000000000000000000000900220048005400540050002f00310030002e00310030002e00310030002e00320030003100000000000000000000000000

python winrm_decrypt.py -p pass@word1 [流量包] > [导出xml文件]


import hashlibimport hmac# ---------------------------------填入信息---------------------------------user = "Administrator"domain = ""ntlm_hash = "3d83254b53697355ef7498b535e7ab29"ntproofstr = "4103e8d84572fa74f220ecc20be704c1"encrypted_session_key = "7433d4ac87cdff2d38b2e8a5840b919d"sessionId = "0000480000000055"try:from Cryptodome.Cipher import ARC4except Exception:print("Warning: You need pycryptodomex")def generateEncryptedSessionKey(keyExchangeKey, exportedSessionKey):cipher = ARC4.new(keyExchangeKey)sessionKey = cipher.encrypt(exportedSessionKey)return sessionKeydef reverse_hex_bytes(hex_string):return ''.join([hex_string[i:i+2] for i in range(0, len(hex_string), 2)][::-1])verbose = Trueuser_bytes = user.upper().encode('utf-16le')domain_bytes = domain.upper().encode('utf-16le')password = bytes.fromhex(ntlm_hash)h = hmac.new(password, digestmod=hashlib.md5)h.update(user_bytes + domain_bytes)respNTKey = h.digest()NTproofStr_bytes = bytes.fromhex(ntproofstr)h = hmac.new(respNTKey, digestmod=hashlib.md5)h.update(NTproofStr_bytes)KeyExchKey = h.digest()RsessKey = generateEncryptedSessionKey(KeyExchKey,bytes.fromhex(encrypted_session_key))sessionId = reverse_hex_bytes(sessionId)print("SessionId:", sessionId)print("SessionKey:", RsessKey.hex())





openssl pkcs12 -in 1.pfx -nocerts -nodes -out 1.pem



python rdp_keyword.py [json文件]
#!/usr/bin/env python3# -*- coding: utf-8 -*-"""RDP 键盘流量解密脚本用于解析从 Wireshark 导出的 JSON 格式 RDP 流量中的键盘事件"""import jsonimport sysfrom typing import List, Dict, Optional# 标准 PS/2 扫描码到 ASCII 字符的映射表# 基于 PS/2 扫描码 Set 1SCANCODE_MAP = {# 基本按键0x01: 'ESC',0x02: '1', 0x03: '2', 0x04: '3', 0x05: '4', 0x06: '5',0x07: '6', 0x08: '7', 0x09: '8', 0x0a: '9', 0x0b: '0',0x0c: '-', 0x0d: '=', 0x0e: 'BACKSPACE',0x0f: 'TAB',0x10: 'q', 0x11: 'w', 0x12: 'e', 0x13: 'r', 0x14: 't',0x15: 'y', 0x16: 'u', 0x17: 'i', 0x18: 'o', 0x19: 'p',0x1a: '[', 0x1b: ']', 0x1c: 'ENTER',0x1d: 'LCTRL',0x1e: 'a', 0x1f: 's', 0x20: 'd', 0x21: 'f', 0x22: 'g',0x23: 'h', 0x24: 'j', 0x25: 'k', 0x26: 'l', 0x27: ';',0x28: "'", 0x29: '`',0x2a: 'LSHIFT',0x2b: '\\', 0x2c: 'z', 0x2d: 'x', 0x2e: 'c', 0x2f: 'v',0x30: 'b', 0x31: 'n', 0x32: 'm', 0x33: ',', 0x34: '.',0x35: '/', 0x36: 'RSHIFT',0x37: '*', 0x38: 'LALT',0x39: 'SPACE',0x3a: 'CAPSLOCK',0x3b: 'F1', 0x3c: 'F2', 0x3d: 'F3', 0x3e: 'F4', 0x3f: 'F5',0x40: 'F6', 0x41: 'F7', 0x42: 'F8', 0x43: 'F9', 0x44: 'F10',0x45: 'NUMLOCK', 0x46: 'SCROLLLOCK',0x47: 'HOME', 0x48: 'UP', 0x49: 'PGUP',0x4a: '-', 0x4b: 'LEFT', 0x4c: 'CENTER', 0x4d: 'RIGHT',0x4e: '+', 0x4f: 'END', 0x50: 'DOWN', 0x51: 'PGDN',0x52: 'INS', 0x53: 'DEL',0x57: 'F11', 0x58: 'F12',# 扩展扫描码 (extended = 1)0x1c: 'ENTER', # 小键盘 Enter0x1d: 'RCTRL', # 右 Ctrl0x35: '/', # 小键盘 /0x37: 'PRINTSCREEN', # Print Screen0x38: 'RALT', # 右 Alt (AltGr)0x47: 'HOME', # 小键盘 70x48: 'UP', # 小键盘 80x49: 'PGUP', # 小键盘 90x4b: 'LEFT', # 小键盘 40x4d: 'RIGHT', # 小键盘 60x4f: 'END', # 小键盘 10x50: 'DOWN', # 小键盘 20x51: 'PGDN', # 小键盘 30x52: 'INS', # 小键盘 00x53: 'DEL', # 小键盘 .}class RDPKeyboardParser:def __init__(self, json_file: str):"""初始化 RDP 键盘解析器Args:json_file: Wireshark 导出的 JSON 文件路径"""self.json_file = json_fileself.packets = []self.key_events = []self.shift_pressed = Falseself.caps_lock_on = Falsedef load_packets(self) -> None:"""加载 JSON 文件中的数据包"""try:with open(self.json_file, 'r', encoding='utf-8') as f:self.packets = json.load(f)print(f"成功加载 {len(self.packets)} 个数据包")except Exception as e:print(f"加载 JSON 文件失败: {e}")sys.exit(1)def extract_scancode_events(self) -> None:"""从数据包中提取 RDP Scancode 事件"""for packet in self.packets:try:# 获取 layers 部分layers = packet.get('_source', {}).get('layers', {})# 检查是否有 RDP 层if 'rdp' not in layers:continuerdp_layer = layers['rdp']# 查找 Scancode 事件if 'Scancode' in rdp_layer and isinstance(rdp_layer['Scancode'], dict):self._process_scancode(rdp_layer['Scancode'], layers)except Exception as e:# 跳过解析错误的数据包print(f"Error processing packet: {e}")continuedef _process_scancode(self, scancode_data: dict, layers: dict) -> None:"""处理单个 Scancode 事件Args:scancode_data: Scancode 数据字典layers: 完整的 layers 字典,用于获取时间戳"""try:# eventheader 是字符串,eventheader_tree 是字典eventheader_tree = scancode_data.get('rdp.fastpath.eventheader_tree', {})# 获取事件标志is_release = eventheader_tree.get('rdp.fastpath.scancode.release', 0) == 1is_extended = eventheader_tree.get('rdp.fastpath.scancode.extended', 0) == 1# 获取按键码keycode = scancode_data.get('rdp.fastpath.scancode.keycode', '')if isinstance(keycode, str) and keycode.startswith('0x'):keycode_int = int(keycode, 16)else:keycode_int = int(keycode) if keycode else 0# 获取时间戳frame = layers.get('frame', {})timestamp = frame.get('frame.time', '')frame_number = frame.get('frame.number', '')# 只记录按键按下事件(不记录释放事件)if not is_release:key_event = {'timestamp': timestamp,'frame_number': frame_number,'keycode': keycode_int,'extended': is_extended,'raw_keycode': keycode}self.key_events.append(key_event)except Exception as e:# 跳过解析错误的事件print(f"Error processing scancode event: {e}")passdef scancode_to_key(self, keycode: int, extended: bool = False) -> str:"""将扫描码转换为按键名称Args:keycode: 扫描码 (十进制整数)extended: 是否为扩展扫描码Returns:按键名称"""# 基础按键映射key = SCANCODE_MAP.get(keycode, f'UNKNOWN(0x{keycode:02x})')# 处理 Shift 修饰键if key == 'LSHIFT' or key == 'RSHIFT':self.shift_pressed = Truereturn keyelif key == 'CAPSLOCK':self.caps_lock_on = not self.caps_lock_onreturn key# 处理字母大小写if len(key) == 1 and key.isalpha():if self.shift_pressed != self.caps_lock_on:key = key.upper()else:key = key.lower()# 处理 Shift + 数字/符号elif len(key) == 1 and self.shift_pressed:shift_map = {'1': '!', '2': '@', '3': '#', '4': '$', '5': '%','6': '^', '7': '&', '8': '*', '9': '(', '0': ')','-': '_', '=': '+', '[': '{', ']': '}', '\\': '|',';': ':', "'": '"', '`': '~', ',': '<', '.': '>','/': '?'}key = shift_map.get(key, key)return keydef reconstruct_keystrokes(self) -> str:"""重建击键序列Returns:重构的击键字符串"""result = []for event in self.key_events:keycode = event['keycode']extended = event['extended']# 重置修饰键状态(在下一个按键之前)if keycode not in [0x2a, 0x36, 0x1d, 0x38, 0x3a]: # Shift, Ctrl, Alt, CapsLockself.shift_pressed = Falsekey = self.scancode_to_key(keycode, extended)result.append(key)return ' '.join(result)def parse(self) -> None:"""执行完整的解析流程"""print("=" * 60)print("RDP 键盘流量解密工具")print("=" * 60)# 1. 加载数据包print("\n[1/3] 加载数据包...")self.load_packets()# 2. 提取 Scancode 事件print("\n[2/3] 提取键盘事件...")self.extract_scancode_events()print(f"找到 {len(self.key_events)} 个按键事件")# 3. 重建击键序列print("\n[3/3] 重建击键序列...")keystrokes = self.reconstruct_keystrokes()# 输出结果print("\n" + "=" * 60)print("解析结果:")print("=" * 60)print(f"\n按键总数: {len(self.key_events)}")print(f"\n击键序列:\n{keystrokes}")# 详细信息(前 50 个按键)print(f"\n前 50 个按键详情:")print("-" * 60)for i, event in enumerate(self.key_events[:50]):keycode = event['keycode']extended = event['extended']timestamp = event['timestamp']key = self.scancode_to_key(keycode, extended)print(f"[{i+1:3d}] {timestamp} | Code: 0x{keycode:02x}({keycode:3d}) | Key: {key}")# 重置修饰键状态if keycode not in [0x2a, 0x36, 0x1d, 0x38, 0x3a]:self.shift_pressed = Falseif len(self.key_events) > 50:print(f"... 还有 {len(self.key_events) - 50} 个按键事件")return keystrokesdef main():if len(sys.argv) != 2:print("用法: python rdp_keyboard_decrypt.py <json_file>")print("示例: python rdp_keyboard_decrypt.py 1.json")sys.exit(1)json_file = sys.argv[1]# 检查文件是否存在try:with open(json_file, 'r') as f:passexcept FileNotFoundError:print(f"错误: 文件 '{json_file}' 不存在")sys.exit(1)except Exception as e:print(f"错误: 无法读取文件 '{json_file}': {e}")sys.exit(1)# 创建解析器并执行解析parser = RDPKeyboardParser(json_file)keystrokes = parser.parse()# 保存结果到文件output_file = json_file.replace('.json', '_keystrokes.txt')try:with open(output_file, 'w', encoding='utf-8') as f:f.write(f"RDP 键盘流量解密结果\n")f.write(f"=" * 60 + "\n\n")f.write(f"按键总数: {len(parser.key_events)}\n\n")f.write(f"击键序列:\n")f.write(keystrokes + "\n\n")f.write(f"详细按键事件:\n")f.write("-" * 60 + "\n")# 重新处理以获取详细列表parser.shift_pressed = Falseparser.caps_lock_on = Falsefor i, event in enumerate(parser.key_events):keycode = event['keycode']extended = event['extended']timestamp = event['timestamp']frame_num = event['frame_number']key = parser.scancode_to_key(keycode, extended)f.write(f"[{i+1:4d}] Frame {frame_num} | {timestamp} | Code: 0x{keycode:02x}({keycode:3d}) | Key: {key}\n")if keycode not in [0x2a, 0x36, 0x1d, 0x38, 0x3a]:parser.shift_pressed = Falseprint(f"\n结果已保存到: {output_file}")except Exception as e:print(f"保存结果文件失败: {e}")if __name__ == '__main__':main()

夜雨聆风