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

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

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

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 -t x 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)

Нашел флаг.

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