Skip to content

Commit

Permalink
add PoC
Browse files Browse the repository at this point in the history
  • Loading branch information
sgxrop committed Feb 12, 2019
0 parents commit 6d62a25
Show file tree
Hide file tree
Showing 19 changed files with 1,248 additions and 0 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SGX-ROP: Practical Enclave Malware with Intel SGX

This repository contains the implementations of the paper "Practical Enclave Malware with Intel SGX".
The repository consists of three parts: `tap_claw`, `demo`, and `egghunter`.

## TAP + CLAW

Contains the Intel TSX-based primitives to check whether a page is mapped and writable without using syscalls.

## Demo

Uses TAP + CLAW inside a (malicious) SGX enclave to break ASLR of the host application, create a ROP payload and mount a simple PoC attack (i.e., create a file in the current directory).

## Egg Hunter

Shows how to use TAP as egg hunter for classical exploits.


## License

All code is licensed under the MIT license.
248 changes: 248 additions & 0 deletions demo/App/App.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>

# include <unistd.h>
# include <pwd.h>
# define MAX_PATH FILENAME_MAX

#include "sgx_urts.h"
#include "App.h"
#include "Enclave_u.h"

/* Global EID shared by multiple threads */
sgx_enclave_id_t global_eid = 0;

typedef struct _sgx_errlist_t {
sgx_status_t err;
const char *msg;
const char *sug; /* Suggestion */
} sgx_errlist_t;

/* Error code returned by sgx_create_enclave */
static sgx_errlist_t sgx_errlist[] = {
{
SGX_ERROR_UNEXPECTED,
"Unexpected error occurred.",
NULL
},
{
SGX_ERROR_INVALID_PARAMETER,
"Invalid parameter.",
NULL
},
{
SGX_ERROR_OUT_OF_MEMORY,
"Out of memory.",
NULL
},
{
SGX_ERROR_ENCLAVE_LOST,
"Power transition occurred.",
"Please refer to the sample \"PowerTransition\" for details."
},
{
SGX_ERROR_INVALID_ENCLAVE,
"Invalid enclave image.",
NULL
},
{
SGX_ERROR_INVALID_ENCLAVE_ID,
"Invalid enclave identification.",
NULL
},
{
SGX_ERROR_INVALID_SIGNATURE,
"Invalid enclave signature.",
NULL
},
{
SGX_ERROR_OUT_OF_EPC,
"Out of EPC memory.",
NULL
},
{
SGX_ERROR_NO_DEVICE,
"Invalid SGX device.",
"Please make sure SGX module is enabled in the BIOS, and install SGX driver afterwards."
},
{
SGX_ERROR_MEMORY_MAP_CONFLICT,
"Memory map conflicted.",
NULL
},
{
SGX_ERROR_INVALID_METADATA,
"Invalid enclave metadata.",
NULL
},
{
SGX_ERROR_DEVICE_BUSY,
"SGX device was busy.",
NULL
},
{
SGX_ERROR_INVALID_VERSION,
"Enclave version was invalid.",
NULL
},
{
SGX_ERROR_INVALID_ATTRIBUTE,
"Enclave was not authorized.",
NULL
},
{
SGX_ERROR_ENCLAVE_FILE_ACCESS,
"Can't open enclave file.",
NULL
},
};

/* Check error conditions for loading enclave */
void print_error_message(sgx_status_t ret)
{
size_t idx = 0;
size_t ttl = sizeof sgx_errlist/sizeof sgx_errlist[0];

for (idx = 0; idx < ttl; idx++) {
if(ret == sgx_errlist[idx].err) {
if(NULL != sgx_errlist[idx].sug)
printf("Info: %s\n", sgx_errlist[idx].sug);
printf("Error: %s\n", sgx_errlist[idx].msg);
break;
}
}

if (idx == ttl)
printf("Error: Unexpected error occurred.\n");
}

