Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
25
Добавлен:
20.04.2024
Размер:
14.57 Mб
Скачать

 

 

 

 

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

 

 

 

 

 

server# sh /etc/ipsec/rc.vpn client# sh /etc/ipsec/rc.vpn

 

 

 

 

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

 

 

 

 

И при необходимости добавить его запуск в один из стартовых файлов. Например, так:

 

 

 

# vi /etc/rc.local

 

 

 

 

 

 

[ -f /etc/ipsec/rc.vpn ] && sh /etc/ipsec/rc.vpn

 

 

 

[полезные мелочи] Чтобы запросить у ядра

 

 

 

ОС перечень действующих IPSec-туннелей и

 

 

 

активных записей в базе SADB, можно вос-

 

 

 

пользоваться штатной утилитой ipsecctl(8):

 

 

 

# ipsecctl -s all

 

 

 

 

 

 

 

 

 

статистика по рулесетам файрвола

 

 

 

 

 

 

 

FLOWS:

 

 

 

 

 

 

 

 

 

создаем новую сессию, указываем IP-адрес шлю-

# openssl rand 24 | hexdump -e '24/1 "%02x"' >

flow esp in from 192.168.2.2 to 192.168.2.1

за, имя пользователя и расположение публичного

/etc/ipsec/esp-enc-key

peer 192.168.2.2

 

 

 

ключа. Если все корректно настроено, после ус-

# openssl rand 20 | hexdump -e '20/1 "%02x"' >

flow esp out from 192.168.2.1 to 192.168.2.2

пешной авторизации правила файрвола на серве-

/etc/ipsec/esp-auth-key

peer 192.168.2.2

 

 

 

ре изменятся, и юзер получит доступ в Интернет.

# chmod 600 /etc/ipsec/esp-*-key

SADB:

 

 

 

Так как утилиты w и who не предоставляют зна-

 

 

esp from 192.168.2.1 to 192.168.2.2 spi

чение PID, список подключенных в текущий мо-

Далее, чтобы не изобретать себе лишние слож-

0x443382b3 3des-cbc hmac-sha1

 

мент пользователей можно посмотреть с по-

ности, можно воспользоваться шаблоном из

esp from 192.168.2.2 to 192.168.2.1 spi

мощью ps, либо pfctl (здесь authpf — название

каталога /usr/share/ipsec:

0xe6917ee7 3des-cbc hmac-sha1

 

анчора, shocker — имя пользователя, 3884 —

# cp /usr/share/ipsec/rc.vpn /etc/ipsec/rc.vpn

 

 

 

 

уникальный идентификатор процесса):

Получить таблицу маршрутизации для инкапсули-

% ps ax | grep authpf

# vi /etc/ipsec/rc.vpn

рованных соединений можно с помощью netstat(1):

 

 

 

 

3884 p1 Is+ 0:00.01 -authpf: shock-

/* В отладочном режиме команды выводятся

% netstat -nr -f encap

 

 

er@192.168.2.2 (authpf)

Routing tables

 

 

 

 

на экран без исполнения, комментируем */

 

 

 

 

# pfctl -a authpf -sA

#DEBUG=echo

Encap:

 

 

 

authpf/shocker(3884)

/* IP-адреса локального и удаленного компь-

Source Port Destination

Port

Proto

 

SA(Address/Proto/Type/Direction)

 

Посмотреть рулесеты для конкретного пользо-

ютеров */

192.168.2.2/32

0

192.168.2.1/32

вателя можно так:

GW_LOCAL=81.211.1.1

0 0 192.168.2.2/50/use/in

 

 

 

GW_REMOTE=85.140.2.2

192.168.2.1/32

0

192.168.2.2/32

# pfctl -a "authpf/shocker(3884)" -s rules

/* Не указываем CIDR-нотации внутренних

0 0 192.168.2.2/50/require/out

 

pass in quick on ral0 inet from 192.168.2.2 to any

 

 

 

 

pass out log quick on fxp1 inet all keep state

подсетей */

 

Для удаления всех IPSec-потоков:

 

tagged 192.168.2.2

LOCAL_NETWORKS=""

 

 

 

 

 

REMOTE_NETWORKS=""

# ipsecadm flush

 

 

 

И по аналогии для таблицы NAT и правил пере-

/* Выбранные методы шифрования и аутен-

 

 

 

 

направления:

Псевдоустройство

enc(4)

представляет

собой

 

тификации */

 

специальный интерфейс обратной петли, позво-

# pfctl -a "authpf/shocker(3884)" -s nat

ENC=3des

ляющий производить фильтрацию IPSec-трафи-

nat on fxp1 inet from 192.168.2.2 to any tag

AUTH=sha1

ка и просматривать прохождение входящих/исхо-

192.168.2.2 -> (fxp1) round-robin

/* Специальные индексы для создания тунне-

дящих пакетов (относится только к транспортно-

rdr pass on fxp1 inet proto tcp from any to any

му режиму) перед тем, как они попадут во власть

port = 4661 -> 192.168.2.2

ëÿ */

ESP- и AH-протоколов. Конечно же, для выполне-

rdr pass on fxp1 inet proto tcp from any to any

SPI_OUT=1000

ния этой операции необходимо обладать права-

port = 4662 -> 192.168.2.2

SPI_IN=1001

