Восстановление дизассемблированных реализаций криптографических алгоритмов

Инновации в информационно-аналитических системах: сб. научн. трудов. Вып. 2 - Курск:

Науком, 2011. - 93 с., ил. ISBN 978-5-4297-0003-8

УДК 621.391

Быков А.В.

ВОССТАНОВЛЕНИЕ ДИЗАССЕМБЛИРОВАННЫХ РЕАЛИЗАЦИЙ КРИПТОГРАФИЧЕСКИХ АЛГОРИТМОВ

Представлено описание разработанного метода восстановления реализаций криптографических алгоритмов в дизассемблированном программном обеспечении, который учитывает характерные особенности вычислений.

В большинстве современных программных комплексов реализованы алгоритмы защиты информации, основу которых составляют криптографические алгоритмы (алгоритмы шифрования, хэш-функций и т.д.). Как правило, такое программное обеспечение (ПО) предоставляется без исходного кода. В таких случаях поиск недокументированных возможностей и потенциальных уязвимостей в ПО может быть выполнен при помощи восстановления криптографических алгоритмов в процессе анализа дизассемблированного ПО. Восстановление криптографических алгоритмов позволяет проверить корректность их реализаций, которая играет ключевую роль в обеспечении стойкой защиты информации. В работе [1] отмечается, что анализ дизассемблированного ПО - очень “трудоемкий” процесс. В связи с этим актуальна задача автоматизации восстановления криптографических алгоритмов в дизассемблированном ПО.

Восстановление алгоритмов может быть осуществлено при помощи декомпилятора (инструментальное средство, получающее на вход программу на языке ассемблера и выдающее на выход эквивалентную ей программу на некотором языке высокого уровня). В ходе декомпиляции программы решаются следующие задачи: выделение структурных единиц программы, в частности, подпрограмм в однородном ассемблерном листинге, выявление параметров подпрограмм и возвращаемых ими значений, структурный анализ, то есть восстановление операторов циклов, ветвлений и т. д., восстановление типов данных. В [2] отмечается, что все эти задачи достаточно трудоемки и алгоритмически неразрешимы, и на сегодняшний день нет известных декомпиляторов, восстанавливающих программы в какой-либо язык высокого уровня, которые качественно справлялись бы со всеми перечисленными выше задачами. Разработчики известных декомпиляторов, таких как Hex-Rays [3], Desquirr [4], Boomerang [5], REC[6] осуществили попытку решить все отмеченные выше задачи, то есть создать универсальный декомпилятор. Результатом работы данных декомпиляторов является преобразование кода программы с языка Assembler в код на языке

62

Инновации в информационно-аналитических системах: сб. научн. трудов. Вып. 2 - Курск:

Науком, 2011. - 93 с., ил. ISBN 978-5-4297-0003-8

программирования высокого уровня (С, С++), который может содержать вставки команд языка Assembler. Такое преобразование целесообразно осуществлять, например, тогда, когда необходимо использовать восстановленную функцию в собственной программе на языке высокого уровня. Однако сложность анализа реализации криптографического алгоритма как на языке высокого уровня, так и на языке Assembler может быть сопоставима [7, 8].

Анализ практического опыта дизассемблирования ПО и использования декомпиляторов показал, что применение существующих универсальных декомпиляторов не всегда позволяет уменьшить трудоемкость проверки корректности реализаций криптографических алгоритмов. В результате исследования результатов работы известных декомпиляторов были отмечены следующие недостатки, затрудняющие их использование для восстановления криптографических алгоритмов:

- сложность выделения функциональных блоков (например, раундов шифрования) криптографических алгоритмов;

- сложность определения назначения переменных (ключ, открытый текст и т.д.), используемых исследуемой реализацией криптографического алгоритма;

- избыточное количество временных переменных, затрудняющих анализ реализации криптографического алгоритма;

- отсутствие сокращения избыточных вычислений (упрощения выражений).

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

Далее представлено описание метода восстановления криптографических алгоритмов с примерами ее использования для автоматизации анализа реализаций алгоритма Rijndael (AES) [9].

