HOME FORUMS MEMBERS RECENT POSTS LOG IN  
× Авторизация
Имя пользователя:
Пароль:
Нет аккаунта? Регистрация
Баннер 1   Баннер 2
НОВЫЕ ТОРГОВАЯ НОВОСТИ ЧАТ
loading...
Скрыть
Вернуться   ANTICHAT > ИНФО > Статьи
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

  #1  
Старый 12.03.2013, 10:33
Unknown
Новичок
Регистрация: 21.06.2005
Сообщений: 0
С нами: 10992741

Репутация: 0
По умолчанию

ZeroAccess plugin P2P или спецификация сетевого протокола как руководство для разработки

Общее

Представляет из себя простой P2P загрузчик. Реализован в ZeroAccess виде плагина. P2P сеть строится следующим образом. Каждый бот имеет свой список пар других ботов. И периодически обменивается с другими ботами своими актуальными IP. Кроме списка IP бот может получать сначала информацию о файле имеющуюся у другого бота, а потом сам файл. Все общение между ботами производится по UDP протоколу, лишь запрос информации и скачивание файлов TCP

Протокол

При старте бот начинает слушать порты UDP, TCP 16464

Введу некоторое обозначение:

Код:
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
Бот считывает список нод из файла, формат файла:

Код:
struct CFG_NODE{
uint32 ip; uint32 time;
};
Все сообщения имеют заголовок формат:

Код:
struct HEAD{
uint32 crc32; uint32 cmd; uint32 hop; uint32 data;
};
За хидером следуют данные зависящие от команды cmd. Команд всего 3и:

Код:
getL - запросить список нод
retL - отдать список нод
newL - публикация ноды
данные за хидером шифруются таким алгоритмом:

Код:
void encrypt(uint8 *data, int len_data){
uint32 *p = (uint32*)data;
uint32 count=len_data>>2;
uint32 key = 'ftp2';
do{
*p ^= key; key = ROL(key, 1); p++; --count;
}while ( count );
}
Команда getL

Бот считывает ноды из файла и с периодом в 1с рассылает сообщение вида:

Код:
struct HEAD{
uint32 crc32; uint32 cmd; // 'getL' uint32 hop; // количество прыжков 0 uint32 data; // сессия, случайное число sess
}; HEAD head;
Нода получает это сообщение и в ответ оправляет информацию о своих нодах и файлах retL. И если hop=0, то выполняет проверку на внешний IP бота отправителя. Для этого отправляет пакет:

Код:
struct HEAD{
uint32 crc32; uint32 cmd; // 'getL' uint32 hop; // количество прыжков 1 uint32 data; // ip отправителя
}; HEAD head;
замете количество прыжков стало равно 1, это сообщение доходит в том случае если бот имеет внешний IP.

Команда retL

Отправляет в ответ на getL

Код:
struct HEAD{
uint32 crc32; uint32 cmd; // 'retL' uint32 hop; // значение из входящего сообщения (0 или 1) uint32 data; // sess из входящего пакета
}; struct BLOCK_NODE{
uint32 ip; uint32 time_delta;
}; struct BLOCK_SIGN{
uint32 name_file; //имя в виде числа 32 бита uint32 time; uint32 size; uint8 sign[128];
}; HEAD head; uint32 count_node; //количество нод не более 16 BLOCK_NODE node[count_node]; uint32 count_sign; //количество файлов не более 16 BLOCK_SIGN sign[count_sign];
Ноды в BLOCK_NODE выбираются в зависимости от времени CFG_NODE.time. При этом ноды сначала упорядочиваются по убыванию. Самое большое значение CFG_NODE.time считается самым актуальным. Выбирается не более 16и самых актуальных нод. И выполняется формирование пакетов BLOCK_NODE, причем время рассчитывается так:

Определяется дельта для от текущей даты:

Код:
BLOCK_NODE.time_delta=now()-CFG_NODE.time
При приеме пакета retL время восстанавливается:

Код:
CFG_NODE.time =now()-BLOCK_NODE.time_delta
Новые ноды добавляются к имеющемуся списку, упорядочиваются, выбираются и сохраняются те которые не старше 32 дней.

Если во входящем пакете hop=1, то бот считает себя нодой с внешним IP (супернодой), и выполняет отправку пакета newL 16 нодам из своего конфига CFG_NODE

Команда newL

Формируется в ответ на retL с hop=1 или newL

Код:
struct HEAD{
uint32 crc32; uint32 cmd; // 'newL' uint32 hop; // 8 прыжков или hop-1 из входящего uint32 data; // ip отправителя
}; HEAD head;
Сообщение рассылается 16и нодам из конфига бота.

При получении ботами newL сообщения, извлекается HEAD.data (ip ноды), и проверяется наличие этого ip с имеющимся списком. Если такого ip не оказалось, то производится его добавление. И повторная рассылка 16и нодам с HEAD.hop - 1, так продолжается пока HEAD.hop не станет равным нулю или ip не будет известен всем нодам.

Загрузка файлов

В пакетах retL имеется количество count_sign и BLOCK_SIGN. Это информация о файлах которая имеется у бота. При получении такого пакета бот проверяет цифровую подпись BLOCK_SIGN.sign, затем смотрит есть ли у него имя файла BLOCK_SIGN.name_file, если такое имя имеется то выполняется проверка времени.

При выполнении всех этих условий выполняется tcp соединение, и отправляется пакет:

Код:
struct BLOCK_FILE{
uint32 name_file; uint32 time; uint32 size;
}; BLOCK_FILE info;
В ответ приходит файл зашифрованный RC4 с ключом md5(info). Файл расшифровывается и проверяется цифровая подпись, которая берётся из ресурсов принятого файла. Если все прошло успешно, то файл сохраняется.

Дополнительная литература

Старая версия протокола p2p модуля, и самого ZeroAccess

hxxp://www.kindsight.net/sites/default/files/Kindsight_Malware_Analysis-ZeroAcess-Botnet-final.pdf

p.s

Хочу заметить что этот протокол рассчитан лишь на загрузку файлов на машины юзеров. Но его можно немного модифицировать, добавить код который сможет туннелировать трафик. В качестве одного из файлов раздавать список IP на которые будут стучаться боты. А те боты на которые происходит обращение будут переправлять траф на наш CC. В результате между ботами и СС, будет прокладка в виде тех же ботов.
 
Ответить с цитированием
Ответ



Предыдущая тема Следующая тема

Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT ™ © 2001- Antichat Kft.