das202311月赛

# PREFACE:说实话一直打不明白这个 das,这今年最后一次算是比较认真打的一次,最后是稳稳第一拿下了但是好像和我关系不大… 不能说没有贡献吧但是光自己做肯定是差很多的… 还是 tcl5555555

# misc

帮着看了一眼,有一道题提出来的是一个 upx 打包的 elf,简单分析发现用的 upx-4.2.1-amd64_linux 版本,直接官网找了再 upx -d 即可,里面 base64 变表,解出来即可

# re

# letsgo

dll 里面 upx 3.94,自己 upx file 加一个 dll 壳,发现了三四个被修改了的标志位,修复即可 upx -d

主程序没东西,有两个地方加载了 dll,断点查看,这里是抽卡用的逻辑

image-20231127102107311

里面有解压图片的操作:

image-20231127102211939

def split_and_process_file(input_file_path):
    # 读取原始文件
    with open(input_file_path, 'rb') as file:
        data = file.read()
    bytes_array = bytearray(data)
    for i in range(len(bytes_array) - 1, -1, -1):
        if i + 2 < len(bytes_array):
            bytes_array[i] ^= bytes_array[i + 2]
            bytes_array[i] ^= 0xf
        bytes_array[i] ^= 0xf
    with open(f'output_{1}.jpg', 'wb') as output_file:
        output_file.write(bytes_array)
split_and_process_file('D:\\reverse\\challange\\das11\\re\\DAS10letsgo\\letsgo\\res\\wwww')
def split_and_process_file(input_file_path):
    with open(input_file_path, 'rb') as file:
        data = file.read()
    split_pattern = b'\xff\xd8\xff\xe0'
    parts = data.split(split_pattern)
    for part_index, part in enumerate(parts):
        bytes_array = bytearray(b'\xFF\xD8\xFF\xE0') + bytearray(part)
        with open(f'flag_{part_index}.jpg', 'wb') as output_file:
            output_file.write(bytes_array)
split_and_process_file('output_1.jpg')

你们二次元差不多得了

image-20231127102432655

于是你发现前面做的没有意义

image-20231127102447196

那就只有这里了:

image-20231127102819995

这里拿到 key:

image-20231127102859858

这里是啥呢:

image-20231127103327070

画一下图发现是蒙特卡罗模拟 π,下面 COERCE_UNSIGNED_INT64 强制将 π 解释为整数,然后作为 seed 生成一组 xor 用的随机数

下面就是一个 aes192,这里 ida 反编译不出来,看看汇编即可找到 key 和密文

image-20231127103525934

image-20231127103542503

最搞心态的一点是,这里的蒙特卡罗模拟是跑不出来的(而且本身模拟 golang 也是一个相当麻烦的操作),首先你得猜这里就是 π,以及四舍五入的情况,进行一定量的爆破操作,结果这地方魔改源码在 rand 里面多加了一个异或!

image-20231127103758800

给你逆天逆完了

脚本:

package main
import (
	"fmt"
	"math"
	"math/rand"
)
func main() {
	bits := math.Float64bits(math.Pi)
	val := bits % 0x5F5E100
	rand.Seed(int64(val))
	key := make([]int, 0)
	for i := 0; i < 24; i++ {
		key = append(key, (rand.Int()^0xa)%100)
	}
	fmt.Println(key)
}
import struct
from Crypto.Cipher import AES
arr = [37, 49, 98, 48, 14, 17, 9, 47, 56, 91, 37, 69, 17, 3, 82, 64, 54, 76, 80, 88, 54, 97, 0, 53]
rawkey = struct.pack("<3Q", 0x5B566461493D5E41, 0x293A774E2E4B3250, 0x4C650A692B391345)
print(rawkey)
for i in range(len(arr)):
    arr[i] ^= rawkey[i]
key = bytes(arr)
aes = AES.new(key, AES.MODE_ECB)
m1 = aes.decrypt(bytes.fromhex("ff44ac7700732a16589f7ff8bdbaa923"))
m2 = aes.decrypt(bytes.fromhex("57c29c367a781ead5fb143469d75f319"))
print(m1 + m2)

# ezpython

image-20231127104104569

反编译拿到:

#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 3.11
import pyDes
def adjust_length(str):
    if len(str) < 8:
        str = str.ljust(8, '0')
    elif len(str) > 8:
        str = str[:8]
    return str
def yuanshen(array, start, end):
    num = len(array)
    dis = [
        float('inf')] * num
    tree = [
        False] * num
    parent = [
        -1] * num
    dis[start] = 0
# WARNING: Decompyle incomplete
def qidong(input, key, IV):
    cipher = pyDes.des(key, pyDes.CBC, IV, pad = None, padmode = pyDes.PAD_PKCS5)
    encrypted_data = cipher.encrypt(input)
    encrypted_hex_list = encrypted_data()
    return encrypted_hex_list
def main():
    data = [
        159,
        41,
        201,
        125,
        67,
        60,
        44,
        34,
        203,
        56,
        116,
        186,
        13,
        71,
        125,
        30,
        84,
        123,
        109,
        54,
        106,
        56,
        17,
        124,
        87,
        236,
        25,
        12,
        80,
        178,
        165,
        123]
    key = input('请输入key: ')
    if len(key) != 8:
        print('wrong key lenth!')
        exit()
    flag = input('请输入flag: ')
    array = [
        [
            0,
            float('inf'),
            float('inf'),
            1,
            3,
            4,
            float('inf'),
            float('inf'),
            float('inf')],
        [
            float('inf'),
            0,
            float('inf'),
            float('inf'),
            float('inf'),
            2,
            float('inf'),
            4,
            float('inf')],
        [
            float('inf'),
            float('inf'),
            0,
            8,
            1,
            float('inf'),
            float('inf'),
            float('inf'),
            1],
        [
            1,
            float('inf'),
            8,
            0,
            3,
            5,
            1,
            2,
            float('inf')],
        [
            3,
            float('inf'),
            1,
            3,
            0,
            float('inf'),
            1,
            5,
            3],
        [
            4,
            2,
            float('inf'),
            5,
            float('inf'),
            0,
            float('inf'),
            1,
            float('inf')],
        [
            float('inf'),
            float('inf'),
            float('inf'),
            1,
            1,
            float('inf'),
            0,
            float('inf'),
            5],
        [
            float('inf'),
            4,
            float('inf'),
            2,
            5,
            1,
            5,
            0,
            float('inf')],
        [
            float('inf'),
            float('inf'),
            1,
            float('inf'),
            3,
            float('inf'),
            float('inf'),
            float('inf'),
            0]]
    t = yuanshen(array, 1, 8)
    IV = (lambda .0: pass# WARNING: Decompyle incomplete
)(t())
    IV = adjust_length(IV)
    check = qidong(flag, key, IV)
    if check == data:
        print('yes,yes,yes!!')
        return None
    ''.join('bad,bad,bad!!')
main()

反编译有问题,iv 拿不到,但是就差八位

image-20231127111045546

晚点出个完整的 python 各个版本应对策略(立 flag & 鸽)dis 一下自己看

结合一下就加上 DASCTF{ 呗,给他爆一位: DASCTF{D0_U_4ls0_l1k3_7uansH3n}

TODO:后面再补,感觉麻烦死了新东西也不多 ,懒了