Ключевой особенностью криптографических алгоритмов является наличие в одной процедуре, реализующей алгоритм, разнородных вычислений (математических операций в различных кольцах, полях, где одна и та же переменная может последовательно выступать в качестве элемента различных колец, полей).

Обозначим a, b ^ &232 - переменные, &232 - кольцо целых чисел по модулю 232, reg1,reg2 - регистры процессора. Ниже приведена последовательность команд языка Assembler, представляющих вычисления, характерные для реализаций алгоритма Rijndael в кольцах &232 (команда 3 - регистры reg1, reg2 участвуют в выражении как элементы кольца & 232 ) и &22 (команды 4,5 - регистр reg 1 выступает как элемент кольца & 232 ).

Пример 1.

1) mov reg1, a;

2) mov reg2,b;

63

Инновации в информационно-аналитических системах: сб. научн. трудов. Вып. 2 - Курск:

Науком, 2011. - 93 с., ил. ISBN 978-5-4297-0003-8

3) add reg и reg 2;

Обозначим содержимое регистра regl: c —a + b

4) and reg1,0FF00h ;

Обозначим содержимое регистра regl: d —c & 0FF00h

5) shr reg1,8.

Обозначим содержимое регистра reg1: e —d >> 8

Существующие декомпиляторы результат обработки последовательности команд 1-5 представляют следующим образом: e —((a + b) &0FF00h)>> 8 (1). Таким образом, в одном выражении участвуют операции разных колец. Экспериментальные исследования показали, что такие выражения могут включать большое количество разнородных вычислений, затрудняя анализ исследуемого криптографического алгоритма.

Основу разработанного метода восстановления криптографических алгоритмов составляет идея разделения разнородных вычислений путем введения новых переменных и упрощения выражений в каждом кольце (поле).

Используя обозначения примера 1, введем новую 32-х битную переменную T —t3_ 12_t1 _10, T —c, где ti - соответствующие 8 бит переменной T, c —a + b. Результатом преобразования последовательности команд 1 - 5 будет выражение: r — 0_0_0_t1, где 0 - нулевой 8-ми битовый вектор. Таким образом, произведенная замена переменных, позволила избавиться от записи каких - либо операций в выражении (1).

Программная реализация метода восстановления криптографических алгоритмов содержит следующие модули:

- предварительной обработки команд языка Assembler;

- обработки управляющей логики;

- обработки циклов;

- обработки потоков данных;

- вывода результатов.

Модуль предварительной обработки команд языка Assembler осуществляет преобразование команд в формулы, например команде “add eax, ebx” соответствует формула “eax = eax + ebx”. Результатом работы данного модуля является список формул, соответствующих командам.

Модуль обработки управляющей логики формирует граф управляющей логики. Характерной особенностью реализаций криптографических алгоритмов является наличие относительно небольшого числа команд условного перехода. Например, в ряде реализаций алгоритма шифрования AES осуществляется проверка значения одной переменной, содержащей число раундов шифрования (10, 12 или 14). Таким образом, граф управляющей логики содержит относительно небольшое количество вершин и, следовательно, небольшое количество различных путей, связывающих начальную и конечную (конечные) вершины. Основной задачей модуля обработки управляющей логики является выделение всех возможных путей и формирование последовательностей команд соответствую-

64

Инновации в информационно-аналитических системах: сб. научн. трудов. Вып. 2 - Курск:

Науком, 2011. - 93 с., ил. ISBN 978-5-4297-0003-8

щих каждому из путей.

