книги хакеры / журнал хакер / 086_Optimized
.pdf
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ò |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ÃÄÀ ÒÎ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ÒÅËß |
È, ÊÎ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ÇÎÂÀ |
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
ß ÏÎËÜ |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
ЙСТВИ |
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
ÒÜ ÄÅ |
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
ÒÛÂÀ |
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
ÐÀÁÀ |
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
ÅÒ ÎÁ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
Ê ÁÓÄ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
ÐÂÛÉ |
ÏÎÒÎ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
РАММЫ |
ÏÅ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ÉÒÈ ÈÇ |
ÏÐÎÃ |
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Î ÂÛ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ЬТУРН |
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
Ó ÊÓË |
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
ÈÒ ÅÌ |
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
ÇÂÎË |
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
ß, ÏÎ |
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
ÀÅÒÑ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
ÄÎËÁ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
ÍÎ ÇÀ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ЧАТЕЛЬ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ÎÊÎÍ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
такое окно мы будем видеть часто ;)
Итак, начнется наш второй поток входом в функцию lpStartRoutine, а закончится — выходом из нее. Первый поток будет обрабатывать действия пользователя и, когда тот окончательно задолбается, позволит ему культурно выйти из программы, без всяких там приколов в стиле «Программа сейчас пошла погулять, зайди попозже».
Пару слов о главном потоке: если он завершится раньше, чем второй, то окно консоли пропадет, а второй поток останется, поэтому, какой пароль будет найден, мы так и не узнаем. Для обмена инфой о готовности потоков существуют средства их синхронизации.
WaitForSingleObject(hThread,INFINITE);
Эту строку надо разместить там, где ты хочешь подождать завершения потока с дескриптором hThread. Первый поток будет тихо переминаться до тех пор, пока не случится что-то с дескриптором созданного вторичного потока, а случиться с ним может только одно: произойдет выход из его функции (lpStartRoutine закончится, то есть (о, чудо!) мы найдем пароль). Значит, ждем в первом потоке окончания второго, потом закрываем файл-словарь и закрываем хэндл вторичного потока. Все, осталось только функцию вторичного потока рассмотреть.
В этой функции мы инициализируем необходимые нам переменные и запускаем главный мастер-цикл, в котором перебор и будет происходить. На каждой итерации в зависимости от того, тупой брутфорс это или перебор по словарю, создаем новую комбинацию, которую будем вставлять в поле ввода пароля (пункт ¹2). Сохраняем комбинацию в переменной pass и делаем страшную вещь:
SendMessage(hPassEdit,WM_SETTEXT,0,LPARAM(pass1));
Это мы послали сообщение pass1 в окно, которым является поле ввода пароля. WM_SETTEXT приказывает ему заполниться текстом, который
МУЧАЕМ ТЕКСТ ОКНА
Текст окна можно считывать и устанавливать. Для обычного окна текст отображается в его заголовке, для кнопки — на ней самой, для текстового поля — введен в текстовое поле. Считывается текст окна API-функцией GetWindowText (аргументы — хэндл окна типа HWND, указатель на буфер, принимающий текст окна, и размер этого буфера в байтах типа Integer). Устанавливается текст окна функцией SetWindowText, принимающей те же самые параметры, только без длины буфера. Второй способ чтения/установки текста окна — посылка ему сообщения WM_GETTEXT/WM_SETTEXT. Тогда lParam — адрес буфера со строкой, а wParam — его размер в байтах (для WM_SETTEXT размер буфера, понятное дело, не нужен и wParam=0).
наша замечательная тулза
лежит по указателю pass1 (пункт ¹3). В общем-то, то же самое действие можно было делать с помощью API-функции SetWindowText (подробнее смотри врезку), но я захотел для разнообразия показать еще и механизм работы с текстом окна через посылаемые ему сообщения.
PostMessage(hIEPassWindow,WM_COMMAND,WPARAM(IDOK),0);
А это мы нажали на кнопку ОК (пункт ¹4). Сообщение WM_COMMAND приходит всякий раз, когда пользователь нажимает какую-нибудь кнопку, заходит в меню или нажимает горячие клавиши. Параметром wParam сообщения является идентификатор сработавшего элемента. Программа именно по нему определяет, что же скомандовал юзер.
Далее необходимо немного поспать. Но не нам, а ему — вторичному потоку. Почему? Потому что теперь, согласно пункту ¹5 нашего супералгоритма, надо проверить, появилось ли ругательное окно с заголовком «Ограничение доступа», которое сообщает о том, что пароль-то неверный! А оно сразу может и не появится, потому что для его появления понадобится какое-то время. Получается, наш поток может раньше закончить поиск этого окна и решить, что оно не вылезло (значит, найден пароль!), а на самом деле это окно появится после окончания поиска (и о правильном подборе и речи быть не может). Поэтому надо с умом управлять параметрами засыпания, поэкспериментировать и посмотреть, чтобы не было ложных срабатываний. Например, если я ничего не делаю в фоне, то нормально действует задержка на 20 мс, но если я на- чинаю запускать что-то тяжеленькое, то прога наша может и неправильный пароль выдать. В общем, ищи оптимум.
Какой переборщик вышел у меня в итоге, ты можешь посмотреть, если залезешь на диск. Очень советую как следует изучить сорцы, чтобы ухватить все нюансы, упущенные в этой статье ;).
ВОТ, СОБСТВЕННО, И ВСЕ
Вот и пришло время заканчивать сие утомительное повествование. Ты теперь знаешь, как взаимодействовать с чужими окнами, сможешь их находить, считывать текст, заполнять поля, изменять текст и содержимое окон, в общем, творить все, что душе угодно. Да и не техническая сторона тут важна. Главное состоит в том, что можно без разбирательств во внутренней логике системы защиты взломать ее с довольно приличной скоростью, хотя и на порядок меньше, чем перебор по внутреннему алгоритму системы. Зато не надо разбираться в ассемблерных кодах и прочих потрохах, так как система все сделает сама, а ты знай себе, чай с вареньем попивай, а не пальцы об клаву гаси. И, если не получится таким методом пароль снять, только потом уже засядешь за сложные вещи, всякие там реверсы и инженеринги. Теперь разреши откланяться и пожелать тебе, чтобы все взламываемые пароли не выходили за рамки банального «1» и всегда отыскивались.
BINARY YOUR’S z
|
|
|
|
|
|
|
|
|
|
ÎÕÀÕ |
|
|
|
|
|
|
|
|
|
Õ ÏÎÒÐ |
|
|
|
|
|
|
|
|
|
ÐÎ×È |
|
|
|
|
|
|
|
|
|
Õ È Ï |
|
|
|
|
|
|
|
|
|
ÍÛÕ |
ÊÎÄÀ |
|
|
|
|
|
|
|
|
ÁËÅÐ |
|
|
|
|
|
|
|
|
|
ÑÑÅÌ |
|
|
|
|
|
|
|
|
|
ß Â À |
|
|
|
|
|
|
|
|
|
ÀÒÜÑ |
|
|
|
|
|
|
|
|
|
ÇÁÈÐ |
|
|
|
|
|
|
|
|
|
ÄÎ ÐÀ |
|
|
|
|
|
|
|
|
|
|
ÇÀÒÎ ÍÅ ÍÀ |
|
|
|
|
|
|
|
|
|
|
XÀÊÅÐ 02 /86/ 06 |
119 |
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|||
P |
|
|
|
|
|
NOW! |
o |
||||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
КОДИНГ///// ISSUE |
||||
|
|
|
|
to |
|
|
|
|
|||
w Click |
|
|
|
|
|
m |
|||||
|
|
|
|
|
|
||||||
w |
|
|
|
|
|
|
|
|
ASSEMBLER |
||
|
w |
|
|
|
|
|
|
|
o |
|
|
|
. |
|
|
|
|
|
.c |
|
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
df |
|
|
n |
e |
|
|
||
|
|
|
|
-xcha |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
TEXT КРИС КАСПЕРСКИ АКА МЫЩЪХ / /
В ПРЯТКИ С ОТЛАДЧИКОМ
ПИШЕМ CRACKME, ПРЯЧУЩИЙ КОД НА API-ФУНКЦИЯХ
“СЕЙЧАС МЫ БУДЕМ ЗАНИМАТЬСЯ УВЛЕКАТЕЛЬНЫМ ДЕЛОМ: ПИСАТЬ CRACKME И ПЫТАТЬ ЕГО НА ПРЕДМЕТ ВЗЛОМА, А CRACKME БУДЕТ МОЛЧАТЬ КАК ПАРТИЗАН, ПОТОМУ ЧТО ПРЯЧЕТ ЗАЩИТНЫЙ КОД В API-ФУНКЦИЯХ, ГДЕ ДО НЕГО НЕ МОЖЕТ ДОТЯНУТЬСЯ НИ ДИЗАССЕМБЛЕР, НИ ДАМПЕР, НИ ДАЖЕ ОТЛАДЧИК. ЭТО ДРЕВНИЙ ПРИЕМ, УХОДЯЩИЙ СВОИМИ КОРНЯМИ В ЭПОХУ MS-DOS, НО НИЧУТЬ НЕ ХУЖЕ РАБОТАЮЩИЙ И В АГРЕССИВНОМ МИРЕ WINDOWS”
ÈÄÅß
Будем исходить из того, что основным орудием хакера является дизассемблер и отлад- чик (а при анализе упакованных программ к ним еще добавляется и дампер). Существует множество хитроумных трюков, затрудняющих трассировку и отравляющих дизассемблеру жизнь, однако они только подогревают интерес хакера и зачастую вызывают непредсказуемые конфликты, что не есть хорошо. А давай просто спрячем защитный код там, где никто не станет его искать? Программные комплексы наших дней содержат миллионы строк кода и потому никогда не анализируются целиком. Если хакер встречает вызов API-функции LoadLibrary, то он искренне верит, что это действительно LoadLibrary, а не что-то еще. Теоретически в API-функцию можно заглянуть отладчиком, однако практи- чески она представляет «черный ящик». Анализируя аргументы и последовательность вызовов API-функций (с помощью API-шпио- нов), хакер получает общее представление о работе защитного механизма, после чего редко приходится прибегать к отладчику/дизассемблеру.
Мыщъх предлагает защищаться так: берем какую-нибудь ненужную API-функцию, которая заведомо не используется, и копируем
поверх нее свой собственный код (далее по тексту называемый X-кодом), выполняющий что-то полезное, например, проверяющий серийный номер. Выбирать лучше всего неброскую, ненапряженную функцию с названием не вызывающим у хакера никаких подозрений, например GetTimeZoneInformation. Естественно, перед копированием необходимо присвоить памяти, где расположена функция, атрибут записи, что достигается вызовом VirtualProtect с флагом PAGE_EXECUTE_READWRITE, а после копирования вернуть исходные атрибуты защиты обратно.
Модификация API-функций носит сугубо локальный характер. Механизм Copy-on-Write автоматически расщепляет все измененные страницы, и потому изменения может увидеть только тот процесс, который их записал. Это значит, что за конфликты с другими процессами можно не волноваться. Заботиться о восстановлении оригинального содержимого API-функций также не нужно.
Поскольку адреса API-функций не остаются постоянными и чаще всего варьируются от одной системы к другой. X-код не может привязываться к своему расположению в памяти и должен полностью перемещаться. Чтобы не заморачиваться, можно разместить X-код внутри нашей программы, а в начало API-
функции внедрить jump. Конечно, это будет более заметно. Стоит хакеру заглянуть отлад- чиком в API-функцию, как он тут же поймет, что она пропатчена, а вот при копировании X-кода поверх API-функции это уже не так очевидно. Развивая мысль дальше, можно не затирать ненужное API, а взять популярную функцию типа CreateFile и слегка «усовершенствовать» ее, например, незаметно расшифровывать содержимое файла или просто помухлевать с аргументами. Допустим, программа открывает файл «file_1». X-код, внедренный в CreateFile, заменяет его на «file_2», передавая управление оригинальной CreateFile,
— пусть она его открывает!
Фактически мы приходим к идее создания APIперехватчика (ака шпиона), только шпионить он должен не за чужим процессом, а за своим собственным, перехватывая нужные API-функ- ции и скрытно выполняя некоторые дополнительные действия. Это серьезно затрудняет дизассемблирование, поскольку ключевые моменты защитного алгоритма идут мимо хакера, который ни хрена не может понять, как это работает и почему (например, можно внедрить в CreateFile процедуру проверки ключевого файла, а в самой программе только имитировать его выполнение, заставляя хакера анализировать километры совершенного левого кода).
120 |
XÀÊÅÐ 02 /86/ 06 |