Розв’язки PicoCTF — сейф-двері 3

Ласкаво просимо назад, ентузіасти 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: Ключові спостереження та корективи

  1. Цикли for в Python та Java:
    У Java умова i >= 17 дозволяє циклу включати індекс 17. Однак у Python функція range виключає кінцеву точку. Щоб відтворити поведінку, я скоригував діапазон, щоб він йшов від 31 до 16 з кроком -2.
  2. Обчислення індексів:
    Значення 23 - i та 46 - i змінюють порядок окремих символів у рядку.
    Уважно відтворюючи ці трансформації, ми можемо розшифрувати оригінальний пароль.
  3. Вихідні дані (Output):
    Скрипт виводить відновлений пароль, який є флагом.

Остаточний флаг (в кодуванні base64):

cGljb0NURntqVTV0X2FfczFtcGwzX2FuNGdyNG1fNF91XzFmYjM4MH0=  

Примітка (Note): Щоб розшифрувати, виконайте:  
echo -n "encoded_string" | base64 --decode

Реальні застосування

Задачі подібного типу демонструють важливість розуміння логіки програм та структури циклів. У реальних сценаріях подібні техніки використовуються для:

  • Реверс-інженерії програмного забезпечення з метою виявлення вразливостей або відновлення втрачених даних (або для обходу перевірок коду в іграх 😇, як я чув/читаю).
  • Аналізу обфускованого коду в шкідливих програмах для розуміння їхньої поведінки.
  • Налагодження (debugging) та оптимізації програм шляхом поетапного розбору їхніх операцій.

Реверс-інженерія — це не лише розв'язання головоломок, це критично важливий навик у кібербезпеці, що допомагає фахівцям розуміти складні системи.

Остаточні думки

Задача “Vault Door 3” є чудовим вправою з реверс-інженерії та розуміння логіки коду. Чудове доповнення до тих двох, які ми вже вирішили. Уважно переклавши логіку Java в Python, ми успішно відновили оригінальний пароль.

Як вам цей опис рішення? Поділіться своїми думками, порадами чи рішеннями в коментарях нижче — я з радістю дізнаюся, як ви підійшли до розв'язку!

Щасливого хакінгу, побачимося в наступному описі!

З найкращими побажаннями,
SoBatista

Перекладено з: PicoCTF Writeups — vault-door-3

Leave a Reply

Your email address will not be published. Required fields are marked *