Epic Technologies™ (no relation to any games companies) is happy to announce the release of Epic DRM™ the new DRM system that allows you to protect your shell commands from unauthorized viewing and modification, even in the hands of untrusted third parties! we have utilized the latest cryptographic algorithms like chacha20 and poly1305 for guaranteed maximum security
we have released a demo (https://git.lain.faith/haskal/spot-the-bug/src/branch/develop/stream-ciphers) containing an implementation of Epic DRM™ including a server program that sends Epic DRM™ protected shell commands to an untrusted client process, and receives protected commands back to execute. Epic DRM™ protects the authenticity and integrity of each command, making it completely safe to execute anything received by the client that can be successfully unprotected
getting started with Epic DRM™:
git clone https://git.lain.faith/haskal/spot-the-bug/
cd spot-the-bug/stream-ciphers
make
now, run ./epic_drm
to start the DRM server, and ./client
to execute an interaction with the server
scope
i'm not going to bother to set up an Official Online Environment for this or anything, so you'll have to run it on your own machine, but imagine that epic_drm
is running as some privileged user with access to juicy data and magic buses and you are an unprivileged user running client
. the goal is to pwn epic_drm
by sending it some data over the communication channel. the goal does not involve dumping, ptracing, or otherwise committing privileged screwing with epic_drm
through boring means
so basically, take a look at the code (it's not a lot uwu) and Spot The Bug!™
feel free to send me questions on mastodon or something
how it works
our technology is way too complicated for anyone but our top level COMPTIA Security+ certified engineers to understand, but we have provided the source code for your consideration (it's also in the repo)
epic_drm
communicates using shared memory. it uses the following structure to organize communications:
struct command_channel {
sem_t sem_c2s;
sem_t sem_s2c;
enum { GET_CMD, EXECUTE_CMD, SUCCESS, ERROR } command;
struct {
uint8_t nonce[24];
uint8_t exec_cmd[CMD_SIZE];
uint8_t mac[16];
} data;
};
and here is the code for epic_drm.c
- the demo implementation of Epic DRM™
/**
* sends a protected command to the client
*/
void get_cmd(struct command_channel* chan, const uint8_t* key) {
log("sending encrypted DRM command");
uint8_t cmd[CMD_SIZE] = "echo 'this shell command has been protected with Epic DRM(tm)'";
getrandom(chan->data.nonce, 24, 0);
crypto_lock(chan->data.mac, chan->data.exec_cmd, key, chan->data.nonce, cmd, CMD_SIZE);
chan->command = SUCCESS;
}
/**
* unprotects and executes data from the client
*/
void execute_cmd(struct command_channel* chan, const uint8_t* key) {
log("decrypting command");
uint8_t cmd[CMD_SIZE];
int res = crypto_unlock(cmd, key, chan->data.nonce, chan->data.mac, chan->data.exec_cmd, CMD_SIZE);
if (res != 0) {
log("decryption error");
chan->command = ERROR;
} else {
log("executing command");
system((const char*)cmd);
chan->command = SUCCESS;
}
}
int main() {
// create random key
uint8_t key[16];
log("generating random key");
getrandom(key, sizeof(key), 0);
// initialize memory
log("opening shm");
shm_unlink(SHM_NAME);
int shm = shm_open(SHM_NAME, O_RDWR | O_CREAT | O_EXCL, 0644);
ftruncate(shm, SHM_SIZE);
struct command_channel* chan = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0);
sem_init(&chan->sem_c2s, 1, 0);
sem_init(&chan->sem_s2c, 1, 0);
// process commands
log("ready");
while (true) {
sem_wait(&chan->sem_c2s);
switch (chan->command) {
case GET_CMD:
get_cmd(chan, key);
break;
case EXECUTE_CMD:
execute_cmd(chan, key);
break;
default:
log("unexpected command");
}
sem_post(&chan->sem_s2c);
}
}
and finally, client.c
- the untrusted client
// this code is untrusted
// but don't worry, Epic DRM(tm) protections are unbreakable
void* get_cmd(struct command_channel* chan) {
// get the protected shell command from the DRM server
void* dst = malloc(sizeof(chan->data));
log("sending get_cmd");
chan->command = GET_CMD;
sem_post(&chan->sem_c2s);
sem_wait(&chan->sem_s2c);
logf("result: %s", chan->command == SUCCESS ? "success" : "error");
if (chan->command == SUCCESS) {
memcpy(dst, &chan->data, sizeof(chan->data));
return dst;
} else {
return NULL;
}
}
void send_cmd(struct command_channel* chan, void* data) {
// send a protected shell command back to the server
log("sending execute_cmd");
memcpy(&chan->data, data, sizeof(chan->data));
chan->command = EXECUTE_CMD;
sem_post(&chan->sem_c2s);
sem_wait(&chan->sem_s2c);
logf("result: %s", chan->command == SUCCESS ? "success" : "error");
}
int main() {
// perform a basic interaction with epic_drm
log("opening drm");
int shm = shm_open(SHM_NAME, O_RDWR, 0);
struct command_channel* chan = mmap(NULL, SHM_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0);
// get protected shell command
void* data = get_cmd(chan);
log("data");
for (size_t i = 0; i < 64; i++) {
uint8_t b = ((uint8_t*)data)[i];
printf("%02x ", b);
if (i % 16 == 15) {
printf("\n");
}
}
printf("...\n");
// send back
send_cmd(chan, data);
log("done");
}
this is based on a mistake someone has made that i had some fun exploiting in the past :P
Comments
No comments yet. Be the first to react!