Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #82, ОКТЯБРЬ 2005 г.

Х-конкурс

GpCH (www.dotfix.net)

Хакер, номер #082, стр. 082-074-2


00406116 85 DB 85

00406117 68 DB 68 ;CHAR 'h'

00406118 FD DB FD

00406119 FF DB FF

0040611A FF DB FF

Олька после распаковки программы не смогла автоматически опознать код, поэтому нажми Ctrl+A. Начало кода теперь примет вид:

0040610E . 8D85 58FDFFFF LEA EAX,DWORD PTR SS:[EBP-2A8]

пролистни код чуток вверх и ты увидишь:

004060EB . 8D85 A8F6FFFF LEA EAX,DWORD PTR SS:[EBP-958]

004060F1 . 50 PUSH EAX

004060F2 . 8D85 B8F6FFFF LEA EAX,DWORD PTR SS:[EBP-948]

004060F8 . 50 PUSH EAX

004060F9 . 8D85 C8F6FFFF LEA EAX,DWORD PTR SS:[EBP-938]

004060FF . 50 PUSH EAX

00406100 . 6A 40 PUSH 40

00406102 . 8D85 D8F6FFFF LEA EAX,DWORD PTR SS:[EBP-928]

00406108 . 50 PUSH EAX

00406109 . E8 2EB2FFFF CALL CrackMe.0040133C

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

00404286 . E8 CFD0FFFF CALL CrackMe.0040135A

0040428B . 33C9 XOR ECX,ECX

0040428D . 83F8 04 CMP EAX,4

Ниже расположена процедура проверки длины пароля:

00404A7E . E8 D7C8FFFF CALL CrackMe.0040135A

00404A83 . 33C9 XOR ECX,ECX

00404A85 . 83F8 0A CMP EAX,0A

Несмотря на то, что пароль должен быть не менее 10 символов, немного проанализировав программу, мы поймем, что больше 10 символов он также не может быть. Потому условимся: имя - более трех символов, пароль - ровно 10 символов.

После проверок идет процедура преобразования имени пользователя и пароля. Этот код на PHP выглядел бы так:

так выглядит преобразование имени и пароля на php

//преобразуем имя пользователя $strName

for ($i=0;$i

for ($j=strlen($strName)-1;$j>gt;-1;$j--) {

$sText .= (ord(substr($strName, $i, 1)) ^ ord(substr($strName, $j, 1)));

}

}

//делаем полученный хэш от имени кратным 10

$sTXT = $sText.substr("0000000000", 1, ((floor(strlen($sText) / 10) * 10) + 10) - strlen($sText));

$sPass = substr($sTXT, 0, 10);

$sText = "";

//криптуем хэш имени первыми 10 символами хэша имени

for ($i=9;$i

for($j=0;$j

$sXOR = (substr($sPass, $j, 1) ^ substr($sTXT, $i + $j + 1, 1));

if (strlen($sXOR) >gt; 1) $sXOR = substr($sXOR,0,1);

$sText .= $sXOR;

}

$sPass = $sText;

sText = "";

}

//получаем имя функции регистрации из пароля $strPass

for($i=0;$i

$code = $code.chr(substr($sPass, $i, 1) ^ ord(substr($strPass, $i, 1)));

}

После этого $code вызывается как функция. Для этого в VB есть функция CallByName. В нашем крэкми ее вызов мы найдем тут:

0040568A . E8 65BCFFFF CALL CrackMe.004012F4

0040568F . 50 PUSH EAX

00405690 . FF35 10304100 PUSH DWORD PTR DS:[413010]

00405696 . 8D85 38FFFFFF LEA EAX,DWORD PTR SS:[EBP-C8]

0040569C . 50 PUSH EAX

0040569D . E8 ECBBFFFF CALL CrackMe.0040128E

004056A2 . 50 PUSH EAX

004056A3 . 8D85 28FFFFFF LEA EAX,DWORD PTR SS:[EBP-D8]

004056A9 . 50 PUSH EAX

004056AA . E8 EBBBFFFF CALL CrackMe.0040129A

004056AF . 8D85 A4F6FFFF LEA EAX,DWORD PTR SS:[EBP-95C]

После вызова функции по адресу 0040568A в регистре eax мы получаем адрес на $code, то есть на функцию, которую нужно вызывать. Еще одна уязвимость данного крэкми состоит в обратимом алгоритме шифровки. Если в качестве пароля ввести имя функции, то в eax уже будет адрес на пароль. То есть наша задача определить имя функции длиной 10 символов, которую нужно вызывать, затем ввести ее вместо пароля, и по адресу 0040568F получить пароль на наше имя. Так как программа запакована, то чтобы в ней рыться, нам нужно сделать ее дамп. Для этого в Olly жмем правой кнопкой по листингу и выбираем в появившемся меню Dump debugged process. Нам не нужен рабочий дамп, поэтому просто жмем в появившемся диалоге Dump и вводим имя файла. Теперь открываем файл в фаре по F3 или в hiew'е и начинаем искать в нем 10-символьные строки среди функций. Листать долго не придется: Picture1 lblPass lblText тNн3Щf?

Назад на стр. 082-074-1  Содержание  Вперед на стр. 082-074-3