Ласкаво просимо назад, ентузіасти CTF! Сьогодні ми вирішуємо задачу "Vault Door 3" з PicoCTF 2019 (продовження цих задач: zero, one). Ця задача пов'язана з реверс-інженерінгом (Reverse Engineering) Java коду та розумінням того, як цикли та масиви символів маніпулюють паролем. Давайте розберемо все поетапно, щоб отримати флаг!
Опис задачі
- Подія (Event): PicoCTF 2019
- Назва задачі (Challenge Name): Vault Door 3
- Категорія (Category): Реверс-інженерія (Reverse Engineering)
- Складність (Difficulty): Середня (Medium)
- Посилання (Link): тут
Опис задачі
Цей сейф використовує цикли for (for-loops) та масиви байтів (byte arrays). Джерельний код цього сейфа знаходиться тут: VaultDoor3.java
Підказки (Hints): Створіть таблицю, що містить значення змінних циклів і відповідні індекси буфера, в які вони записують значення.
Крок 1: Розуміння коду
Задача надає наступний код Java (важлива частина — це метод checkPassword, який перевіряє пароль):
import java.util.*;
class VaultDoor3 {
public static void main(String args[]) {
VaultDoor3 vaultDoor = new VaultDoor3();
Scanner scanner = new Scanner(System.in);
System.out.print("Enter vault password: ");
String userInput = scanner.next();
String input = userInput.substring("picoCTF{".length(),userInput.length()-1);
if (vaultDoor.checkPassword(input)) {
System.out.println("Access granted.");
} else {
System.out.println("Access denied!");
}
}
// Наша команда моніторингу безпеки помітила деякі вторгнення на менш захищені двері.
// Доктор Зло попросив мене побудувати міцнішу
// двері сейфа для захисту своїх планів кінця світу. Я просто *знаю*, що ці двері
// не дозволять якимось допитливим агентам проникнути в наші справи. Муа ха!
//
// -Міньйон #2671
public boolean checkPassword(String password) {
if (password.length() != 32) {
return false;
}
char[] buffer = new char[32];
int i;
for (i=0; i<8; i++) {
buffer[i] = password.charAt(i);
}
for (; i<16; i++) {
buffer[i] = password.charAt(23-i);
}
for (; i<32; i+=2) {
buffer[i] = password.charAt(46-i);
}
for (i=31; i>=17; i-=2) {
buffer[i] = password.charAt(i);
}
String s = new String(buffer);
return s.equals("jU5t_a_sna_3lpm18gb41_u_4_mfr340");
}
}
Що робить цей код?
- Він перевіряє, чи введений пароль (після трансформацій) збігається з рядком:
“jU5tasna3lpm18gb41u4mfr340”. - Щоб вирішити задачу, потрібно звернути зворотну трансформацію, яку було застосовано до пароля.
Крок 2: Реверс-інженерія пароля
Для реверс-інженерії я перевів код Java на Python. Метою було взяти заданий рядок (jU5tasna3lpm18gb41u4mfr340), змоделювати цикли та відновити оригінальний пароль.
Ось Python скрипт, який я створив:
def checkPassword(password):
if not len(password) == 32:
return False
buffer = [""] * 32
for i in range(8):
buffer[i] = password[i]
for i in range(8, 16):
buffer[i] = password[23 - i]
for i in range(16, 32, 2):
buffer[i] = password[46 - i]
for i in range(31, 16, -2):
buffer[i] = password[i]
print(''.join(buffer)) # Об'єднуємо та виводимо відновлений пароль
checkPassword("jU5t_a_sna_3lpm18gb41_u_4_mfr340")
Крок 3: Ключові спостереження та корективи
- Цикли for в Python та Java:
У Java умоваi >= 17
дозволяє циклу включати індекс17
. Однак у Python функціяrange
виключає кінцеву точку. Щоб відтворити поведінку, я скоригував діапазон, щоб він йшов від31
до16
з кроком-2
. - Обчислення індексів:
Значення23 - i
та46 - i
змінюють порядок окремих символів у рядку.
Уважно відтворюючи ці трансформації, ми можемо розшифрувати оригінальний пароль. - Вихідні дані (Output):
Скрипт виводить відновлений пароль, який є флагом.
Остаточний флаг (в кодуванні base64):
cGljb0NURntqVTV0X2FfczFtcGwzX2FuNGdyNG1fNF91XzFmYjM4MH0=
Примітка (Note): Щоб розшифрувати, виконайте:
echo -n "encoded_string" | base64 --decode
Реальні застосування
Задачі подібного типу демонструють важливість розуміння логіки програм та структури циклів. У реальних сценаріях подібні техніки використовуються для:
- Реверс-інженерії програмного забезпечення з метою виявлення вразливостей або відновлення втрачених даних (або для обходу перевірок коду в іграх 😇, як я чув/читаю).
- Аналізу обфускованого коду в шкідливих програмах для розуміння їхньої поведінки.
- Налагодження (debugging) та оптимізації програм шляхом поетапного розбору їхніх операцій.
Реверс-інженерія — це не лише розв'язання головоломок, це критично важливий навик у кібербезпеці, що допомагає фахівцям розуміти складні системи.
Остаточні думки
Задача “Vault Door 3” є чудовим вправою з реверс-інженерії та розуміння логіки коду. Чудове доповнення до тих двох, які ми вже вирішили. Уважно переклавши логіку Java в Python, ми успішно відновили оригінальний пароль.
Як вам цей опис рішення? Поділіться своїми думками, порадами чи рішеннями в коментарях нижче — я з радістю дізнаюся, як ви підійшли до розв'язку!
Щасливого хакінгу, побачимося в наступному описі!
З найкращими побажаннями,
SoBatista
Перекладено з: PicoCTF Writeups — vault-door-3