ми суперпользователя (несоответствие контроль-

rdr pass on fxp1 inet proto udp from any to any

/* Указываем абсолютные пути к файлам с

ных сумм не должно тебя здесь смущать, мы же

port = 4665 -> 192.168.2.2

ведем прослушивание на псевдоинтерфейсе):

rdr pass on fxp1 inet proto udp from any to any

ключами */

 

 

 

 

port = 4672 -> 192.168.2.2

KEYFILE=/etc/ipsec/esp-enc-key

# tcpdump -n -e -ttt -vv -i enc0 port 445

 

rdr on ral0 inet proto tcp from 192.168.2.2 to

AUTHKEYFILE=/etc/ipsec/esp-auth-key

tcpdump: WARNING: enc0: no IPv4 address

any port = ftp -> 127.0.0.1 port 8021

 

 

assigned

 

 

 

 

На стороне клиента скрипт будет выглядеть с

tcpdump: listening on enc0, link-type ENC

[ipsecadm: направь криптопотоки

минимальными правками:

Aug 13 18:55:31.373180 (authentic,confiden-

в нужное русло] Как вариант, можно отка-

 

 

tial): SPI 0x0bf80add: 192.168.2.2.1066 >

 

заться от использования isakmpd и посмотреть

# vi /etc/ipsec/rc.vpn

192.168.2.1.445: P

 

 

 

в сторону ipsecadm(8) — программы управле-

 

 

1804009685:1804009748(63) ack 2812031580

ния защищенными соединениями. Чтобы про-

[snip]

win 17520 (DF) (ttl 128, id 33135, len 103)

верить ее работу в действии, рассмотрим сце-

GW_LOCAL=85.140.2.2

Aug 13 18:55:31.373589 (authentic,confiden-

нарий, когда и на сервере (TECHLAB), и на клиен-

GW_REMOTE=81.211.1.1

tial): SPI 0xcd270528: 192.168.2.1.445 >

 

те (HOME) установлена OpenBSD.

[snip]

192.168.2.2.1066: . 1:1425(1424) ack 63 win

 

SPI_OUT=1001

17088 (ttl 64, id 46806, len 1464, bad cksum

[ HOME ]-(fxp1)-------[ ISP ]-------(fxp0)-

SPI_IN=1000

14! differs by 3902)

 

 

[ TECHLAB ]

[snip]

 

 

 

 

 

 

 

Приведенная схема работы в сочетании с кор-

Последовательно создаем два ключа — один

После того, как с помощью программы безопас-

ректно настроенным dhcp-сервером и полуп-

для шифрования трафика (3DES, 192 bit), дру-

ного копирования scp(8) ключи (/etc/ipsec/esp-

розрачным мостом, выполняющим фильтра-

гой для аутентификации (SHA1, 160 bit):

{auth,enc}-key) будут переданы клиенту, останет-

цию на основе MAC-адреса клиента (см.

# mkdir -m 700 /etc/ipsec

ся только запустить rc.vpn на каждом из хостов:

статью «Файрвол-невидимка»), сослужит тебе

 

 

хорошую службу. Удачи

 

 

 

 

 

 

UNIXOID 109]