/* Initialize the enclave:
* Step 1: try to retrieve the launch token saved by last transaction
* Step 2: call sgx_create_enclave to initialize an enclave instance
* Step 3: save the launch token if it is updated
*/
int initialize_enclave(void)
{
char token_path[MAX_PATH] = {'\0'};
sgx_launch_token_t token = {0};
sgx_status_t ret = SGX_ERROR_UNEXPECTED;
int updated = 0;

/* Step 1: try to retrieve the launch token saved by last transaction
* if there is no token, then create a new one.
*/
/* try to get the token saved in $HOME */
const char *home_dir = getpwuid(getuid())->pw_dir;

if (home_dir != NULL &&
(strlen(home_dir)+strlen("/")+sizeof(TOKEN_FILENAME)+1) <= MAX_PATH) {
/* compose the token path */
strncpy(token_path, home_dir, strlen(home_dir));
strncat(token_path, "/", strlen("/"));
strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME)+1);
} else {
/* if token path is too long or $HOME is NULL */
strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME));
}

FILE *fp = fopen(token_path, "rb");
if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
}

if (fp != NULL) {
/* read the token from saved file */
size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
/* if token is invalid, clear the buffer */
memset(&token, 0x0, sizeof(sgx_launch_token_t));
printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
}
}
/* Step 2: call sgx_create_enclave to initialize an enclave instance */
/* Debug Support: set 2nd parameter to 1 */
ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, &global_eid, NULL);
if (ret != SGX_SUCCESS) {
print_error_message(ret);
if (fp != NULL) fclose(fp);
return -1;
}

/* Step 3: save the launch token if it is updated */
if (updated == FALSE || fp == NULL) {
/* if the token is not updated, or file handler is invalid, do not perform saving */
if (fp != NULL) fclose(fp);
return 0;
}

/* reopen the file with write capablity */
fp = freopen(token_path, "wb", fp);
if (fp == NULL) return 0;
size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
if (write_num != sizeof(sgx_launch_token_t))
printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
fclose(fp);
return 0;
}

/* OCall functions */
void ocall_print_string(const char *str)
{
/* Proxy/Bridge will check the length and null-terminate
* the input string to prevent buffer overflow.
*/
printf("\033[90m[DEBUG]\033[39m <%s>\n", str);
}

#define INFO "\033[92m[INFO ]\033[39m "

int call_enclave() {
int a = 3, b = 5, c = 0;
printf(INFO "Calling enclave function\n");
ecall_add_numbers(global_eid, &c, a, b);
printf(INFO "Successfully returned\n");
return c;
}

void do_add() {
printf(INFO "Adding numbers in enclave\n");
printf(INFO "3 + 5 = %d\n", call_enclave());
printf(INFO "Done adding\n");
}

void add() {
printf(INFO "Wrapper for addition\n");
do_add();
printf(INFO "Wrapper end\n");
}

/* Application entry */
int SGX_CDECL main(int argc, char *argv[])
{
(void)(argc);
(void)(argv);


/* Initialize the enclave */
if(initialize_enclave() < 0){
printf("Enter a character before exit ...\n");
getchar();
return -1;
}


/* Utilize trusted libraries */
add();

/* Destroy the enclave */
printf(INFO "Enter a character before exit ...\n");
getchar();

sgx_destroy_enclave(global_eid);

printf(INFO "Application exited normally\n");

return 0;
}

35 changes: 35 additions & 0 deletions demo/App/App.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef _APP_H_
#define _APP_H_

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#include "sgx_error.h"
#include "sgx_eid.h"

#ifndef TRUE
# define TRUE 1
#endif

#ifndef FALSE
# define FALSE 0
#endif

# define TOKEN_FILENAME "enclave.token"
# define ENCLAVE_FILENAME "enclave.signed.so"

extern sgx_enclave_id_t global_eid; /* global enclave id */

#if defined(__cplusplus)
extern "C" {
#endif

sgx_status_t ecall_add_numbers(sgx_enclave_id_t id, int* res, int a, int b);

#if defined(__cplusplus)
}
#endif

#endif /* !_APP_H_ */
Loading

0 comments on commit 6d62a25

Please sign in to comment.