Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,52 @@

## What is this repo?

This repo allows you to concatenate shellcodes, running from different address spaces and links between them.
Each shellcode will ensure the next will run, and will constitute from various primitives.
Allows you to write PIC and fast shellcodes in C! keeping your logic simple, easy to expand, test and maintain.
Shellcodes are seperated to "primitives", each one provides a behavior, and to create a full grown shellcode you can concatenate multiple primitives, or to create one primtives doing all of your logic.

For starters, we will only support MIPS (le/be).
Supported architectures:

- X86 and X64
- Mips (LE and BE)
- Arm 32bit

Adding another architecture is very simple!

## What does this mean?

For example, see our implementation of goto:

```c
void start(void) {
void (*goto_address)() = (void (*)())(GOTO_ADDRESS);

goto_address();
}
```

Our implementation of memcpy:

```c
void __attribute__((noreturn)) start(void) {
u8 *src = (u8 *)MEMCPY_SOURCE_ADDRESS;
u8 *dst = (u8 *)MEMCPY_DEST_ADDRESS;
u32 len = (u32)MEMCPY_LEN;

u8 *end = src + len;

while (src < end - 1) {
*dst = *src;
src++;
dst++;
}

*dst = *src;

__builtin_unreachable();
}
```

Super easy and to write even more complex code!

## Shellcode primitives

Expand All @@ -23,7 +65,6 @@ A final "Shellcode Structure" example:
```python
first_step = ShellcodeStep(
"first_step",
0xbfc00000,
[
ShellcodePrimitiveMemcpy("copy_next_stage", 0x80abcdef, 0x8f0ed0b0, 0x100),
ShellcodePrimitivePrint("print_debug", 0x80901234, "This is a print!\n"),
Expand Down
4 changes: 2 additions & 2 deletions shellblocks/primitives/jump_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ def __init__(self, nickname: str, hook_address: int, goto_address: int):
def generate(self, path: Path, compiler: CompilerArch):
step = ShellcodeStep(
self.nickname,
0x0, # This should be PIC
[
ShellcodePrimitiveGoto(
self.nickname,
self.goto_address
),
],
0x1000
0x1000,
base_address=0x0, # This should be PIC
)

out_file = step.generate(path / self.nickname / "goto_temp", compiler)
Expand Down
8 changes: 7 additions & 1 deletion shellblocks/shellcode_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@


class ShellcodeStep:
def __init__(self, nickname: str, base_address: int, primitives: [ShellcodePrimitive], max_len: int):
def __init__(
self,
nickname: str,
primitives: [ShellcodePrimitive],
max_len: int,
base_address: int = 0
):
self.nickname = nickname
self.base_address = base_address
self.primitives = primitives
Expand Down
8 changes: 4 additions & 4 deletions tests/test_goto.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ def test_goto_sanity(get_mu, temp_dir_path, arch_helper, compiler_arch, goto_pag

step = ShellcodeStep(
"first_step",
shellcode_address,
[
ShellcodePrimitiveGoto("copy_next_stage", goto_address),
],
0x1000
0x1000,
base_address=shellcode_address,
)

out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
Expand Down Expand Up @@ -64,11 +64,11 @@ def test_goto_is_pic(get_mu, temp_dir_path, arch_helper, compiler_arch, shellcod

step = ShellcodeStep(
"first_step",
shellcode_address,
[
ShellcodePrimitiveGoto("copy_next_stage", goto_address),
],
0x1000
0x1000,
base_address=shellcode_address,
)

out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
Expand Down
12 changes: 6 additions & 6 deletions tests/test_jump_hook.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ def generate_memset_to_goto(temp_dir_path,

step = ShellcodeStep(
"first_step",
shellcode_address,
[
expected_goto_primitive,
],
0x1000
0x1000,
base_address=shellcode_address,
)

out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
Expand All @@ -39,11 +39,11 @@ def generate_memset_to_goto(temp_dir_path,

step = ShellcodeStep(
"first_step",
shellcode_address,
[
expected_memset_primitive,
],
0x1000
0x1000,
base_address=shellcode_address,
)

out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
Expand Down Expand Up @@ -95,11 +95,11 @@ def test_jump_hook_sanity(

step = ShellcodeStep(
"first_step",
shellcode_address,
[
jump_hook_pritimive,
],
0x1000
0x1000,
base_address=shellcode_address
)

out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_memcpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ def memcpy_get_shellcode(temp_dir_path, compiler_arch, memcpy_helper, copy_len):

step = ShellcodeStep(
"first_step",
helper.shellcode_address,
[
ShellcodePrimitiveMemcpy(
"copy_next_stage",
Expand All @@ -54,7 +53,8 @@ def memcpy_get_shellcode(temp_dir_path, compiler_arch, memcpy_helper, copy_len):
copy_len
),
],
0x1000
0x1000,
base_address=helper.shellcode_address,
)

out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_memset.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,15 +53,15 @@ def memset_get_shellcode(temp_dir_path, compiler_arch, memset_helper, copy_bytes

step = ShellcodeStep(
"first_step",
helper.shellcode_address,
[
ShellcodePrimitiveMemset(
"copy_next_stage",
helper.copy_addr,
copy_bytes
),
],
0x1000 * len(copy_bytes)
0x1000 * len(copy_bytes),
base_address=helper.shellcode_address
)

out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_print.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ def print_shellcode(compiler_arch, temp_dir_path, print_function_addr, string_to

step = ShellcodeStep(
"first_step",
shellcode_address,
[
ShellcodePrimitivePrint("print_stuff", print_function_addr, string_to_print),
],
0x1000
0x1000,
base_address=shellcode_address,
)

out_file = step.generate(temp_dir_path / step.nickname, compiler_arch)
Expand Down
4 changes: 2 additions & 2 deletions tests/test_step.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
def test_step_too_large_fails(temp_dir_path):
step = ShellcodeStep(
"first_step",
0x1000,
[
ShellcodePrimitiveMemcpy(
f"copy_next_stage{i}",
Expand All @@ -17,7 +16,8 @@ def test_step_too_large_fails(temp_dir_path):
)
for i in range(6)
],
0x10
0x10,
base_address=0x1000,
)

with pytest.raises(Exception):
Expand Down