黄河流域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逆向

image-20250524092221774

主函数

调用 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

posted @ 2025-05-30 10:59  ethan——1231  阅读(28)  评论(1)    收藏  举报