返回
38
0

CTF Binary-[Re挑战题]-JvavMaster[Score=5]

Aristore,2025-07-07 21:23

参考文章:GUI—— 从的可执行exe文件中提取jar包并反编译成Java - 知乎

下载JD-GUI

Win+R输入%temp%,按时间降序,运行程序后刷新打开刚刚冒出来的文件夹

把文件夹里的jvav.jar拖到jd-gui进行反编译

exp如下:

import numpy as np

# 1. 复现 Java 中的 random 函数
def random(seed):
    x = seed
    x ^= (x << 11) & 0xFFFFFFFF
    x ^= (x >> 4) & 0xFFFFFFFF
    x ^= (x << 5) & 0xFFFFFFFF
    x ^= (x >> 14) & 0xFFFFFFFF
    return x & 0xFF

# 2. 生成 MATRIX
MATRIX = np.zeros((11, 11), dtype=int)
for i in range(11):
    for j in range(11):
        MATRIX[i, j] = random(i * 11 + j)

# 3. 定义 TARGET 向量
TARGET = np.array([
    140286, 171210, 157332, 135722, 144003, 174006, 144135,
    152772, 144501, 155988, 156148
])

# 4. 求解线性方程组
# key_float = np.linalg.inv(MATRIX).dot(TARGET)  # 另一种方法
key_float = np.linalg.solve(MATRIX, TARGET)

# 5. 将解四舍五入为整数,并转换为字节
key_bytes = [int(round(x)) for x in key_float]
key_str = "".join(chr(b) for b in key_bytes)

print(f"生成的 MATRIX:\n{MATRIX}")
print(f"\n求解出的 Key (bytes): {key_bytes}")
print(f"求解出的 Key (string): {key_str}")

# 辅助函数,复现 Java 的 rol 和 ror
def rol(b, shift):
    shift &= 7
    return ((b << shift) | (b >> (8 - shift))) & 0xFF

def ror(b, shift):
    shift &= 7
    return ((b >> shift) | (b << (8 - shift))) & 0xFF

# 1. 提取所有指令
instructions = []
i = 0
# Java的switch没有default,所以我们需要一个映射
# opcode_map[random(i)] -> [op, idx, param]
# 这里我们直接模拟Java的 getInstruction
def getInstruction(index):
    # 此处省略了Java中庞大的switch-case,直接用一个字典代替
    # key是index, value是[op, idx, param]
    inst_map = {0:[3,24,-43], 1:[-52,41,29], 3:[5,9,4], 12:[2,15,2], 13:[-52,25,-119], 14:[-52,30,18], 21:[4,7,3], 22:[2,23,-49], 23:[-52,46,79], 24:[-52,26,-113], 26:[1,11,-31], 27:[-52,33,121], 37:[-52,34,-35], 38:[-52,28,77], 39:[1,47,-64], 40:[2,4,30], 42:[-52,6,-126], 43:[2,1,-39], 48:[-52,2,-45], 49:[4,35,4], 50:[-1,0,0], 51:[-52,19,59], 60:[-52,29,-105], 61:[4,36,6], 62:[5,13,1], 68:[-52,5,73], 70:[5,22,1], 71:[-52,44,108], 73:[1,21,-106], 74:[1,27,51], 75:[-52,3,76], 80:[1,12,40], 81:[-52,39,35], 82:[-52,38,-78], 92:[4,14,5], 93:[-52,43,-43], 95:[2,20,111], 96:[-52,40,61], 97:[5,18,2], 98:[5,10,2], 108:[-52,16,-77], 109:[3,31,-1], 111:[-52,37,44], 116:[2,17,-23], 118:[-52,45,4], 119:[1,8,84], 121:[-52,0,114], 122:[-52,42,-21], 123:[2,32,11], 128:[4,34,6], 130:[-52,47,4], 131:[1,28,125], 141:[-52,4,46], 142:[-52,1,-44], 143:[1,6,-84], 148:[-52,35,94], 149:[3,2,-93], 150:[4,19,4], 152:[-52,36,27], 153:[1,29,116], 155:[-52,13,-37], 164:[4,41,7], 165:[-52,24,119], 166:[-52,9,-98], 168:[3,25,-37], 169:[-52,15,12], 171:[1,30,14], 176:[-52,7,6], 178:[3,46,41], 179:[-52,23,-72], 189:[2,26,61], 190:[3,33,-37], 191:[-52,11,-113], 196:[-52,18,24], 197:[5,40,4], 199:[-52,10,-95], 200:[-52,31,-57], 201:[1,16,-7], 202:[1,37,-1], 209:[-52,17,-46], 210:[-52,8,-94], 211:[5,45,3], 220:[4,0,4], 222:[-52,32,-56], 223:[5,42,3], 225:[3,5,11], 226:[4,44,1], 227:[-52,22,32], 236:[-52,21,72], 238:[5,3,4], 239:[-52,27,-9], 244:[3,39,120], 245:[-52,12,-119], 247:[5,38,2], 248:[2,43,83], 249:[-52,14,-25], 250:[-52,20,105]}
    return inst_map.get(index)