[XÀÊÅÐ 10 [82] 05 >

 

 

 

 

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

 

 

 

 

FERRUM

PC_ZONE

ИМПЛАНТ

ВЗЛОМ

СЦЕНА

UNIXOID

КОДИНГ

КРЕАТИФФ

ЮНИТЫ

 

 

 

 

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

 

 

 

 

STILLHAND

110

Грабим формы!

ЧТО ТАКОЕ ФОРМГРАББЕР? ЭТО ПРОГРАММА, КОТОРАЯ ПЕРЕХВАТЫВАЕТ И СОХРАНЯЕТ ДАННЫЕ, ВВОДИМЫЕ В ФОРМАХ В БРАУЗЕРЕ. ИСПОЛЬЗУЮТСЯ ТАКИЕ ПРОГРАММЫ В ОСНОВНОМ ДЛЯ ПЕРЕХВАТА ПАРОЛЕЙ/НОМЕРОВ КРЕДИТНЫХ КАРТ (ИЛИ ЛЮБЫХ ДРУГИХ ДАННЫХ), ВВОДИМЫХ НА САЙТАХ. КОНЕЧНО, ДЛЯ ЭТОЙ ЦЕЛИ МОЖНО ИСПОЛЬЗОВАТЬ КЕЙЛОГЕР, НО РАЗБИРАТЬ ЕГО КИЛОМЕТРОВЫЕ ЛОГИ НЕУДОБНО, ПОЭТОМУ НУЖНА УЗКОСПЕЦИАЛИЗИРОВАННАЯ СИСТЕМА ДЛЯ ПЕРЕХВАТА ИСКЛЮЧИТЕЛЬНО ФОРМ. КАК ТАКУЮ ШТУКУ НАПИСАТЬ ТЫ МОЖЕШЬ УЗНАТЬ

В ЭТОЙ СТАТЬЕ | Ms-Rem (Ms-Rem@yandex.ru)

Пишем простой формграббер

Что такое вводимая в браузере форма? В каком виде она отправляется по сети? Какие функции при этом вызываются? Прежде чем писать формграббер, мы должны ответить на все эти вопросы.

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

GET /index.htm HTTP/1.1

Host: www.nifiga.net

Connection: close

В данном случае методом запроса является GET, после которого идет краткий URL запроса и протокол (HTTP 1.1). URL может быть представлен как в кратком (/index.htm), так и в полном (www.nifiga.net/index.htm) виде. Все, что ниже, является заголовками запроса. Например, заголовок Host содержит адрес сервера, к которому будет направлен запрос. Имя и параметры заголовка запроса всегда разделены двоеточием. Заголовок запроса отделен от тела запроса двумя переводами строки (0D0A).

Рассмотрим теперь передачу по сети данных, введенных в форму. В этом случае запрос будет подобен этому:

POST http://192.168.0.58/dragon/?.goods.save_goods HTTP/1.1 Referer: http://192.168.0.58/dragon/?.goods.form_edit_goods&category_id=121

Content-Type: multipart/form-data; boundary=---------------------------

7d534bae9d6 Connection: Close Host: 192.168.0.58 Content-Length: 1024

Cookie: dragon_cookie_index=yes; dragon_cookie_goods=yes Authorization: Basic Z29sZDp4YXZhRkQz

-----------------------------7d534bae09d6 Content-Disposition: form-data; name="goods[goodsId]"' Data

-----------------------------7d534bae09d6 Content-Disposition: form-data; name="goods[goodsName]"' Name

Content-Disposition: form-data; name="goods[goodsDescription]"' Description

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

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

F

 

 

 

 

 

 

 

t

 

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

r

 

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

to

 

 

 

очень важная информация, и в формграббере ее нужно обязательно сохра-

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

w

 

 

 

 

 

 

 

íÿòü.o

Присутствует также поле Content-Type, которое определяет тип содер-

 

w

 

 

 

 

 

 

 

 

.

 

 

 

 

 

 

.c

 

 

 

 

p

 

 

 

 

g

 

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

жимого запроса. Тип form-data означает, что передаются данные формы, а boundary — строка разделитель полей формы. Поле Cookie содержит посылаемые браузером куки. В них могут храниться авторизационные данные, поэтому содержимое этого поля нас может интересовать. Поле Authorization содержит строку http-авторизации, эти данные также могут представлять для нас интерес. На этом заголовок запроса заканчивается, идет два перевода строки, и начинается тело запроса. Элементы тела запроса разделены между собой строкой, которая передавалась в boundary заголовка запроса.

Каждый элемент имеет строку, идентифицирующую его назначение (Content-Disposition) и одну или несколько строк с данными. Так выглядит запрос, отправленный методом POST. Но содержимое форм может еще передаваться методом GET, при этом параметры передаются прямо в URL запроса. Подобный URL может выглядеть так: http://www.yandex.ru/yandsearch? rpt=rad&text=FormData. Я думаю, ты и сам сможешь понять, что этот запрос значит.

Рассмотрим теперь, что происходит при посылке запроса весьма популярным браузером Internel Explorer. Сначала данные вводятся в поля ввода браузера, при нажатии кнопки Submit происходит отправка этих данных в COMобъект Internet Explorer’а, который является движком браузера. Дальше в COM-объекте происходит формирование запроса и передача его в функциям HttpOpenRequest и HttpSendRequest (WinInet API). Эти функции собирают запрос окончательно и отправляют его через сокеты (send и recv в ws2_32.dll). Далее данные, направленные на сокеты, отправляются в ядро системы, где после обработки в стеке протоколов TCP/IP они отсылаются че- рез сеть. С другими браузерами дело может обстоять несколько иначе, например, они могут не пользоваться функциями WinInet API, а формировать запрос вручную. В любом случае, они отправляют данные через сокеты.

Вернемся теперь к нашим баранам (точнее, к формграбберам). Для перехвата данных формы нам нужно вклиниться в описанный выше процесс на любой его стадии. Например, можно получить хэндл окна Internet Explorer, перечислить все дочерние окна, отобрать среди них те, которые нам нужны, и с помощью GetWindowText снять с каждого из них введенный текст. Этот метод применяется в некоторых троянах.

Можно вклиниться и на уровне COM-объекта, через его интерфейсы можно не только снифать посылаемые данные, но даже посылать свои. Этот метод используется в трояне Pinch для обхода файрволов. Недостаток тут только в громоздкости и неудобстве программирования COM-объектов.

Более перспективным мне кажется метод перехвата функций HttpOpenRequest и HttpSendRequest, так как он позволяет легко получать данные форф. Причем не просто получать, но и сразу же отправлять их, куда надо в обход файрволов. Функция HttpOpenRequest осуществляет открытие соединения, а HttpSendRequest — отсылку самого запроса. Рассмотрим их прототипы:

HINTERNET HttpOpenRequest( HINTERNET hConnect, LPCTSTR lpszVerb, LPCTSTR lpszObjectName, LPCTSTR lpszVersion, LPCTSTR lpszReferer, LPCTSTR* lpszAcceptTypes, DWORD dwFlags, DWORD_PTR dwContext

);

hConnect — хэндл открытого соединения.

lpszVerb — строка метода запроса (GET, POST, HEAD etc). lpszObjectName — URL, к которому направляется запрос. В нем могут передаваться данные формы. Я думаю, ты уже разобрался с форматом этих данных из предыдущего описания.

lpszVersion — версия используемого протокола (HTTP/1.0 или HTTP/1.1). lpszReferer — содержимое заголовка Referer (адрес страницы с которой был послан запрос).

lpszAcceptTypes — типы принимаемых браузером данных.

dwFlags — комбинация управляющих флагов. Подробнее о них ты можешь почитать в MSDN.

dwContext — дополнительные данные, которые приложение может передать с запросом.

BOOL HttpSendRequest( HINTERNET hRequest, LPCTSTR lpszHeaders, DWORD dwHeadersLength, LPVOID lpOptional, DWORD dwOptionalLength

);

 

 

 

 

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

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

t

 

P

D

 

 

 

 

 

 

 

 

o

 

 

 

 

NOW!

r

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

m

w Click

 

 

 

 

 

 

o

 

w

 

 

 

 

 

 

 

 

 

по прошествии определенного времени результат работы

 

 

 

 

 

 

.c

 

 

.

 

 

 

 

 

 

 

 

 

p

df

 

 

 

 

e

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

-x cha

 

 

 

 

 

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

КОДИНГ 112]

