Browse Source

dos2unix convert

pull/11/head
Stefan Schwarz 8 years ago
parent
commit
6a9a82f706
  1. 292
      src/libxt_ts3init.c
  2. 282
      test/torture.py

292
src/libxt_ts3init.c

@ -1,146 +1,146 @@
/* /*
* "ts3init" match extension for iptables * "ts3init" match extension for iptables
* Niels Werensteijn <niels werensteijn [at] teamspeak com>, 2016-10-03 * Niels Werensteijn <niels werensteijn [at] teamspeak com>, 2016-10-03
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License; either version 2 * under the terms of the GNU General Public License; either version 2
* or 3 of the License, as published by the Free Software Foundation. * or 3 of the License, as published by the Free Software Foundation.
*/ */
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <getopt.h> #include <getopt.h>
#include <xtables.h> #include <xtables.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include "ts3init_random_seed.h" #include "ts3init_random_seed.h"
#include "ts3init_match.h" #include "ts3init_match.h"
#define param_act(t, s, f) xtables_param_act((t), "ts3init", (s), (f)) #define param_act(t, s, f) xtables_param_act((t), "ts3init", (s), (f))
#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) #define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x)))
static void ts3init_help(void) static void ts3init_help(void)
{ {
printf( printf(
"ts3init match options:\n" "ts3init match options:\n"
" --client Match ts3init client packets.\n" " --client Match ts3init client packets.\n"
" --server Match ts3init server packets.\n" " --server Match ts3init server packets.\n"
" --command <command> Match packets with the specified command.\n" " --command <command> Match packets with the specified command.\n"
); );
} }
static const struct option ts3init_opts[] = { static const struct option ts3init_opts[] = {
{.name = "client", .has_arg = false, .val = '1'}, {.name = "client", .has_arg = false, .val = '1'},
{.name = "server", .has_arg = false, .val = '2'}, {.name = "server", .has_arg = false, .val = '2'},
{.name = "command", .has_arg = true, .val = '3'}, {.name = "command", .has_arg = true, .val = '3'},
{NULL}, {NULL},
}; };
static int ts3init_parse(int c, char **argv, int invert, unsigned int *flags, static int ts3init_parse(int c, char **argv, int invert, unsigned int *flags,
const void *entry, struct xt_entry_match **match) const void *entry, struct xt_entry_match **match)
{ {
struct xt_ts3init_mtinfo *info = (void *)(*match)->data; struct xt_ts3init_mtinfo *info = (void *)(*match)->data;
int command; int command;
switch (c) { switch (c) {
case '1': case '1':
param_act(XTF_ONLY_ONCE, "--client", info->specific_options & CHK_TS3INIT_CLIENT); param_act(XTF_ONLY_ONCE, "--client", info->specific_options & CHK_TS3INIT_CLIENT);
param_act(XTF_NO_INVERT, "--client", invert); param_act(XTF_NO_INVERT, "--client", invert);
info->specific_options |= CHK_TS3INIT_CLIENT; info->specific_options |= CHK_TS3INIT_CLIENT;
*flags |= CHK_TS3INIT_CLIENT; *flags |= CHK_TS3INIT_CLIENT;
return true; return true;
case '2': case '2':
param_act(XTF_ONLY_ONCE, "--server", info->specific_options & CHK_TS3INIT_SERVER); param_act(XTF_ONLY_ONCE, "--server", info->specific_options & CHK_TS3INIT_SERVER);
param_act(XTF_NO_INVERT, "--server", invert); param_act(XTF_NO_INVERT, "--server", invert);
info->specific_options |= CHK_TS3INIT_SERVER; info->specific_options |= CHK_TS3INIT_SERVER;
*flags |= CHK_TS3INIT_SERVER; *flags |= CHK_TS3INIT_SERVER;
return true; return true;
case '3': case '3':
param_act(XTF_ONLY_ONCE, "--command", info->specific_options & CHK_TS3INIT_COMMAND); param_act(XTF_ONLY_ONCE, "--command", info->specific_options & CHK_TS3INIT_COMMAND);
param_act(XTF_NO_INVERT, "--command", invert); param_act(XTF_NO_INVERT, "--command", invert);
command = atoi(optarg); command = atoi(optarg);
if (command < 0 || command > 255) if (command < 0 || command > 255)
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"ts3init: invalid command number"); "ts3init: invalid command number");
info->specific_options |= CHK_TS3INIT_COMMAND; info->specific_options |= CHK_TS3INIT_COMMAND;
info->command = (__u8)command; info->command = (__u8)command;
*flags |= CHK_TS3INIT_COMMAND; *flags |= CHK_TS3INIT_COMMAND;
return true; return true;
default: default:
return false; return false;
} }
} }
static void ts3init_save(const void *ip, const struct xt_entry_match *match) static void ts3init_save(const void *ip, const struct xt_entry_match *match)
{ {
const struct xt_ts3init_mtinfo *info = (const void *)match->data; const struct xt_ts3init_mtinfo *info = (const void *)match->data;
if (info->specific_options & CHK_TS3INIT_CLIENT) if (info->specific_options & CHK_TS3INIT_CLIENT)
{ {
printf(" --client"); printf(" --client");
} }
if (info->specific_options & CHK_TS3INIT_SERVER) if (info->specific_options & CHK_TS3INIT_SERVER)
{ {
printf(" --server"); printf(" --server");
} }
if (info->specific_options & CHK_TS3INIT_COMMAND) if (info->specific_options & CHK_TS3INIT_COMMAND)
{ {
printf(" --command %i", (int)info->command); printf(" --command %i", (int)info->command);
} }
} }
static void ts3init_print(const void *ip, const struct xt_entry_match *match, static void ts3init_print(const void *ip, const struct xt_entry_match *match,
int numeric) int numeric)
{ {
printf(" -m ts3init"); printf(" -m ts3init");
ts3init_save(ip, match); ts3init_save(ip, match);
} }
static void ts3init_check(unsigned int flags) static void ts3init_check(unsigned int flags)
{ {
bool client = flags & CHK_TS3INIT_CLIENT; bool client = flags & CHK_TS3INIT_CLIENT;
bool server = flags & CHK_TS3INIT_SERVER; bool server = flags & CHK_TS3INIT_SERVER;
if (client && server) if (client && server)
{ {
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"ts3init_: --client and --server can not be specified at the same time"); "ts3init_: --client and --server can not be specified at the same time");
} }
if (flags & CHK_TS3INIT_COMMAND) if (flags & CHK_TS3INIT_COMMAND)
{ {
if (!client && !server) if (!client && !server)
{ {
xtables_error(PARAMETER_PROBLEM, xtables_error(PARAMETER_PROBLEM,
"ts3init: --command requires either --client or --server"); "ts3init: --command requires either --client or --server");
} }
} }
} }
/* register and init */ /* register and init */
static struct xtables_match ts3init_mt_reg[] = static struct xtables_match ts3init_mt_reg[] =
{ {
{ {
.name = "ts3init", .name = "ts3init",
.revision = 0, .revision = 0,
.family = NFPROTO_UNSPEC, .family = NFPROTO_UNSPEC,
.version = XTABLES_VERSION, .version = XTABLES_VERSION,
.size = XT_ALIGN(sizeof(struct xt_ts3init_mtinfo)), .size = XT_ALIGN(sizeof(struct xt_ts3init_mtinfo)),
.userspacesize = XT_ALIGN(sizeof(struct xt_ts3init_mtinfo)), .userspacesize = XT_ALIGN(sizeof(struct xt_ts3init_mtinfo)),
.help = ts3init_help, .help = ts3init_help,
.parse = ts3init_parse, .parse = ts3init_parse,
.print = ts3init_print, .print = ts3init_print,
.save = ts3init_save, .save = ts3init_save,
.extra_opts = ts3init_opts, .extra_opts = ts3init_opts,
.final_check = ts3init_check, .final_check = ts3init_check,
}, },
}; };
static __attribute__((constructor)) void ts3init_mt_ldr(void) static __attribute__((constructor)) void ts3init_mt_ldr(void)
{ {
xtables_register_matches(ts3init_mt_reg, ARRAY_SIZE(ts3init_mt_reg)); xtables_register_matches(ts3init_mt_reg, ARRAY_SIZE(ts3init_mt_reg));
} }

