Для этой задачи нам дан 32-битный двоичный файл ELF (разделенный). При осмотре в Хоппере я заметил, что основная процедура начинается с sub_804851b, как видно на картинке ниже.

Мы заинтересованы в том, чтобы избежать 0x0804855b, потому что этот раздел вызывается в результате неправильного ввода. Таким образом, единственный способ добиться этого — если eax == 1 (см. 0x084854a) после вызова sub_8048451. Действительно, наша новая цель состоит в том, чтобы перевернуть sub_804851 и лучше понять, как можно установить eax в 1.

Переход к sub_8048451 и просмотр декомпилированного исходного кода показывает

Здорово! Теперь мы можем начать понимать, как работает наша проверка ввода, чтобы создать рабочий флаг. На этом этапе лучше всего переписать часть кода в редакторе, чтобы он лучше читался. Важно отметить, что значения по адресам памяти от 0x0804a20 до 0x0804a25 сравниваются в операторах if, что может указывать на то, что они являются значениями, составляющими флаг. Таким образом, мы можем переписать исходный код, чтобы визуализировать это поведение.

int validate(int a, int b, int c, int d, int e, int f) {
     int success = 0;
     if (b != 0x31) {
       success = 0x0;
     } else {
       a = a ^ 0x34;
       c = c ^ 0x32;
       d = d ^ 0xffffff88;
       if (e != 0x58) {
         success = 0x0;
       } else {
         if (f != 0x0) {
           success = 0x0;
         } else {
           if (c != 0x7c) {
             success = 0x0;
           } else {
             if (a != 0x78) {
               success = 0x0;
             } else {
               if (d != 0xdd) {
                 success = 0x0;
               } else {
                 success = 0x1;
               }
             }
           }
         }
       }
     }
     return success;
}

Этот код немного легче читать. Наша функция проверки принимает 6 целых чисел в качестве параметров и проверяет их на заданные условия, чтобы вернуть 1 в качестве успеха (установка eax = 1). Ниже я покажу, как я решил для «а», а затем повторю процесс для остальных значений.

int a = [(какое-то значение) XOR 0x34] == 0x78

Таким образом, int a = 0x34 XOR 0x78 равно: 0x4c. На самом деле 0x4c — это L в ASCII.

int b= 0x31Iв ASCII

int c = [(некоторое значение) XOR 0x32] == 0x7c = 0x32 XOR 0x7cNв ASCII

int d = [(некоторое значение) XOR 0xffffff88] == 0xddU в ASCII

int e = 0x58X в ASCII.

int d = 0x0NULL в ASCII.

Вот и все! Наш флаг — LINUX.