
- •Курсовая работа
- •Постановка задачи на курсовую работу
- •Внешнее предварительное исследование программного продукта
- •Предварительный анализ кода программы в отладчике
- •3.1. Точки останова
- •3.2. Поиск введенных данных
- •0012F63c 00404ff7 return to textguar.00404ff7 from textguar.004030d0
- •00404Ff2 |. E8 d9e0ffff call textguar.004030d0
- •00405008 |. E8 c3e0ffff call textguar.004030d0
- •«Жесткий» взлом
- •00404Da9 |. 75 03 |jnz short textguar.00404dae
- •00405024 |. E8 b7010000 call textguar.004051e0
- •00405029 |. 85C0 test eax,eax
- •0040502B |. 74 39 je short textguar.00405066
- •Подробный анализ механизма защиты. Осуществление мягкого взлома.
- •Блок-схема алгоритма модуля защиты
- •Рекомендации по улучшению механизма защиты
- •Заключение
Подробный анализ механизма защиты. Осуществление мягкого взлома.
Для осуществления мягкого взлома, мне необходимо исследовать код процедуры, вызываемой командами:
004051E0 /$ 68 C4474100 PUSH textguar.004147C4 ; ASCII "12345"
004051E5 |. 68 44474100 PUSH textguar.00414744 ; ASCII "dilyara"
004051EA |. E8 D1FEFFFF CALL textguar.004050C0
Сюда через стек передаются введенные мной данные – пароль и имя пользователя.
004050C0 /$ 53 PUSH EBX
004050C1 |. 8B5C24 0C MOV EBX,DWORD PTR SS:[ESP+C]
004050C5 |. 56 PUSH ESI
004050C6 |. 8B35 5CE14000 MOV ESI,DWORD PTR DS:[<&KERNEL32.lstrlen>
В регистр ESI передается адрес функции получения длины строки.
004050CC |. 57 PUSH EDI
004050CD |. 53 PUSH EBX ; /String
004050CE |. FFD6 CALL ESI ; \lstrlenA
004050D0 |. 83F8 03 CMP EAX,3
004050D3 |. 0F8C 9A000000 JL textguar.00405173
Через стек передается введенный пароль, и через функцию lstrlenA в регистр EAX заносится длина введенного пароля. Затем длина пароля сравнивается с цифрой 3, и в случае, если она меньше, происходит переход на адрес 00405173.
004050D9 |. 8B7C24 10 MOV EDI,DWORD PTR SS:[ESP+10]
004050DD |. 57 PUSH EDI ; /String
004050DE |. FFD6 CALL ESI ; \lstrlenA
004050E0 |. 83F8 03 CMP EAX,3
004050E3 |. 0F8C 8A000000 JL textguar.00405173
В регистр EDI из стека заносится введенное имя пользователя и аналогичным образом подсчитывается его длина. В случае, если длина меньше трех символов, происходит переход на адрес 00405173, по которому содержится следующий код:
00405173 |> 5F POP EDI
00405174 |. 5E POP ESI
00405175 |. 33C0 XOR EAX,EAX
00405177 |. 5B POP EBX
00405178 \. C3 RETN
Как видно, здесь происходит возврат из данной процедуры с обнулением регистра EAX. Значит, длина пароля и имени пользователя должны быть не менее трех символов для того, чтобы они были приняты программой.
Поскольку введенные мной данные удовлетворяют перечисленным условиям, код выполняется дальше. А дальше я обнаружила интересный фрагмент кода:
004050FE |> 8A07 MOV AL,BYTE PTR DS:[EDI]
;Заносим в регистр AL код первого символа имени пользователя
00405100 |. 33F6 XOR ESI,ESI
;обнуляем регистр
00405102 |. 84C0 TEST AL,AL
;делаем проверку на ноль
00405104 |. 8BCF MOV ECX,EDI
;в регистр ECX заносится имя пользователя
00405106 |. 74 3D JE SHORT textguar.00405145
;если первый символ имеет код 00, то переход на адрес 00405145, иначе - нет
00405108 |> 3C 20 /CMP AL,20
0040510A |. 74 2B |JE SHORT textguar.00405137
0040510C |. 3C 0D |CMP AL,0D
0040510E |. 74 27 |JE SHORT textguar.00405137
00405110 |. 3C 0A |CMP AL,0A
00405112 |. 74 23 |JE SHORT textguar.00405137
;здесь происходит проверка первого символа на равенство с кодами 20, 0D, 0A
;если код символа равен одному из них, происходит переход на адрес 00405137
00405114 |. 3C 61 |CMP AL,61
00405116 |. 7C 0C |JL SHORT textguar.00405124
00405118 |. 3C 7A |CMP AL,7A
0040511A |. 7F 08 |JG SHORT textguar.00405124
;61 – шестнадцатеричный ASCII код строчного символа ‘a’, 7A – ‘z’
;здесь смотрится, входит ли символ в диапазон от ‘a’ до ‘z’
;если не входит, то происходит переход на адрес 00405124
0040511C |. 0FBEC0 |MOVSX EAX,AL
0040511F |. 83E8 20 |SUB EAX,20
00405122 |. EB 03 |JMP SHORT textguar.00405127
;а если входит, то в регистр EAX заносится значение равное уменьшенному
;коду данного символа на 20 (в шестнадцатеричной системе)
;это эквивалентно переводу символа в верхний регистр
;61 – ‘a’, 41 – ‘A’ и т.д.
;затем происходит переход на адрес 00405127
00405124 |> 0FBEC0 |MOVSX EAX,AL
00405127 |> 8D14C5 000000>|LEA EDX,DWORD PTR DS:[EAX*8]
;EDX := EAX * 8
0040512E |. 2BD0 |SUB EDX,EAX
;EDX := EDX - EAX
00405130 |. 8D1496 |LEA EDX,DWORD PTR DS:[ESI+EDX*4]
;EDX := ESI + EDX * 4
00405133 |. 8D7402 11 |LEA ESI,DWORD PTR DS:[EDX+EAX+11]
;ESI := EDX + EAX + 11
00405137 |> 8A41 01 |MOV AL,BYTE PTR DS:[ECX+1]
;в регистр AL заносится код следующего символа имени пользователя
0040513A |. 41 |INC ECX
;увеличивается значение регистра на единицу
0040513B |. 84C0 |TEST AL,AL
;если код следующего символа не равен нулю, то цикл повторяется
0040513D |.^ 75 C9 \JNZ SHORT textguar.00405108
В результате работы данного цикла, на основании имени пользователя меняются следующие регистры: EAX, EDX, EBP, и ESI. По завершении работы данного цикла они принимали значения:
EAX 0000004116 = 6510
EDX 00003AD316 = 1505910
EBP 0000011116 = 27310
ESI 00003B2516 = 1514110
Просматривая дальнейший код, я обнаружила следующее:
00405145 |> 8A03 MOV AL,BYTE PTR DS:[EBX]
;заносится код первого символа пароля
00405147 |. 8BCB MOV ECX,EBX
;в регистр ECX заносится значение EBX
00405149 |. 84C0 TEST AL,AL
;код первого символ проверяется на равенство нулю
0040514B |. 74 10 JE SHORT textguar.0040515D
0040514D |> 3C 30 /CMP AL,30
0040514F |. 7C 04 |JL SHORT textguar.00405155
00405151 |. 3C 39 |CMP AL,39
00405153 |. 7E 08 |JLE SHORT textguar.0040515D
00405155 |> 8A41 01 |MOV AL,BYTE PTR DS:[ECX+1]
00405158 |. 41 |INC ECX
00405159 |. 84C0 |TEST AL,AL
0040515B |.^ 75 F0 \JNZ SHORT textguar.0040514D
Данный фрагмент кода проверяет, лежит ли код первого символа пароля в диапазоне от 30 до 39, что соответствует цифрам 0 – 9. Как только программа находит символ, лежащий в данном диапазоне, она передает это значение в стек и вызывает еще одну процедуру, в которую, в результате, передается пароль 12345 (это означает, что пароль должен начинаться с цифры):
0040515D |> 51 PUSH ECX
0040515E |. E8 30240000 CALL textguar.00407593
После которой идет следующая комбинация команд:
00405163 |. 83C4 04 ADD ESP,4
00405166 |. 33C9 XOR ECX,ECX
00405168 |. 3BC6 CMP EAX,ESI
0040516A |. 0F94C1 SETE CL
0040516D |. 5F POP EDI
0040516E |. 5E POP ESI
0040516F |. 8BC1 MOV EAX,ECX
00405171 |. 5B POP EBX
00405172 |. C3 RETN
Как видно, здесь и происходит установка значения регистра EAX. Значит, необходимо просмотреть код вызываемой процедуры.
00407593 /$ FF7424 04 PUSH DWORD PTR SS:[ESP+4]
00407597 |. E8 6CFFFFFF CALL textguar.00407508
0040759C |. 59 POP ECX
0040759D \. C3 RETN
Процедура вызывает еще одну процедуру, в которую снова передает введенный пароль. Среди этого кода я обнаружила цикл, который использует введенный мной пароль:
00407554 |> 833D EC1D4100>/CMP DWORD PTR DS:[411DEC],1
0040755B |. 7E 0C |JLE SHORT textguar.00407569
;этот переход осуществляется всегда. Возможно, эта область памяти
;используется для проверки чего-либо в программе.
...
...
00407569 |> A1 E01B4100 |MOV EAX,DWORD PTR DS:[411BE0]
0040756E |. 8A0470 |MOV AL,BYTE PTR DS:[EAX+ESI*2]
;в регистр AL := EAX+ESI*2, при том, что в ESI хранится код текущего
;символа
00407571 |. 83E0 04 |AND EAX,4
00407574 |> 85C0 |TEST EAX,EAX
00407576 |. 74 0D |JE SHORT textguar.00407585
00407578 |. 8D049B |LEA EAX,DWORD PTR DS:[EBX+EBX*4]
;EAX := EBX+EBX*4
0040757B |. 8D5C46 D0 |LEA EBX,DWORD PTR DS:[ESI+EAX*2-30]
; EBX := ESI+EAX*2-30
0040757F |. 0FB637 |MOVZX ESI,BYTE PTR DS:[EDI]
;в регистр ESI заносится код следующего символа пароля
00407582 |. 47 |INC EDI
;регистр увеличивается на единицу
00407583 |.^ EB CF \JMP SHORT textguar.00407554
;цикл повторяется до тех пор, пока не будет встречен незначащий символ
00407585 |> 83FD 2D CMP EBP,2D
00407588 |. 8BC3 MOV EAX,EBX
;в EAX заносятся результаты вычисления, произведенного над паролем
0040758A |. 75 02 JNZ SHORT textguar.0040758E
...
0040758E |> 5F POP EDI ;имя
0040758F |. 5E POP ESI ;3B25
00407590 |. 5D POP EBP ;111
00407591 |. 5B POP EBX ;пароль
00407592 \. C3 RETN
;происходит возврат
Поскольку решение о правильности пароля принимается далее, эта процедура предназначена лишь для преобразования введенного пароля и сохранения результата модификации в регистре EAX.
Посмотрим, чему равны регистры в результате:
EDX 00003AD316 = 1505910
EAX 0000303916 = 1234510
EBP 0000003116 = 4910
Вспомним, что дальнейший код после вызова этих процедур следующий:
00405163 |. 83C4 04 ADD ESP,4
00405166 |. 33C9 XOR ECX,ECX
00405168 |. 3BC6 CMP EAX,ESI
0040516A |. 0F94C1 SETE CL
0040516D |. 5F POP EDI
0040516E |. 5E POP ESI
0040516F |. 8BC1 MOV EAX,ECX
00405171 |. 5B POP EBX
00405172 |. C3 RETN
Ключевой здесь является строка с кодом сравнения регистров EAX и ESI. Регистр ESI содержит результат вычислений, произведенных с использованием имени пользователя. Регистр EAX содержит результат вычислений, произведенных с использованием пароля.
Посмотрим на их содержимое перед проверкой:
EAX 0000303916 = 1234510
ESI 00003B2516 = 1514110
Как видно, процедуры формируют шестнадцатеричные последовательности, соответствующие имени пользователя и паролю, а затем программа сравнивает данные значения. Так как для имени dilyara соответствует шестнадцатеричная последовательность 3B25, которой в свою очередь соответствует десятичное значение 15141, можно сделать вывод, что это и есть искомый пароль под данное имя пользователя.
После ввода имени «dilyara» и пароля «15141» я получила сообщение о том, что программа успешно зарегистрирована. Надпись UNREGISTERED исчезла. Также пункт меню регистрации стал неактивен. Информация о программе содержала следующее:
Таким образом, можно получить полностью работоспособный пароль, обнаружив в программе место сравнения двух регистров, и переведя значение одного из них в десятичный формат.