Back Content Forward

В статье описанно как построить аннонимную систему для серфинга по вебу. Основываться это система будет на cgi-proxy или анонимайзерах. Верняк все пользовались сервисом по типа anonymaizer.com - однако использовать эту систему для чего-то более серьёзного чем просмотр новостей нельзя =) В чём плюсы системы, котурую я хочу предложжитть:

  • скрытие вашего реального ипа

  • Засорение логов провайдера

  • Серфинг с разными территориальными адресами, при этом вы можете выбрать локацию нужную вам

Какие затраты потребуются от вас ? Никаких, кроме умственных ;) от вас потребуется только время желание и немножко программирования.

Для начала давайте прикиним какими путями можно выследить взломщика или злоумышленника, атаковавшего определённый сервер (учитывая гибкость протокола http - через него можно провести практически любую атаку на практически любой сервер)... или просто человека, который хочет быть свободным... Тут можно действовать двумя путями:

  • Анализ логов сервера

  • Предупредительные системы - анализ логов провайдера

Второй случай - это уже сбор компромата на известное лицо, но тем не менее - провайдеры это те человеко подобные существа, которым мы предоставляем бесплатную возможность просматриватть наш трафик и собирать наши пароли. Поэтому защите от анализа логов провайдером надо уделить самое пристальное внимание.

Спасут ли известные анонимайзеры от хотя бы одной из этих проблем ? Нет. В обоих случаях в логах отразится адрес анонимайзера (не говоря о том что трафик не шифруется, а следовательно любой желающий может наблюдать за вашей деятельностью) - поэтому компетентые органы знают куда обращаться за предоставлением доказательст (учитывая что анонимайзеры - это проекты, приносящие прибыль их владельцам) ;)

Конечно есть можно использовать цепочку из нескольких анонимайзеров - но во первых длинна GET запроса, которым передаются данные(ещё один минус) это всего 255 байт - поэтому большую цепь выстроить не удаться. Ну и кроме того такая цепь остановит органы не надолго - тк в данном случае для получения логов им придется делать не один, а несколько звонков.

Итак что же будем собирать мы? Незаметную прозрачную анонимную распрелелённую систему с шифрованием трафика. Для начала зарегестрируйте себе кучу аккаунтов на бесплатных хостингах - при этом стараясь в названии соблюдать конспирацию - те не hackerz-proxy.bla.ru - а что типа jonny1976.homepage.us =) если кого то смущает словосочетание куча акков - то для нашей системы нам потребуется как минимум 30-50 хостингов (ссылки в конце статьи), расположенных в разных странах, если у вас появилось желание продолжать - то вполне по силам любому написать скрипт для автоматической регистрации аккаунтов.

После регистрации мы произвольно разделяем всё на три группы:

  • Точки входа

  • промежуточные сервера

  • Точки выхода

Как будет гоняться наш трафик ? Вы соединяетесь со случайной точкой входа, передаёте ей запрос в котором будет указан путь и конечная цель - после этого запрос идёт по пути через промежуточные сервера в конце попадая на точку выхода и улетая в реальный мир.

ВНИМАНИЕ - точки выхода могут являться промежуточными серверами, а вот точки входа нет. Точно так же промежуточные сервера не могут являться ни входными, ни выходными точками. почему это так ? Вопервых вам придётся иногда менять точки выхода - ведь десять различных адресов на выходе не есть круто - а если у вас не будет чёткого разделения на типы серверов, то будет не понятно чего имено менять. Во вторых почему входному серверу нельзя стать промежуточным (выходным он не может стать по определению - тогда теряются все преимущества по сравнению с анонимайзерами, кроме разве что шифрования) - если органы начнут копать - то они начнут с выходных точек (что естественно) и продолжат внедряться внутрь системы - те перейдут к промежуточным серверам - и тут о чудо - к одному из промежуточных серверов подконнектится искомый субект .... Можно ли использовать выходные сервера в качестве промежуточных ? Можно только осторожно =) помните что при разработке такой системы главным фактором является длинна цепочки и что вас будут искать начиная с точек выхода. Так что если подконтрольная органам точка выхода станет первым промежуточным сервером в цепи - то ваше дело подчти закрыто =) Я предлогаю использовать один выходной сервер в конце цепочки промежуточных. Это удлинит цепь - а значит усложнит анализ и в то же время не раскроет большую порцию информации о нашей системе.

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

