Как мне найти лицензионный ключ для этой программы? - PullRequest
0 голосов
/ 30 июня 2019

Я пытаюсь решить это упражнение для университета. Мы должны «взломать» программу, в которой отсутствует файл лицензии, необходимый для запуска программы. Мы работаем только с оболочкой Linux.

Итак, я уже создал этот отсутствующий файл лицензии. Это .ini, который включает в себя владельца лицензии и лицензионный ключ. Единственное, что я сейчас ищу, это правильный лицензионный ключ. Задача говорит, что мы должны использовать «strace» и «ltrace» для решения этой проблемы. Вот что я получаю в качестве вывода:

fopen("license.ini", "r")                                   =0x55c088307380

fgets("LicenseHolder=annabell.krause@ex"..., 4096, 0x55c088307380)  = 0x7ffe72450860

strncmp("LicenseKey=", "LicenseHolder=annabell.krause@ex"..., 11)   = 3

strncmp("LicenseHolder=", "LicenseHolder=annabell.krause@ex"..., 14)    = 0

sscanf(0x7ffe72450860, 0x55c08753c16b, 0x7ffe72450800, 0xffffc000)  = 1

fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380) = 0x7ffe72450860

strncmp("LicenseKey=", "LicenseKey=aoeklycf", 11)           = 0

sscanf(0x7ffe72450860, 0x55c08753c121, 0x7ffe72450840, 0xfffff800)  = 1

fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380)          = 0

memfrob(0x7ffe72450840, 8, 0, 0xfbad2498)                   = 0x7ffe72450840

strncmp("KEOAFSIL", "aoeklycf", 8)                          = -22

fwrite("ERROR: License key is invalid.\n", 1, 31, 0x7faeabe60680
ERROR: License key is invalid.
)                                   = 31

+++ exited (status 1) +++

Так что я думаю, что ответ лежит где-то внутри функции memfrob и strncmp в конце. Но я не знаю, каков будет следующий шаг.

1 Ответ

4 голосов
/ 30 июня 2019

Давайте посмотрим на библиотеку трассировки вызова по вызову. Важная часть находится в шаге 5.

Анализ

  1. Открыть файл

    fopen("license.ini", "r")                                   =0x55c088307380
    

    Открывает файл лицензии.

  2. Разобрать владельца лицензии

    fgets("LicenseHolder=annabell.krause@ex"..., 4096, 0x55c088307380)  = 0x7ffe72450860
    

    Читает строку из файла: LicenseHolder=annabell.krause@ex….

    strncmp("LicenseKey=", "LicenseHolder=annabell.krause@ex"..., 11)   = 3
    

    Строка начинается с LicenseKey=? Возвращаемое значение 3 означает нет, это не так.

    strncmp("LicenseHolder=", "LicenseHolder=annabell.krause@ex"..., 14)    = 0
    

    Строка начинается с LicenseHolder=? Да, это так.

    sscanf(0x7ffe72450860, 0x55c08753c16b, 0x7ffe72450800, 0xffffc000)  = 1
    

    К сожалению, ltrace не разыменовал ни один из адресов, чтобы показать нам содержимое. Мы знаем, что 0x7ffe72450860 является текущей строкой, поэтому она предположительно извлекает адрес электронной почты из текущей строки.

  3. Разобрать лицензионный ключ

    fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380) = 0x7ffe72450860
    

    Читается еще одна строка: LicenseKey=aoeklycf.

    strncmp("LicenseKey=", "LicenseKey=aoeklycf", 11)           = 0
    

    Строка начинается с LicenseKey=? Да, это так.

    sscanf(0x7ffe72450860, 0x55c08753c121, 0x7ffe72450840, 0xfffff800)  = 1
    

    Разбор текущей строки. Предположительно, он извлекает введенный вами лицензионный ключ aoeklycf и сохраняет его в переменной для последующего сравнения с ожидаемым лицензионным ключом. Что-то вроде sscanf(line, "LicenseKey=%s", licenseKey);.

  4. Конечный из файла

    fgets("LicenseKey=aoeklycf", 4096, 0x55c088307380)          = 0
    

    Он пытается прочитать другую строку и нажимает EOF. Не обращайте внимания на первый аргумент, он просто показывает, что осталось в буфере от последнего вызова.

  5. Сравнение лицензионных ключей

    memfrob(0x7ffe72450840, 8, 0, 0xfbad2498)                   = 0x7ffe72450840
    

    «Зашифровывает» 8 байтов некоторой области памяти, XOR, каждый байт с 42. Это можно изменить, снова запустив memfrob(). Я помещаю «шифрует» в кавычки, потому что это едва ли можно назвать шифрованием. Это просто немного запутывания.

    Обратите внимание, что 0x7ffe72450840 является адресом из sscanf() выше. Он вызывает переменную, которую я назвал licenseKey выше, строку LicenseKey=, извлеченную из входного файла.

    strncmp("KEOAFSIL", "aoeklycf", 8)                          = -22
    

    Это денежная линия. Он сравнивает фактические и ожидаемые значения и дает сбой.

  6. Сообщение об ошибке

    fwrite("ERROR: License key is invalid.\n", 1, 31, 0x7faeabe60680)                                   = 31
    

    Ошибка печатается.

Синтез

Но автор не хочет, чтобы вы могли запускать простой поиск строк, например strings ./program, чтобы извлечь лицензионный ключ из исполняемого файла. Чтобы предотвратить это, вам нужно ввести frobbed версию лицензионного ключа в license.ini, а не необработанную строку strings find.

Код может выглядеть примерно так:

char *expected = "aoeklycf";
char actual[BUFSIZE];

sscanf(line, "LicenseKey=%s", actual);
memfrob(actual);
if (strncmp(actual, expected, strlen(expected)) != 0) {
    error("ERROR: License key is invalid.\n");
}

Вы извлекли aoeklycf из программы? Если это так, вы пропустили шаг memfrob(). license.ini необходимо указать «зашифрованную» версию лицензионного ключа: KEOAFSIL.

...