Shellcoding by gjjur4356




                                   What is Shellcode?

   What is shellcode?
       Shellcode is any code that does what you want once
        you've bypassed a system's perimeter defenses
       The first shellcode tried to open a shell, which explains
        the origin of the name
       Today, shellcode can do many different things, e.g.:
            Download and execute arbitrary programs
            Install backdoors, trojans, rootkits
            Conduct a DoS attack on the system
            Attempt privilege escalation


   Assembly language primer
   Tools
   Basic shellcode walkthrough
   Creating an exploit skeleton
   Removing bad characters
   Encoding
   setuid(0)
   Reverse bind shell
   Other types of shellcode
   Shellcoding resources
   Detection and prevention

                                    Assembly Primer

   First, why do we use assembly language, not C?
       Compilers add a lot of plumbing code (w/ large binaries)
       There are often several ways to do the same thing
            Some ways avoid bad characters
            Some ways have less bytes of code
       We can hand (space) optimize the code
       Assembly language is cool

                                      Assembly Primer

   System calls:
       0-5 arguments:
            Arguments go in ebx, ecx, edx, esi, edi
            eax is used to select which system call to execute
       6+ arguments:
            Arguments go onto the stack
            eax is used to select which system call to execute
       Socket-related
            Arguments go on the stack
            eax = 0x66
            ebx is used to select which socket function

                               Assembly Primer

   Intel vs. AT&T syntax
       push eax         =>    push %eax
       push 0x1         =>    push $0x80
       mov eax, ebx     =>    mov %ebx, %eax
       push byte ptr 0x1 =>   pushb 0x1


   A regular text editor
       Used to edit the assembly source file
   gdb
       Used to disassemble the code
       Used to find addresses of instructions and/or data
       Used to debug your shellcode
       Used to examine memory/register contents
   objdump
       Used to disassemble the code, and check for bad

                                     Basic Shellcode

   execve("/bin/sh", ["/bin/sh",0], 0);
        Push a null-terminator onto the stack
        Push /bin/sh onto the stack
        Save the top of the stack in a register (string pointer)
        Push a null-terminator onto the stack
        Push the string pointer onto the stack
        Save the top of the stack in a register (args pointer)
        Setup the eax register to make the execve syscall
        Call the interrupt to execute the system call

                             Exploit Skeleton

char shellCode[] = "\x31\xc0\xb0\x0b\x52...";

int main() {
   void (*runShellcode)(void) = (void *)shellCode;

                         Removing Bad Chars

   Arguably, the most difficult byte to remove is 0
       0 is a null-terminator, a common value
   You remove all bad characters in the same way:
       Write the code as normal
       Compile
       Search the hex codes for bad characters
       Find the assembly language corresponding to that char
       Use alternative code that has the same effect instead

                       Removing Bad Chars

   Removing 0s (NULLs):
       mov eax, 0    =>   xor eax, eax
       mov eax, 1    =>   xor eax, eax; mov al, 1
       0x71000001    =>   not 0x8EFFFFFE
       /bin/sh\0     =>   /bin/shZ


   Most encoders use the following axioms to reversibly
    encode assembly language code:
       ((A + B) – B) = A
       ((A XOR B) XOR B) = A
   The code of the program itself is treated like data and
    modified in memory


   An advanced form of encoding is an alphanumeric
       These encoders bypass most validation functions and
        IDSs, since the resulting code is all alphanumeric ASCII


   The setuid() function changes the effective user ID
    (UID) of the process
       UID=0 is that of the superuser, root
   Some process (e.g. Apache) will use setuid() to drop
    to normal user permissions once they perform
    whatever needed root privileges
       Setuid(0) can get those root privileges back

                           Reverse Bind Shell

   Create a socket: socketId = socket(...)
   Create an address struct (destination IP, port)
   Connect to that address/port: connect(socketId, addr)
   Redirect standard input, output and error to the socket
   Execute /bin/sh

                                    More Examples

   Add user
       Write a new line to /etc/passwd
   Download and exec
       Read data from socket and write it to the file, & exec
   Stop IDS
       Run a command, e.g. /etc/init.d/snort stop
   Open firewall
       Run a command, e.g. iptables -F INPUT
   Denial of service
       Fork bomb


   Milworm has a very large collection of shellcode
    examples for several different platforms
   The Metasploit framework has a decent collection of
    shellcode also
       MSF also has generic encoders
   Unfortunately, many of these examples are presented
    in exploit skeleton format
       These can be easily disassembled using the following
    cc shellcode.c ­o shellcode
    objdump ­d shellcode

                      Detection & Prevention

   To detect shellcode:
       Look for shellcode signatures
       Look for system calls (false positives)
       Look for encoder signatures
   To prevent shellcode:
       Use setuid() sparingly
       Run as normal users with no shell privileges
       Run remote services in chroot jails
       Enable stack protectors/randomizers
       Seal up the vulnerabilities themselves

To top