-
-
Notifications
You must be signed in to change notification settings - Fork 267
CLI Reference
Inceptor provides mainly three main generators, each one with an independent set of parameters. Following the breakdown of all the parameters accepted by inceptor, with a brief explanation of how they are interpreted by the tool.
By default inceptor uses the cl.exe
Windows utility to build the final binary. Using this option, a user can force inceptor to use another compiler.
Currently implemented C/C++ compilers are:
- CL.EXE
- CLANG-CL.EXE
- CLANG-CL.EXE (LLVM)
By default, inceptor automatically chooses which transformer to utilise basing on a variety of factors. However, this behaviour can be overridden. This option forces inceptor to use a specific loader instead of the default one.
All the transformers will transform the input file into PIC shellcode, which can then be embedded into a shellcode injection template.
Inceptor executes the compiler with default arguments, which can be seen enabling the debug configuration compilers = 1
, in the config.ini
file.
As explained in the project main page, inceptor can tranform managed EXEs and DLLs into shellcode, but while a managed EXE can be transformed from its EntryPoint (let's say main()
), a DLL can have multiple namespaces and classes. In these cases, inceptor offers a way to specify which class will be used as EntryPoint during the shellcode conversion.
The class name can be specified in the format <namespace.class>.
As explained in the project main page, inceptor can tranform unmanaged EXEs and DLLs into shellcode, but while an EXE can be transformed from its EntryPoint (let's say main()
), a DLL can have multiple exported functions. In these cases, inceptor offers a way to specify which exported function will be used as EntryPoint during the shellcode conversion.
When converting a managed DLL, this option can be used to specify the method within the class to use as main EntryPoint.
Using this options, it is possible to provide the compiler with a definition file .def
, which can be used to list exported functions. This method is primarily used to avoid exported function name mangling.
As outlined in this whitepaper, inceptor can use both LD and LI encoders. This option will instruct inceptor to encode the shellcode using 1 or more LD encoders.
The encoders can be also chained together, like:
-e enc1 -e enc2 -e enc3
This will encode the shellcode with enc1, then with enc2, then with enc3.
This is the name of the final, output binary. Important note: the extension of the output file instructs inceptor to produce a specific type of binary:
-
.dll
extension will instruct inceptor to build an unmanaged DLL -
.exe
extension will instruct inceptor to build an unmanaged EXE
This option will instruct inceptor to load whatever module specified by MODULES. This option can be used multiple times to load multiple modules at once.
In the following example, both the Unhook and the Syscalls modules will be loaded.
python inceptor.py native -m unhook -m syscalls to_pack.raw -o packed.exe
It is possible to list all loadable modules, by executing:
python inceptor.py --list-modules
Currently, it is still not possible to check if a module is compatible with a generator. This feature is on the roadmap, of course.
If set, this flag instructs inceptor to use a process injection template.
This option will set the process image name to perform process injection against. Please be aware that this functionality is still implemented using CreateToolhelp32Snapshot
, hence is not fully compatible with direct syscalls invokation.
It is still possible to use it, even with the syscalls module loaded, but the functionality is not, by itself, implemented using syscalls.
This option sets the architecture of the final binary.
Setting this flag, the shellcode will be encoded using the Shikata-Ga-Nai encoder. The Shikata-Ga-Nai encoder is a polymorphic LI encoder, known to be hard to detect.
If set, this flag will instruct inceptor to sign the final binary using a technique among:
- CarbonCopy: Dump the SSL certificate from an online domain and sign the binary with it (requires an active internet connection)
- LazySign: Create a self-signed certificate using a given domain and use it to sign the binary
- SigThief: Dump the certificate (and other info) from a legitimately signed EXE/DLL, and copy the signature information to the binary
By default, inceptor uses CarbonCopy.
If set, this flag will instruct inceptor to sign the binary with LazySign
If set, this option will instruct inceptor to sign the binary stealing the signature information from the binary referenced by SIGN_STEAL.
In the following example, inceptor will copy the signature information from ntdll.dll
, and copy them in the final binary packed.dll
.
python inceptor.py native to_pack.exe -o packed.dll --sign --sign-steal C:\Windows\system32\ntdll.dll
By setting this option, inceptor will use the specified domain to generate/dump the Code Signing certificate.
If set, this flag will instruct inceptor to perform IR-based obfuscation. As the obfuscation for C/C++ binary is obtained by using LLVM during compilation, this is effectively a shortcut for -C llvm
.
This means this two command line are equivalent and will generate an obfuscated binary:
# Example 1: using compiler (-C) option
python inceptor -C llvm to_pack.raw -o packed.exe
# Example 2: using obfuscate (-O) flag
python inceptor -O to_pack.raw -o packed.exe
This is a very controversal flag, and has already been marked for removal as redundant.
If set, this flag will instruct inceptor to generate a wrapper DLL of a packed executable. The standard template used for DLL wrappers is the "write-and-execute", and consist in writing the packed.exe to disk and launch it as it was a normal EXE file.
To give a better example, imagine you are packing a Metasploit payload:
# msfvenom windows/x64/exec CMD="notepad.exe" -f raw -o to_pack.raw
python inceptor.py to_pack.raw -o packed.exe --dll
This command will generate two files:
-
packed.exe
: The packed binary -
packed.dll
: A 'drop & exec' DLL, which will writepacked.exe
into%TEMP%
and try to execute it viasystem()
There are several considerations to do before even thinking of building a payload like that, but the most important are:
- The DLL, once loaded by LoadLibrary or via rundll32, will write an EXE to disk
- The EXE will be then run via
system()
, so it will be likely blocked by AppLocker
If set, this option will instruct inceptor to clone metadata information from the binary referenced by the binary CLONE. This can help bypassing certain type of binary inspection.
If set, this option will instruct inceptor to add a delay of DELAY seconds before execution. Currently, this is implemented via a simple sleep()
statement.
If set, this flag will instruct inceptor to remove the starting console window when the executable is launched, using compiler flags.
By default inceptor uses the csc.exe
Windows utility to build the final binary. Using this option, a user can force inceptor to use another compiler (well, it could, if there was any other supported compiler).
Currently implemented C# compilers are:
- CSC.EXE
By default, inceptor automatically chooses which transformer to utilise basing on a variety of factors. However, this behaviour can be overridden. This option forces inceptor to use a specific loader instead of the default one.
All the transformers will transform the input file into PIC shellcode, which can then be embedded into a shellcode injection template.
Inceptor executes the compiler with default arguments, which can be seen enabling the debug configuration compilers = 1
, in the config.ini
file.
As explained in the project main page, inceptor can tranform managed EXEs and DLLs into shellcode, but while a managed EXE can be transformed from its EntryPoint (let's say main()
), a DLL can have multiple namespaces and classes. In these cases, inceptor offers a way to specify which class will be used as EntryPoint during the shellcode conversion.
The class name can be specified in the format <namespace.class>.
As explained in the project main page, inceptor can tranform unmanaged EXEs and DLLs into shellcode, but while an EXE can be transformed from its EntryPoint (let's say main()
), a DLL can have multiple exported functions. In these cases, inceptor offers a way to specify which exported function will be used as EntryPoint during the shellcode conversion.
When converting a managed DLL, this option can be used to specify the method within the class to use as main EntryPoint.
As outlined in this whitepaper, inceptor can use both LD and LI encoders. This option will instruct inceptor to encode the shellcode using 1 or more LD encoders.
The encoders can be also chained together, like:
-e enc1 -e enc2 -e enc3
This will encode the shellcode with enc1, then with enc2, then with enc3.
This is the name of the final, output binary. Important note: the extension of the output file instructs inceptor to produce a specific type of binary:
-
.dll
extension will instruct inceptor to build a managed DLL (usable as a service, Regsvr32.exe InstallUtil, MSSQL, etc.) -
.exe
extension will instruct inceptor to build a managed EXE
This option will instruct inceptor to load whatever module specified by MODULES. This option can be used multiple times to load multiple modules at once.
In the following example, both the DInvoke and the Syscalls modules will be loaded.
python inceptor.py dotnet -m dinvoke -m syscalls to_pack.raw -o packed.exe
It is possible to list all loadable modules, by executing:
python inceptor.py --list-modules
Currently, it is still not possible to check if a module is compatible with a generator. This feature is on the roadmap, of course.
If set, this flag instructs inceptor to use a process injection template.
This option will set the process image name to perform process injection against. Please be aware that this functionality is still implemented using System.Diagnostics.Process.GetProcessesByName
, hence is not fully compatible with direct syscalls invokation.
It is still possible to use it, even with the syscalls module loaded, but the functionality is not, by itself, implemented using syscalls.
This option sets the architecture of the final binary. The dotnet generator accept an apparently "strange" set of options, which can be summarised as below:
- x64: Compile for 64-bit architecture (expects 64-bits shellcode)
- x86: Compile for 32-bit architecture (expects 64-bits shellcode)
- anycpu: Compile for anycpu (guess on the shellcode)
- anycpu-x64: Compile for anycpu (expects 64-bits shellcode)
- anycpu-x86: Compile for anycpu (expects 32-bits shellcode)
The note "expects x-bits shellcode", implies that any utility architecture dependent (sgn, donut, etc..) will operate with support for x-bits architecture.
Setting this flag, the shellcode will be encoded using the Shikata-Ga-Nai encoder. The Shikata-Ga-Nai encoder is a polymorphic LI encoder, known to be hard to detect.
If set, this flag will instruct inceptor to sign the final binary using a technique among:
- CarbonCopy: Dump the SSL certificate from an online domain and sign the binary with it (requires an active internet connection)
- LazySign: Create a self-signed certificate using a given domain and use it to sign the binary
- SigThief: Dump the certificate (and other info) from a legitimately signed EXE/DLL, and copy the signature information to the binary
By default, inceptor uses CarbonCopy.
If set, this flag will instruct inceptor to sign the binary with LazySign
If set, this option will instruct inceptor to sign the binary stealing the signature information from the binary referenced by SIGN_STEAL.
In the following example, inceptor will copy the signature information from ntdll.dll
, and copy them in the final binary packed.dll
.
python inceptor.py dotnet to_pack.exe -o packed.dll --sign --sign-steal C:\Windows\system32\ntdll.dll
By setting this option, inceptor will use the specified domain to generate/dump the Code Signing certificate.
If set, this flag will instruct inceptor to perform IR-based obfuscation. As the obfuscation for C/C++ binary is obtained by using several external utilities, inceptor will also ask to the user which one has to be used.
Currently, three external utilities are used for obfuscation:
- ConfuserEx
- AsStrongAsFuck
- LoGIC.NET
If set, this option will instruct inceptor to clone metadata information from the binary referenced by the binary CLONE. For managed binaries, this process is dual:
- An
AssemblyInfo.cs
is generated from the VersionInfo of another binary, and it's used to compile the C# binary - All resouces (including icons) are then copied using ResourceHacker
If set, this option will instruct inceptor to add a delay of DELAY seconds before execution. Currently, this is implemented via a simple Sleep()
statement.
If set, this flag will instruct inceptor to remove the starting console window when the executable is launched, using compiler flags.
By default, inceptor automatically chooses which transformer to utilise basing on a variety of factors. However, this behaviour can be overridden. This option forces inceptor to use a specific loader instead of the default one.
All the transformers will transform the input file into PIC shellcode, which can then be embedded into a shellcode injection template.
As explained in the project main page, inceptor can tranform managed EXEs and DLLs into shellcode, but while a managed EXE can be transformed from its EntryPoint (let's say main()
), a DLL can have multiple namespaces and classes. In these cases, inceptor offers a way to specify which class will be used as EntryPoint during the shellcode conversion.
The class name can be specified in the format <namespace.class>.
As explained in the project main page, inceptor can tranform unmanaged EXEs and DLLs into shellcode, but while an EXE can be transformed from its EntryPoint (let's say main()
), a DLL can have multiple exported functions. In these cases, inceptor offers a way to specify which exported function will be used as EntryPoint during the shellcode conversion.
When converting a managed DLL, this option can be used to specify the method within the class to use as main EntryPoint.
As outlined in this whitepaper, inceptor can use both LD and LI encoders. This option will instruct inceptor to encode the shellcode using 1 or more LD encoders.
The encoders can be also chained together, like:
-e enc1 -e enc2 -e enc3
This will encode the shellcode with enc1, then with enc2, then with enc3.
This is the name of the final, output PowerShell script.
This option will instruct inceptor to load whatever module specified by MODULES. This option can be used multiple times to load multiple modules at once.
In the following example, the AMSI bypass module will be loaded.
python inceptor.py powershell -m amsi to_pack.raw -o packed.ps1
It is possible to list all loadable modules, by executing:
python inceptor.py --list-modules
Currently, it is still not possible to check if a module is compatible with a generator. This feature is on the roadmap, of course.
If set, this flag instructs inceptor to use a process injection template.
This option will set the process image name to perform process injection against.
This option sets the architecture of the shellcode/EXE/DLL used, and it's mainly used to instruct any utility architecture dependent (sgn, donut, etc..) to operate with support for x-bits architecture.
Setting this flag, the shellcode will be encoded using the Shikata-Ga-Nai encoder. The Shikata-Ga-Nai encoder is a polymorphic LI encoder, known to be hard to detect.
If set, this flag will instruct inceptor to perform code-based obfuscation using chameleon.
If set, this option will instruct inceptor to add a delay of DELAY seconds before execution. Currently, this is implemented via a simple Sleep()
statement.