Title
CVE-2021-33669 – SAP Mobile SDK Certificate Provider – Insecure Temporary File Storage – Potential Symlink Attack & Denial of Service
CVE ID
CVE-2021-33669
CVSS Score
7.8
Internal ID
SICK-2021-032
Vendor
SAP
Product
SAP Mobile SDK Certificate Provider
Product Versions
3.0.7 and below
Vulnerability Details
A vulnernability in the SAP Mobile SDK Certificate Provider version 3.0.7 and below causes a race condition in the execSync() function through the use of single-threaded file creation within the global read/write temporary folders for Windows, RiscOS, Linux. A local unprivileged attacker can read and potentially write to files created in almost every known insecure temporary directory: C:\TEMP, C:\TMP, \TEMP, \TMP, /tmp, /var/tmp, /usr/tmp. An attacker can abuse the execSync function by read/writing to either the stdoutFile or codeFile, as well as execute arbitrary code if any scriptFile is created, and used as well as potential Denial of Service via the sleepFile lockfile.
Vendor Response
SAP Internal ID: SR-21-00474
Fixed in: https://github.com/SAP/mobilesdk-certificateprovider/commit/88af36beb7c8081f3713a6ad53d6396f6ec825ee
Proof of Concept
./iOS/X509KapselSample/platforms/ios/cordova/node_modules/shelljs/shell.js
Note this may also affect “KapselSDK”
Insecure filename generation (readable by all, potentially writable)
// e.g. 'shelljs_a5f185d0443ca...'
function randomFileName() {
function randomHash(count) {
if (count === 1)
return parseInt(16*Math.random(), 10).toString(16);
else {
var hash = '';
for (var i=0; i<count; i++)
hash += randomHash(1);
return hash;
}
}
return 'shelljs_'+randomHash(20);
}
Exploit is exactly explained below in the commented code below:
// Hack to run child_process.exec() synchronously (sync avoids callback hell)
// Uses a custom wait loop that checks for a flag file, created when the child process is done.
// (Can't do a wait loop that checks for internal Node variables/messages as
// Node is single-threaded; callbacks and other internal state changes are done in the
// event loop).
function execSync(cmd, opts) {
var stdoutFile = path.resolve(tempDir()+'/'+randomFileName()),
codeFile = path.resolve(tempDir()+'/'+randomFileName()),
scriptFile = path.resolve(tempDir()+'/'+randomFileName()),
sleepFile = path.resolve(tempDir()+'/'+randomFileName());
var options = extend({
silent: config.silent
}, opts);
Known exploitable directories:
// Cross-platform method for getting an available temporary directory.
// Follows the algorithm of Python's tempfile.tempdir
// http://docs.python.org/library/tempfile.html#tempfile.tempdir
function tempDir() {
if (state.tempDir)
return state.tempDir; // from cache
state.tempDir = writeableDir(process.env['TMPDIR']) ||
writeableDir(process.env['TEMP']) ||
writeableDir(process.env['TMP']) ||
writeableDir(process.env['Wimp$ScrapDir']) || // RiscOS
writeableDir('C:\\TEMP') || // Windows
writeableDir('C:\\TMP') || // Windows
writeableDir('\\TEMP') || // Windows
writeableDir('\\TMP') || // Windows
writeableDir('/tmp') ||
writeableDir('/var/tmp') ||
writeableDir('/usr/tmp') ||
writeableDir('.'); // last resort
return state.tempDir;
}
Disclosure Timeline
- 2021-04-13 – Researcher discover vulnerabilities
- 2021-06-08 – Vendor assigns CVE-2021-33669 & publishes advisory
- 2021-10-04 – Researcher publishes their advisory 3 months later, according to SAP rules
Links
https://github.com/SAP/mobilesdk-certificateprovider/security/advisories/GHSA-r2j9-h6q9-cq8g
https://github.com/SAP/mobilesdk-certificateprovider
https://github.com/sickcodes/security/blob/master/advisories/SICK-2021-032.md
https://sick.codes/sick-2021-032
Researchers
Sick Codes: https://github.com/sickcodes || https://twitter.com/sickcodes
CVE Links
https://sick.codes/sick-2021-032
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2021-33669