黄河流域wp
2025黄河流域公安院校个人挑战赛wp
1.qgd
第一段
iwannaknow/what_DO_you_mean#@!
解密
encrypted = [88, 47, 80, 54, 95, 57, 90, 54, 94, 47]
decrypted = []
for i, byte in enumerate(encrypted):
key = 0x31 if i % 2 == 0 else 0x58
decrypted_byte = byte ^ key
decrypted.append(decrypted_byte)
# 转换为字符
flag = ''.join(chr(c) for c in decrypted)
print("Decrypted flag part 1:", flag)
第二段
pyc反编译得到
from secret import decrypt
key = bytes.fromhex('EC3700DFCD4F364EC54B19C5E7E26DEF6A25087C4FCDF4F8507A40A9019E3B48BD70129D0141A5B8F089F280F4BE6CCD')
ciphertext = b'%d4z\'0L%10%ca%0b%0b%aa%15%beK0"%bf%b2%c6%05'
cipher = decrypt(ciphertext, key)
a = bytes(input('flag呢'), 'utf-8', **('encoding',))
if a == cipher:
print('没错没错')
else:
print('不对不对')
但是我们是不知道 decrypt加密函数是什么
原来是版本不对,应该是python3.9的版本
secret.pyc
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.9
def key_schedule(key = None):
S = list(range(128))
v6 = 0
for j in range(128):
v6 = (S[j] + key[j % len(key)] + v6) % 128
v6 = (v6 ^ 55) % 128
S[j] = S[v6]
S[v6] = S[j]
return S
def next_byte(state = None):
S = state['S']
state['i'] = (state['i'] + 1) % 128
state['j'] = (state['j'] + S[state['i']]) % 128
S[state['i']] = S[state['j']]
S[state['j']] = S[state['i']]
v2 = S[(S[state['i']] + S[state['j']]) % 128]
return (16 * v2 | v2 >> 4) & 255
def decrypt(ciphertext = None, key = None):
state = {
'S': key_schedule(key),
'i': 0,
'j': 0 }
plaintext = bytearray()
for byte in ciphertext:
plaintext.append(byte ^ next_byte(state))
return bytes(plaintext)
是RC4加密
最后结果是what_DO_you_mean#@!
flag{iwannaknow/what_DO_you_mean#@!}
2.Victory Melody
vm逆向
主函数
调用 sub_140011109()获取用户输入
调用 sub_140011389()验证输入
vm
sub_140011800- VM初始化函数:
分配0x50C字节内存
从 unk_14001D000 复制0x33字节的字节码到偏移268处
sub_140011890 - VM执行引擎:
-
实现了一个字节码解释器
-
支持多种指令操作码:
0x10: 设置寄存器a1[0]
0x11: 设置寄存器a1[1]
0x20: 写入内存
0x30: 异或运算
0x40: 调用函数
0x50: 内存比较并返回结果
字节码
[
0x20, 0x10, 0x5B, 0x20, 0x11, 0x58, 0x20, 0x12, 0x56, 0x20,
0x13, 0x6E, 0x20, 0x14, 0x11, 0x20, 0x15, 0x4E, 0x20, 0x16,
0x00, 0x40, 0x11, 0x21, 0x10, 0x00, 0x30, 0x10, 0x01, 0x30,
0x10, 0x02, 0x30, 0x10, 0x03, 0x30, 0x10, 0x04, 0x30, 0x10,
0x05, 0x30, 0x10, 0x06, 0x30, 0x10, 0x07, 0x30, 0x50, 0x10,
0x07
]
解密
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
VM逆向解密脚本
分析虚拟机字节码,找到正确的输入
"""
import hashlib
class VMEmulator:
def __init__(self):
# VM内存结构
self.reg_a = 0 # a1[0] - 寄存器A
self.reg_b = 0 # a1[1] - 寄存器B
self.pc = 0 # a1[2] - 程序计数器
self.memory = [0] * 256 # 内存区域 (从偏移12开始)
self.input_data = [0] * 32 # 用户输入数据 (a1+3开始)
# 字节码
self.bytecode = [
0x20, 0x10, 0x5B, 0x20, 0x11, 0x58, 0x20, 0x12, 0x56, 0x20,
0x13, 0x6E, 0x20, 0x14, 0x11, 0x20, 0x15, 0x4E, 0x20, 0x16,
0x00, 0x40, 0x11, 0x21, 0x10, 0x00, 0x30, 0x10, 0x01, 0x30,
0x10, 0x02, 0x30, 0x10, 0x03, 0x30, 0x10, 0x04, 0x30, 0x10,
0x05, 0x30, 0x10, 0x06, 0x30, 0x10, 0x07, 0x30, 0x50, 0x10,
0x07
]
# 目标内存状态 (预期结果)
self.target_memory = []
def reset(self):
"""重置VM状态"""
self.reg_a = 0
self.reg_b = 0
self.pc = 0
self.memory = [0] * 256
self.input_data = [0] * 32
def set_input(self, input_string):
"""设置输入数据"""
input_bytes = input_string.encode('utf-8')
for i, byte_val in enumerate(input_bytes):
if i < len(self.input_data):
self.input_data[i] = byte_val
# 补齐剩余位置为0
for i in range(len(input_bytes), len(self.input_data)):
self.input_data[i] = 0
def execute_instruction(self):
"""执行单条指令"""
if self.pc >= len(self.bytecode):
return False
opcode = self.bytecode[self.pc]
if opcode == 0x10: # 设置寄存器A
self.reg_a = self.bytecode[self.pc + 1]
self.pc += 2
elif opcode == 0x11: # 设置寄存器B
self.reg_b = self.bytecode[self.pc + 1]
self.pc += 2
elif opcode == 0x20: # 写入内存
addr = self.bytecode[self.pc + 1]
value = self.bytecode[self.pc + 2]
self.memory[addr] = value
self.pc += 3
elif opcode == 0x30: # 异或运算
# 关键修正:异或操作是对输入数据进行,不是内存
addr = self.reg_a
if addr < len(self.input_data):
self.input_data[addr] ^= self.reg_b
self.pc += 1
elif opcode == 0x40: # 调用函数 (读取输入)
# 这里模拟读取用户输入到input_data
print("模拟读取用户输入...")
self.pc += 1
elif opcode == 0x50: # 内存比较
start_addr = self.bytecode[self.pc + 1]
length = self.bytecode[self.pc + 2]
# 比较input_data和memory中的数据
result = 0
for i in range(length):
if i < len(self.input_data) and (start_addr + i) < len(self.memory):
if self.input_data[i] != self.memory[start_addr + i]:
result = 1
break
return result # 返回比较结果
else:
print(f"未知指令: 0x{opcode:02X}")
return False
return True
def run(self, max_steps=1000):
"""运行VM直到结束"""
steps = 0
while steps < max_steps:
result = self.execute_instruction()
if isinstance(result, int): # 比较指令返回结果
return result
if not result: # 执行失败或结束
break
steps += 1
return -1 # 超时或异常
def analyze_bytecode(self):
"""分析字节码,提取目标数据"""
print("=== 字节码分析 ===")
print("指令序列:")
pc = 0
target_data = {}
while pc < len(self.bytecode):
opcode = self.bytecode[pc]
if opcode == 0x20 and pc + 2 < len(self.bytecode):
addr = self.bytecode[pc + 1]
value = self.bytecode[pc + 2]
target_data[addr] = value
print(f" 内存[{addr:02X}] = 0x{value:02X} ('{chr(value) if 32 <= value <= 126 else '?'}')")
pc += 3
elif opcode == 0x10 and pc + 1 < len(self.bytecode):
value = self.bytecode[pc + 1]
print(f" 设置寄存器A = {value}")
pc += 2
elif opcode == 0x11 and pc + 1 < len(self.bytecode):
value = self.bytecode[pc + 1]
print(f" 设置寄存器B = {value}")
pc += 2
elif opcode == 0x30:
print(f" 异或运算: 内存[A] ^= B")
pc += 1
elif opcode == 0x40:
print(f" 读取用户输入")
pc += 1
elif opcode == 0x50 and pc + 2 < len(self.bytecode):
start = self.bytecode[pc + 1]
length = self.bytecode[pc + 2]
print(f" 比较: input_data[0:{length}] vs memory[{start:02X}:{start:02X}+{length}]")
pc += 3
else:
pc += 1
return target_data
def solve(self):
"""求解正确的输入"""
print("=== 开始求解 ===")
# 分析字节码获取目标数据
target_data = self.analyze_bytecode()
# 模拟执行初始化部分(设置内存值)
self.reset()
pc = 0
# 执行初始化指令(0x20指令)
while pc < len(self.bytecode):
opcode = self.bytecode[pc]
if opcode == 0x20:
addr = self.bytecode[pc + 1]
value = self.bytecode[pc + 2]
self.memory[addr] = value
pc += 3
elif opcode == 0x40: # 到达输入指令停止
break
else:
pc += 1
print(f"\n目标内存状态:")
for addr in sorted(target_data.keys()):
print(f" 内存[{addr:02X}] = 0x{target_data[addr]:02X}")
# 分析异或操作模式 - 重新分析VM逻辑
print(f"\n重新分析VM执行逻辑:")
# 从字节码看,异或操作的流程是:
# 1. 读取输入 (0x40)
# 2. 设置B=0x21 (0x11, 0x21)
# 3. 对input[0]到input[7]分别进行异或0x21
# 4. 最后比较处理后的input和memory[0x10:0x17]
# 所以逆向过程是:原始输入 = 目标值 ^ 0x21
print("VM执行流程:")
print("1. 读取用户输入到input[]")
print("2. 对input[0-7]每个字节都异或0x21")
print("3. 比较处理后的input与memory[0x10-0x16]")
# 获取目标值和比较长度
compare_length = 7 # 从字节码分析得出
target_values = []
for i in range(compare_length):
addr = 0x10 + i
if addr in target_data:
target_values.append(target_data[addr])
else:
target_values.append(0)
print(f"\n目标值 (memory[0x10-0x16]):", [f"0x{x:02X}" for x in target_values])
print("异或值: 0x21 (对所有字节)")
# 计算原始输入:target ^ 0x21
result_bytes = []
print(f"\n逆向计算:")
for i, target in enumerate(target_values):
original = target ^ 0x21
result_bytes.append(original)
char_repr = chr(original) if 32 <= original <= 126 else f'\\x{original:02X}'
print(f" input[{i}] = 0x{target:02X} ^ 0x21 = 0x{original:02X} ('{char_repr}')")
# 转换为字符串
solution = ''.join(chr(x) if 32 <= x <= 126 else f'\\x{x:02X}' for x in result_bytes)
print(f"\n计算出的输入: '{solution}'")
# 验证解
self.verify_solution(solution)
return solution
def verify_solution(self, solution):
"""验证解的正确性"""
print(f"\n=== 验证解: '{solution}' ===")
self.reset()
self.set_input(solution)
result = self.run()
print(f"VM执行结果: {result}")
if result == 0:
print("✓ 验证成功! 这是正确的输入")
# 计算MD5
md5_hash = hashlib.md5(solution.encode()).hexdigest()
print(f"Flag: flag{{{md5_hash}}}")
else:
print("✗ 验证失败,需要进一步分析")
def main():
print("VM逆向工程解密工具")
print("=" * 50)
vm = VMEmulator()
solution = vm.solve()
print(f"\n最终答案: {solution}")
if __name__ == "__main__":
main()
结果是
zywO0o!
md5加密后就是
flag{ccd5cace2d47f2fc8b3a7c632f5f7b49}
3.R
rust逆向
魔改的RC4加密
4.数学天才
字典是 1234567890$
爆破得到压缩包的密码是295$25$23
打开得到
DJ?ELtbo`0+o8F0Eb2G9dPN
随波逐流嗦两次就能嗦出来flag
就是synt{E3@1_Z@gu_t3avh5!}
然后rot13
flag{R3@1_M@th_g3niu5!}
<E:8E?W^Z<=tEZ)=lP6n>;.Tg>q@+!/6=B)/6_%hLg*.rH<gLN

浙公网安备 33010602011771号