DeadSec CTF 2024 Misc Writeup


好久没做这么爽了噜
DK盾云服务器: DK盾
最近活动是香港的1-1-3 9.9/月

Misc

Welcome

进discord群签到即可

Mic check

就是他说什么就重复什么即可

from pwn import *
context.log_level="debug"
p = remote('34.121.62.108',31646)

for i in range(1, 101):
    response = p.recvuntil(b'submit test words > ').decode()
    word = response.split('>')[1].split('[')[0].strip()
    p.sendline(word.encode())
p.recv()
p.recv()

flag_injection

题目是这样的

from string import ascii_lowercase
from time import sleep
from os import getenv

ALPHABET     = set(ascii_lowercase + "_")
SECRET_FLAG  = getenv("FLAG", "DEAD{test_flag_which_is_exactly_this_long}")
SECRET_FLAG  = SECRET_FLAG.replace("{", "_").replace("}", "_").replace("DEAD","dead")

assert len(SECRET_FLAG) == 42, "Bad flag length"
assert set(SECRET_FLAG).issubset(ALPHABET), "Bad flag chars"

def get_flag():
    print(SECRET_FLAG)

def split_flag():
    start_offset = int(input("Start of flag substring: "))
    end_offset   = int(input("End of flag substring: "))
    new_flag     = SECRET_FLAG[start_offset:end_offset]
    assert       len(new_flag) >= 13, "Can't have such a small piece"
    anything     = input("Anything to add? Tell me: ").strip()[:20]
    assert       set(anything).issubset(ALPHABET), "That's a crazy thing to add!"
    new_flag     += anything
    globals()[new_flag] = ":)"

if __name__ == "__main__":
    split_flag()
    what_to_do = input("What should I do now? Tell: ")
    if not set(what_to_do).issubset(ALPHABET):
        print("Plz no hack :(")
    else:
        # No brute force for you. Test locally instead!
        sleep(10)
        print(eval(what_to_do))

弄了好一会,在本地都不知道怎么弄,毕竟只能用小写和下划线,没得括号可以用

突然发现会这样,上午在本地测的时候也遇到了,但是没想到

在这里插入图片描述

于是乎尝试让他自己说出flag

在这里插入图片描述

dead_ivswjlv

在这里插入图片描述

看来太长了是不行的

在这里插入图片描述

就一直这样下去就行了

最后拼接,得到dead_ivswjlvahxmifksxjgifrzfhljkdprcaubac_,然后下划线换成括弧,dead的大小写转换一下

验证一下

在这里插入图片描述

因此得到flag为DEAD{ivswjlvahxmifksxjgifrzfhljkdprcaubac}

GoLParty

生命游戏,要连续答对题目,我用这个修改的:https://github.com/thomas-broethaler/conways-game-of-life/blob/master/conways_game_of_life.ipynb

然后要注意的点主要就是接收整个情况了

from pwn import *
import numpy as np
from copy import deepcopy


