• XSS.stack #1 – первый литературный журнал от юзеров форума

CrackMe CTF Challenge

4nt1_t3rr0r

floppy-диск
Пользователь
Регистрация
09.09.2024
Сообщения
4
Реакции
1
Привет всем,

Я работаю над задачей CTF, которая включает в себя реверс-инжиниринг флага и анализ основной функции предоставленного бинарного файла. Вот с чем я столкнулся до сих пор:

Описание задачи:

Цель - выполнить реверс-инжиниринг бинарного файла, чтобы извлечь флаг. Формат флага ожидается как алфавитно-цифровой, заключённый в фигурные скобки.

Буду благодарен за любые советы по подходу к декодированию или расшифровке флага, если он зашифрован или замаскирован.



C#:
// CrackMe
// Token: 0x06000003 RID: 3 RVA: 0x0000206C File Offset: 0x0000026C
public static void Main(string[] args)
{
    Console.Write("Please enter the flag:");
    string text = Console.ReadLine();
    bool flag = text.Length == 24 && (int)(text.get_Chars(19) - text.get_Chars(3) * text.get_Chars(16) + text.get_Chars(10)) == -6684 && text.get_Chars(4) * text.get_Chars(21) + text.get_Chars(8) + text.get_Chars(11) == 'ར' && text.get_Chars(15) * text.get_Chars(14) - text.get_Chars(16) + text.get_Chars(14) == '◓' && text.get_Chars(12) * text.get_Chars(0) - text.get_Chars(15) - text.get_Chars(12) == '᷄' && text.get_Chars(23) + text.get_Chars(23) * text.get_Chars(1) == '␢' && (int)(text.get_Chars(19) - text.get_Chars(2) - text.get_Chars(16) - text.get_Chars(20)) == -218 && (int)(text.get_Chars(6) - text.get_Chars(12) - text.get_Chars(6) + text.get_Chars(5)) == -33 && (int)(text.get_Chars(0) * text.get_Chars(23) * text.get_Chars(1) + text.get_Chars(8)) == 611447 && text.get_Chars(4) + text.get_Chars(11) + text.get_Chars(2) - text.get_Chars(7) == '~' && text.get_Chars(7) * text.get_Chars(9) - text.get_Chars(9) == '⸺' && text.get_Chars(20) * text.get_Chars(3) + text.get_Chars(19) * text.get_Chars(21) == '⒖' && (int)(text.get_Chars(9) - text.get_Chars(14) * text.get_Chars(2) + text.get_Chars(17)) == -6266 && text.get_Chars(8) * text.get_Chars(21) + text.get_Chars(21) + text.get_Chars(13) == 'ၬ' && text.get_Chars(15) + text.get_Chars(8) - text.get_Chars(18) == 'M' && (int)(text.get_Chars(9) - text.get_Chars(15) * text.get_Chars(15)) == -10307 && (int)(text.get_Chars(19) - text.get_Chars(12) - text.get_Chars(5) * text.get_Chars(19)) == -4267 && (int)(text.get_Chars(12) - text.get_Chars(15) - text.get_Chars(0) - text.get_Chars(17)) == -149 && text.get_Chars(2) + text.get_Chars(16) + text.get_Chars(5) == 'þ' && (int)(text.get_Chars(22) * text.get_Chars(4) * text.get_Chars(21) * text.get_Chars(11)) == 23525040 && text.get_Chars(12) + text.get_Chars(14) - text.get_Chars(9) + text.get_Chars(10) == '×' && text.get_Chars(10) + text.get_Chars(7) - text.get_Chars(1) == '\u0096' && text.get_Chars(13) - text.get_Chars(22) + text.get_Chars(5) * text.get_Chars(11) == '▥' && text.get_Chars(15) * text.get_Chars(10) + text.get_Chars(23) - text.get_Chars(21) == '⠝' && text.get_Chars(14) + text.get_Chars(2) - text.get_Chars(14) == 'D' && text.get_Chars(23) - text.get_Chars(4) - text.get_Chars(19) == '\b' && text.get_Chars(8) + text.get_Chars(16) - text.get_Chars(3) + text.get_Chars(17) == 'Ì' && text.get_Chars(7) + text.get_Chars(18) + text.get_Chars(11) == 'Ŏ' && text.get_Chars(22) * text.get_Chars(5) - text.get_Chars(8) + text.get_Chars(20) == 'ሦ' && text.get_Chars(22) * text.get_Chars(21) - text.get_Chars(14) == 'ன' && (int)(text.get_Chars(8) - text.get_Chars(11) * text.get_Chars(1) * text.get_Chars(4)) == -557502 && text.get_Chars(9) + text.get_Chars(10) - text.get_Chars(18) == 'd' && text.get_Chars(12) - text.get_Chars(2) + text.get_Chars(21) * text.get_Chars(21) == '౱' && text.get_Chars(5) + text.get_Chars(15) - text.get_Chars(19) == '\u0088' && text.get_Chars(20) * text.get_Chars(12) + text.get_Chars(3) == 'ⴍ' && (int)(text.get_Chars(13) * text.get_Chars(12) * text.get_Chars(7)) == 1669356 && text.get_Chars(5) * text.get_Chars(13) - text.get_Chars(23) == '▓' && text.get_Chars(4) - text.get_Chars(6) + text.get_Chars(10) == 'a' && text.get_Chars(9) + text.get_Chars(20) + text.get_Chars(17) == 'Ĥ' && text.get_Chars(20) + text.get_Chars(1) + text.get_Chars(5) * text.get_Chars(21) == 'ጋ' && text.get_Chars(14) * text.get_Chars(11) + text.get_Chars(13) - text.get_Chars(18) == '⩡' && text.get_Chars(23) - text.get_Chars(21) + text.get_Chars(4) * text.get_Chars(2) == 'ሑ' && text.get_Chars(18) * text.get_Chars(23) + text.get_Chars(3) * text.get_Chars(9) == '䣀' && text.get_Chars(8) + text.get_Chars(17) + text.get_Chars(15) + text.get_Chars(9) == 'Ű' && (int)(text.get_Chars(19) - text.get_Chars(15) + text.get_Chars(15) - text.get_Chars(21)) == -6 && text.get_Chars(13) - text.get_Chars(7) + text.get_Chars(6) * text.get_Chars(6) == 'ጝ' && text.get_Chars(8) + text.get_Chars(12) - text.get_Chars(19) + text.get_Chars(6) == 'Ñ' && (int)(text.get_Chars(14) - text.get_Chars(16) - text.get_Chars(15) * text.get_Chars(23)) == -12757 && text.get_Chars(11) - text.get_Chars(6) + text.get_Chars(18) == '\u008d';
    if (flag)
    {
        Console.WriteLine("You found the FLAG!");
    }
    else
    {
        Console.WriteLine("Flag is not correct :(");
    }
}

