книги хакеры / журнал хакер / специальные выпуски / Специальный выпуск 58_Optimized
.pdf
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
||
|
|
|
C |
|
E |
|
|
|
|
|
|
C |
|
E |
|
|
|
||||||
|
|
X |
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
||||||
|
- |
|
|
|
|
|
d |
|
|
- |
|
|
|
|
|
d |
|
||||||
|
F |
|
|
|
|
|
|
|
t |
|
|
F |
|
|
|
|
|
|
|
t |
|
||
|
D |
|
|
|
|
|
|
|
|
i |
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
r |
||||
P |
|
|
|
|
|
NOW! |
o |
P |
|
|
|
|
|
NOW! |
o |
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
|
|
|
|
|
BUY |
|
|
|
|
|
|
|
BUY |
|
|
||||||||
|
|
|
|
to |
|
|
|
|
|
|
|
|
|
|
to |
|
|
|
|
|
|
||
w Click |
|
|
|
|
|
|
m |
w Click |
|
|
|
|
|
|
m |
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
w |
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
|
w |
|
|
|
|
|
|
|
|
o |
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|
. |
|
|
|
|
g |
.c |
|
||||||
|
|
p |
|
|
|
|
|
|
|
|
|
p |
|
|
|
|
|
|
|
||||
|
|
|
df |
|
|
n |
e |
|
|
|
|
df |
|
|
n |
e |
|
||||||
|
|
|
|
-xcha |
|
|
|
|
|
|
|
|
|
-x cha |
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
I N T R O
Øироко распространено мнение, что для взлома компьютерной сети, особенно крупной и секретной, нужно преодолеть много преград сложной системы безопасности, обойти брандмауэр и т.д. Только тогда удастся проникнуть в святая святых - к суперсерверам и хранилищам секретных данных :). Однако со
временем выяснилось, что клиентские приложения – компьютеры и программы рядовых пользователей, имеющих доступ к интересуемой сети, – гораздо уязвимее, чем сложные серверные системы. Поэтому проще взломать их ("клиентов"), а дальше - копаться в сети изнутри. Вспомнить хотя бы старину Митника, который в свое время похожим способом (правда, по большей части используя фрикерские приемы и чудеса социальной инженерии) проникал туда, куда ему не сделовало соваться.
Сегодня, когда промышленный шпионаж обретает грандиозные масштабы, следует особенно тщательно заниматься безопасностью обычных офисных компьютеров: банальный троян может принести сотни миллионов убытков. Украденные исходники Half-Life 2, Cisco IOS - подтверждения тому. Можно сказать, что сейчас охота на "клиентов" находится на стадии бурного развития. Безопасность клиентских приложений стала настолько актуальной, что мы решили уделить этой проблеме целый номер, добавив в качестве приправы безопасность сетевых и криптографических протоколов как важнейшие компоненты современных компьютерных систем.
Конечно, защиты на 100% не было, нет и не будет. Тот же человеческий фактор никуда никогда не денется. Однако стремиться минимизировать риски, думаю, стоит всегда.
AvaLANche feat. Андрей Каролик
|
|
|
|
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 |
|
|
|||
¹ 09 (58) |
|
to |
|
|
|
|
|
|||
w Click |
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
n |
e |
|
|||
|
|
|
|
-x cha |
|
|
|
|
ÎÑ
4 Windows на страже порядка
Защита от посягательства на наши приложения, или почему она никого не пугает
10 Сокрушительная атака
Buffer overflow на службе взломщиков
16 Как скрытое становится явным
Проникновение в Protected Storage
ВЗЛОМ
18 Инструктаж перед боем
Ошибки клиентских приложений
24 Издевательство над окнами
Эмуляция ввода с клавиатуры
28 Ultimate adventure
Стратегия поиска дыр в двоичном коде
34 Защити свои приложения
Как защититься от атаки на переполнение буфера
38 Вся правда об антивирусах
Обзор и анализ самых популярных антивирусов
44 Жесткий тест файрволов
Проверим, кто же хуже всех
48 Интервью с Agnitum
Вопросы разработчикам Outpost Firewall
50 Stealth patching своими руками
Малоизвестные способы взлома
56 Мнение профессионала
Интервью с ЗАРАЗА
58 Полоса препятствий
Преодоление файрволов снаружи и изнутри
62 Утечка данных
Через служебную информацию и сетевой протокол в клиентском приложении
66 Как работает брандмауэр
Пакетные фильтры и прокси
ЗАЩИТА
72 Сделай это безопасным!
Создание и исследование криптографических протоколов
78 Забытый протокол от AOL
Instant messenger, flooder, bruteforcer? Легко!
84 Безопасность сетевых протоколов
Взгляд со стороны клиента
SPECial delivery
88 Обзор книг
Что полистать
90 Обзор сайтов
Что посмотреть
92 Вирусы по-женски
Интервью с девушкой вирусным аналитиком
96 FAQ
По взлому клиентских приложений и безопасности сетевых протоколов
ЭКСПЕРТ НОМЕРА
Крис Касперски aka мыщъх
Небрежно одетый мыщъх, 28 лет, не обращающий внимание ни на мир, ни на тело, в котором живет, и обитающий исключительно в дебрях машинных кодов и зарослях технических спецификаций. Не общителен, ведет замкнутый образ жизни хищного грызуна, практи- чески никогда не покидающего свою норку. Основная специализация – реинженеринг (дизассемблирование), поиск уязвимостей в существующих защитных механизмах и разработка собственных систем защиты. Хакерские мотивы творчества не случайны и объясняются по-детски естественным желанием заглянуть "под капот" компьютера и малость потыкать его "ломом" и "молоточком".
ÎÑ
4 Windows на страже порядка
Защита от посягательства на наши приложения, или почему она никого не пугает
КЛИЕНТ
38 Вся правда об антивирусах
Обзор и анализ самых популярных антивирусов
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
|
||
P |
|
|
|
|
|
NOW! |
o |
|
|||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|
|||
w Click |
to |
|
|
|
|
m |
» |
||||
|
|
|
|
|
|||||||
|
|
|
|
|
|
|
|||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
|
. |
|
|
|
|
|
.c |
|
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
df |
|
|
n |
e |
|
|
||
|
|
|
|
-xcha |
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ОФФТОПИК КЛИЕНТ
CÎÔÒ |
44 Жесткий тест |
104 NoNaMe |
файрволов |
Самый вкусный софт |
Проверим, кто же |
HARD |
õóæå âñåõ |
|
|
106 Фотики для... |
|
Небо! Море! Отдых! |
|
111 Быть первым |
|
MSI NX 7800GTX |
|
112 Паяльник |
|
Таймер с "волшебной" |
|
лампочкой |
|
ÑREW |
|
116 E-ìûëî |
|
Пишите письма |
|
STORY |
|
118 Жизнь прекрасна |
|
ÍÀRD
106 ФОТИКИ ДЛЯ
Небо!Море!Отдых!
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
|
X |
|
|
|
|
|
|||
|
|
- |
|
|
|
|
|
d |
|
||
|
|
F |
|
|
|
|
|
|
t |
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
||
|
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
|
||||
Редакция |
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
||
» главный редактор |
w |
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|||
Николай «AvaLANche» Черепанов |
w Click |
|
|
|
|
|
o |
m |
|||
|
|
w |
|
|
|
|
|
|
|
|
|
(avalanche@real.xakep.ru) |
|
. |
df |
|
|
n |
.c |
|
|||
|
|
p |
|
|
|
|
|
||||
|
|
|
|
|
|
|
g |
|
|
||
|
|
|
|
|
-x cha |
|
e |
|
» выпускающие редакторы
Александр «Dr.Klouniz» Лозовский (alexander@real.xakep.ru),
Андрей Каролик (andrusha@real.xakep.ru)
» редакторы
Ашот Оганесян (ashot@real.xakep.ru), Николай «GorluM» Андреев (gorlum@real.xakep.ru)
»редактор CD и раздела ОФФТОПИК
Иван «SkyWriter» Касатенко (sky@real.xakep.ru)
»литературный редактор, корректор
Валентина Иванова (valy@real.xakep.ru)
Art
»арт-директор
Кирилл «KROt» Петров (kerel@real.xakep.ru) Дизайн-студия «100%КПД»
»верстальщик
Алексей Алексеев
» художник
Константин Комардин
Реклама
»директор по рекламе ИД (game)land
Игорь Пискунов (igor@gameland.ru)
»руководитель отдела рекламы цифровой и игровой группы
Ольга Басова (olga@gameland.ru)
»менеджеры отдела
Виктория Крымова (vika@gameland.ru) Ольга Eмельянцева (olgaeml@gameland.ru)
» трафик-менеджер
Марья Алексеева (alekseeva@gameland.ru) тел.: (095) 935.70.34 ôàêñ: (095) 780.88.24
PR
» директор по PR цифровой группы
Глеб Лашков (lashkov@gameland.ru)
Распространение
»директор отдела дистрибуции и маркетинга
Владимир Смирнов (vladimir@gameland.ru)
»оптовое распространение
Андрей Степанов (andrey@gameland.ru)
»региональное розничное распространение
Андрей Наседкин (nasedkin@gameland.ru)
»подписка
Алексей Попов (popov@gameland.ru) тел.: (095) 935.70.34 ôàêñ: (095) 780.88.24
PUBLISHING
»издатель
Сергей Покровский (pokrovsky@gameland.ru)
»учредитель
ÎÎÎ «Ãåéì Ëýíä»
»директор
Дмитрий Агарунов (dmitri@gameland.ru)
»финансовый директор
Борис Скворцов (boris@gameland.ru)
Горячая линия по подписке
òåë.: 8 (800) 200.3.999
Бесплатно для звонящих из России
Для писем
101000, Москва, Главпочтамт, а/я 652, Хакер Спец
Web-Site http://www.xakep.ru
E-mail spec@real.xakep.ru
Мнение редакции не всегда совпадает с мнением авторов. Все материалы этого номера представляют собой лишь
информацию к размышлению. Редакция не несет ответственности за незаконные действия, совершенные с ее использованием, и возможный причиненный ущерб.
За перепечатку наших материалов без спроса - преследуем.
Отпечатано в типографии «ScanWeb», Финляндия
Зарегистрировано в Министерстве Российской Федерации по делам печати, телерадиовещанию
и средствам массовых коммуникаций ÏÈ ¹ 77-12014 от 4 марта 2002 г.
Тираж 42 000 экземпляров. Цена договорная.
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
w Click |
|
|
|
|
|
|
||||
|
|
|
|
|
|
m |
||||
w |
|
|
|
|
Content: |
|||||
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
.c |
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-xcha |
|
|
|
|
4 Windows на страже порядка
Защита от посягательства на наши приложения, или почему она никого не пугает
10 Сокрушительная атака
Buffer overflow на службе взломщиков
16 Как скрытое становится явным
Проникновение в Protected Storage
ÎÑ
4ÎÑ WINDOWS НАСТРАЖЕПОРЯДКА
Deeoni$ (arustamovv2000@mail.ru; ICQ 982-622)
WINDOWS ÍÀ СТРАЖЕ ПОРЯДКА
ЗАЩИТА ОТ ПОСЯГАТЕЛЬСТВА НА НАШИ ПРИЛОЖЕНИЯ, ИЛИ ПОЧЕМУ ОНА НИКОГО НЕ ПУГАЕТ
|
|
|
|
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 |
|
|
|
|
Ãлавным компонентом "обороны" ОС Windows являются четыре кольца защиты. В ring 3 работают все приложения, запущенные пользователями
(в том числе и администраторами). Отсюда мы имеем доступ лишь к стандартным функциям, разрешенным для использования напрямую в программах.
|
Ê |
ольца ring 1 и ring 2 в Windows |
|
NT не используются. Ring 0 – |
|
|
||
|
||
|
это самое мощное кольцо. В |
|
|
||
|
||
|
||
|
нем работает ядро системы и |
|
|
||
|
||
|
драйверы. Привилегирован- |
ные команды и ввод-ввод для третьего кольца запрещены, для взаимодействия с аппаратной частью компьютера вызываются системные сервисы ядра ОС, которые оформлены как шлюзы. При вызове такого шлюза процесс переходит в нулевое кольцо, и там ядро ОС и драйверы обрабатывают запрос и возвращают результаты приложению. После перехода в нулевое кольцо приложение не может как-либо контролировать свое исполнение, пока управление не будет возвращено коду третьего кольца. Это необходимое условие защиты, оно обеспечивает безопасность всей системы.
Получив привилегии нулевого кольца, мы, по сути, становимся на этой машине богами. Однако в современных ОС проникнуть на этот уровень защиты очень трудно.
Кольца защиты существовали и в "девятках", но Windows часто падала из-за всяческих глюков в приложениях. Эта проблема была решена после создания виртуального адресного пространства, которое у каждого процесса свое. Благодаря такому решению устойчивость системы к сбоям значительно повысилась. Вместе с ней поднялся и уровень защиты от всяческих вредоносных
программ. Рассмотрим подробнее это чудоизобретение.
Каждый вновь созданный процесс получа- ет в свое распоряжение 4 Гб памяти. Там располагается сам код программы, отображаются подгруженные библиотеки, в том числе системные. Никакой другой процесс не может получить доступ к данным и процедурам, находящимся в чужом адресном пространстве. В результате приложение не может перезаписать жизненно важные структуры других программ, выполняющихся одновременно с ним.
Все это сильно ограничивает нас в возможностях и, с другой стороны, защищает. Но стопроцентной защиты не бывает. Сейчас я продемонстрирую, как можно вторгнуться в чужое адресное пространство и использовать законного владельца этого пространства в своих целях. Более того, при проявлении некоторой смекалки можно будет догадаться, как можно получить доступ к некоторым функциям ядра. Итак, начнем с того, как внедрить свой код в посторонний процесс.
ВНЕДРЕНИЕ DLL
С ИСПОЛЬЗОВАНИЕМ РЕЕСТРА
Наверное, каждый, даже непродвинутый пользователь из числа наших братьев меньших :) знает, что такое реестр, для чего он нужен и что в нем можно трогать, а что нельзя. Но не каждый догадывается о том, что с
|
Windows 95 |
|
Windows NT |
|
|
|
Системная область (1 Гб). Код |
|
|
|
|
0xFFFFFFFF - |
операционной системы. Доступна всем |
|
|
|
|
0xC0000000 |
процессам для чтения\записи (но лучше |
Ãá |
Системная область (2 Гб). |
0xFFFFFFFF - |
|
|
этого не делать) |
Преданзанченна для |
|||
|
0x80000000 |
||||
|
2 |
||||
0xBFFFFFFF - |
Системная область (1 Гб). Предназначена |
операционной системы |
|
||
|
|
||||
для размещения объектов, разделяемых |
|
|
|
||
0x80000000 |
|
|
|
||
между процессами |
|
|
|
||
|
|
|
Частная собственность |
|
|
0õ7FFFFFFF - |
Частная собственность процесса (~2 Гб). |
|
процесса (64 Кб). Область для |
0x7FFFFFFF - |
|
|
выявления указателей с |
||||
0x00400000 |
Область доступна для чтения\записи |
|
0x7FFF0000 |
||
|
неправильными значениями. |
||||
|
|
|
|
||
|
|
|
Недоступна |
|
|
|
Частная собственность процесса (~4 Мб). |
Ãá |
Частная собственность |
|
|
0x003FFFFF - |
Область предназначенна для размещения |
0x7FFEFFFF - |
|||
процесса (~2 Гб). Область |
|||||
2 |
|||||
0x00010000 |
структур, требуемых DOS. Доступна для |
0x00010000 |
|||
|
доступна для чтения\записи |
||||
|
чтения\записи (но лучше этого не делать) |
|
|
||
|
|
|
|
||
|
Частная собственность процесса (64 Кб). |
|
Частная собственность |
|
|
0x0000FFFF - |
Область предназначена для |
|
процесса (64 Кб). Область для |
0x0000FFFF - |
|
0x00000000 |
использования DOS. Недоступна для |
|
выявления пустых указателей. |
0x00000000 |
|
|
записи. |
|
Всегда свободна |
|
|
|
|
|
|
|
Рис. 1. Распределение адресного пространства в ОС семейства Windows
ХАКЕРСПЕЦ 09(58) 2005
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|||
|
F |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
t |
|
||
P |
D |
|
|
|
|
|
|
|
|
o |
|
|
|
|
|
NOW! |
r |
||||||
|
|
|
|
|
BUY |
|
|
||||
|
|
|
|
to |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
m |
|
w Click |
|
|
|
|
|
|
o |
||||
|
w |
|
|
|
|
|
|
|
|
|
|
|
. |
|
|
|
|
|
|
.c |
|
||
|
|
|
|
|
|
|
|
e |
|
||
|
|
p |
df |
|
|
|
|
помощью этой хитрой штуки можно |
|||
|
|
|
|
|
g |
|
|
|
|||
|
|
|
|
|
n |
|
|
|
|
||
|
|
|
|
-xcha |
|
|
|
|
|
заставить практически любое приложение выполнять твой код, – воспользуемся параметром реестра:
HKEY_LOCAL_MACHINE\Software\Microsoft\ Windows_NT\CurrentVersion\Windows\AppI mt_DLLs
Значением параметра AppInit_DLLs может быть как имя одной DLL (с указанием пути доступа), так и имена нескольких DLL, разделенных пробелами или запятыми. Так как пробел используется здесь в качестве разделителя, в именах файлов не должно быть пробелов. Система считывает путь только первой DLL в списке: пути остальных DLL игнорируются, поэтому лучше разметать свои DLL в системном каталоге Windows, чтобы не указывать пути. На рис. 2 показано, что мы хотим внедрить код SuperDLL.dll.
При следующей перезагрузке компьютера Windows сохранит значе- ние этого параметра. Далее, когда User32.dll будет спроецирован на адресное пространство процесса, этот модуль получит уведомление DLL_PROCESS_ATTACH и после его обработки вызовет LoadLibrary для всех DLL, указанных значением AppInit_DLLs. В момент загрузки каждая DLL инициализируется вызовом ее функции DLLMain с параметром fwdReason, равным DLL_PROCESS_ATTACH.
Это простейший способ внедрения DLL. Нам не надо делать ничего, кроме как запустить regedit.exe и подредактировать соответствующий ключик. Но у этого способа есть свои недостатки, и они довольно существенны.
Во-первых, написанная в поту и крови dll проецируется на адресные пространства только тех процессов, на которые спроецирован модуль
Рис. 2. Инициализируем параметр AppInit_DLLs собственной DLL
User32.dll. Его, как известно, используют все GUI-приложения, но в большинстве консольных программ эта библиотека ни к чему. Из этого вытекает первый недостаток: код можно внедрить только в приложения с графическим интерфейсом.
Во-вторых, DLL будет проецироваться на адресные пространства всех запущенных GUI-процессов. Чем больше приложений "подомнет" под себя твой код, тем вероятнее то, что кто-ни- будь где-нибудь повиснет или вылетит. Другими словами, значительно повышается риск непредвиденных ошибок.
В-третьих, внедренные инструкции обычно нужны не на всем протяжении работы процесса. После того как DLL сделает свое дело, тебе захочется поскорее убрать ее из памяти. Но - не выйдет. Поэтому перейдем к следующему способу, более продвинутому.
ВНЕДРЕНИЕ DLL С ПОМОЩЬЮ ЛОВУШЕК
Все недостатки, перечисленные немного выше, становятся неактуальны, если для внедрения dll использовать хуки (ловушки). Хук можно поставить используя следующую APIфункцию:
HHOOK SetWindowsHookEx(int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId);
Первым параметром этой функции является тип устанавливаемого хука. Например, idHook может быть равен WH_GETMESSAGE. Эта разновидность ловушки срабатывает при генерировании процессом какого-либо сообщения. Параметр lpfn – это указатель на процедуру (в адресном пространстве нашего процесса), которую система должна вызывать всякий раз при срабатывание хука, то есть при обработке окном сообщения. hMod идентифицирует DLL, содержащую функцию, на которую указывает lpfn. В Windows значение hMod для DLL фактически задаст адрес виртуальной памяти, по которому DLL спроецирована на адресное пространство. Последнее значение, передаваемое SetWindowsHookEx, указывает поток, для которого предназначена ловушка. Передавая 0, мы сообщаем системе, что ставим хук для всех существующих в ней GUI-процессов. В случае удачного выполнения функция вернет хэндл на хук-процедуру. В противном случае будет NULL.
ЛИСТИНГ
PTHREAD_START_ROUTIHE pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress (GetModuleHandle(TEXT("Kernel32")), "LoadLibraryA");
HANDLE hThread = CreateRemoteThread(hProcessRemote, NULL, 0, pfnThreadRtn, "C:\\Windows\\SuperDLL.dll", 0, NULL);
5
Теперь рассмотрим это подробнее. Допустим, у нас есть процесс A, поставивший хук WH_GETMESSAGE и наблюдающий за сообщениями, которые обрабатываются окнами в системе. Поток процесса B собирается направить сообщение какому-либо окну. Система проверяет, не установлена ли для данного потока соответствующая ловушка, затем выясняет, спроецирована ли DLL, содержащая функцию хука, на адресное пространство процесса B. Если указанная DLL еще не спроецирована, система отображает ее на адресное пространство процесса B и увеличивает счетчик блокировок проекции DLL в процессе B на один. После этого ОС проверяет, не совпадают ли значения hMod этой DLL, относящиеся к процессам A и B. Если hMod в обоих процессах одинаковы, то и адрес функции хука в этих процессах тоже одинаков. Тогда система может просто вызвать lpfn в адресном пространстве процесса A. Если же hMod отличаются, то определяется адрес функции в адресном пространстве процесса B по формуле:
lpfn B = hMod B + (lpfn A – hMod A)
Вычитая hMod из lpfn A, мы получа- ем смещение адреса функции ловушки. Добавляя это смещение к hMod B, будем иметь адрес lpfn, соответствующий проекции DLL в адресном пространстве процесса B. При этом счетчик блокировки в процессе B увеличивается на один и вызывается lpfn в адресном пространстве процесса B. После возврата из функции счетчик блокировки проекции DLL в адресном пространстве процесса B уменьшается на один.
Когда система внедряет или проецирует DLL, содержащую функцию фильтра ловушки, проецируется вся DLL, а не только эта функция. А зна- чит, потокам, выполняемым в контексте процесса B, теперь доступны все функции такой DLL.
В отличие от внедрения DLL с помощью реестра, этот способ позволяет в любой момент отключить DLL от адресного пространства процесса вызовом функции:
BOOL UnhookWindowsHookEx(HHOOK hhk);
Единственный параметр hhk – это хэндл хука, который мы хотим убрать и который возвращается при вызове SetWindowsHookEx. Когда поток обращается к этой функции, система просматривает внутренний список процессов, в которые ей пришлось внедрить данную DLL, и уменьшает счетчик ее блокировок на один. Как только этот счетчик обнуляется, DLL автоматически выгружается. Система увеличивает его непосредственно перед вызовом lpfn. Это позволяет избежать нарушения доступа к памяти. Если бы счет-
чик не увеличивался, то другой поток »
|
|
|
|
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 |
|
S E C U R I T Y - Ô Î Ê Ó Ñ Û |
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
|
||
|
S E C U R I T Y - Ô Î Ê Ó Ñ Û |
-xcha |
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
X |
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- |
|
|
|
|
|
d |
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
F |
|
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r |
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
P |
|
|
|
|
|
NOW! |
o |
||||
6 |
|
ÎÑ |
|
|
|
WINDOWSНАСТРАЖЕПОРЯДКА |
|
|
|
|
|
BUY |
|
|
||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w Click |
to |
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m |
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
|
|
||
мог бы вызвать |
|
ВНЕДРЕНИЕ КОДА В СРЕДЕ WINDOWS 98 ЧЕРЕЗ |
|
w |
|
|
|
|
|
|
|
|
o |
|
||||||||||||||||||||||||
|
|
. |
df |
|
|
n |
e |
|
||||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
p |
|
|
|
.c |
|
||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-x cha |
g |
|
||||||
UnhookWindowsHookEx в тот момент, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||
ПРОЕЦИРУЕМЫЙ В ПАМЯТЬ ФАЙЛ |
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||||
когда поток процесса B пытается вы- |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||
полнить код функции ловушки. |
|
|
Эта задача в Windows 98, по сути, тривиальна. В ней все 32-раз- |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||
ВНЕДРЕНИЕ DLL С ПОМОЩЬЮ |
|
рядные приложения делят верхние два гигабайта своих адресных |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||
|
пространств. Выделенный там блок памяти доступен любому при- |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
УДАЛЕННЫХ ПОТОКОВ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
|
|
Этот способ внедрения DLL самый |
|
ложению. С этой целью мы должны использовать проецируемые в |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
гибкий из всех. В нем используются |
|
память файлы. Сначала мы создаем проекцию файла, а потом вы- |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||
многие особенности Windows, напри- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
|
зываем MapViewOfFile и делаем ее видимой. Далее мы записываем |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
мер потоки и синхронизация потоков, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
|
нужную информацию в эту область своего адресного пространства |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
управление виртуальной памятью и |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
многое другое. Суть этого метода зак- |
|
(она одинакова во всех адресных пространствах). Чтобы все это ра- |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||
лючается в том, чтобы создать в чу- |
|
ботало, нам, вероятно, придется вручную писать машинные коды, а |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||
жом процессе поток, который подгру- |
|
это затруднит перенос программы на другую процессорную плат- |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||
зит в этот процесс нужную нам DLL. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
|
форму. Но это не очень страшно: все равно Windows 98 работает |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
Большинство API-функций Windows |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
|
только на процессорах типа x86. |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
позволяют процессу управлять лишь |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
самим собой, тем самым исключается |
|
Данный метод тоже довольно труден, потому что нам нужно будет |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||
риск испортить что-нибудь в работе |
|
заставить поток другого процесса выполнять код в проекции фай- |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||
других приложений. Однако есть и та- |
|
ла, для чего понадобятся какие-то средства управления удаленным |
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||||||||||||
кие функции, которые позволяют уп- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
|
потоком. Здесь пригодилась бы функция CreateRemoteThread, но |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
равлять чужим процессом. Изначаль- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
|
Windows 98 ее не поддерживает. |
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
но многие из них были рассчитаны на |
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||||||||||||
применение в отладчиках и других |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
инструментальных средствах. Но нич- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||
то не мешает использовать их и в |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||||
обычных программах. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||
|
Итак, как же реализовать это на |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||
практике? Для начала создать в нуж- |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
ном нам процессе свой поток – для |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
этого есть волшебная функция |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||||
CreateRemoteThread. Вот ее описание: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
Кольца защиты
Теперь быстренько рассмотрим па-
раметры, передаваемые этой функ- |
навливает дополнительные флаги, |
щает идентификатор, приписанный |
|
ции. hProcess - хэндл процесса, кото- |
управляющие потоком. Он принимает |
системой новому потоку. Вообще, |
|
рому будет принадлежать новый по- |
одно из двух значений: 0 (исполнение |
прототип CreateRemoteThread практи- |
|
ток. lpThreadAttributes – это указатель |
потока начинается немедленно) или |
чески полностью идентичен |
|
на структуру с security-атрибутами. |
CREATE_SUSPENDED. В последнем |
CreateThread, за исключением хэндла |
|
dwStackSize определяет размер стека, |
случае система создает поток, иници- |
процесса, которого в последней функ- |
|
отведенный новому потоку. |
ализирует его и приостанавливает до |
öèè íåò. |
|
lpStartAddress есть адрес функции |
последующих указаний. Последний |
Теперь возникла проблема: как зас- |
|
потока, а lpParameter – параметр, пе- |
параметр - это адрес переменной типа |
тавить созданный нами удаленный |
|
редаваемый ей. dwCreationFlags уста- |
DWORD, в которой функция возвра- |
поток загрузить нужную DLL? Очень |
|
|
|
просто: вызвать LoadLibrary. |
|
|
|
HMODULE LoadLibrary(LPCTSTR lpFileName); |
|
|
|
||
|
|
Единственный передаваемый пара- |
|
|
|
метр – это указатель на строку, содер- |
|
|
|
жащую путь к DLL. Существуют две |
|
|
|
реализации этой API: LoadLibraryA, |
|
|
|
LoadLibraryW. Первая предназначена |
|
|
|
для работы со строкой в ANSI-коди- |
|
|
|
ровке, а вторая – в юникоде. Волею |
|
|
|
судеб прототипы LoadLibrary и функ- |
|
|
|
ции потока почти идентичны: обе при- |
|
|
|
нимают единственный параметр и |
|
|
|
возвращают некое значение. Кроме |
|
|
|
того, обе используют одни и те же |
|
|
|
правила вызова - WINAPI. Теперь |
|
|
|
включим мозг и стараемся придумать, |
|
|
|
как использовать это… Догадался? |
|
|
|
Нужно создать новый поток, адрес |
|
|
|
функции которого является адресом |
|
Поток процесса B пытается создать подкласс окна, сформированного потоком |
|||
|
|||
процесса A |
|
|
|
|
|
|
ХАКЕРСПЕЦ 09(58) 2005
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
||||
|
|
X |
|
|
|
|
|
||||
|
- |
|
|
|
|
|
d |
|
|||
|
F |
|
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
||||
|
|
|
|
|
|
|
|||||
|
|
|
|
|
BUY |
|
|
||||
|
|
|
|
to |
|
|
|
|
|
|
|
w Click |
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
m |
||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
g |
.c |
|
|||
|
|
p |
|
|
|
|
|
|
|
||
|
|
|
df |
|
|
n |
e |
|
|||
|
|
|
|
-xcha |
|
|
|
|
|
Кольца защиты x86
LoadLibraryA или LoadLibraryW. Это должно выглядеть примерно так:
HANDLE hThread =
CreateRemoteThread(hProcessRemote,
NULL, 0, LoadlibraryA,
"C:\\Windows\\SuperDLL.dll", 0, NULL);
Новый поток в удаленном процессе немедленно вызовет LoadlibraryA (или LoadlibraryW, если ты поклонник
юникода), передавая ей адрес полного имени DLL. Возникает вопрос: "Неужели все так просто?" Ан нет! Есть пара проблемок, которые непременно требуют решения.
Первая заключается в том, что нельзя вот так просто передать CreateRemoteThread в четвертом параметре LoadlibraryA или LoadlibraryW. Причина этого кроется в устройстве раздела импорта, который
Конечно, теоретически ОС может загрузить что угодно и куда угодно,
но на практике kernel32.dll находится всегда в одном и том же месте.
Цепочка функций-фильтров в Windows |
САГА ОБ ОТЛАДЧИКАХ
Отладчик может выполнять над отлаживаемым процессом особые операции. Когда отлаживаемый процесс загружен и его адресное пространство создано, но первичный поток еще не выполняется, система автоматически уведомляет об этом отладчик. В этот момент отладчик может внедрить в него нужный код (используя, например, WriteProcessMemory), а затем заставить его первичный поток выполнить внедренный код.
Этот метод требует манипуляций со структурой CONTEXT потока отлаживаемого процесса, а значит, код будет зависим от типа процессора, и его придется модифицировать при переносе на другую процессорную платформу. Кроме того, почти наверняка придется вручную корректировать машинный код, который должен быть выполнен отлаживаемым процессом. Нельзя забывать и о жесткой связи между отладчиком и отлаживаемой программой: как только отладчик закрывается, Windows немедленно закрывает и отлаживаемую программу. Избежать этого невозможно.
7
состоит из шлюзов к импортируемым API. Так что когда код вызывает LoadlibraryA, в разделе импорта исполнительного файла генерируется вызов соответствующего шлюза, а уже оттуда происходит вызов нужной функции. Следовательно, прямая ссылка на LoadlibraryA в вызове CreateRemoteThread преобразуется в обращение к шлюзу в разделе импорта. Это заставит поток выполнять неизвестно что, и это приведет, скорее всего, к нарушению доступа. Чтобы напрямую вызывать LoadLibraryA, минуя шлюз, с помощью GetProcAddress нужно выяснить ее точный адрес в памяти.
Получив адрес LoadLibrary в нашем процессе, его можно запросто использовать в удаленном. Как это становится возможным? kernel32.dll, содержащая функцию загрузки DLL, всегда проецируется на один и тот же диапазон адресов, поэтому в разных процессах точки входа в API-функ- цию будут совпадать. Конечно, теоретически ОС может загрузить что угодно и куда угодно, но на практике kernel32.dll находится всегда в одном и том же месте.
С первой проблемой покончено, возьмемся за вторую. Ее суть заклю- чается в том, что строка с полным именем библиотеки находится в адресном пространстве нашего процесса. Это нехорошо, так как мы передаем этот параметр удаленному потоку в другом процессе, а по этому адресу может быть что угодно. Приложение из-за этого сразу загнется, издав предсмертное сообщение о необрабатываемом исключении.
Все это решается очень просто. Нужно разместить эту злосчастную строку в адресном пространстве удаленного процесса и при вызове CreateRemoteThread передавать именно смещение в чужом процессе. В этом деле поможет такая функция API:
LPVOID VirtualAllocEx(HANDLE hProcess, LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
Единственным примечательным параметром функции является hProcess, который должен содержать хэндл другого процесса. После выделения памяти нужно записать туда строку с полным именем DLL, для чего пригодится WriteProcessMemory:
BOOL WriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten);
Параметр hProcess идентифицирует удаленный процесс, lpBaseAddress и lpBuffer определяют адреса в адресных пространствах удаленного и локального процесса, a nSize - число передаваемых байтов. По адресу, на ко- »
|
|
|
|
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 |
|
S E C U R I T Y - Ô Î Ê Ó Ñ Û |
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
X |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
r |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
P |
|
|
|
|
|
NOW! |
o |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
BUY |
|
|
8 |
|
ÎÑ |
|
|
WINDOWSНАСТРАЖЕПОРЯДКА |
|||||||||||
w Click |
to |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
m |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
w |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
. |
|
|
|
|
|
.c |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
df |
|
|
n |
e |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
S E C U R I T Y - Ô Î Ê Ó Ñ Û |
-xcha |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|||
|
|
|
|
|
|
|
|
|
|
|
|
|||||||||||||
|
|
|
|
|
|
|
|
|
Все эти процессы спокойно уживаются друг с другом |
|
|
|||||||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
торый указывает параметр lpNumberOfBytesWritten, возвращается число фактически считанных или записанных байтов.
Теперь немного (коротко и ясно) обобщим сказанное. Первым делом мы выделяем блок памяти в адресном пространстве удаленного процесса при помощи VirtualAllocEx. Затем копируем в полученный блок строку с полным именем библиотеки функцией WriteProcessMemory, после чего получаем GetProcAdress'ом адрес LoadLibraryA или LoadLibraryW внутри Kernel32. И, в конце концов, вызываем CreateRemoteThread, создавая удаленный поток в требуемом процессе, который вызовет соответствующую LoadLibrary и передаст ей адрес выделенного участка памяти.
На этом этапе DLL внедрена в удаленный процесс, а ее функция DllMain получила уведомление DLL_PROCESS_ATTACH и может приступить к выполнению нужного кода. Когда DllMain вернет управление, удаленный поток выйдет из LoadLibrary и вернется в функцию BaseThreadStart, которая в свою очередь вызовет ExitThread и завершит этот поток.
Теперь в адресном пространстве подопытного процесса болтается никому не нужная библиотека и кусок памяти. Чтобы избавиться от них, нужно проделать все вышесказанное, но с
точностью до наоборот: сначала освободить выделенную память при помощи VirtualFreeEx, затем определить реальный адрес FreeLibrary в kernel32 функцией GetProcAdress, а после этого опять создать удаленный поток, который вызовет FreeLibrary и передаст ей хэндл нашей DLL.
ВНЕДРЕНИЕ ТРОЯНСКОЙ DLL
Последний рассмотренный нами метод состоит в подмене реально используемой в приложении библиотеки на свою. Например, точно известно, что какая-то программа подгружает xxx.dll. Можно написать свою библиотеку и назвать ее тем же именем, что и искомая, предварительно переименовав последнюю. Для корректной работы придется экспортировать те же идентификаторы, что и в исходной xxx.dll, задействовав механизм переадресации функций. Но здесь есть одна заковырка: если подменять, например, библиотеку от Microsoft, то при следующем обновлении они вполне могут изменить эту DLL, добавив туда новые функции или сделав еще чтонибудь. Это значит, что не удастся загрузить приложения, использующие эти новые функции.
Этот метод можно также применить для конкретной программы, присвоив нашей библиотеке уникальное имя и добавив ее в раздел импорта exe-
|
|
|
Распределение памяти в Win9x |
|
Распределение памяти в WinNT |
|
|
|
|
|
|
|
hang |
e |
|
|
|
|
|
|
|
|
C |
|
E |
|
|
|||
|
|
X |
|
|
|
|
|
|||
|
- |
|
|
|
|
|
d |
|
||
|
F |
|
|
|
|
|
|
t |
|
|
|
D |
|
|
|
|
|
|
|
i |
|
|
|
|
|
|
|
|
|
r |
||
P |
|
|
|
|
|
NOW! |
o |
|||
|
|
|
|
|
|
|
||||
|
|
|
|
|
BUY |
|
|
|||
|
|
|
|
to |
|
|
|
|
|
|
|
|
Click |
|
|
|
|
|
|
||
w |
|
|
|
|
|
|
m |
|||
w |
|
|
|
|
|
|
|
|
|
|
|
w |
|
|
|
|
|
|
|
o |
|
|
. |
|
|
|
|
|
|
.c |
|
|
|
|
p |
|
|
|
|
g |
|
|
|
|
|
|
df |
|
|
n |
e |
|
||
|
|
|
|
-x cha |
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
файла. И здесь без глубоких знаний форматов exe- и dll-файлов не выживешь.
ПЕРЕХВАТ API-ФУНКЦИЙ
Теперь немного о перехвате APIфункций. Заниматься этим можно только в своем процессе (в чужом слишком сложно), но, комбинируя техники перехвата и внедрения кода, можно добиться неплохих результатов.
Перехват API-вызовов с использованием раздела импорта
В разделе импорта содержится список DLL, необходимых модулю для нормальной работы. Кроме того, в нем перечислены все идентификаторы, которые модуль импортирует из каждой DLL. Вызывая импортируемую функцию, поток получает ее адрес фактически из раздела импорта.
Метод перехвата с использованием раздела импорта выглядит так: определяется точка входа перехватываемой функции, составляется список модулей, в настоящий момент загруженных в контекст требуемого процесса, а затем - перебираются дескрипторы импорта этих модулей в поиске адресов перехватываемой функции. В случае совпадения этот адрес заменяется на адрес нашего обработчика.
Этот способ хорош тем, что код перехватываемой функции не изменяется, поэтому обеспечивается корректная работа в многопоточном приложении. А недостаток в том, что
ХАКЕРСПЕЦ 09(58) 2005