class GameOfLife:

    def __init__(self, cells=[], generations=1):
        self.cells = cells.copy()
        self.generations = generations
        self.dim_y = len(cells)
        self.dim_x = len(cells[0])
        self.cur_dim_y = 0
        self.cur_dim_x = 0

    def get_neighbors(self, y, x):
        neighbor_list = []
        for i in range(y - 1, y + 2):
            if i < 0 or i > (self.cur_dim_y - 1):
                continue
            else:
                for j in range(x - 1, x + 2):
                    if j < 0 or j > (self.cur_dim_x - 1):
                        continue
                    elif i == y and j == x:
                        continue
                    else:
                        neighbor_list.append(self.cells[i][j])
        return neighbor_list

    def check_neighbors(self, cur_cell, neighbor_list):
        next_gen_cell = cur_cell
        alive_count = neighbor_list.count(1)
        if cur_cell == 1:
            if alive_count == 2 or alive_count == 3:
                next_gen_cell = 1
            else:
                next_gen_cell = 0
        else:
            if alive_count == 3:
                next_gen_cell = 1
        return next_gen_cell

    def add_empty_boarder(self, cur_field, cur_dim_y, cur_dim_x):
        new_field = np.zeros((cur_dim_y + 2, cur_dim_x + 2))
        for y, row in enumerate(cur_field):
            for x, cur_cell in enumerate(row):
                new_field[y + 1, x + 1] = cur_cell
        return new_field

    def remove_empty_boarder(self, new_cells):
        new_cells = np.array(new_cells)
        removing = True
        while removing == True:
            if len(new_cells) == 0:
                return [[]]
            elif np.count_nonzero(new_cells[0]) == 0:
                new_cells = np.delete(new_cells, 0, 0)
            elif np.count_nonzero(new_cells[::-1][0]) == 0:
                new_cells = np.delete(new_cells, -1, 0)
            elif np.count_nonzero(new_cells.T[0]) == 0:
                new_cells = np.delete(new_cells, 0, 1)
            elif np.count_nonzero(new_cells.T[::-1][0]) == 0:
                new_cells = np.delete(new_cells, -1, 1)
            else:
                removing = False
        return new_cells

    def evaluate_generations(self):
        self.cells = deepcopy(self.add_empty_boarder(self.cells, self.dim_y, self.dim_x))
        new_cells = deepcopy(self.cells)
        for generation in range(0, self.generations):
            self.cur_dim_y = len(self.cells)
            self.cur_dim_x = len(self.cells[0])
            new_cells = deepcopy(self.add_empty_boarder(new_cells, self.cur_dim_y, self.cur_dim_x))
            self.cells = deepcopy(new_cells)
            for y, row in enumerate(self.cells):
                for x, cur_cell in enumerate(row):
                    neighbor_list = self.get_neighbors(y, x)
                    new_cells[y][x] = self.check_neighbors(cur_cell, neighbor_list)
        new_cells = self.remove_empty_boarder(new_cells)
        return new_cells.tolist()


def get_generation(cells, generations):
    result = GameOfLife(cells=cells, generations=generations)
    return result.evaluate_generations()


context.log_level = "debug"
p = remote('34.44.175.226', 31532)

p.recvuntil(b'Game On :D')

correct_count = 0
first_time = True
while correct_count < 10:
    if first_time:
        initial_grid = p.recvuntil(b'[*]').decode().split('\n')[2:-2]
        first_time = False
    else:
        initial_grid = p.recvuntil(b'[*]').decode().split('\n')[:-2]

    p.recvuntil(b' Enter the number of live cells after ')
    generations = int(p.recvuntil(b' generations: ').decode().split(' ')[0])

    def parse_grid(grid):
        return [[1 if cell == '■' else 0 for cell in row] for row in grid]
    print(len(initial_grid),initial_grid)

    initial_grid_array = parse_grid(initial_grid)

    result_grid = get_generation(initial_grid_array, generations)
    live_cells_after_generations = sum(sum(row) for row in result_grid)

    print(f"Number of live cells after {generations} generations: {live_cells_after_generations}")

    p.sendline(str(int(live_cells_after_generations)).encode())

    response = p.recvline()
    print(response.decode())

    if b'Correct!' in response:
        correct_count += 1
    else:
        exit()

    #b'[+] Correct!\n'
    #b'[*] Game Over! Thank you for playing.\n'
    #b'[+] Congratulations! Here is your flag: DEAD{GoL_P4rty_W4s_4_Fun_4nd_1ntr1gu1ng_G4m3}'

MAN in the middle

这个题吧,昨天想了一天都不知道怎么处理01串,今天刚起来晃了一眼题就想明白了。

首先拿到的是一个音频文件

在这里插入图片描述

放大看能发现

在这里插入图片描述

因此尝试直接去看十六进制,发现只有32767和-32767这两种。然后每种长度是44个短样本,写个脚本把他转换成01串

def convert_waveform_to_binary(input_file, output_file):
    with open(input_file, 'rb') as f:
        data = f.read()

    binary_data = []
    for i in range(0, len(data), 88):
        sample = data[i:i+88]
        if sample == b'\xFF\x7F' * 44:
            binary_data.append('1')
        elif sample == b'\x01\x80' * 44:
            binary_data.append('0')
        else:
            print(f"Unexpected value: {sample[:8]}... (showing first 8 bytes)")

    binary_string = ''.join(binary_data)

    with open(output_file, 'w') as f:
        f.write(binary_string)

    print(f"Decoded binary data written to {output_file}")