Обозначим CFG ={ X, Л\ - граф управляющей логики, X - множество вершин, Л - множество дуг, // , xj2 v? x)n, ^ - путь из начальной вершины

в одну из конечных вершин в графе CFG. При этом, xj — xb %ig{1,...,Nj , где N - количество различных путей.

В отличие от известных декомпиляторов, анализ потоков данных (data flow analysis) проводится не для всей дизассемблированной функции - реализации криптографического алгоритма, а для каждого из построенных путей f,i —{l,2,...,Nj . Данный подход позволяет корректно рассмотреть все режимы работы криптографического алгоритма и упростить формулы, описывающие зависимости данных, полученных в результате работы алгоритма, от входных переменных.

Кроме построения путей, модуль обработки управляющей логики осуществляет выделение циклов и формирование последовательностей команд, соответствующих циклам. Наличие циклов в реализациях алгоритма шифрования Rijndael обусловлено тем, что во всех раундах шифрования, кроме последнего, выполняются одинаковые вычисления. Таким образом, все раунды шифрования, кроме последнего, могут быть представлены в виде цикла.

Модуль обработки циклов позволяет выделять переменные (регистры процессора, ячейки памяти), значения которых были изменены в процессе выполнения цикла. Пусть T =\t1,t2v.^tmj - переменные, значения которых изменяются после выполнения цикла, тогда каждой переменной ti можно поставить в

соответствие вектор ui — 0,...,°ДА...,о). После выполнения последовательности команд цикла (одной цикловой итерации) каждой переменной tj можно поставить в соответствие вектор s j — sjл,•••, sj ,m), где

s

D1, если значение tk участвовало в формировании tj

j 0, в противном случае

Тогда переменные ti1,•••,til G T назовем существенными, если соответствующие им вектора si1,•••, sit образуют базис набора векторов

{Uji,...,Sjmje{l,2,...,mjj . Модуль обработки циклов осуществляет выделение существенных переменных и определяет их зависимость от количества цикловых итераций.

Модуль обработки потоков данных спроектирован с учетом необходимости обрабатывать разнородные вычисления и состоит из процедур: распознавания разнородных операций, упрощения выражений для каждого из распознаваемых видов операций, сокращения числа вводимых дополнительно переменных.

Процедура распознавания разнородных операций определяет новые переменные при переходе от одного типа вычислений (под вычислениями разных

65

Инновации в информационно-аналитических системах: сб. научн. трудов. Вып. 2 - Курск:

Науком, 2011. - 93 с., ил. ISBN 978-5-4297-0003-8

типов понимаются математические операции в различных кольцах, полях) к другому (например, при переходе от вычислений в кольце & 232 к вычислениям в кольце Z22), после чего формируются выражения (формулы), в которых участвуют вновь определенные переменные и операции только одного типа. После формирования выражений применяется процедура их упрощения - уменьшения количества используемых операций и переменных. Процедура сокращения числа вводимых дополнительно переменных позволяет избежать наличия нескольких одинаково определенных переменных.

Следующий пример более подробно раскрывает работу модуля обработки потоков данных и модуля вывода результатов.

Пример 2.

Фрагмент дизассемблированного кода:

.text:0043D0F3

.text:0043D0F7

.text:0043D0F9

.text:0043D0FC

.text:0043D0FF

.text:0043D102

mov esi, [esp+14h+arg_0]

mov eax, [esi]

mov ebx, [esi+4]

mov ecx, [esi+8]

mov edx, [esi+0Ch]

mov ebp, [esp+14h+arg_8]

.text:0043D10D

.text:0043D110

.text:0043D113

.text:0043D116

xor eax, [ebp+0] xor ebx, [ebp+4] xor ecx, [ebp+8] xor edx, [ebp+0Ch]

.text:0043D143

.text:0043D146

.text:0043D149

.text:0043D14C

.text:0043D14F

.text:0043D152

.text:0043D155

.text:0043D15C

.text:0043D15F

.text:0043D166

.text:0043D169

.text:0043D170

.text:0043D173

.text:0043D17A

.text:0043D17D

.text:0043D184

.text:0043D187

.text:0043D18E

.text:0043D191

.text:0043D198

.text:0043D19B

.text:0043D1A0

.text:0043D1A2

add ebp, 10h

mov [esp+14h+var_14], ebp mov esi, [ebp+8] mov edi, [ebp+0Ch] rol ebx, 10h movzx ebp, cl

xor esi, ds:dword_471B00[ebp*4] movzx ebp, dh

xor esi, ds:dword_471F00[ebp*4] movzx ebp, bh

xor esi, ds:dword_472700[ebp*4] movzx ebp, dl

xor edi, ds:dword_471B00[ebp*4] movzx ebp, ah

xor edi, ds:dword_471F00[ebp*4] movzx ebp, bl

xor edi, ds:dword_472300[ebp*4] movzx ebp, al

mov ebp, ds:dword_471B00[ebp*4]

shr ebx, 10h

and eax, 0FFFF0000h

or eax, ebx

shr edx, 10h

66

Инновации в информационно-аналитических системах: сб. научн. трудов. Вып. 2 - Курск:

Науком, 2011. - 93 с., ил. ISBN 978-5-4297-0003-8

.text:0043D1A5

.text:0043D1A8

.text:0043D1AF

.text:0043D1B2

.text:0043D1B9

.text:0043D1BC

.text:0043D1C3

.text:0043D1C6

.text:0043D1CD

.text:0043D1D0

.text:0043D1D7

.text:0043D1DA

.text:0043D1DD

.text:0043D1E0

.text:0043D1E7

.text:0043D1EA

.text:0043D1F1

.text:0043D1F4

.text:0043D1FB

.text:0043D1FE

.text:0043D205

.text:0043D207

.text:0043D209

.text:0043D20B

.text:0043D20E

.text:0043D211

.text:0043D214

.text:0043D217

.text:0043D21A

.text:0043D21D

.text:0043D220

.text:0043D223

.text:0043D226

.text:0043D22D

.text:0043D230

.text:0043D237

.text:0043D23A

.text:0043D241

.text:0043D244

.text:0043D24B

movzx ebx, ah

xor ebp, ds:dword_471F00[ebx*4] movzx ebx, dh

xor ebp, ds:dword_472700[ebx*4] movzx ebx, dl

mov ebx, ds:dword_472300[ebx*4] movzx edx, ch

xor ebx, ds:dword_471F00[edx*4] movzx edx, al

xor ebx, ds:dword_471B00[edx*4] shr eax, 10h shr ecx, 10h movzx edx, cl

xor ebp, ds:dword_472300[edx*4] movzx edx, ch

xor edi, ds:dword_472700[edx*4] movzx edx, al

xor esi, ds:dword_472300[edx*4] movzx edx, ah

xor ebx, ds:dword_472700[edx*4] mov eax, ebp mov ecx, esi mov edx, edi

mov ebp, [esp+14h+var_14] xor eax, [ebp+0] xor ebx, [ebp+4] add ebp, 10h

mov [esp+14h+var_14], ebp mov esi, [ebp+8] mov edi, [ebp+0Ch] rol ebx, 10h movzx ebp, cl

xor esi, ds:dword_471B00[ebp*4] movzx ebp, dh

xor esi, ds:dword_471F00[ebp*4] movzx ebp, bh

xor esi, ds:dword_472700[ebp*4] movzx ebp, dl

xor edi, ds:dword_471B00[ebp*4] movzx ebp, ah

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

address: 43D14F ebx = [arg_0+4]A[arg_8+4],

Denote T[1] = ebx, where T[1] = t7_t6_t5_t4; address: 43D152 ecx = [arg_0+8]A[arg_8+8],

67

Инновации в информационно-аналитических системах: сб. научн. трудов. Вып. 2 - Курск:

Науком, 2011. - 93 с., ил. ISBN 978-5-4297-0003-8

Denote T[2] = ecx, where T[2] = tB_tA_t9_t8; address: 43D15C edx = [arg_0+C]A[arg_8+C],

Denote T[3] = edx, where T[3] = tF_tE_tD_tC; address: 43D17A eax = [arg_0]A[arg_8],

Denote T[4] = eax, where T[4] = t13_t12_t11_t10;

Определены новые переменные T[1], T[2], T[3], T[4]. В следующих четырех выражениях представлен первый раунд шифрования алгоритма Rijndael:

address: 43D220 ebx = [arg_8+14]A[M471B00+0_0_0_t4*4]A[M471F00+ 0_0_0_t9*4]A A[M472300+0_0_0_tE*4]A[M472700+0_0_0_t13*4],

Denote T[5] = ebx, where T[5] = t17_t16_t15_t14;

address: 43D223 ecx = [arg_8+18]A[M471B00+0_0_0_t8*4]A[M471F00+0_0_0_tD*4]A A[M472300+0_0_0_t12*4]A[M472700+0_0_0_t7*4],

Denote T[6] = ecx, where T[6] = t1B_t1A_t19_t18;

address: 43D22D edx = [arg_8+1C]A[M471B00+0_0_0_tC*4]A[M471F00+0_0_0_t11*4]A A[M472300+0_0_0_t6*4]A[M472700+0_0_0_tB*4],

Denote T[7] = edx, where T[7] = t1F_t1E_t1D_t1C;

address: 43D24B eax = [arg_8+10]A[M471B00+0_0_0_t10*4]A[M471F00+0_0_0_t5*4]A A[M472300+0_0_0_tA*4]A[M472700+0_0_0_tF*4],

Denote T[8] = eax, where T[8] = t23_t22_t21_t20;

Определены новые переменные T[5], T[6], T[7], T[8], которые содержат результат одного (первого) раунда шифрования. В ходе несложного анализа восстановленного алгоритма шифрования Rijndael было определено, что [arg_0] указывает на открытый текст, [arg_8] - расширенный ключ. В восстановленном алгоритме наглядно представлена зависимость результатов одного раунда шифрования от входных данных. В случае, если алгоритм Rijndael реализован корректно, эта зависимость должна сохраняться во всех раундах шифрования, кроме последнего. Выражения вида “[M471B00+0_0_0_t4*4]” представляют собой отображения 8-ми битовой переменной (в данном случае t4) в z22 по правилам, которые определены 256 константами из z22, расположенными по адресам 471B00, 471F00, 472300, 472700.

Таким образом, для того, чтобы подтвердить корректность реализации алгоритма Rijndael без учета констант (в рассмотренном примере константы расположены по адресам 471B00, 471F00, 472300, 472700), достаточно:

- проверить характер зависимости результатов первого раунда шифрования от входных данных (один раунд шифрования представлен четырьмя выражениями вида ebx = [arg_8+14]A[M471B00+0_0_0_t4*4]A[M471F00+ +0_0_0_t9*4]A a [M472300+ 0_0_0_tE*4]A[M472700+0_0_0_t13*4]);

- убедиться в том, что во всех раундах шифрования, за исключением последнего, характер зависимости результатов от входных данных одинаков;

- проверить характер зависимости результатов последнего раунда шифрования от входных данных;

68

Инновации в информационно-аналитических системах: сб. научн. трудов. Вып. 2 - Курск:

Науком, 2011. - 93 с., ил. ISBN 978-5-4297-0003-8

- проверить число раундов шифрования (10, 12 или 14).

Таким образом, предложено описание метода восстановления криптографических алгоритмов, который, в отличие от известных универсальных декомпиляторов учитывает характерные особенности криптографических алгоритмов. Данный метод позволяет идентифицировать их функциональные блоки (раунды шифрования, переменные, содержащие ключ, открытый текст и т.д.). Полученное описание восстановленного алгоритма содержит существенно меньшее (более чем в 2 раза) количество переменных в сравнении с результатами работы известных декомпиляторов.

Программная реализация разработанного метода восстановления криптографических алгоритмов реализована в виде подключаемого модуля (“plug-in”) к дизассемблеру IDA версии 5.2. Реализация в виде подключаемого модуля к дизассемблеру, а не отдельной программы была осуществлена для обеспечения возможности наиболее полного изучения системы защиты программного обеспечения.

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

Библиографический список

1. E. Eilam, Reversing: secrets of reverse engineering, Wiley publishing, 2005. - 590 с.

2. Долгова К.Н., Чернов А.В., О некоторых задачах обратной инженерии, Труды Института системного программирования РАН, 2008.

3. Hex-Rays Decompiler SDK. http://www.hex-rays.com.

4. David Eriksson, Designing an object-oriented decompiler, Department of Software Engineering and Computer Science Blekinge Institute of Technology, 2002.

5. Boomerang Decompiler Home Page. http://boomerang.sourceforge.net.

6. REC Decompiler Home Page. http://www.backerstreet.com/rec.

7. F. Riguzzi, A survey of software metrics, Universita degli Studi di Bologna, DEIS Technical Report no. DEIS-LIA-96-010.

8. Новичков А., Метрики кода и их практическая реализация в IBM Rational ClearCase, Технология клиент-сервер, № 1, 2008.

9. Federal Information Processing Standards Publication 197, November 26, 2001. - 48 с.

69