[XÀÊÅÐ 10 [82] 05 >

формграббером очень часто воруют e-gold аккаунты

hRequest — хэндл запроса, полученный функцией HttpOpenRequest. lpszHeaders — указатель на заголовки запроса. Формат заголовков HTTPпротокола мы рассмотрели выше.

dwHeadersLength — размер заголовков.

lpOptional — указатель на тело запроса. В нашем случае он будет содержать данные формы. С форматом этих данных мы уже тоже разобрались. dwOptionalLength — размер данных тела запроса.

[перехватываем WinInet API] Теперь нам нужно научиться перехватывать функции HttpOpenRequest и HttpSendRequest и сохранять в лог проходящие через них данные.

Для этого нам нужно сначала загрузить свою DLL во все процессы системы. Это можно сделать, например, прописав DLL в разделе реестра HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ Windows в ключ AppInit_DLLs (или с помощью хуков или создания удаленных потоков – прим. ред). Такая библиотека будет подгружена во все процессы, имеющие в своем адресном пространстве user32.dll (а это все GUI приложения). Для перехвата будем использовать метод сплайсинга. Заключается он в перезаписи начала кода перехватываемой функции 5 байтным jmp на свою функцию с предварительным копированием затертых байт в выделенный буфер и установкой после них jmp на продолжение функции. Главная проблема тут состоит в том, что нам нужно скопировать целое количество инструкций, а они могут иметь разный размер, следовательно, нам понадобится дизассемблер длин. Все вышеописанное уже реализовано в моей библиотеке advApiHook, поэтому можно просто подключить ее и не париться.

Сам же код DLL будет выглядеть приблизительно так:

library FormGrab;

uses

windows,

advApiHook;

var

TrueHttpSendRequest: function (hRequest: dword; lpszHeaders: PChar;

dwHeadersLength: dword; lpOptional: pointer; dwOptionalLength: dword): boolean; stdcall;

function NewHttpSendRequest(hRequest: dword; lpszHeaders: PChar; dwHeadersLength: dword; lpOptional: pointer; dwOptionalLength: dword): boolean; stdcall;

begin

MessageBoxA(0, lpszHeaders, lpOptional, 0);

Result := TrueHttpSendRequest(hRequest, lpszHeaders, dwHeadersLength, lpOptional, dwOptionalLength);

end;

begin

HookProc('wininet.dll', 'HttpSendRequestA', @NewHttpSendRequest, @TrueHttpSendRequest);

end.

[фильтрация полученных данных] При большом коли- честве машин, на которых установлен формграббер возникают сложности в отсеивании необходимых нам данных. Обыч- но хакера ведь интересуют данные, введенные только в определенных формах и на конкретных сайтах, поэтому требуется сохранять не все полученные данные, а только те, которые реально пригодятся. Для этого можно проанализировать URL и Referer запроса и отсеять только нужные формы. Неплохо будет анализировать не только запрос, но и ответ сервера. Например, при вводе какого-либо пароля нам нужно получить только правильные пароли, а случайные ошибки ввода следует фильтровать. Для этого можно анализировать код ответа

сервера, либо содержимое возвращаемой HTML-страницы по определенным ключевым словам. Таким образом работает большинство формграбберов.

Недостаток вышеприведенного способа один — он работает только с Internet Explorer’ом и другими браузерами, построенными на его движке (например, Avant Browser). Для преодоления этого недостатка можно перехватывать не WinInet API, а send из ws2_32.dll, после чего нам нужно будет собирать посылаемый запрос в буфере и сохранять его в момент окончания отправки данных. Этот момент можно определить по вызову closesocket для интересующего нас сокета, либо можно извлечь ContentLength из передаваемых заголовков и определить по нему момент окончания передачи тела запроса. Естественно, первый метод значительно проще в реализации, да и особых недостатков у него не имеется. Нам просто нужно вести список сокетов, и для каждого сокета строить список принятых пакетов. При закрытии сокета собранные данные обрабатываются. Для всего этого нам нужно перехватывать всего три API-функции: connect, send и cosesocket. Этот метод будет работать со всеми браузерами без исключения, но он сложен в реализации и имеет один неприятный недостаток — невозможность перехвата шифрованных форм. Большинство банковских служб, интернет-магазинов и других требующих безопасности ресурсов работают не по открытому HTTP-протоколу, а через SSL/TSL-соединение, и все данные передаются по сети в шифрованном виде. Естественно, в таком же виде они и посылаются на сокеты. Поэтому нам нужно сохранять только данные, отправляемые по нешифрованному HTTP-протоколу. Отличить простой HTTP от SSL легко: первый имеет стандартный порт сервера 80, а второй — 443. Конечно, эти сервисы могут быть и на нестандартных портах, но это случается весьма редко, поэтому нам нужно перехватывать трафик, идущий только на 80 порт, это легко определить по параметрам вызова connect.

[законность] Ты, наверно, не раз задумывался о том, что будет в случае поимки автора формграббера. Будет ли это дело квалифицировано по статье 273 УК РФ «Создание и распостранение вредоносных программ для ЭВМ» зависит от того, какова функциональность твоего формграббера, и от того, нанес ли он кому-нибудь реальный ущерб. Простой формграббер, сохраняющий на диск все отправляемые через браузер данные, под категорию вредоносных программ вряд ли попадает, так как подобные вещи используют даже в сетях крупных организаций для наблюдения над своими сотрудниками. А вот формграббер, определяющий банковские системы и отправляющий данные на мыло в обход файрволов, под категорию вредоносных программ, несомненно, попадает. Конечно, если никто от хакерского творения не пострадал, то никто никого искать не будет, а формграббер просто добавят в базы антивирусов, но если денег лишился влиятельный человек или солидная организация, то могут развернуться весьма масштабные поиски. В таком случае, если автора поймают, то, скорее всего, дадут не 273, а 159 статью (мошенничество), и наказание за это будет более строгим, чем за написание вредоносных программ. В общем, не рекомендую тебе заниматься ÷åì-ëèáî, что может êàê-òî плохо отразиться на твоей будущей светлой жизни

Эта библиотека, будучи прописанной в реестре, будет выводить

 

сообщение с содержимым посылаемого запроса. Реальный же

 

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

 

Причем целесообразнее будет не просто сохранять запрос в не-

 

изменном виде, а разбирать его структуру и вытаскивать из нее

прописываем DLL в реестре

нужные данные. При достижении какого-либо размера лога, или

 

 

 

 

 

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

 

 

 

 

www.streetracingmag.ru

Чтобы реализовать ввод данных с клавиатуры, в нашем приложении придется уже поизвращаться: открыть NtCreateFile’ом драйвер клавиатуры (\\Device\\KeyboardClass), привязать к нему NtCreateEvent’ом событие и т.д. и т.п. — механизм всего этого дела тебе придется изучать самому, уродуя дизассемблер autochk.exe.
На английском языке о разработке native-прило- жений ты можешь про- честь на www.sysinternals.com
в статье Inside Native Applications, датированной аж 98ым годом.

 

 

 

 

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

 

 

 

 

FERRUM

PC_ZONE

ИМПЛАНТ

ВЗЛОМ

СЦЕНА

UNIXOID

КОДИНГ

КРЕАТИФФ

ЮНИТЫ

 

 

 

 

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

 

 

 

 

114

Родные

приложения

НАВЕРНОЕ, НЕ РАЗ ТЕБЕ ПРИХОДИЛОСЬ АВАРИЙНО ЗАВЕРШАТЬ РАБОТУ ТВОЕЙ ВИНДЫ. ПРИ СЛЕДУЮЩЕМ ЗАПУСКЕ ЕЩЕ ДО СТАРТА ОБОЛОЧКИ ТЕБЕ ПРЕДЛАГАЛОСЬ ПРОВЕРИТЬ ТВОЙ ВИДАВШИЙ ВИДЫ ЖЕСТКИЙ ДИСК НА ПРЕДМЕТ ЦАРАПИН, BAD-СЕКТОРОВ, ПОТЕРЯННЫХ КЛАСТЕРОВ И ПРОЧИХ ПОВРЕЖДЕНИЙ С ПОМОЩЬЮ СКАНДИСКА. БЕЛЫМ ШРИФТОМ НА СВЕТЛО-ГОЛУБОМ ФОНЕ ОН ПЕРЕЧИСЛЯЛ ВСЕ ВОЗМОЖНЫЕ НЕПОЛАДКИ, ПОСЛЕ ЧЕГО ВЫПЛЕВЫВАЛ: «ГУЛЯЙ, МОЛОДОЙ, ЖИТЬ БУДЕШЬ», И ПРОДОЛЖАЛ НОРМАЛЬНУЮ ЗАГРУЗКУ WINDOWS. БЫЛО ВЕДЬ ТАКОЕ? А НЕ ЗАДАВАЛСЯ ЛИ ТЫ ВОПРОСОМ, КАК РАБОТАЕТ ЭТОТ САМЫЙ СКАНДИСК? ЧТО ЭТО ЗА ПРОГРАММА ТАКАЯ, КОТОРАЯ МОЖЕТ СУЩЕСТВОВАТЬ ЕЩЕ ДО СТАРТА ВИНДЫ С ЕЕ ЗАМЕЧАТЕЛЬНЫМ GUI-ВЫМ ИНТЕРФЕЙСОМ, А? ПОВЕРЬ МНЕ, ЭТА ТЕМА СТОИТ ТОГО, ЧТОБЫ С НЕЙ КАК СЛЕДУЕТ РАЗОБРАТЬСЯ | Николай

«gorl» Андреев (gorlum@real.xakep.ru)

Вникаем в Дзен виндовых

Native-приложений

Нет, ты только не подумай, что мы сейчас будем копаться с тем, как скандиск находит. Это нам сегодня абсолютно не в кассу. Мы будем

изучать особый тип приложений, вызываемых еще до старта Win32подсистемы, так называемых Native-приложений.

Как ты, наверное, знаешь, отли- чительная особенность Windows 2000 и более старших ее версий в том, что в ней реализовано несколько подсистем, обеспечивающих работу приложений Win32 (то есть обычных виндовых, использующих так всеми любимые kernel32.dll, user32.dll и еще сотню другую динамически зависающих библиотек), POSIX и OS/2. А отли- чительная особенность Native-при- ложений, о которых, собственно, и идет сегодня речь, в том, что они не относятся ни к одной из вышеперечисленных подсистем. Они сами по себе. Ключ к пониманию этого факта в самом названии. Что может напоминать слово Native? Конечно же, API: где

Native, там и API. Родной системный интерфейс винды, на котором строятся все прочие интерфейсы для работы тех или иных приложений. Так вот, не относящиеся к тем или иным, Native-приложения — это программы, использующие исключительно Native API, то есть полностью абстрагирующиеся от неприятных наворотов небольшой кучки виндовых подсистем, обеспечивающих почти никому ненужную сов-

[что нужно для...] Раз ты дочитал до этого места, вопрос «зачем?» у тебя уже не стоит. Следующий вопрос, наверное, — «как?». Что ж, как обыч- но — очень просто. В старой доброй студии напишем проект, скомпилируем, проапдейтим запись в реестре и все — геморроя не очень много.
Первое с чем надо разобраться, так это с тем, как написать при относительно обычных условиях приложение, использующее только Native API. То есть, что для этого требуется. Оказывается, не очень много:
– Visual Studio .NET, в которой компилируются все представ-
ленные мной ранее мучаем код проекты на Си. Я не
прописываем пути к DDK в настройках студии
Для удобной модификации PE-файлов советую воспользоваться тебе связкой из следующих функций: NtCreateFile, NtCreateSection и ZwMapViewOfSection. С их помощью ты отобразишь нужный тебе файл себе в адресное пространство и скорректируешь его так, словно это твой собственный код, а не какой-ни- будь системный ;).
Чтобы твоя студия умела находить h- и lib-файлы, входящие комплект DDK, ты должен прописать в ее настройках дополнительные пути для поиска. Для этого лезь в студии в меню Tools -> Option, в закладке Projects выбирай VC++ Directories и добавляй пути к папкам DDK в Include files и Library files.

 

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

 

 

 

 

 