Теперь давайте разберёмся со скрытием трафика. Трафик системы должен быть достаточно незаметным при анализе с помощью снифферов, да ивообще сайты не должны вызывать подозрения у хостеров - те должны содержать какой-то контент и иметь свои 3-5 человек посетителей в день. Начать надо с оформления сайтов...нет дизайном вам заниматься не придётся =) всегда можно честно сделать копи пасте с различных хомяков - благо их развилось достаточное количество... В дополнение не поленитесь зарегистрировать сайты в поисковиках - дабы на них приходил ещё и левый народ.

Передавайте параметры скриптам только методом POST - с помощью этого вы сможете передавать в обе стороны данные не ограниченные жёсткими рамками. При возможности использования .htaccess не побрезгуйте и переопределите url mypage/my.jpg в скрипт, что бы в данном случае показывать посетителям нормальное фото проверяйте пришли ли какие-то данные через post - если нет, значит это нормальный посетитель, жаждущий увидеть вашу фотографию ;)

Соответвенно все передачи данных между клиентами и серверами должны происходить как с одной стороны аплоад файла на сервер, а с другой как выдача файла с определённым content-type.

Ну и конечно общие советы - встраивайте свои скрипты в коды других популярных open source решений. если скрипт всё же висит отдельно то назвайте его нейтрально - типа upload.php/file.php/index.php...etc

думаю этих простых средств хватит что бы защитить от пассивного анализа трафика. Однако органы бездействовать не будут и перейдут в активное наступление - а именно обнаружат ваши скрипты и их исходный код (защитите его как можете - лучшее имхо решение встраивать бекдоры в опен соурс продукцию) станет предметом их анализа. Тут может помочь только шифрование.

Сразу замечу что мы будем говорить о использовании шифрования на основе 2-х ключей - открытого и закрытого. Шифрование осуществляется по типу матрёшки или стека - те отдельно для каждоо промежуточного сервера. Таким образом содержание пакета будет известно только вам и точке выхода.

Но здесь перед нами опять встаёт проблема - как мы должны хранить и распределять ключи. Идеального средства здесь к сожалению нет (как и вообще в разделе криптографии посвящённой системам хранения ключей). У нас есть два варианта:

  • Сеансовые ключи, меняющиеся для каждого соединения

  • Постоянные ключи - определяются зарранее и меняются раз в месяц например.

У каждого из из этих способов есть свои минусы и плюсы.

Рассмотрим для начала сеансовые ключи - скрипт генерирует уникальный ключ для каждой сессии и помнит его например в течение часа. После этого ключ удаляется. Плюсы - даже узнав все закрытые ключи со всех промежуточных серверов органы не смогут читать данные предыдущих сеансов(при условии надёжности алгоритма шифрования). Минусы - медленный старт сесси - тк нам потребуются все ключи серверов по пути - то придётся опросить 20-25 серверов для одного сеанса.

Использование же предопределённого ключа так же имеет свои недостатки. однако когда мы говорим о предопределённом ключе имеется ввиду ключ сессии сгенерированный на основе этого ключа. Это несколько ослложнит жизнь органам, но это не будет являться полноценным протоколом согласования ключей.

Пожалуй наиболее рациональным решением является использование на промежуточных серверах постоянных ключей, а на входе и выходе только сессионные ключи.

Ещё одной проблой является хранение списка подконтрольных серверов - можно хранить весь список серверов у себя на компьютере, а с другой стороны можно сформировать распределённую систему хранения на промежуточных серверах. Минусом первой является тот факт, что если вы не единственный пользователь этой системы - то вам придётся согласовывать ваши базы между собой. При использовании распределённой системы - в случае если ваш сервер накроют - то произойдёт утечка информации о некоторых серверах. Личчно моё мнение что везде где возможно следует использовать локальный тип хранения данных. В случае же распределённого хранения базы не забывайте её шифрануть - а ключ передавать от клиента. В идеале адрес каждого сервера следует зашифровать своим ключём - это сделает невозможным утечку базы серверов - но в этом случае на локальных компах вам понадобятся базы уже с ключами =)

Прикинем примерную структуру протокола: наиболее простейший вид протокола имеет такой вид(естественно в не шифрованной форме):

  • Адрес следующего сервера

  • URL скрипта на следующем сервере

  • Тело запроса

