wp_hub
Checking for sudo privileges of the wp_hub
user after performing a manual system enumeration
wp_hub@wallpaperhub:~$ sudo -l
Matching Defaults entries for wp_hub on wallpaperhub:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, use_pty,
!env_reset
User wp_hub may run the following commands on wallpaperhub:
(root) NOPASSWD: /usr/bin/web-scraper /root/web_src_downloaded/*.html
The wp_hub
user is able to execute the /usr/bin/web-scraper /root/web_src_downloaded/*.html
command as the root
account without getting prompted for password
web-scraper
wp_hub@wallpaperhub:/$ sudo -u root /usr/bin/web-scraper /root/web_src_downloaded/*.html
Error reading file /root/web_src_downloaded/*.html: [Error: ENOENT: no such file or directory, open '/root/web_src_downloaded/*.html'] {
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/root/web_src_downloaded/*.html'
}
Executing the command returns an error that no such file or directory for; /root/web_src_downloaded/*.html
Additionally, it seems to perform a syscall; open
wp_hub@wallpaperhub:/$ ll /usr/bin/web-scraper
lrwxrwxrwx 1 root root 23 Feb 11 10:11 /usr/bin/web-scraper -> /opt/scraper/scraper.js*
Checking the executable, /usr/bin/web-scraper
, reveals that it’s just a symlink to a JavaScript file; /opt/scraper/scraper.js
/opt/scraper/scraper.js
wp_hub@wallpaperhub:/$ ll /opt/scraper/scraper.js
-rwxr-xr-x 1 root root 1659 Feb 11 10:11 /opt/scraper/scraper.js*
wp_hub@wallpaperhub:/$ cat /opt/scraper/scraper.js
#!/usr/bin/env node
const fs = require('fs');
const { Window } = require("happy-dom");
// Check if a file path is provided as a command-line argument
const filePath = process.argv[2];
if (!filePath) {
console.error('Please provide a file path as an argument.');
process.exit(1);
}
const window = new Window();
const document = window.document;
// Read the content of the provided file path
fs.readFile(filePath, 'utf-8', (err, data) => {
if (err) {
console.error(`Error reading file ${filePath}:`, err);
return;
}
// Use document.write() to add the content to the document
document.write(data);
// Log all external imports (scripts, stylesheets, meta tags)
const links = document.querySelectorAll('link');
const scripts = document.querySelectorAll('script');
const metaTags = document.querySelectorAll('meta');
console.log('----------------------------');
// Output the links (CSS imports)
console.log('CSS Links:');
links.forEach(link => {
console.log(link.href);
});
console.log('----------------------------');
// Output the scripts (JS imports)
console.log('JavaScript Links:');
scripts.forEach(script => {
if (script.src) {
console.log(script.src);
} else {
console.log('Inline script found.');
}
});
console.log('----------------------------');
// Output the meta tags (for metadata)
console.log('Meta Tags:');
metaTags.forEach(meta => {
console.log(`Name: ${meta.name}, Content: ${meta.content}`);
});
console.log('----------------------------');
});
The /opt/scraper/scraper.js
file is a simple NodeJS application that takes a file as an argument to scrape its data, such as CSS/JS import links and metadata
Interesting thing is that it uses the happy-dom module to open up a new window. This must be what the earlier syscall was
happy-dom
wp_hub@wallpaperhub:/opt$ ll
total 12
drwxr-xr-x 3 root root 4096 Feb 11 10:11 ./
drwxr-xr-x 23 root root 4096 Nov 7 00:33 ../
drwxr-xr-x 3 root root 4096 Feb 11 10:11 scraper/
wp_hub@wallpaperhub:/opt$ cd scraper/ ; ll
total 24
drwxr-xr-x 3 root root 4096 Feb 11 10:11 ./
drwxr-xr-x 3 root root 4096 Feb 11 10:11 ../
drwxr-xr-x 6 root root 4096 Feb 11 10:11 node_modules/
-rw-r--r-- 1 root root 273 Feb 11 10:11 package.json
-rw-r--r-- 1 root root 1794 Feb 11 10:11 package-lock.json
-rwxr-xr-x 1 root root 1659 Feb 11 10:11 scraper.js*
wp_hub@wallpaperhub:/opt/scraper$ cat package.json
{
"name": "scraper",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"happy-dom": "^15.9.0"
}
}
It uses happy-dom 15.9.0
Vulnerabilities
Checking
happy-dom 15.9.0
online for vulnerabilities reveals a code injection vulnerability; CVE-2024-51757
Given that the sudo command contains a wildcard bit(*
), the first argument to the /opt/scraper/scraper.js
file can be controlled
Moving on to the Privilege Escalation phase