F

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

t

 

 

 

 

 

 

 

 

P

D

 

 

 

 

 

 

 

 

o

 

 

 

 

 

 

 

 

 

 

 

NOW!

r

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

 

o

m

 

местимость. Причем

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

 

.c

 

 

 

 

 

 

 

 

 

 

p

df

 

 

 

 

e

 

 

 

 

 

 

 

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

-xcha

 

 

 

 

 

 

только Native API оз-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

начает, что в таблице

 

 

 

 

 

 

 

 

 

 

 

 

 

 

импорта

экзешника

 

 

 

 

 

 

 

 

 

 

 

 

 

 

уже привычного нам

 

 

 

 

 

 

 

 

 

 

 

 

 

 

PE-формата мы не

 

 

 

 

 

 

 

 

 

 

 

 

 

 

сможем встретить ни-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

÷åãî,

кроме

ntdll.dll,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

библиотеки,

экспор-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

тирующей

äëÿ

ïîëü-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

зовательских

прило-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

жений

родной

äëÿ

 

 

 

 

 

 

 

 

 

 

 

очищенные от накипи настройки проекта

 

 

 

 

 

 

 

 

 

 

 

 

 

nt`евых форточек на-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Win32-приложения

бор функций. Запус-

 

каются такие программы исключительно системой, менеджером сессий smss.exe, у пользователя выполнить их не получится.

«Круто, — скажешь ты, — но зачем мне вся эта родная майкрософтовская ересь?» О, вот здесь в моем рассказе и начнется самое интересное. Характерной особенностью Native-приложений, как я уже замечал, является то, что они могут выполняться еще до запуска и инициализации Win32-подсистемы. То есть до того, как в память будут загружены explorer.exe, winlogon.exe и еще чертов миллион библиотек, ими используемых. Собственно, как раз за счет этого скандиск и может беспрепятственно шарить по диску, править сектора и т.п. — ничего еще не загружено, ко всему есть доступ, можно даже диск форматировать!

Так, допустим, форматирование нам сейчас и не нужно, но вот возможность модифицировать некоторые файлики может оказаться очень кстати. Взять, подправить чуток sfc.dll, капельку explorer.exe, совсем немного kernel32.dll, и живи себе — радуйся, с новыми экстравагантными способами обхода файрвола, невидимости и автозапуска. Ой, опять я об «этом» заговорил. Успокою любителей мирного программирования: большинство задач, требующих прямого и беспрепятственного доступа к диску решаются именно с помощью разработки Native-приложений. Вот, незаменимый Partition Magic, например, когда ему требуется хардкорно перелопатить весь диск, после рестарта уползает как раз на приятный дозагрузочный светлоголубой фон, где и осуществляет свое не самое темное дело.

В конце концов, Native-приложения нужны хотя бы для того, чтобы у приятелей твоих челюсть отпала от вида Hello World! еще до загрузки Windows. Это ведь не какой-нибудь банальный MessageBox, это preload-программа.

буду изменять своей привычке.

Windows DDK, набор для создания драйверов. Он нам нужен не как среда для разработки, а как источник драгоценных определений структур ядра и типов данных, активно используемых Native API, уже не говоря о том, что библиотеку ntdll.lib в других местах задолбаешься искать.

Заголовочный файл nt.h, взятый мной откуда-то из Сети. Ранее он имел немного другое название, но я его подредактировал, подправил для использования в Native-прило- жениях и поэтому переименовал. В нем содержатся описания функций, экспортируемых ntdll.dll. Как это ни печально, в ntddk.h описана лишь малая часть необходимых для работы native-функций, поэтому приходится использовать отнюдь не родные заголовки.

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

 

 

 

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

Native-приложения для

 

 

 

-x cha

 

 

 

 

 

 

 

 

анализа, а autochk не хватает, покопай CSRSS.EXE.

[структура приложения] Ìàðê

 

Руссинович (www.sysinternals.com)

 

советует писать нативные прог-

 

раммы, пользуясь исключительно

 

DDK. Для тех, кто всю жизнь раз-

 

рабатывает драйвера, — это, ко-

Для работы с реестром в

нечно, идеальный вариант, но мне,

Native-приложении тебе

честно говоря, привычнее визуаль-

предстоит разобраться с

ная студия (причем не самая но-

функциями NtCreateKey,

вая). Я создал в ней самый обыч-

NtOpenKey,

ный Win32-проект и просто чуть-

NtQueryValueKey è

чуть подкорректировал: убрал все,

NtSetValueKey.

что можно было убрать из настро-

 

ек, оставил все либо «по умолчанию», либо «взять из исходника», а в са-

мом сорце я написал следующее:

 

#pragma comment(linker, "/SUBSYSTEM:NATIVE") #pragma comment(linker,"/BASE:0x00010000") #pragma comment(lib, "ntdll.lib")

Вместо обычной подсистемы WINDOWS я указал NATIVE, чтобы

 

компилятор понял, с чем имеет дело, немного сдвинул вниз вирту-

 

альный адрес, по которому будет доступен образ приложения в па-

 

мяти, и подключил библиотеку для работы с ntdll.dll. Все это можно

 

было сделать, и путешествуя по Properties Pages проекта.

 

Это все, что касалось настроек, а теперь плавно погружаемся в кодинг.

]

#define _X86_

115

#include <ntddk.h>

КОДИНГ

#include "nt.h"

 

Вот таким незамысловатым образом начинается сам код программы (не

 

считая прагм): два хедера — один из DDK (не забудь, кстати, прописать

 

пути к основным папкам DDK, содержащим хедеры и либы) с описани-

 

ем основных структур и типов, другой — с описаниями функций, экспор-

 

тируемых ntdll.dll. Определение идентификатора _X86_ нужно для того,

 

чтобы компилятор знал, какой вариант структур в ntddk выбирать, а то

 

они могут различаться в зависимости от платформы.

 

Как программирование, так и выполнения любого более или менее

 

обычного приложения начинается с функции main (WinMain,

 

_tWinMain, в общем, название может быть любым, а смысл остается

 

— точка входа), наш случай не исключение. У родных форточкам

 

программ тоже есть main-функция, однако ее описание несколько от-

>

личается. Во-первых, у нее не два параметра, как у консольных при-

05

ложений, и не 4, как у обычных Win32, а один — указатель на какую-

[82]

 

то структуру. И я так бы и забил на его предназначение — ну, PVOID,

10

ну, и черт с ним — если бы не исследования мастера Руссиновича.

[XÀÊÅÐ

Этот указатель он окрестил как PSTARTUP_ARGUMENT и ввел нес-

колько интересных определений:

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

X

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

F

 

 

 

 

 

 

 

t

 

 

D

 

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

r

P

 

 

 

 

 

NOW!

o

 

 

 

 

 

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

to

 

 

 

 

 

 

w Click

 

 

 

 

 

 

 

 

 

 

 

 

 

 

m

 

w

 

 

 

 

 

 

 

//oструктура, указатель на которую передается точке входа

w

 

 

 

 

 

 

 

 

 

 

 

.

 

 

 

 

 

 

.c

 

 

 

p

 

 

 

 

g

 

 

 

 

 

df

 

 

n

e

 

 

 

 

 

-xcha

 

 

 

 

 

typedef struct { ULONG Unknown[3];

PENVIRONMENT_INFORMATION Environment;

} STARTUP_ARGUMENT, *PSTARTUP_ARGUMENT;

//структура, на которую ссылается STARTUP_ARGUMENT

//из интересного содержит командную строку, с которой

//было запущено приложение и имя файла

typedef struct {

ULONG Unknown[21]; UNICODE_STRING CommandLine; UNICODE_STRING ImageFile;

} ENVIRONMENT_INFORMATION, *PENVIRONMENT_INFORMATION;

 

 

 

 

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

дизассемблируем autochk.exe, чтобы узнать что-нибудь новенькое

КОДИНГ 116]

Во-вторых, main-функция — войдовая, то есть она ничего не возвращает. Я уверен, что ты в курсе, что обычно для завершения работы приложения в main’е используется что-нибудь вроде return 0, но если ты думаешь, что в нашей функции достаточно будет написать просто return, то ты ошибаешься. По ret’у мы ускачем неизвестно куда, так как в стеке может быть любая белиберда. Здесь подход иной:

NtTerminateProcess(NtCurrentProcess(), 0);

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

void native_main(PSTARTUP_ARGUMENT arg)

{

NtTerminateProcess(NtCurrentProcess(), 0);

}

Странное имя для main-функции, не правда ли? Компилятор тоже так подумает, поэтому надо его предупредить добавлением еще одной прагмы.

#pragma comment(linker, "/ENTRY:native_main")

Хорошая функция получается ;), правда, абсолютно бесполезная. Это поправимо.

[hello world!] Давай для начала научим программу выводить что-ни- будь на прелестный светло-голубой экран, предвещающий скорое появления окошка для ввода пароля. Прежде всего надо усвоить, что строка для низкоуровневой части Windows — это unicode-строка (а по этому поводу в срочном порядке лезь в настройки своего проекта, где в закладке General меняй Character Set на Use Unicode Character Set, чтобы все строки по умолчанию создавались в юникоде). Причем не просто массив слов (слова — это такие штуки, в которые 2 байта влезают), а специальная структура данных, содержащая указатель на массив и его текущую и максимальную длины:

typedef struct _UNICODE_STRING { USHORT Length;

USHORT MaximumLength; PWSTR Buffer;

} UNICODE_STRING;

Этот тип данных тебе запомнится надолго, так как в другом виде строки здесь не перевариваются. Для удобной работы с подобными строками ntdll экспортирует целый ряд функций, из которых следует отметить: + VOID RtlInitUnicodeString(IN OUT PUNICODE_STRING, IN PWSTR) — функция, инициализирующая структуру UNICODE_STRING обычной unicode-строкой.

– VOID RtlInitAnsiString(IN OUT PANSI_STRING, IN PCSZ) — нужна для того чтобы инициализировать упомянутую выше ANSI_STRING с помощью самой обычной строки.

//если не настроить проект на использование Unicode Character Set,

//то придется делать так

UNICODE_STRING unicodeString;

ANSI_STRING ansiString;

RtlInitAnsiString(&ansiString, L“\nOh, damnet, not again!!!”); RtlAnsiStringToUnicodeString(&unicodeString, &ansiString, TRUE);

//TRUE в третьем параметре определяет, выделять ли память

//ïîä Unicode-строку, если мы ее выделили, то впоследствии

//придется ее освободить с помощью RtlFreeUnicodeString

Этих трех функций хватит на все про все. Можно, конечно, покопать DDK в поисках еще нескольких, но они вряд ли тебе пригодятся.

Ну, а чтобы вывести на экран полученную в нужном формате строчку, нужна одна очень простая функция, всего с одним параметром. Угадай, с каким?

// выводим многострадальную строку на голубой экран

NtDisplayString(&unicodeString);

[работа с файлами] Вывод на экран — это просто замечательно! Можно удивить друзей ascii-графикой перед загрузкой, а, разобравшись с вводом с клавиатуры, можно и какую-нибудь простенькую диалоговую программку написать. Но всего это для нормального программирования мало. Для использования в целях разработки RAT тут нужно хотя бы с файлами работать, с реестром, уметь драйвера загружать. Это все не сложно, но требует определенного погружения в тему. К примеру, некоторым очень непривычно использование вместо обычного имени файла для функции NtCreateFile структуры OBJECT_ATTRIBUTES.

typedef struct _OBJECT_ATTRIBUTES { ULONG Length;

HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes;

PVOID SecurityDescriptor; PVOID SecurityQualityOfService;

} OBJECT_ATTRIBUTES;

Люди ее зачем-то вручную заполняют, над каждым полем думают, му- чаются. А есть удобный макрос. Чтобы открыть файл в user mode, атрибуты объекта я определяю вот так:

[XÀÊÅÐ 10 [82] 05 >

// запихиваю в string нужную мне строку

UNICODE_STRING string;

RtlInitUnicodeString(&string, L”\nHello... hm... World?”);

– NTSTATUS RtlAnsiStringToUnicodeString(IN OUT PUNICODE_STRING, IN PANSI_STRING, IN BOOLEAN) — функция, преобразующая ANSI_STRING в UNICODE_STRING. Бывает очень полезна, если по какой-нибудь никому неведомой причине у тебя появилась ansi-строка, да еще и в структуре ANSI_STRING (которая, к слову, отличается от похожей по названию uni- code-структуры только указателем — в одной PWSTR, в другой — PCHAR).

InitializeObjectAttributes(&oa, &filename, NULL, NULL, NULL);

filename здесь — это UNICODE_STRING с именем файла, причем записанным в специальном формате, перед полным путем нужно поставить \\??\\. explorer.exe в такой записи выглядит как \\??\\C:\\Windows\\explorer.exe. Ну, а само открытие соответственно:

status = NtCreateFile (&hFile, GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE | FILE_APPEND_DATA, &oa, &io, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE|FILE_SHARE_READ, FILE_OVERWRITE_IF, _SYNCHRONOUS_IO_NONALERT, NULL, 0);

 

 

 

 

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

С ДЕРЕВЯННОЙ ЛОШАДКОЙ

 

 

 

 

 

 

 

 

 

 

to

BUY

 

 

 

 

 

 

 

 

 

 

to

BUY

 

 

 

 

 

 

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

 

 

 

 

 

 

 

 

 

 

СТАЛОСКУЧНО?

 

 

 

 

 

 

 

 

 

 

 

 

Играй

просто!

GamePost

PlayStation 2 (Slim) RUS GameCube

Xbox

$175.99

$139.99

$269.99

PSP (EURO)

Game Boy Advance

Nintendo DS

value pack

SP Cobalt

Dualscreen

 

 

 

$269.99

$99.99

$179.99

ÍÅ ÏÎÐÀ ËÈ

СМЕНИТЬ ИГРУ?

* Огромный

* Èãðû äëÿ âñåõ

* Коллекционные

выбор компью-

телевизионных

фигурки из

терный игр

приставок

èãð

*

WarCraft III

Action Figure:

$42.99 Ticondrius

 

 

 

 

hang

e

 

 

 

 

 

 

 

 

 

 

C

 

E

 

 

 

 

 

 

 

X

 

 

 

 

 

 

 

 

 

-

 

 

 

 

 

d

 

 

 

 

F

 

 

 

 

 

 

 

i

 

 

 

 

 

 

 

 

 

 

 

t

 

 

 

P

D

 

 

 

 

 

 

 

 

o

 

 

 

 

 

 

NOW!

r

 

 

 

 

 

 

 

BUY

 

 

 

 

 

 

 

 

to

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

w

 

 

 

 

 

 

 

 

 

 

 

 

w Click

 

 

 

 

 

 

 

m

от Win32 API, как видишь,

 

 

w

 

 

 

 

 

 

 

Отличияo

 

 

.

 

 

 

 

 

 

.c

 

 

 

 

 

p

df

 

 

 

 

e

 

 

 

 

 

 

 

 

g

 

 

 

 

 

 

 

 

 

 

n

 

 

 

 

 

 

 

 

 

 

-xcha

 

 

минимальны, появляются, конечно,

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

некоторые новые структуры и опреде-

 

 

 

 

 

 

 

 

 

 

ления, но с ними очень легко разоб-

 

 

 

 

 

 

 

 

 

 

раться. Поэтому бери книги Неббета,

 

 

 

 

 

 

 

 

 

 

Солдатова, а если хочешь научиться

 

 

 

 

 

 

 

 

 

 

и драйвера из своего Native-приложе-

 

 

 

 

 

 

 

 

 

 

ния грузить, то и Хогланда (www.rootk-

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

it.com), и разбирайся. Если вдруг ка-

статья гуру о native-приложениях

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

кие-нибудь вопросы возникнут в процессе изучения — пиши, помогу кодом

 

 

 

 

 

 

 

 

 

или советом по мере возможности. На этом я заканчиваю свое повествова-

 

 

 

 

 

 

 

 

 

ние, надеюсь, что оно не побудит тебя к чему-нибудь противозаконному

ОРИГИНАЛЬНЫЙ HELLOWORLD

Немного измененный мной код Марка Руссиновича, копирующий параметры запуска в кучу и выводящий их на экран.

#pragma comment(linker, "/SUBSYSTEM:NATIVE") #pragma comment(linker, "/ENTRY:native_main") #pragma comment(lib, "ntdll.lib")

#pragma comment(linker,"/BASE:0x00010000")

 

#define _X86_

 

#include <ntddk.h>

 

#include <stdio.h>

 

#include "nt.h"

 

typedef struct {

 

ULONG Unknown[21];

 

UNICODE_STRING CommandLine;

 

UNICODE_STRING ImageFile;

 

} ENVIRONMENT_INFORMATION, *PENVIRONMENT_INFORMATION;

 

typedef struct {

 

ULONG Unknown[3];

 

PENVIRONMENT_INFORMATION Environment;

 

} STARTUP_ARGUMENT, *PSTARTUP_ARGUMENT;

 

typedef struct {

 

ULONG Length;

 

ULONG Unknown[11];

 

} RTL_HEAP_DEFINITION, *PRTL_HEAP_DEFINITION;

 

void native_main(PSTARTUP_ARGUMENT Argument)

 

{

 

PUNICODE_STRING commandLine;

 

PWCHAR stringBuffer, argPtr;

 

UNICODE_STRING helloWorld;

]

RTL_HEAP_DEFINITION heapParams;

 

118

memset(&heapParams, 0, sizeof(RTL_HEAP_DEFINITION));

 

КОДИНГ

heapParams.Length = sizeof(RTL_HEAP_DEFINITION);

Heap = RtlCreateHeap(2, 0, 0x100000, 0x1000, 0, &heapParams);

 

 

commandLine = &Argument->Environment->CommandLine;

 

argPtr = commandLine->Buffer;

 

while (*argPtr != L' ') argPtr++;

 

argPtr++;

 

stringBuffer = RtlAllocateHeap( Heap, 0, 256 );

 

swprintf(stringBuffer, L"\n%s", argPtr);

 

helloWorld.Buffer = stringBuffer;

 

helloWorld.Length = wcslen(stringBuffer) * sizeof(WCHAR);

 

helloWorld.MaximumLength = helloWorld.Length + sizeof(WCHAR);

>

NtDisplayString(&helloWorld);

05

 

10 [82]

RtlFreeHeap(Heap, 0, stringBuffer);

NtTerminateProcess(NtCurrentProcess(), 0);

[XÀÊÅÐ

}

 

 

 

 

 

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. Я банально об этом забыл рассказать ;). Тут нет ничего сложного. Для того чтобы Nativeприложение запускалось до загрузки винды (собственно, никак иначе его и не запустить… стандартными средствами) нужно залезть в реестр, в HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\ Session Manager, открыть там ключ BootExecute (там уже лежит autochk — это наш любимый скандиск) и добавить в него новую строку с именем программы, которое ты хотел бы стартовать. Прога, естественно, должна к моменту перезагрузки уже лежать в папке system32. Можно процесс регистрации немного автоматизировать. Создай файл с расширением reg со следующим содержанием:

REGEDIT4

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager] "BootExecute"=hex(7):61,75,74,6f,63,68,65,63,6b,20,61,75,74,6f,63,68,6b,20,2a,\ 00,6e,61,74,69,76,65,20,48,65,6c,6c,6f,20,57,6f,72,6c,64,21,00,00

А затем запусти. К ключу BootExecute добавится строчка «native», запускающая native.exe, приложение, сорцы которого ты можешь найти на диске.

Другой вариант — это написать небольшой код специально для регистрации нашего приложения. У меня на это нехитрое дело ушло 5 минут.

BOOL RegistryAdd(PSTR szAppName)

{

char szRegEntry[1024]; DWORD dwBytes = 1024; BOOL ret = FALSE; HKEY hk;

char *szKeyPath = "SYSTEM\\CurrentControlSet\\Control\\Session Manager";

// открываем ключик

if (RegCreateKey(HKEY_LOCAL_MACHINE, szKeyPath, &hk) != ERROR_SUCCESS)

return 0;

// скидываем все данные в буфер

if (RegQueryValueEx(hk, "BootExecute", 0,0, (LPBYTE)szRegEntry, &dwBytes))

szRegEntry[0] = 0;

// добавляем к буферу свою строчку lstrcat(&szRegEntry[dwBytes-1], szAppName);

if (RegSetValueEx(hk, "BootExecute", 0, REG_MULTI_SZ, (LPBYTE) szRegEntry, dwBytes + lstrlen(szAppName) + 1)) goto finally;

ret = TRUE;

finally: {

// закрываем ключик

if (hk) RegCloseKey(hk);

}

return ret;

}

прописываем приложение в реестре

Соседние файлы в папке журнал хакер