while True:
    rand_val = random(i)
    opcode = getInstruction(rand_val)
    if opcode is None: # Java的switch会跳过没有case的值
        i += 1
        continue
    if opcode[0] == -1: # 终止指令
        break
    # Java的byte是-128到127, Python中用 & 0xFF 模拟无符号字节
    instructions.append([(opcode[0] & 0xFF), (opcode[1] & 0xFF), (opcode[2] & 0xFF)])
    i += 1

# 2. 从检查指令确定最终数据状态
final_data = [0] * 48
modification_instructions = []

for op, idx, param in instructions:
    if op == 204: # 检查指令
        final_data[idx] = param
    else:
        modification_instructions.append((op, idx, param))

# 3. 逆向执行修改指令
# 从后往前遍历指令列表
for op, idx, param in reversed(modification_instructions):
    if op == 1: # ADD -> SUB
        final_data[idx] = (final_data[idx] - param) & 0xFF
    elif op == 2: # SUB -> ADD
        final_data[idx] = (final_data[idx] + param) & 0xFF
    elif op == 3: # XOR -> XOR
        final_data[idx] = final_data[idx] ^ param
    elif op == 4: # ROL -> ROR
        final_data[idx] = ror(final_data[idx], param)
    elif op == 5: # ROR -> ROL
        final_data[idx] = rol(final_data[idx], param)

encrypted_data = bytes(final_data)
print(f"\n求解出的加密后数据 (encrypted_data):\n{encrypted_data.hex()}")

def decrypt(ciphertext, key_bytes):
    # KSA (魔改版)
    box = list(range(256))
    for i in range(256):
        box[i] = (255 - i) ^ 0x83

    x = 0
    key_len = len(key_bytes)
    for j in range(256):
        x = (x + box[j] + key_bytes[(j + 72) % key_len]) % 256
        box[j], box[x] = box[x], box[j]

    # PRGA (魔改版) & Decryption
    x = 0
    y = 0
    plaintext = bytearray(len(ciphertext))
    for k in range(len(ciphertext)):
        x = (x + 3) % 256
        y = (y - box[x]) & 0xFF
        box[x], box[y] = box[y], box[x]
        
        index = (box[x] ^ box[y]) % 256
        keystream_byte = box[index]

        # 解密操作: P = (E ^ 0x77) - K
        encrypted_byte = ciphertext[k]
        temp = (encrypted_byte ^ 0x77) & 0xFF
        decrypted_byte = (temp - keystream_byte) & 0xFF
        plaintext[k] = decrypted_byte
        
    return plaintext

# 传入第一步的key和第二步的encrypted_data
flag = decrypt(encrypted_data, [ord(c) for c in key_str])

print(f"\n最终解密得到的 Flag: {flag.decode()}")

运行结果:

生成的 MATRIX:
[[  0 165  74 239 149  48 223 122  43 142  97]
 [196 190  27 244  81 119 210  61 152 226  71]
 [168  13  92 249  22 179 201 108 131  38 238]
 [ 75 164   1 123 222  49 148 197  96 143  42]
 [ 80 245  26 191 153  60 211 118  12 169  70]
 [227 178  23 248  93  39 130 109 200 220 121]
 [150  51  73 236   3 166 247  82 189  24  98]
 [199  40 141 171  14 225  68  62 155 116 209]
 [128  37 202 111  21 176  95 250  50 151 120]
 [221 167   2 237  72  25 188  83 246 140  41]
 [198  99  69 224  15 170 208 117 154  63 110]]

求解出的 Key (bytes): [106, 118, 97, 118, 95, 109, 97, 115, 116, 101, 114]
求解出的 Key (string): jvav_master

求解出的加密后数据 (encrypted_data):
27ad70c44c42d6c04ee986ae61b73f0ebabb60b3d8b24087a252ccc4d0230438d3a277e56c2dca5bd33a5f2836206644

最终解密得到的 Flag: flag{W0w_y0u_4r3_4_r34L_jv4V_4nD_3X34j_m4573r!!}
暂无回复。你的想法是什么?


bottom-logo1
bottom-logo2captionbottom-logo3
GeeSec
商务合作
bottom-logo4