282
test/torture.py

@ -1,141 +1,141 @@
""" """
Generates as fast as possible COMMAND_GET_COOKIE packets to see how well Generates as fast as possible COMMAND_GET_COOKIE packets to see how well
the TeamSpeak 3 Server can withstand a simple DOS attack. the TeamSpeak 3 Server can withstand a simple DOS attack.
It has two modes: It has two modes:
* a testing mode that checks that the server continues to reply with correct * a testing mode that checks that the server continues to reply with correct
messages, even when under heavy load. messages, even when under heavy load.
* a spoofing mode, where answers are not expected or waited for, but the source * a spoofing mode, where answers are not expected or waited for, but the source
ip and port are spoofed, in order to trick simple filtering. ip and port are spoofed, in order to trick simple filtering.
""" """
from socket import socket, getaddrinfo, IPPROTO_UDP, AF_INET, SOCK_RAW, IPPROTO_RAW, inet_aton from socket import socket, getaddrinfo, IPPROTO_UDP, AF_INET, SOCK_RAW, IPPROTO_RAW, inet_aton
from argparse import ArgumentParser from argparse import ArgumentParser
from select import select from select import select
from random import randint from random import randint
from itertools import repeat from itertools import repeat
from struct import pack, unpack_from from struct import pack, unpack_from
from time import time from time import time
from sys import version_info, exit from sys import version_info, exit
if version_info < (3,0): if version_info < (3,0):
print('python3 required.') print('python3 required.')
exit(1) exit(1)
parser = ArgumentParser(description='Tests if the ts3init module, can withstand heavy loads.') parser = ArgumentParser(description='Tests if the ts3init module, can withstand heavy loads.')
parser.add_argument('host', help='target host') parser.add_argument('host', help='target host')
parser.add_argument('--port', type=int, default=9987, help='target port') parser.add_argument('--port', type=int, default=9987, help='target port')
parser.add_argument('--count', type=int, default=100000, help='number of packets to send') parser.add_argument('--count', type=int, default=100000, help='number of packets to send')
parser.add_argument('--response', type=int, default=1, help='what command number is expected to be returned from the server') parser.add_argument('--response', type=int, default=1, help='what command number is expected to be returned from the server')
parser.add_argument('--spoof', action='store_const', const=True, default=False, help='should the source address be spoofed') parser.add_argument('--spoof', action='store_const', const=True, default=False, help='should the source address be spoofed')
parser.add_argument('--version', type=int, default=1459504131, help='version number send to the server') parser.add_argument('--version', type=int, default=1459504131, help='version number send to the server')
args = parser.parse_args() args = parser.parse_args()
def generateSpoofedHeader(dest_address, dest_port, payload): def generateSpoofedHeader(dest_address, dest_port, payload):
# checksum functions needed for calculation checksum # checksum functions needed for calculation checksum
def checksum(msg): def checksum(msg):
s = 0 s = 0
for i in range(0, len(msg), 2): for i in range(0, len(msg), 2):
w = msg[i+1] + (msg[i] << 8) w = msg[i+1] + (msg[i] << 8)
s = s + w s = s + w
s = (s>>16) + (s & 0xffff); s = (s>>16) + (s & 0xffff);
s = s + (s >> 16); s = s + (s >> 16);
s = ~s & 0xffff s = ~s & 0xffff
return s return s
source_address = randint(0, (1 << 32) - 1) source_address = randint(0, (1 << 32) - 1)
source_port = randint(0, (1 << 16) - 1) source_port = randint(0, (1 << 16) - 1)
udp_length = 8 + len(payload) udp_length = 8 + len(payload)
udp_checksum = checksum(pack('!I4sxBHHHH2x', udp_checksum = checksum(pack('!I4sxBHHHH2x',
source_address , dest_address, IPPROTO_UDP, udp_length, source_address , dest_address, IPPROTO_UDP, udp_length,
source_port, dest_port, udp_length) + payload) source_port, dest_port, udp_length) + payload)
if udp_checksum == 0: if udp_checksum == 0:
udp_checksum = (1 << 16) - 1 udp_checksum = (1 << 16) - 1
return pack('!BBHHHBBHI4sHHHH', return pack('!BBHHHBBHI4sHHHH',
(4 << 4) + 5, # Version, IHL (4 << 4) + 5, # Version, IHL
0, # TOS 0, # TOS
0, # Total Length, kernel will fill the correct total length 0, # Total Length, kernel will fill the correct total length
0, # Identification 0, # Identification
0, # Fragment Offset 0, # Fragment Offset
255, # TTL 255, # TTL
IPPROTO_UDP, # Protocol IPPROTO_UDP, # Protocol
0, # Header checksum, kernel will fill the correct checksum 0, # Header checksum, kernel will fill the correct checksum
source_address, # Source Address source_address, # Source Address
dest_address, # Destination Address dest_address, # Destination Address
source_port, # Source Port source_port, # Source Port
dest_port, # Destination Port dest_port, # Destination Port
udp_length, # UDP Length udp_length, # UDP Length
udp_checksum); # UDP Checksum udp_checksum); # UDP Checksum
def generatePayload(version): def generatePayload(version):
number = randint(0, (1 << 32) - 1) number = randint(0, (1 << 32) - 1)
return pack('!8sHHBIBII8x', return pack('!8sHHBIBII8x',
b'TS3INIT1', # Literal b'TS3INIT1', # Literal
101, # Packet ID 101, # Packet ID
0, # Client ID 0, # Client ID
0x88, # Flags, 0x88, # Flags,
version, # Version version, # Version
0, # Command 0, # Command
int(time()), # Timestamp int(time()), # Timestamp
number); # Random-Sequence number); # Random-Sequence
def validateResponse(answer, expectedCommand): def validateResponse(answer, expectedCommand):
(literal, packet_id, flags, command) = unpack_from('!8sHBB', answer) (literal, packet_id, flags, command) = unpack_from('!8sHBB', answer)
return (literal == 'TS3INIT1' return (literal == 'TS3INIT1'
and packet_id == 101 and packet_id == 101
and flags == 0x88 and flags == 0x88
and command == expectedCommand) and command == expectedCommand)
target = getaddrinfo(args.host, args.port, 0, 0, IPPROTO_UDP)[0] target = getaddrinfo(args.host, args.port, 0, 0, IPPROTO_UDP)[0]
print("Sending %i packets to %s:%i..." % (args.count, *target[4])) print("Sending %i packets to %s:%i..." % (args.count, *target[4]))
if not args.spoof: if not args.spoof:
send = 0 send = 0
sendErrors = 0 sendErrors = 0
recieved = 0 recieved = 0
invalid = 0 invalid = 0
sock = socket(*target[0:3]) sock = socket(*target[0:3])
try: try:
sock.connect(target[4]) sock.connect(target[4])
sock.setblocking(False) sock.setblocking(False)
finished_writing = False finished_writing = False
while True: while True:
(canRead, canWrite, _) = select([sock.fileno()], [sock.fileno()] if not args.spoof and send < args.count else [] , [], 1) (canRead, canWrite, _) = select([sock.fileno()], [sock.fileno()] if not args.spoof and send < args.count else [] , [], 1)
if canRead: if canRead:
data = sock.recv(128) data = sock.recv(128)
if not validateResponse(data, args.response): if not validateResponse(data, args.response):
invalid += 1 invalid += 1
recieved += 1 recieved += 1
if canWrite: if canWrite:
try: try:
packet = generatePayload(args.version) packet = generatePayload(args.version)
sock.send(packet) sock.send(packet)
send += 1 send += 1
except: except:
sendErrors += 1 sendErrors += 1
if not canRead and not canWrite: if not canRead and not canWrite:
break break
finally: finally:
sock.close() sock.close()
print("send: %i(errors: %i); recieved: %i; invalid: %i" % (send, sendErrors, recieved, invalid)) print("send: %i(errors: %i); recieved: %i; invalid: %i" % (send, sendErrors, recieved, invalid))
else: else:
send = 0 send = 0
sendErrors = 0 sendErrors = 0
sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW) sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)
try: try:
dest_address = inet_aton(target[4][0]) dest_address = inet_aton(target[4][0])
dest_port = target[4][1] dest_port = target[4][1]
for _ in repeat(None, args.count): for _ in repeat(None, args.count):
try: try:
payload = generatePayload(args.version) payload = generatePayload(args.version)
packet = generateSpoofedHeader(dest_address, dest_port, payload) + payload packet = generateSpoofedHeader(dest_address, dest_port, payload) + payload
select([sock.fileno()], [] , [], 0) select([sock.fileno()], [] , [], 0)
sock.sendto(packet, target[4]) sock.sendto(packet, target[4])
send += 1 send += 1
except BaseException as e: except BaseException as e:
print(e) print(e)
sendErrors += 1 sendErrors += 1
finally: finally:
sock.close() sock.close()
print("send: %i(errors: %i);" % (send, sendErrors)) print("send: %i(errors: %i);" % (send, sendErrors))

Loading…
Cancel
Save