Получая такой пакет сервер расшифровывает его. Если поле следующий сервер пустует - значит извлекаем адрес из тела запроса и передаём его. Если адрес следующего сервера не пуст - значит соединяемся с ним и передаём ему весь остальной пакет.

Переходя к реализии всего выше описанного я вначале хотел привести пример прокси без поддержки шифрования (тут уж на вкус и цвет товарищей нет - кто-то довольствуется DES, а кто-то и AES не доверяет) - однако прикинул что в нете действительно полно статей про написание проксей. Поэтому в качестве рекомендации к прочтению приведу статью KMiNT21 http://uinc.ru/articles/24/

Именно после прочтения этой статьи и желания преодолеть один прокси, закрывающий некоторые ресурсы я начал работать над данной темой 2 года назад... Однако приведу некоторые полезные советы, о которых авторы примеров простейших проксей забывают. Например удобнее хранить спикос сокетов не в виде массива, а ввиде списка, оформленного как-то так:


typedef struct _SOCKET_INFO {
// буфферы, для хранения данных
CHAR Buffer[DATA_BUFSIZE];
WSABUF DataBuf;

//сокет
SOCKET Socket;

// любая полезная информация:
DWORD BytesSend;
DWORD BytesRecv;
...

// указатель на следующий элемент списка:
_SOCKET_INFORMATION *Next;
} SOCKET_INFO, * LPSOCKET_INFO;

LPSOCKET_INFO SocketInfo;

Ну и соответвенно некоторые функции для работы со списками (вырезка практически из школьной программы=):


// добавляем новый элемент в список
void CreateSocketInformation (SOCKET s)
{
LPSOCKET_INFO SI;

if ((SI = (LPSOCKET_INFO) GlobalAlloc (GPTR, sizeof (LPSOCKET_INFO))) == NULL){
// alloc error
return;
}

SI->Socket = s;
SI->BytesSend = 0;
SI->BytesRecv = 0;

SI->Next = SocketInfo;

SocketInfoList = SI;
}

// получаем данные о нужном нам сокете:
LPSOCKET_INFO GetSocketInformation (SOCKET s)
{
LPSOCKET_INFO *SI = SocketInfo;

while (SI){
if (SI->Socket == s)
return SI;

SI = SI->Next;
}

return NULL;
}

// освобождаем память:
void FreeSocketInformation (SOCKET s)
{
LPSOCKET_INFO *SI = SocketInfo;
LPSOCKET_INFO *PrevSI = NULL;

while (SI){
if (SI->Socket == s){
if (PrevSI)
PrevSI->Next = SI->Next;
else
SocketInfo = SI->Next;

closesocket(SI->Socket);
GlobalFree(SI);
return;
}

PrevSI = SI;
SI = SI->Next;
}
}

Работа с этими функциями проходит примерно так, это код соотвенно в оконной процедуре:


SOCKET Accept;
LPSOCKET_INFO SI;

...

//новое подключение:
case FD_ACCEPT:

if ((Accept = accept (wParam, NULL, NULL)) == INVALID_SOCKET){
// accept error
break;
}

CreateSocketInformation (Accept);

....

//закрытие сокета:
case FD_CLOSE:
FreeSocketInformation (wParam);
break;

...

//передача/приём данных:
case FD_READ:

SI = GetSocketInformation (wParam);

SI->DataBuf.buf = SI->Buffer;
SI->DataBuf.len = DATA_BUFSIZE;

if (WSARecv (SI->Socket, &(SI->DataBuf), 1, &RecvBytes, &Flags, NULL, NULL) == SOCKET_ERROR){
if (WSAGetLastError () != WSAEWOULDBLOCK){
// recv error
FreeSocketInformation (wParam);
return 0;
}
}

...

Для реализации серверной стороны используйте любой язык, к которому у вас лежит душа - тут всё действительно просто - получили пакет - передали дальше... думаю трудностей в реализации возникнуть не должно.

А как быть в интернет кафе? Да там не удаться установить прокси - придётся немного модифицировать код прокси - в частности изменять все встречающиеся адреса урл в странице на что-то типа javascript:submit(url) - для передачи пост методом. Для шифрования данных так же можно использовать js - линк в конце статьи. Для ввода данных лучше всего использовать виртуальную клавиатуру - тк в интернет кафе могут быть и клавиатурные шпионы.

05.06.05
набранно на кпк в дождливый выходной на природе - так что извиняйте за ошибки =)

Links:

Back Content Forward