Skip to content
Andrew Bassett edited this page Jun 5, 2020 · 6 revisions

Welcome to the shellcode-tool wiki!

What is shellcode?
In the context of computer security, a shellcode is a small executable payload -- typically a string of hexadecimal digits -- that is used to exploit a vulnerable program or system.

How do you create a shellcode?
First, you'll need to either create or obtain an executable binary that can exploit a target vulnerability once compiled to shellcode and sent as a payload. In many cases, shellcodes are programmed in assembler or C as they will give you low-level access to your operating system and computer hardware, and greater control over what your shellcode will look like. Once you have a binary, you can use a program like objdump to extract the shellcode.

What does the shellcode.py script do?
Shellcode.py solves the problem of the time-consuming process of compiling a source code file, deconstructing the binary into a working shellcode, and testing it in a vulnerable program. Given a source assembly code file or executable binary, shellcode.py will compile, deconstruct, and automatically test your shellcode.

What are the limitations of the shellcode.py script?
Shellcode.py is intended for use on 32/64-bit Assembler code on x86 Linux Systems with Python 3 and gcc-multilib installed. Theoretically it may work on OSX, but it has not been tested there whatsoever. Future updates will include support for Windows and OSX.

Also important to note is that it is essential for a working shellcode to avoid two things:

  • Variables referenced by name: Since shellcode is sent in as a payload to a foreign program or system, the shellcode will have no way of knowing where a variable resides in the stack if referenced by name. However, recall that the 'call' instruction pushes the current address on the stack; this can be used to your advantage. Take a look at how the string "apbassett" is referenced in test/test-files/shellcode1.s. This is a good, simple example of the kind of relative memory addressing techniques you will need to employ.
  • Null bytes: When the compiler makes the conversion from assembler to machine code, certain opcodes and string variables may include null (0x00) hexadecimal digits. Since shellcode is often loaded into an exploitable string buffer, a null byte will act as a null-terminator, ending the execution of the shellcode. You'll want to employ strategies to prevent any null bytes from appearing in your shellcode: for example, if you need to set a register to 0, instead of executing mov $0x00, %eax you could do xor %eax, %eax as that will eliminate all 1 bits in the register, producing the same result. See test/test-files/shellcode4.s for an example. The other shellcode example programs are more simple in nature and do not follow this guideline.

The shellcode.py script currently does not evaluate the quality of the shellcode in this way, so it is up to the programmer to ensure their shellcode will work on a real program that is not designed to be exploited.

Use responsibly and enjoy!

Clone this wiki locally