/* killer.c - Kills an instance of the Honeynet project's "the-binary" DoS agent. Copyright (c) 2002 Chris Eagle 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 #include #include #include #include #include #include #include #include #include #include #define BUF_SIZE 202 #define STATUS_BYTE 3 #define STATE_BYTE 4 void sub23decode(unsigned char *buf, int len) { int i; unsigned char offset = 23, prev = 0; for (i = 0; i < len; i++, offset += 23) { prev += buf[i] = buf[i] - prev - offset; } } void plus23encode(unsigned char *buf, int len) { int i; unsigned char prev = 0; for (i = 0; i < len; i++) { prev = buf[i] = buf[i] + prev + 23; } } int txPacket(int fd, struct in_addr *dest, unsigned char *packet, int len) { struct sockaddr_in to; int result = -1; unsigned char txpacket[182]; if (fd != -1) { to.sin_addr = *dest; to.sin_port = 0; to.sin_family = AF_INET; txpacket[0] = 2; memcpy(txpacket + 2, packet, len); plus23encode(txpacket + 2, len); result = sendto(fd, txpacket, 182, 0, (struct sockaddr*) &to, sizeof(to)); } return result == -1; } struct in_addr source; char *exec(char *command, struct in_addr *agent, int getResults) { struct L { char *text; struct L *next; }; struct L *list, *l; struct L *temp; int len, count = 0, fdAgent; fd_set r, w, e; unsigned char buf[800]; unsigned char *data = buf + 22; char *results = NULL; list = l = (struct L *) malloc(sizeof(struct L)); l->text = NULL; l->next = NULL; fdAgent = socket(AF_INET, SOCK_RAW, 11); if (fdAgent < 0) return; buf[1] = 2; buf[2] = 0; memcpy(buf + 3, &source.s_addr, 4); txPacket(fdAgent, agent, buf, 10); if (getResults) { sprintf(data, "\x01\x03%s", command); } else { sprintf(data, "\x01\x07%s", command); } txPacket(fdAgent, agent, data, strlen(data) + 1); if (!getResults) return NULL; while (1) { struct timeval tv = {3, 0}; FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e); FD_SET(fdAgent, &r); if (!select(fdAgent + 1, &r, &w, &e, &tv)) break; len = recv(fdAgent, buf, 800, 0); if (len > 0) { if (len < 400 || buf[20] != 3) continue; sub23decode(data, len - 22); if (data[1] == 3 || data[1] == 4) { l->text = (char*) malloc(400); memcpy(l->text, data + 2, 400); count++; l->text[398] = 0; l = l->next = (struct L *) malloc(sizeof(struct L)); l->text = NULL; l->next = NULL; } } else { break; } } close(fdAgent); if (count) { char *proc, *str; results = (char*) malloc(400 * count); len = 0; temp = NULL; for (l = list; l->text; l = l->next) { memcpy(results + len, l->text, 399); len += 398; free(l->text); free(temp); temp = l; } free(temp); } else { fprintf(stdout, "There appears to be no active agent on %s\n", inet_ntoa(*agent)); } return results; } void killer(struct in_addr *agent) { int count = 0, i; char *results, *str, *proc, *agentName; int procs[50]; char killcmd[50]; str = results = exec("ps -x", agent, 1); if (results) { while (proc = strstr(str, "[mingetty]")) { str = proc + 1; while (*proc != '\n') proc--; proc++; procs[count++] = atoi(proc); } free(results); } if (count) { results = exec("ps -e", agent, 1); if (results) { for (i = 0; i < count; i++) { str = results; sprintf(killcmd, "%d ", procs[i]); while (proc = strstr(str, killcmd)) { if (proc) { str = strchr(proc, '\n'); if (str) { *str = 0; while (*str != ' ') str--; str++; if (strstr(str, "mingetty")) { while (*str) str++; *str = '\n'; } else { fprintf(stdout, "Cross your fingers!\n"); fprintf(stderr, "The agent binary is named: %s (I hope)\n", str); fprintf(stderr, "Killing %s on %s\n", str, inet_ntoa(*agent)); sprintf(killcmd, "pkill -9 %s", str); exec(killcmd, agent, 0); break; } } } } } free(results); } } } void usage(char *cmd) { fprintf(stdout, "Usage: %s -i -n \n", cmd); fprintf(stdout, " -i: the ip of the machine you are running this on\n"); fprintf(stdout, " sorry, but I am too lame to figure it out reliably.\n"); fprintf(stdout, " -a: the ip of the infected host\n"); exit(1); } int main(int argc, char **argv) { struct in_addr target; pthread_t readThread; int result, r, haveOwnIP = 0, haveTgt = 0; void *tResult; unsigned char buf[10]; while (1) { r = getopt(argc, argv, "i:a:"); if (r < 0) break; switch (r) { case 'i': inet_aton(optarg, &source); haveOwnIP = 1; break; case 'a': inet_aton(optarg, &target); haveTgt = 1; break; default: usage(argv[0]); } } if (!haveOwnIP || !haveTgt) { usage(argv[0]); } fprintf(stdout, "If at first you don't succeed, ...!\n"); killer(&target); }