convert_waveform_to_binary('flag.data', 'binary_output.txt') #flag.data是wav的纯data数据,去掉了开头部分

得到01串后,首先会发现不是直接能from binary的,猜测是一种波形编码。

这里经过尝试后没有解出来,第二天才发现是在转换的时候自己弄错了,实际上就直接按照01和10替换成1和0就行。

with open('binary_output.txt', 'r') as file:
    binary_str = file.readline().strip()

converted_str = ""

for i in range(0, len(binary_str), 2):
    pair = binary_str[i:i + 2]
    if pair == "10":
        converted_str += "0"
    elif pair == "01":
        converted_str += "1"
    else:
        pass
    
print(converted_str)
#0110110101100001011011100110001101101000011001010111001101110100011001010111001000100000011001010110111001100011011011110110010001101001011011100110011100100000011010010111001100100000011000010010000001101101011001010111010001101000011011110110010000100000011011110110011000100000011001010110111001100011011011110110010001101001011011100110011100100000011001000110100101100111011010010111010001100001011011000010000001100100011000010111010001100001001000000110100101101110001000000111011101101000011010010110001101101000001000000110010101100001011000110110100000100000011000100110100101110100001000000110111101100110001000000110010001100001011101000110000100100000011010010111001100100000011100100110010101110000011100100110010101110011011001010110111001110100011001010110010000100000011000100111100100100000011101000111011101101111001000000111011001101111011011000111010001100001011001110110010100100000011011000110010101110110011001010110110001110011001011000010000001100101011011100111001101110101011100100110100101101110011001110010000001100001001000000111010001110010011000010110111001110011011010010111010001101001011011110110111000100000011000010111010000100000011101000110100001100101001000000110110101101001011001000110010001101100011001010010000001101111011001100010000001100101011000010110001101101000001000000110001001101001011101000010000001110000011001010111001001101001011011110110010000101110001000000111010001101000011010010111001100100000011101000111001001100001011011100111001101101001011101000110100101101111011011100010000001110011011001010111001001110110011001010111001100100000011000010111001100100000011000100110111101110100011010000010000001100001001000000110001101101100011011110110001101101011001000000110000101101110011001000010000001100100011000010111010001100001001000000111001101101001011001110110111001100001011011000010110000100000011011010110000101101011011010010110111001100111001000000110100101110100001000000110100001101001011001110110100001101100011110010010000001100101011001100110011001100101011000110111010001101001011101100110010100100000011001100110111101110010001000000111001101111001011011100110001101101000011100100110111101101110011011110111010101110011001000000110001101101111011011010110110101110101011011100110100101100011011000010111010001101001011011110110111000101110001000000110010001100101011101100110010101101100011011110111000001100101011001000010000001100010011110010010000001100111001011100010000001100101001011100010000001110100011010000110111101101101011000010111001100101100001000000110110101100001011011100110001101101000011001010111001101110100011001010111001000100000011001010110111001100011011011110110010001101001011011100110011100100000011010010111001100100000011101110110100101100100011001010110110001111001001000000111010101110011011001010110010000100000011010010110111000100000011101100110000101110010011010010110111101110101011100110010000001100011011011110110110101101101011101010110111001101001011000110110000101110100011010010110111101101110001000000111000001110010011011110111010001101111011000110110111101101100011100110010110000100000011010010110111001100011011011000111010101100100011010010110111001100111001000000110010101110100011010000110010101110010011011100110010101110100001011100010000001101001011101000111001100100000011100000111001001101001011011010110000101110010011110010010000001100001011001000111011001100001011011100111010001100001011001110110010100100000011011000110100101100101011100110010000001101001011011100010000001101001011101000111001100100000011100100110111101100010011101010111001101110100011011100110010101110011011100110010000001100001011001110110000101101001011011100111001101110100001000000111010001101001011011010110100101101110011001110010000001100101011100100111001001101111011100100111001100100000011000010110111001100100001000000110010101100001011100110110010100100000011011110110011000100000011000110110110001101111011000110110101100100000011100100110010101100011011011110111011001100101011100100111100100101100001000000110000101110011001000000111010001101000011001010010000001110010011001010110011101110101011011000110000101110010001000000111010001110010011000010110111001110011011010010111010001101001011011110110111001110011001000000110010101101110011000010110001001101100011001010010000001110100011010000110010100100000011100100110010101100011011001010110100101110110011001010111001000100000011101000110111100100000011011010110000101101001011011100111010001100001011010010110111000100000011100110111100101101110011000110110100001110010011011110110111001101001011110100110000101110100011010010110111101101110001000000111011101101001011101000110100000100000011101000110100001100101001000000111010001110010011000010110111001110011011011010110100101110100011101000110010101110010001011100010000001100010011110010010000001100101011011010110001001100101011001000110010001101001011011100110011100100000011101000110100001100101001000000110001101101100011011110110001101101011001000000111001101101001011001110110111001100001011011000010000001110111011010010111010001101000011010010110111000100000011101000110100001100101001000000110010001100001011101000110000100100000011100110111010001110010011001010110000101101101001011000010000001101101011000010110111001100011011010000110010101110011011101000110010101110010001000000110010101101110011000110110111101100100011010010110111001100111001000000110110101101001011101000110100101100111011000010111010001100101011100110010000001110100011010000110010100100000011100100110100101110011011010110010000001101111011001100010000001110011011110010110111001100011011010000111001001101111011011100110100101111010011000010111010001101001011011110110111000100000011011000110111101110011011100110010110000100000011011010110000101101011011010010110111001100111001000000110100101110100001000000110000100100000011100100110010101101100011010010110000101100010011011000110010100100000011000110110100001101111011010010110001101100101001000000110011001101111011100100010000001101000011010010110011101101000001011010111001101110000011001010110010101100100001000000110010001101001011001110110100101110100011000010110110000100000011001000110000101110100011000010010000001110100011100100110000101101110011100110110110101101001011100110111001101101001011011110110111000101110001000000110000101101110011001000010000001101000011001010111001001100101001000000110100101110011001000000111100101101111011101010111001000100000011001100110110001100001011001110011101000100000011001000110010101100001011001000111101101101101001101000110111001100011011010000011001100110101001101110011001101110010010111110011010001011111001101110110100000110011010111110111011100110001011011100111110100100000011001110110111101101111011001000010000001101010011011110110001000100001

得到flag:dead{m4nch3573r_4_7h3_w1n}

Forgotten Password

题目描述是这样的:

I was going to create this extremely easy forensics challenge for you, but accidentally used the flag as the password when I encrypted the archive. This flag is now deleted, and since it is not possible to brute-force it, I guess that means this challenge can no longer be solved, or can it?

给了两个文件,一个加密的zip,一个py文件,内容是这样的:

from io import BytesIO
import os
import subprocess
import pycdlib # pip install pycdlib

try:
    FLAG = open("flag.txt","r").read()
except FileNotFoundError:
    FLAG = "fake_flag_for_testing"

iso = pycdlib.PyCdlib()
iso.new(interchange_level=4)

iso.add_fp(BytesIO(FLAG.encode()), len(FLAG), '/flag.txt;1')

iso.write('challenge.iso')
iso.close()

subprocess.check_output(["zip", "challenge.zip", "challenge.iso", "-P", FLAG])

其实给出这个py文件主要就是生成iso

这里手动也生成两个iso,先单独对比两个iso的区别:

在这里插入图片描述

不同点在于生成的时间,但是比赛的iso不清楚时区,所以我就放弃去还原这个

接着用zip压缩这俩文件,分别得到这样的

在这里插入图片描述

发现都有32字节的\x00,其实拿到题的时候就想用bkcrack,但是注意到https://github.com/kimci86/bkcrack/blob/master/example/tutorial.md里说的

The not so easy way: deflated file
Let us assume the zip file did not contain the uncompressed spiral.svg.

Then, to guess some plaintext, we can guess the first bytes of the original advice.jpg file from its extension. The problem is that this file is compressed. To run the attack, one would have to guess how those first bytes are compressed, which is difficult without knowing the entire file.

In this example, this approach is not practical. It can be practical if the original file can easily be found online, like a .dll file for example. Then, one would compress it using various compression software and compression levels to try and generate the correct plaintext.

