Skip to content

CLI Reference

klezVirus edited this page Sep 21, 2021 · 3 revisions

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.

Native

-C COMPILER, --compiler COMPILER

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)

-t TRASFORMER, --transformer TRASFORMER

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.

-a COMPILER_ARGS, --compiler-args COMPILER_ARGS

Inceptor executes the compiler with default arguments, which can be seen enabling the debug configuration compilers = 1, in the config.ini file.

--classname CLASSNAME

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>.

--function FUNCTION

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.

--exports EXPORTS

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.

-e ENCODER, --encoder ENCODER

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.

-o OUTFILE, --outfile OUTFILE

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

-m MODULES, --modules MODULES

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.

-P, --pinject

If set, this flag instructs inceptor to use a process injection template.

-P0 PROCESS, --process PROCESS

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.

--arch {x86,x64}

This option sets the architecture of the final binary.

--sgn

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.

-s, --sign

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.

-so, --sign-offline

If set, this flag will instruct inceptor to sign the binary with LazySign

-ss SIGN_STEAL, --sign-steal SIGN_STEAL

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

-sd SIGN_DOMAIN, --sign-domain SIGN_DOMAIN

By setting this option, inceptor will use the specified domain to generate/dump the Code Signing certificate.

-O, --obfuscate

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

--dll

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:

  1. packed.exe: The packed binary
  2. packed.dll: A 'drop & exec' DLL, which will write packed.exe into %TEMP% and try to execute it via system()

There are several considerations to do before even thinking of building a payload like that, but the most important are:

  1. The DLL, once loaded by LoadLibrary or via rundll32, will write an EXE to disk
  2. The EXE will be then run via system(), so it will be likely blocked by AppLocker

--clone CLONE

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.

--delay DELAY

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.

-hw, --hide-window

If set, this flag will instruct inceptor to remove the starting console window when the executable is launched, using compiler flags.

Dotnet

-C COMPILER, --compiler COMPILER

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

-t TRASFORMER, --transformer TRASFORMER

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.

-a COMPILER_ARGS, --compiler-args COMPILER_ARGS

Inceptor executes the compiler with default arguments, which can be seen enabling the debug configuration compilers = 1, in the config.ini file.

--classname CLASSNAME

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>.

--function FUNCTION

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.

-e ENCODER, --encoder ENCODER

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.

-o OUTFILE, --outfile OUTFILE

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

-m MODULES, --modules MODULES

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.

-P, --pinject

If set, this flag instructs inceptor to use a process injection template.

-P0 PROCESS, --process PROCESS

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.

--arch {x86,x64,anycpu,anycpu-x86,anycpu-x64}

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.

--sgn

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.

-s, --sign

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.

-so, --sign-offline

If set, this flag will instruct inceptor to sign the binary with LazySign

-ss SIGN_STEAL, --sign-steal SIGN_STEAL

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

-sd SIGN_DOMAIN, --sign-domain SIGN_DOMAIN

By setting this option, inceptor will use the specified domain to generate/dump the Code Signing certificate.

-O, --obfuscate

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

--clone CLONE

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:

  1. An AssemblyInfo.cs is generated from the VersionInfo of another binary, and it's used to compile the C# binary
  2. All resouces (including icons) are then copied using ResourceHacker

--delay DELAY

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.

-hw, --hide-window

If set, this flag will instruct inceptor to remove the starting console window when the executable is launched, using compiler flags.

PowerShell

-t TRASFORMER, --transformer TRASFORMER

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.

--classname CLASSNAME

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>.

--function FUNCTION

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.

-e ENCODER, --encoder ENCODER

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.

-o OUTFILE, --outfile OUTFILE

This is the name of the final, output PowerShell script.

-m MODULES, --modules MODULES

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.

-P, --pinject

If set, this flag instructs inceptor to use a process injection template.

-P0 PROCESS, --process PROCESS

This option will set the process image name to perform process injection against.

--arch {x86,x64}

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.

--sgn

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.

-O, --obfuscate

If set, this flag will instruct inceptor to perform code-based obfuscation using chameleon.

--delay DELAY

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.