Null Ahmedabad, апрель 2023 г., CTF Write-up

May 01 2023
Сообщество, известное как Null Ahmedabad, было основано группой из четырех человек. 18 февраля 2018 года состоялась их инаугурационная встреча, которая стала возможной при содействии Университета Ганпат.

Сообщество, известное как Null Ahmedabad, было основано группой из четырех человек. 18 февраля 2018 года состоялась их инаугурационная встреча, которая стала возможной при содействии Университета Ганпат. Их основное мероприятие — это ежемесячное собрание, на котором участники собираются для обсуждения вопросов безопасности и CTF (практических задач). Со временем Null Ahmedabad продолжает расширять свое присутствие, предлагая дополнительные форматы встреч и семинаров. Для всех, кто интересуется информационной безопасностью, будь то студент, энтузиаст или профессионал, Null Ahmedabad является идеальным сообществом, в котором можно общаться с другими хакерами и профессионалами в районе Ахмедабада.

В апреле 2023 года Null Ahmedabad организовал соревнование CTF, в котором мне удалось занять третье место. В результате этого достижения я решил написать рецензию.

Чтобы изучить нулевое сообщество, нажмите :https://null.community/chapters/17-ahmedabad

Фото Алекса Чумака на Unsplash

1. Отказано в доступе?

Подсказка вызова говорит:

Null Ahmedabad впервые запускает интернет-магазин одежды! Однако мы опасаемся, что в нашем коде могут быть уязвимости. Как член открытого сообщества безопасности, вам поручено найти и сообщить о любых уязвимостях (флаги), с которыми вы можете столкнуться.

Наш магазин находится по адресу:http://nullahm.kuldeep.io:5000/

Счастливые покупки! :)

Я начал изучать сайт; он имеет функцию входа и регистрации.

Я зарегистрировал свою учетную запись и вошел в систему. Я начал копаться в коде JavaScript и нашел конечную точку graphql.

Если вы знакомы с graphql, вы, вероятно, знаете, что он поддерживает запросы самоанализа, которые обычно запрещены по соображениям безопасности.

Итак, я попытался запустить запрос самоанализа, и это сработало.

Я проверил результат и нашел поле под названием «allUsers».

Я попытался получить доступ к узлу allUsers, и теперь я могу получить доступ к данным всех пользователей.

И я нашел флаг.

2. Прикрепленные строки

Подсказка вызова говорит:

Я уверен, что не оставил никаких секретов в этом бинарнике, но мой менеджер все еще сомневается во мне. Не могли бы вы проверить бинарный файл и доказать, что он ошибается?

Он имеет исполняемый двоичный файл для загрузки.

Я скачал бинарный файл, и его статистика метаданных:

64-битный исполняемый файл ELF LSB pie, x86–64, версия 1 (SYSV), динамически связанный, интерпретатор /lib64/ld-linux-x86–64.so.2, BuildID[sha1]=9b34236e59bfcdbdb606def64c05cdfdbce9753b, для GNU/Linux 4.4. 0, не раздетый

Это похоже на вызов старой школы; Я знаю, что формат флага — «nullahm». Поэтому я попытался использовать строки против двоичного файла.

строки -n 7 -tx chal | grep нуллам

Найден секрет в бинарнике.

3. Исторически незащищенный

Приглашение на вызов говорит:

Расшифруйте это и получите флаг: ubsshot{d4f_700_345f}

Это похоже на флаг, но он зашифрован, как говорится в подсказке. Если я сравниваю зашифрованный флаг с форматом флага, то есть «nullahm», кажется, что это шифр Виженера.

Vigenère Cipher уязвим для атак с известным открытым текстом. У меня есть часть известного открытого текста, т.е. ubsshot = nullahm.

Поэтому я написал небольшой скрипт для извлечения ключа:

def solve_historically_insecure(ciphertext, plaintext):

    ciphertext = ciphertext.upper()
    plaintext = plaintext.upper()
    key = ""
    for i in range(len(plaintext)):
        key += chr(((ord(ciphertext[i]) - ord(plaintext[i])) % 26) + ord('A'))
    return key
ciphertext = "ubsshot"
plaintext = "nullahm"
key = solve_historically_insecure(ciphertext, plaintext)
print("Key : ",key)

Теперь я могу использовать ключ против зашифрованного текста,

def vigenere_decode(ciphertext, key):
    plaintext = ''
    key_len = len(key)
    for i in range(len(ciphertext)):
        shift = ord(key[i % key_len]) - 65
        if ciphertext[i].isupper():
            plaintext += chr((ord(ciphertext[i]) - shift - 65) % 26 + 65)
        elif ciphertext[i].islower():
            plaintext += chr((ord(ciphertext[i]) - shift - 97) % 26 + 97)
        else:
            plaintext += ciphertext[i]
    return plaintext

ciphertext = "ubsshot{d4f_700_345f}"
key = solve_historically_insecure(ciphertext, plaintext)
plaintext = vigenere_decode(ciphertext, key)
print("Plain Text : ",plaintext)

      
                

Спасибо, что нашли время, чтобы прочитать эту запись.