春秋杯夏季赛2024 RE wp

1. snake

py打包,pyc反编译

# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.8

import pygame
import random
import key

def initialize(key):
    key_length = len(key)
    S = list(range(256))
    j = 0
    for i in range(256):
        j = (j + S[i] + key[i % key_length]) % 256
        S[i] = S[j]
        S[j] = S[i]
    return S


def generate_key_stream(S, length):
    i = 0
    j = 0
    key_stream = []
    for _ in range(length):
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i] = S[j]
        S[j] = S[i]
        key_stream.append(S[(S[i] + S[j]) % 256])
    return key_stream


def decrypt(data, key):
    S = initialize(key)
    key_stream = generate_key_stream(S, len(data))
    decrypted_data = None((lambda .0 = None: [ i ^ data[i] ^ key_stream[i] for i in .0 ])(range(len(data))))
    return decrypted_data

pygame.init()
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
SNAKE_SIZE = 20
SNAKE_SPEED = 20
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
window = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption('贪吃蛇')
font = pygame.font.Font(None, 36)
snake = [
    (200, 200),
    (210, 200),
    (220, 200)]
snake_direction = (SNAKE_SPEED, 0)
food = ((random.randint(0, WINDOW_WIDTH - SNAKE_SIZE) // SNAKE_SIZE) * SNAKE_SIZE, (random.randint(0, WINDOW_HEIGHT - SNAKE_SIZE) // SNAKE_SIZE) * SNAKE_SIZE)
key_bytes = bytes((lambda .0: [ ord(char) for char in .0 ])(key.xor_key))
data = [
    101,
    97,
    39,
    125,
    218,
    172,
    205,
    3,
    235,
    195,
    72,
    125,
    89,
    130,
    103,
    213,
    120,
    227,
    193,
    67,
    174,
    71,
    162,
    248,
    244,
    12,
    238,
    92,
    160,
    203,
    185,
    155]
decrypted_data = decrypt(bytes(data), key_bytes)
running = True
if running:
    window.fill(BLACK)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN or event.key == pygame.K_UP:
            snake_direction = (0, -SNAKE_SPEED)
        elif event.key == pygame.K_DOWN:
            snake_direction = (0, SNAKE_SPEED)
        elif event.key == pygame.K_LEFT:
            snake_direction = (-SNAKE_SPEED, 0)
        elif event.key == pygame.K_RIGHT:
            snake_direction = (SNAKE_SPEED, 0)
            continue
            snake_head = (snake[0][0] + snake_direction[0], snake[0][1] + snake_direction[1])
            snake.insert(0, snake_head)
            snake.pop()
            if snake[0] == food:
                food = ((random.randint(0, WINDOW_WIDTH - SNAKE_SIZE) // SNAKE_SIZE) * SNAKE_SIZE, (random.randint(0, WINDOW_HEIGHT - SNAKE_SIZE) // SNAKE_SIZE) * SNAKE_SIZE)
                snake.append(snake[-1])
    if snake[0][0] < 0 and snake[0][0] >= WINDOW_WIDTH and snake[0][1] < 0 and snake[0][1] >= WINDOW_HEIGHT or snake[0] in snake[1:]:
        running = False
    for segment in snake:
        pygame.draw.rect(window, WHITE, (segment[0], segment[1], SNAKE_SIZE, SNAKE_SIZE))
    pygame.draw.rect(window, RED, (food[0], food[1], SNAKE_SIZE, SNAKE_SIZE))
    score_text = font.render(f'''Score: {len(snake)}''', True, WHITE)
    speed_text = font.render(f'''Speed: {SNAKE_SPEED}''', True, WHITE)
    window.blit(score_text, (10, 10))
    window.blit(speed_text, (10, 40))
    score = len(snake)
    if score >= 9999:
        flag_text = font.render('Flag: ' + decrypted_data.decode(), True, WHITE)
        window.blit(flag_text, (10, 70))
    pygame.display.update()
    pygame.time.Clock().tick(10)
    continue
pygame.quit()
# Visit https://www.lddgo.net/string/pyc-compile-decompile for more information
# Version : Python 3.8
xor_key = 'V3rY_v3Ry_Ez'

(要用python3.8运行脚本)

魔改RC4,照抄一下就行

#snake_wp

def initialize(key):
    key_length = len(key)
    S = list(range(256))
    j = 0
    for i in range(256):
        j = (j + S[i] + key[i % key_length]) % 256
        S[i], S[j] = S[j], S[i]  # Corrected the swap operation
    return S

def generate_key_stream(S, length):
    i = 0
    j = 0
    key_stream = []
    for _ in range(length):
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]  # Corrected the swap operation
        key_stream.append(S[(S[i] + S[j]) % 256])
    return key_stream

def decrypt(data, key):
    S = initialize(key)
    key_stream = generate_key_stream(S, len(data))
    decrypted_data = [i ^ data[i] ^ key_stream[i] for i in range(len(data))]  # Corrected decryption logic
    return decrypted_data
key = 'V3rY_v3Ry_Ez'
data = [101,
    97,
    39,
    125,
    218,
    172,
    205,
    3,
    235,
    195,
    72,
    125,
    89,
    130,
    103,
    213,
    120,
    227,
    193,
    67,
    174,
    71,
    162,
    248,
    244,
    12,
    238,
    92,
    160,
    203,
    185,
    155]
key_bytes = bytes([ord(char) for char in key]) 
dd = decrypt(bytes(data), key_bytes)
flag = ''
for i in range(len(dd)):
    flag += chr(dd[i])
print(flag)
#flag{KMLTz3lT_MePUDa7A_P5LpzCBT}

2. HardSignIn

修改文件头的UPX

进去看不到啥主逻辑,看到一个回调函数,查看一下引用

去个花

tls0有个SMC

#SMC
addr=0x401890
size=0xAA
for i in range(size):
    tmp=(get_wide_byte(addr+i))^0x66
    patch_byte(addr+i,tmp)

跑一下得到main

然后是后面几个去花看一下逻辑

tls1删掉这一坨花就行

内容是反调试,11行直接绕过

tls2把这一坨删掉

13行反调试直接绕

tls3看起来比较奇怪,实际上还是反调试。

第九行直接绕

然后继续分析main,有个主要的加密和校验部分

进去看一下大致能看出来三个加密,依次为换表base64、rc4、魔改XTEA

然后就是取参数,要动调,绕过前面的反调试之后会有奇怪的异常,原程序的SMC不知有什么问题。这里建议手动解SMC之后,把tls0里的异或改为0

然后动调就正常了,各个参数都取出来

#HardSingin_wp
import base64
import string
#第三个加密 魔改XTEA,轮数改为100
from ctypes import * 

def xtea_decrypt(v,k,r):
	v0=c_uint32(v[0])
	v1=c_uint32(v[1])
	delta=0x9e3779b9
	sum1=c_uint32(delta*r)
	for i in range(r):
		v1.value-=(((v0.value<<4)^(v0.value>>5))+v0.value)^(sum1.value+k[(sum1.value>>11)&3])
		sum1.value-=delta
		v0.value-=(((v1.value<<4)^(v1.value>>5))+v1.value)^(sum1.value+k[sum1.value&3])
	return v0.value,v1.value

#端序转换的函数,方便处理数据
def byte2uint32(d):
    l=[]
    for i in range(len(d)//4):
        tmp=d[i*4:i*4+4]
        l.append(tmp[3]*256**3+tmp[2]*256**2+tmp[1]*256+tmp[0])
    return l

def uint322byte(uint32_list):
    byte_array = []
    for number in uint32_list:
        byte_array.append(number & 0xFF)
        byte_array.append((number >> 8) & 0xFF)
        byte_array.append((number >> 16) & 0xFF)
        byte_array.append((number >> 24) & 0xFF)
    return byte_array

#第二个加密 RC4
def rc4(data, key):
    S = list(range(256))
    j = 0
    out = []
 
    for i in range(256):
        j = (j + S[i] + key[i % len(key)]) % 256
        S[i], S[j] = S[j], S[i]
 
    i = j = 0
    for char in data:
        i = (i + 1) % 256
        j = (j + S[i]) % 256
        S[i], S[j] = S[j], S[i]
        out.append(char ^ S[(S[i] + S[j]) % 256])
 
    return bytes(out)
 
#第一个加密 换表base64
def base64_kai_decode(str1, new_table):
    original_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
    return(base64.b64decode(str1.translate(str.maketrans(new_table,original_table))))


if __name__=='__main__':
    #XTEA
    enc = [ 0x59, 0x1B, 0xFD, 0xB4, 0x6B, 0xB8, 0xBE, 0xD9, 0xB3, 0xD3, 0x77, 0xD6, 0xF0, 0x65, 0x5F, 0x18, 
    0xA0, 0x9D, 0x3A, 0x53, 0x6D, 0x4A, 0x7B, 0x26, 0x74, 0x3A, 0x9C, 0x4E, 0x20, 0x43, 0x19, 0xD8, 
    0x72, 0xED, 0x95, 0xB5, 0x9C, 0x05, 0x22, 0x56, 0xCB, 0x7A, 0x11, 0x91, 0x9F, 0x7A, 0xBC, 0x0C, 
    0x4A, 0x69, 0x6D, 0xCE, 0x3D, 0xB4, 0xAB, 0x29, 0x61, 0xFA, 0x62, 0x32, 0xB4, 0xEC, 0x4C, 0xB6 ]

    enc_uint32 = byte2uint32(enc)
    # 0xb4fd1b59, 0xd9beb86b, 0xd677d3b3, 0x185f65f0, 0x533a9da0, 0x267b4a6d, 0x4e9c3a74, 0xd8194320, 
    # 0xb595ed72, 0x5622059c, 0x91117acb, 0xcbc7a9f, 0xce6d694a, 0x29abb43d, 0x3262fa61, 0xb64cecb4
    '''
    for byte in enc_uint32:
        print(hex(byte), end=', ') 
    print()
    '''

    key = [0x0CAA5BDD,0xD6846924,0x51041EB8,0x8B2AAB06]
    round = 100
    for i in range(0,len(enc_uint32)-1,2):
        tmp = [0]*2
        tmp[0] = enc_uint32[i]
        tmp[1] = enc_uint32[i+1]
        res = xtea_decrypt(tmp,key,round)
        for j in res:
            print(hex(j), end=', ') 
        print()
    
    enc1 = [0x7b00edbc, 0x9316f486,
            0xdc87f995, 0x7fa2a867,
            0x9f62e24d, 0xe9ae347b,
            0x357e0345, 0x708bd042,
            0xc72efbf0, 0x73b9e9dd,
            0x751acce3, 0x14fddcad,
            0x1645c8a8, 0x82a6e31,
            0x9f1d0f2c, 0xefd5ba07]
    enc1_byte = uint322byte(enc1)
    # 0xbc, 0xed, 0x0, 0x7b, 0x86, 0xf4, 0x16, 0x93, 0x95, 0xf9, 0x87, 0xdc, 0x67, 0xa8, 0xa2, 0x7f, 
    # 0x4d, 0xe2, 0x62, 0x9f, 0x7b, 0x34, 0xae, 0xe9, 0x45, 0x3, 0x7e, 0x35, 0x42, 0xd0, 0x8b, 0x70, 
    # 0xf0, 0xfb, 0x2e, 0xc7, 0xdd, 0xe9, 0xb9, 0x73, 0xe3, 0xcc, 0x1a, 0x75, 0xad, 0xdc, 0xfd, 0x14, 
    # 0xa8, 0xc8, 0x45, 0x16, 0x31, 0x6e, 0x2a, 0x8, 0x2c, 0xf, 0x1d, 0x9f, 0x7, 0xba, 0xd5, 0xef
    '''
    for byte in enc1_byte:
        print(hex(byte), end=', ') 
    print()
    '''
    
    #RC4
    data = bytes(enc1_byte)
    key = bytes([0x76, 0x89, 0x33, 0x49, 0x19, 0x13, 0xC3, 0xC7, 0xAD, 0xD8, 0xE4, 0x68, 0xFC, 0x48, 0x04, 0xBC])
    enc2 = rc4(data, key)
    print(enc2)
    # b'C+vFCnHRGPghbmyQMXvFMRNd7fNCG8jcU+jcbnjRJTj2GTCOGUvgtOS0CTge7fNs'

    #base64
    table = "4yZRiNP8LoK/GSA5ElWkUjXtJCz7bMYcuFfpm6+hV0rxeHIdwv32QOTnqg1BDsa9"
    print(base64_kai_decode(enc2.decode(),table))
    # b'flag{C0ngr@tulat1on!Y0u_Re_suCces3fu1Ly_Signln!}'

3. bedtea

前面就是输入和两个反调试

29行的反调试动调的时候改一下rax寄存器的值就行

40行的反调试改一下ZF值为1即可,本来是往左边跳转(检测到调试),修改后往右边,异或0x33

主要加密部分,三个魔改TEA

轮数改了,key也是变化的

动调直接取key,是斐波那契数列

HIDWORD取最高位的dword,就是最左边(图一中是0xD),key就是最低位(图一中0x3),DWORD1比最低位高一个dword(图一中0x5),DWORD2比最低位高两个dword(图一中0x8)

37-39操作比较难看,实际上是通过二叉树对数据倒序,比较难看出来

数据都存到xmmword里面去了,可以查看一下xmmword_408060,发现里面的数据是动调出来密文的倒序

最后比对的地方,可以得到密文

#beatea_wp
from ctypes import * 
enc = [0x76,  0x71,  0x9D,  0xE7,  0x70,  0x77,  0x3F,  0xA3,  
    0x02,  0xF1,  0x8D,  0xC9,  0x02,  0xC6,  0xA2,  0x4B,  
    0xBA,  0x19,  0x56,  0x05,  0xF2,  0x89,  0x5E,  0xE0]

def byte2uint32_r(d):
    l=[]
    for i in range(len(d)//4):
        tmp=d[i*4:i*4+4]
        l.append(tmp[0]*256**3+tmp[1]*256**2+tmp[2]*256+tmp[3])
    return l

def hexprint(arr):
    for byte in arr:
        print(hex(byte), end=', ') 
    print()

for i in range(len(enc)):
    enc[i] ^= 0x33
hexprint(enc)

enc_uint32 = byte2uint32_r(enc)
enc_uint32 = enc_uint32[::-1]
hexprint(enc_uint32)

def tea_kai_de(v,k):
    v0=c_uint32(v[0])
    v1=c_uint32(v[1])
    delta=0x9E3449B8
    sum1=c_uint32(0x987E55D0)
    while(sum1.value != 0):
        v1.value -= ( (v0.value*32) + k[2] )^(v0.value + sum1.value)^( (v0.value >> 4) + k[3] )
        v0.value -= ( (v1.value*32) + k[0] )^(v1.value + sum1.value)^((v1.value >> 4) + k[1])
        sum1.value -= delta
    return v0.value,v1.value

def dec(enc,k,i):
    tmp = [0]*2
    tmp[0] = enc[i]
    tmp[1] = enc[i+1]
    tmp = tea_kai_de(tmp,k)
    enc[i] = tmp[0]
    enc[i+1] = tmp[1]

key1 = [0x3,0x5,0x8,0xD]
key2 = [0x15,0x22,0x37,0x59]
key3 = [0x90,0xE9,0x179,0x262]

dec(enc_uint32,key1,0)
dec(enc_uint32,key2,2)
dec(enc_uint32,key3,4)
hexprint(enc_uint32)

def uint322byte(uint32_list):
    byte_array = []
    for number in uint32_list:
        byte_array.append(number & 0xFF)
        byte_array.append((number >> 8) & 0xFF)
        byte_array.append((number >> 16) & 0xFF)
        byte_array.append((number >> 24) & 0xFF)
    return byte_array

flag_byte = uint322byte(enc_uint32)
hexprint(flag_byte)

flag = ''
for i in flag_byte:
    flag += chr(i)
print(flag)
#flag{y0u_reallyl1ke_te@}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值