1.png
 
The binary expects a flag of length 24 in complex mathematical expressions involve character Unicode like 'ར', '◓'...

You need to work on solving each of the conditions

Код:
(int)(text.get_Chars(19) - text.get_Chars(3) * text.get_Chars(16) + text.get_Chars(10)) == -6684:
This involves characters at positions 19, 3, 16, and 10 as example

i can suggest Ghidra, IDA Pro, or Binary Ninja to understand exactly how the flag is validated. disassemble it to see the actual instructions and calculations and use breakpoints to track variable states at runtime and observe how the flag is processed.


Python:
import string
chars = string.ascii_letters + string.digits
def check_flag(flag):
    try:
        if len(flag) != 24:
            return False
        # Add conditions one by one
        if ord(flag[19]) - ord(flag[3]) * ord(flag[16]) + ord(flag[10]) != -6684:
            return False
        if ord(flag[4]) * ord(flag[21]) + ord(flag[8]) + ord(flag[11]) != ord('ར'):
            return False
        if ord(flag[15]) * ord(flag[14]) - ord(flag[16]) + ord(flag[14]) != ord('◓'):
            return False
        # Add the reset of conditions here ....
        return True
    except:
        return False

# Brute-force
def brute_force_flag():
    for c0 in chars:
        for c1 in chars:
            flag = c0 + c1  # Adjust the positions as needed
            if check_flag(flag):
                return flag

