IOT
blink
有个明文flag
,我看不太懂但我大受震撼
sharkp
关键字搜索一下,关注以下两个包
有个elf文件,导出一下
沙箱跑一下得到ip115.195.88.161
这个接口有命令执行 setSystemAdmin
DS
easydatalog
翻阅了一下,看到大段的十六进制信息,应该有zip、jpg什么的,提取一下十六进制数据,根据文件头文件尾信息提取出图片和压缩文件,python extract.py error.log
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
| import re
def is_http_header(line): """检查是否为 HTTP 请求头行""" http_patterns = [ r'HTTP/[\d.]+', r'Content-Type:', r'Content-Length:', r'User-Agent:', r'Accept', r'Host:', r'Connection:', r'\d+ bytes', r'\\r\\n$' ]
for pattern in http_patterns: if re.search(pattern, line): return True return False
def extract_hex_content(log_content): """从日志内容中提取十六进制数据""" hex_data = "" current_data = ""
for line in log_content.split('\n'): if 'dumpio_in (data-HEAP):' not in line: continue
content = line.split('dumpio_in (data-HEAP):')[1].strip()
if is_http_header(content): continue
if '=FFD8FF' in content or '=504B0304' in content: match = re.search(r'=((?:[A-Fa-f0-9]+))(?:&|$)', content) if match: if current_data: hex_data += current_data current_data = "" current_data = match.group(1) else: parts = content.split('&') if parts and validate_hex_string(parts[0]): current_data += parts[0] if len(parts) > 1: hex_data += current_data current_data = ""
if current_data: hex_data += current_data
return hex_data
def validate_hex_string(hex_string): """验证字符串是否为有效的十六进制数据""" return bool(re.match('^[A-Fa-f0-9]+$', hex_string))
def find_jpeg_files(hex_string): """在十六进制字符串中查找JPEG文件""" jpeg_header = "FFD8FF" jpeg_footer = "00FFD9" jpeg_files = []
pos = 0 while True: start = hex_string.find(jpeg_header, pos) if start == -1: break
end = hex_string.find(jpeg_footer, start) if end == -1: break
end += 6
jpeg_file = hex_string[start:end] if len(jpeg_file) > 6 and validate_hex_string(jpeg_file): jpeg_files.append(jpeg_file)
pos = end
return jpeg_files
def find_zip_files(hex_string): """在十六进制字符串中查找ZIP文件""" zip_header = "504B0304" zip_footer = "504B0506" zip_files = []
pos = 0 while True: start = hex_string.find(zip_header, pos) if start == -1: break
footer_pos = hex_string.find(zip_footer, start + 8) if footer_pos == -1: break
end = footer_pos + 6 while end < len(hex_string): if not validate_hex_string(hex_string[end:end+2]): break end += 2 zip_file = hex_string[start:end] if len(zip_file) > 8 and validate_hex_string(zip_file): zip_files.append(zip_file) pos = end return zip_files
def save_files(files, file_type): """将提取的文件保存到磁盘""" for i, hex_content in enumerate(files): try: binary_content = bytes.fromhex(hex_content) filename = f"extracted_{i}.{file_type}" with open(filename, "wb") as f: f.write(binary_content) print(f"已保存文件: {filename} (大小: {len(binary_content)} 字节)") print(f"文件头32字节: {binary_content[:32].hex().upper()}") except Exception as e: print(f"保存文件 {i} 时出错: {str(e)}")
def process_log(log_content): """处理日志内容并提取文件""" hex_data = extract_hex_content(log_content) print(f"提取的十六进制数据总长度: {len(hex_data)}") if not hex_data: print("未找到有效的十六进制数据") return with open("hex_data.txt", "w") as f: f.write(hex_data) jpeg_files = find_jpeg_files(hex_data) print(f"找到 {len(jpeg_files)} 个JPEG文件") if jpeg_files: save_files(jpeg_files, "jpg") zip_files = find_zip_files(hex_data) print(f"找到 {len(zip_files)} 个ZIP文件") if zip_files: save_files(zip_files, "zip")
if __name__ == "__main__": import sys if len(sys.argv) > 1: with open(sys.argv[1], 'r') as f: log_content = f.read() else: log_content = sys.stdin.read() process_log(log_content)
|
图片是个盲水印,一把梭
根据密码解压zip文件得到data.csv
easyrawencode
vol先确定镜像文件的系统配置文件profile volatility_2.6_win64_standalone.exe -f "easyrawencode.raw" imageinfo
vol扫一下
volatility_2.6_win64_standalone.exe -f "easyrawencode.raw" --profile=Win7SP1x64 filescan | findstr /i /r "\.png \.jpg \.gif \.zip \.rar \.7z \.pdf \.txt \.doc"
rsa目录下有个encrypted_data.zip
扫一下rsa目录发现三个文件volatility_2.6_win64_standalone.exe -f "easyrawencode.raw" --profile=Win7SP1x64 filescan | find "rsa"
hack.py
内容如下,hackkey
在环境变量里
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
| import os import hashlib from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.PublicKey import RSA
hackkey = os.getenv('hackkey') if not hackkey: raise ValueError("Environment variable 'hackkey' is not set")
with open('private.pem', 'r') as f: private_key = RSA.import_key(f.read()) public_key = private_key.publickey().export_key()
aes_key = hashlib.sha256(hackkey.encode()).digest()
with open('data.csv', 'rb') as f: data = f.read()
cipher_aes = AES.new(aes_key, AES.MODE_EAX) ciphertext, tag = cipher_aes.encrypt_and_digest(data) cipher_rsa = PKCS1_OAEP.new(RSA.import_key(public_key)) enc_aes_key = cipher_rsa.encrypt(aes_key)
with open('encrypted_data.bin', 'wb') as f: f.write(ciphertext)
print(enc_aes_key.hex()) print(cipher_aes.nonce.hex()) print(tag.hex())
|
控制台获取一下enc_aes_key
、cipher_aes_nonce
、tag
volatility_2.6_win64_standalone.exe -f "easyrawencode.raw" --profile=Win7SP1x64 consoles
获取环境变量volatility_2.6_win64_standalone.exe -f "easyrawencode.raw" --profile=Win7SP1x64 envars | findstr /i "hackkey"
得到4etz0hHbU3TgKqduFL
根据数据解密encrypted_data.zip
解压出来的encrypted_data.bin
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
| import os import hashlib from Crypto.Cipher import AES, PKCS1_OAEP from Crypto.PublicKey import RSA
hackkey = '4etz0hHbU3TgKqduFL'
with open('private.pem', 'r') as f: private_key = RSA.import_key(f.read())
enc_aes_key = bytes.fromhex("20d96098010eb9b326be6c46e1ce1ca679e29f1d65dec055cf8c46c6436c3356af2dc312b2d35466308b9fff0dd427b44a37e34fca12992e45db2ddd81884bd8eb5bccd3c595e8a9a352bd61322e1d52329d6c8638bbfce65edffbc4d3a5759e88c0f90e31ce518837552a3a09d8e7e3c374f3857bfe501cce2066fb233ff1f5faac18d73c3b665a54e8c55574f16bf4678c5ce835d2a14a65f8c1cec012435a8c06314cbe727a3a9b6060dfd6cdb850073423841178f6f409bb7ce8d4863c6f58855954d34af3d2964c488c9057c8c5072a54e43f1f8039d32409eb1ff3abca41c0b302788c4c56c1a4be4506ff5b8aff0242e21c0ee7ffee2da20ed9434334") cipher_aes_nonce = bytes.fromhex('d919c229aab6535efa09a52c589c8f47') tag = bytes.fromhex('5b204675b1b173c32c04b0b8a100ee29')
cipher_rsa = PKCS1_OAEP.new(private_key) aes_key = cipher_rsa.decrypt(enc_aes_key)
with open('encrypted_data.bin', 'rb') as f: ciphertext = f.read()
cipher_aes = AES.new(aes_key, AES.MODE_EAX, nonce=cipher_aes_nonce) data = cipher_aes.decrypt_and_verify(ciphertext, tag)
with open('data.csv', 'wb') as f: f.write(data)
|
需要解密个性签名,经过尝试是先base64后rc4,key是密码
1 2 3 4 5 6 7 8 9 10 11
| from Crypto.Cipher import ARC4 import base64 with open('data.csv', 'r', encoding='utf-8') as f: lines = f.readlines() for line in lines[1:]: line = line.strip().split(',') rc4key = line[2].encode() rc4 = ARC4.new(rc4key) signature = rc4.decrypt(base64.b64decode(line[6])) with open('decrypted_data.csv', 'a', encoding='gbk') as f: f.write(f'{line[0]},{line[1]},{line[2]},{line[3]},{line[4]},{line[5]},{signature.decode()}\n')
|
搜索拿到flag DASCTF{fc450e2a9062a39049d501cb5ce287d0}