通常来说都是对储存的进行明文,而对于压缩的,很难去做,通常都是有完全相同的文件

这里看到有相同的32字节的00,就在思考是否可以尝试用bkcrack去爆破呢,由于这个00字节虽然是32,但是无法得知是在何处开始

虽然不知道何处开始,但是能观察到创建的例子开头第一个是在61处,第二是在64处,由于只需要12位已知,因此可以折中选择一个,然后用16的大小

首先bkcrack -L challenge.zip看看

bkcrack 1.7.0 - 2024-05-26
Archive: .\challenge.zip
Index Encryption Compression CRC32    Uncompressed  Packed size Name
----- ---------- ----------- -------- ------------ ------------ ----------------
    0 ZipCrypto  Deflate     17ee7183        53248          382 challenge.iso

接着尝试破解.\bkcrack.exe -C .\challenge.zip -c challenge.iso -x 68 0000000000000000000000000000

在这里插入图片描述

得到key是6b13ebc5 cc0be8ac 709e18f9

然后.\bkcrack.exe -C .\challenge.zip -k 6b13ebc5 cc0be8ac 709e18f9 -D dec.zip

解压后直接搜索即可

在这里插入图片描述

DEAD{weird_how_this_encryption_is_the_default_in_2024}

Crypto

Flag killer

from binascii import hexlify, unhexlify

def FLAG_KILLER(value):
    index = 0
    temp = []
    output = 0
    while value > 0:
        temp.append(2 - (value % 4) if value % 2 != 0 else 0)
        value = (value - temp[index]) // 2
        index += 1
    temp = temp[::-1]
    for index in range(len(temp)):
        output += temp[index] * 3 ** (len(temp) - index - 1)
    return output

output = '0e98b103240e99c71e320dd330dd430de2629ce326a4a2b6b90cd201030926a090cfc5269f904f740cd1001c290cd10002900cd100ee59269a8269a026a4a2d05a269a82aa850d03a2b6b900883'

def reverse_FLAG_KILLER(output_segment):
    for i in range(4096):
        if FLAG_KILLER(i) == int(output_segment, 16):
            return i
    return None

index = 0
reversed_flag = ''
while index < len(output):
    segment = output[index:index+5]
    original_value = reverse_FLAG_KILLER(segment)
    if original_value is None:
        print("Error: No matching value found.")
        break
    reversed_flag += '%03x' % original_value
    index += 5
print(reversed_flag)
#444541447b3236336638373165383830653964633764323430313030303330346663363065393863376335383807d 注意07d改成7d
#-->DEAD{263f871e880e9dc7d2401000304fc60e98c7c588}
CTF中的Miscellaneous(简称Misc)是指一类涵盖了多个领域的题目,常见的包括密码学、网络协议、二进制分析等。 在CTF比赛中,解决这类题目的方法主要有以下几种: 1. 阅读题目描述:首先要仔细阅读题目描述,通常会提供一些线索或提示,例如题目类型、题目背景或所需的技术知识。这些大致的信息能够帮助你确定解题方法的方向。 2. 分析题目附件或源代码:如果题目提供了附件或源代码,要仔细分析其中的内容。有时可能需要进行逆向工程、二进制分析或查找隐藏信息。需要注意的是,不同题目类型可能需要使用不同的分析工具和技术。 3. 猜测和尝试:在整个解题过程中,可能需要多次猜测和尝试。例如,对于密码学类题目,尝试使用不同类型的密码学算法进行解密;对于网络协议类题目,尝试使用Wireshark等工具进行数据包分析。 4. 查找前人的经验:CTF解题是一个积累经验的过程,很多题目类型都有经典解法,可以通过学习前人的经验来提高解题效率。可以参考CTF比赛的writeup、CTF讨论论坛或CTF相关的学习资源等。 5. 团队合作:在解题过程中,可以与队友或其他选手进行合作,分享解题过程中的思路和发现。这样可以锻炼团队合作的能力,也能够快速找到解题思路或解题方法。 综上所述,CTFMisc题目的解题方法主要包括阅读题目描述、分析附件或源代码、猜测和尝试、查找前人的经验以及团队合作等。通过不断学习和实践,提高解题的技巧和经验,才能更好地应对各种Misc题目的挑战。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值