西湖论剑2024年预赛

MZ #

flag为一段有意义的文本

用静态数组实现的链表

多解,需要爆破

#from ida_bytes import get_bytes
#
#start = 0xc79078
#length = 5000
#
#with open("dump", "wb") as fp:
#    fp.write(get_bytes(start, length*8))

from pwn import *
import string
from hashlib import sha1

with open("/tmp/dump", "rb") as fp:
	raw = fp.read()

start = 0xc79078
length = 5000
data = []
for i in range(0, length*8, 8):
	value = u32(raw[i:i+4])
	ptr = u32(raw[i+4:i+8]) - start
	assert(ptr % 8 == 0)
	data.append([value, ptr//8])

secret = "dc0562f86bec0a38508e704aa9faa347101e1fdb"
assert(len(secret)==40)
keys = string.digits + string.ascii_letters + '_@$!~'
keys = keys.encode()

def find_flag(curr, flag, temp):
	if len(flag) == 48:
		#print(f"found {flag}")
		if sha1(temp).hexdigest() == secret:
			print(flag)
		return

	for c in keys:
		try:
			node = data[curr + c]
		except:
			continue
		if c - 5 == node[0]:
			t = (~(c+1))&0xff
			find_flag(node[1], flag + chr(c), temp + bytes([t]))
		elif c + 5 == node[0]:
			t = (~(c-1))&0xff
			find_flag(node[1], flag + chr(c), temp + bytes([t]))

find_flag(0, '', b'')
#Somet1mes_ch0ice_i5_more_import@nt_tHan_effort~!

BabyCPP #

Just CPP

变异的 XTEA 和 RC4

XTEA 用了 MD5 的参数作密钥

RC4 流最后多了一步加法

from pwn import *

cipher = [51, -78, 73, -116, 57, -35, 96, 95, 95, 119, 114, -85, 56, -39, -19, -25, -13, -16, 102, 103, 22, -56, 83,
          0x80, 113, -78, -6, 94, 124, 43, -69, 11, -27, -120, -126, 11, 6, -116, -115, -83, 71, -75, -123, -69, 6, -115, 1, 43]
cipher = bytes(c & 0xff for c in cipher)

mask = 0xffff_ffff
keys = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476]

def bad_xtea_decrypt(values, keys):
    delta = 0
    for i in range(256):
        delta = (delta + 0xdeadbeef) & mask
    for i in range(256):
        delta = (delta - 0xdeadbeef) & mask

        v0, v1 = values[0], values[1]
        x = (delta + keys[(delta >> 11) & 3]) & mask
        y = (v0 + ((v0 >> 3) ^ (v0 << 6))) & mask
        values[1] = (v1 - (x ^ y)) & mask

        v0, v1 = values[0], values[1]
        x = (delta + keys[delta & 3]) & mask
        y = (v1 + ((v1 >> 7) ^ (v1 << 2))) & mask
        values[0] = (v0 - (x ^ y)) & mask
    
def ksa(key):
    j, sbox = 0, list(range(256))
    for i in range(256):
        j = (j + key[i % len(key)] + sbox[i]) & 255
        sbox[i], sbox[j] = sbox[j], sbox[i]
    return sbox

key = b'gaLf_Ek@f_A_s1_sih7'
box = ksa(key)

def bad_rc4_stream(sbox, msglen):
    result = []
    i, j = 0, 0
    for _ in range(msglen):
        i = (i + 1) & 255
        j = (j + sbox[i]) & 255
        sbox[i], sbox[j] = sbox[j], sbox[i]
        s = sbox[(sbox[i] + sbox[j]) & 255]
        result.append([sbox[i], sbox[j], s])
    return result

stream = bad_rc4_stream(box, len(cipher))
#print(stream)

results = []
def bad_rc4_decrypt(index, result):
    if index == len(cipher):
        results.append(result)
        return

    si = stream[index][0]
    sj = stream[index][1]
    ss = stream[index][2]
    for b in range(256):
        if (sj ^ (si + (ss ^ b))) & 255 == cipher[index]:
            bad_rc4_decrypt(index + 1, result + bytes([b]))

bad_rc4_decrypt(0, b'')
#print(results)

for middle in results:
    flag = b''
    for i in range(0, 48, 8):
        v0 = u32(middle[i:i+4])
        v1 = u32(middle[i+4:i+8])
        values = [v0, v1]
        bad_xtea_decrypt(values, keys)
        flag += p32(values[0])
        flag += p32(values[1])
    print(flag)

# df8d8ab87c22a396041f9bde6a40c4987c22a396041f9bde

复盘 #

WIP

Qrohttre #

easygateway #

easygateway to getshell

hardgateway #

hardgateway to getshell