米好信安杯CTF线上挑战赛【WriteUp】

which 发布于 2025-06-13 77 次阅读


签到

南京紫金山

flag{118.85,32.07}

Crypto-1

内存溢出

from Crypto.Cipher import DES
from Crypto.Util.Padding import unpad
import binascii

# ================== 配置区 ==================
# 密文(十六进制字符串,长度需为16的倍数)
CIPHERTEXT_HEX = "e4bed2ec2a02fa52cb29591c776eee893fe2b2b7072cd389178245b788e46b15a1f14f060f2ba069"
# 已知密钥前缀(5字节)
KEY_PREFIX = b"3HUD7"
# ===========================================

def pkcs7_unpad(data):
    try:
        return unpad(data, DES.block_size, style='pkcs7')
    except Exception:
        return None

def try_decrypt(cipher_hex, key):
    if len(key) != 8:
        return None
    try:
        cipher = DES.new(key, DES.MODE_ECB)
        ct = binascii.unhexlify(cipher_hex)
        pt_padded = cipher.decrypt(ct)
        pt = pkcs7_unpad(pt_padded)
        if pt is None:
            return None
        try:
            text = pt.decode('utf-8')
            return text, pt
        except Exception:
            return None
    except Exception:
        return None

def brute_force(cipher_hex, prefix):
    results = []
    total = 256 ** 3
    print(f"开始爆破,密钥前缀:{prefix.decode(errors='ignore')}")
    for i in range(total):
        k = prefix + bytes([ (i >> 16) & 0xff, (i >> 8) & 0xff, i & 0xff ])
        res = try_decrypt(cipher_hex, k)
        if res:
            text, pt = res
            print(f"[发现] 密钥: {k} | 明文: {text}")
            results.append((k, text, pt))
        if i % 500000 == 0:
            print(f"进度: {i}/{total}")
    return results

def main():
    print("=== DES ECB 密钥爆破工具 ===")
    if len(CIPHERTEXT_HEX) % 16 != 0:
        print("密文长度不正确,需为16的倍数。")
        return
    # 先尝试已知的"3HUD7???"(问号)
    test_key = KEY_PREFIX + b"???"
    res = try_decrypt(CIPHERTEXT_HEX, test_key)
    if res:
        text, pt = res
        print(f"直接尝试密钥 {test_key} 成功,明文为: {text}")
    else:
        print("直接尝试密钥未成功,准备爆破...")
        # 是否进行全量爆破
        go = input("是否开始全量爆破密钥后3字节?(y/n): ").strip().lower()
        if go == 'y':
            found = brute_force(CIPHERTEXT_HEX, KEY_PREFIX)
            if not found:
                print("未找到可用密钥。")
            else:
                print(f"共找到{len(found)}组可能的密钥和明文。")
        else:
            print("已取消爆破。")

if __name__ == "__main__":
    main()

flag{0355e3d4f3951598d7fe1add6081bc1a}

Crypto-2

压缩包密码爆破123456

恩尼格玛密码机 Enigma 机器:在线加密和解密 - cryptii --- The Enigma machine: Encrypt and decrypt online - cryptii

flag{YOUGETITGOODLOCKFORYOU}

WEB-1

SSTI

fenjing一把嗦

 flag{45f262f8515a42a85400321eccae7f0b}

WEB-2

SSRF

发现连接不上试试8081发现连接成功

flag{4e520a1f-4c9d-4f27-b10d-cbc7d20dfb16}

MISC-1

'双击看到一个压缩包

提示四位密码

密码为1996

看到OurSecret隐写特征

猜测密码为CTF

word里面出现提示CFRS?CSRF?

[[R[FSFSF]]FSF][[R[FSFSF]]FF] 为0

[C[C[C[SFS]]]][C[C[C[SFS]]]] 为1 [C[C[C[SFS]]]] 为1 将对应字符替换,之后进行转换

flag{92f38c0023da46433a66e77b2543ec59}

MISC-2

通过 file 查看⽂件类型为 pcapng。 添加后缀通过 wireshark 打开

发现是USB流量直接使用工具一把梭

flag{bit43}

Reverse-2

小端序 key

flag{Revers1ng_1s_Fun!}

Reverse-1

程序是用install4j 打包的,动态调试

temp 目录加载 jar 包

 flag{afb94494b9fe826f46c6f331199a3300}

PWN2

32 位保护全关

首先是向栈中push一个字符串,然后输出该字符串后再向栈中输入0x3c个字符。注意在read的时候并没有设置ecx,所以这个时候ecx仍然等于esp,所以就是直接向栈上写入0x3c个字符。

很明显有栈溢出
将栈抬升0x14后直接ret,这里ret的值就是最开始push的_exit,所以我们可以直接覆盖返回地址。由于没有开启NX保护,所以可以先泄漏栈地址,然后直接往栈上写入shellcode即可。
注意到最开始的时候是把esp的值给push到了栈中,而且刚好在_exit后面。
所以我们可以先将返回地址_exit给覆盖为0x08048087,这样就会再一次调用read函数,而这里ecx是等于esp的
那么就可以泄漏栈地址了,然后再向栈上写入shellcode并返回到栈上执行即可。

flag{4f546000e0-a30e-4bff-ed1c-c73828db4a}