flag = brute_force_flag()
if flag:
    print("Flag found:", flag)
else:
    print("Flag not found")

Run the script to try and find valid flag characters based on the conditions ( i didnt write all conditions , you need add them all )
 
ive write it down will all conditions ..

Python:
import string
chars = string.ascii_letters + string.digits
def check_flag(flag):
    try:
        if len(flag) != 24:
            return False
        
        if ord(flag[19]) - ord(flag[3]) * ord(flag[16]) + ord(flag[10]) != -6684:
            return False
        if ord(flag[4]) * ord(flag[21]) + ord(flag[8]) + ord(flag[11]) != ord('ར'):
            return False
        if ord(flag[15]) * ord(flag[14]) - ord(flag[16]) + ord(flag[14]) != ord('◓'):
            return False
        if ord(flag[12]) * ord(flag[0]) - ord(flag[15]) - ord(flag[12]) != ord('᷄'):
            return False
        if ord(flag[23]) + ord(flag[23]) * ord(flag[1]) != ord('␢'):
            return False
        if ord(flag[19]) - ord(flag[2]) - ord(flag[16]) - ord(flag[20]) != -218:
            return False
        if ord(flag[6]) - ord(flag[12]) - ord(flag[6]) + ord(flag[5]) != -33:
            return False
        if ord(flag[0]) * ord(flag[23]) * ord(flag[1]) + ord(flag[8]) != 611447:
            return False
        if ord(flag[4]) + ord(flag[11]) + ord(flag[2]) - ord(flag[7]) != ord('~'):
            return False
        if ord(flag[7]) * ord(flag[9]) - ord(flag[9]) != ord('⸺'):
            return False
        if ord(flag[20]) * ord(flag[3]) + ord(flag[19]) * ord(flag[21]) != ord('⒖'):
            return False
        if ord(flag[9]) - ord(flag[14]) * ord(flag[2]) + ord(flag[17]) != -6266:
            return False
        if ord(flag[8]) * ord(flag[21]) + ord(flag[21]) + ord(flag[13]) != ord('ၬ'):
            return False
        if ord(flag[15]) + ord(flag[8]) - ord(flag[18]) != ord('M'):
            return False
        if ord(flag[9]) - ord(flag[15]) * ord(flag[15]) != -10307:
            return False
        if ord(flag[19]) - ord(flag[12]) - ord(flag[5]) * ord(flag[19]) != -4267:
            return False
        if ord(flag[12]) - ord(flag[15]) - ord(flag[0]) - ord(flag[17]) != -149:
            return False
        if ord(flag[2]) + ord(flag[16]) + ord(flag[5]) != ord('þ'):
            return False
        if ord(flag[22]) * ord(flag[4]) * ord(flag[21]) * ord(flag[11]) != 23525040:
            return False
        if ord(flag[12]) + ord(flag[14]) - ord(flag[9]) + ord(flag[10]) != ord('×'):
            return False
        if ord(flag[10]) + ord(flag[7]) - ord(flag[1]) != ord('\u0096'):
            return False
        if ord(flag[13]) - ord(flag[22]) + ord(flag[5]) * ord(flag[11]) != ord('▥'):
            return False
        if ord(flag[15]) * ord(flag[10]) + ord(flag[23]) - ord(flag[21]) != ord('⠝'):
            return False
        if ord(flag[14]) + ord(flag[2]) - ord(flag[14]) != ord('D'):
            return False
        if ord(flag[23]) - ord(flag[4]) - ord(flag[19]) != ord('\b'):
            return False
        if ord(flag[8]) + ord(flag[16]) - ord(flag[3]) + ord(flag[17]) != ord('Ì'):
            return False
        if ord(flag[7]) + ord(flag[18]) + ord(flag[11]) != ord('Ŏ'):
            return False
        if ord(flag[22]) * ord(flag[5]) - ord(flag[8]) + ord(flag[20]) != ord('ሦ'):
            return False
        if ord(flag[22]) * ord(flag[21]) - ord(flag[14]) != ord('ன'):
            return False
        if ord(flag[8]) - ord(flag[11]) * ord(flag[1]) * ord(flag[4]) != -557502:
            return False
        if ord(flag[9]) + ord(flag[10]) - ord(flag[18]) != ord('d'):
            return False
        if ord(flag[12]) - ord(flag[2]) + ord(flag[21]) * ord(flag[21]) != ord('౱'):
            return False
        if ord(flag[5]) + ord(flag[15]) - ord(flag[19]) != ord('\u0088'):
            return False
        if ord(flag[20]) * ord(flag[12]) + ord(flag[3]) != ord('ⴍ'):
            return False
        if ord(flag[13]) * ord(flag[12]) * ord(flag[7]) != 1669356:
            return False
        if ord(flag[5]) * ord(flag[13]) - ord(flag[23]) != ord('▓'):
            return False
        if ord(flag[4]) - ord(flag[6]) + ord(flag[10]) != ord('a'):
            return False
        if ord(flag[9]) + ord(flag[20]) + ord(flag[17]) != ord('Ĥ'):
            return False
        if ord(flag[20]) + ord(flag[1]) + ord(flag[5]) * ord(flag[21]) != ord('ጋ'):
            return False
        if ord(flag[14]) * ord(flag[11]) + ord(flag[13]) - ord(flag[18]) != ord('⩡'):
            return False
        if ord(flag[23]) - ord(flag[21]) + ord(flag[4]) * ord(flag[2]) != ord('ሑ'):
            return False
        if ord(flag[18]) * ord(flag[23]) + ord(flag[3]) * ord(flag[9]) != ord('䣀'):
            return False
        if ord(flag[8]) + ord(flag[17]) + ord(flag[15]) + ord(flag[9]) != ord('Ű'):
            return False
        if ord(flag[19]) - ord(flag[15]) + ord(flag[15]) - ord(flag[21]) != -6:
            return False
        if ord(flag[13]) - ord(flag[7]) + ord(flag[6]) * ord(flag[6]) != ord('ጝ'):
            return False
        if ord(flag[8]) + ord(flag[12]) - ord(flag[19]) + ord(flag[6]) != ord('Ñ'):
            return False
        if ord(flag[14]) - ord(flag[16]) - ord(flag[15]) * ord(flag[23]) != -12757:
            return False
        if ord(flag[11]) - ord(flag[6]) + ord(flag[18]) != ord('\u008d'):
            return False
        
        return True

    except:
        return False

# Brute-force
def brute_force_flag():
    for c0 in chars:
        for c1 in chars:
            for c2 in chars:
                flag = c0 + c1 + c2 + "..."  # Keep building the flag step by step
                if check_flag(flag):
                    return flag

flag = brute_force_flag()
if flag:
    print("Flag found:", flag)
else:
    print("Flag not found")

You can expand the brute-force loop to include 24 characters, start with small parts of the flag and add the loops gradually to improve performance, especially since brute-forcing can be time-consuming.

again reverse-engineering specific parts of the flag using Ghidra or IDA will be way better...
 
Вижу 2 варианта решения:
1. Symbolic Execution, что по сути = брутфорсу 36^24(a-z0-9) вариантов
2. Это буквально система выражений в матане, в этом я не силен конечно, но возможно просто есть выражение с одной неизвестной (возможно есть для матана уже инструменты для патоматического решения системы уравнений), например такой https://mathforyou.net/online/equation/system/ (но тут до 10 лимит)

А вообще поиграл бы с тобой в цтф, хех
 
Последнее редактирование:


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх