0xBAADF00D

Follow the heap memory...

VM en Bridge Avec VMware ESX Chez OVH

Il est intéressant de vouloir affecter une IP publique à une de vos machines virtuelles tournantes sur votre VMware ESX flambant neuf. Puisqu’ ESX ne propose pas de NAT (allez savoir pourquoi chez VMware les produit payant ont moins de fonctionnalité que les gratuits), créer une “appliance” qui aura pour seul but de fournir de l’internet à toutes les autres n’est pas idiot. Voyons comment procéder pour que votre machine virtuelle puisse dialoguer avec le monde.

De base chez OVH, vous aurez droit à 3 IP de type “Fail-Over” gratuitement que vous pouvez utiliser. Il est également possible d’acheter des blocs d’IP RIPE, mais il faut passer en abonnement pro (15 euros/mois). Pour cette partie je vous laisse procéder comme vous le souhaitez.

Une fois que vous avez pris possession de vos IP, rendez-vous dans la section “MAC virtuelle pour VPS” qui se trouve dans la catégorie “Services”. Le but est de demander à OVH de vous générer des adresses MAC compatible VMware pour chacune de vos IP publiques que vous souhaitez attribuer à vos machines virtuelles. Si vous avez plusieurs MAC à générer, prenez votre mal en patience car OVH impose une attente de 5 minutes entre chaque génération.

A ce stade, vous avez donc XX couple(s) MAC virtuelle ? IP publique. Rendez-vous dans le client vSphere puis :

  1. Choisissez “Editer la configuration” sur la machine virtuelle qui va recevoir une IP Publique.
  2. Editez la carte réseau puis attribuez-lui l’adresse MAC virtuelle fournie par OVH.
  3. Lancez votre VM

Sous Linux, éditez le fichier /etc/network/interfaces pour modifier la configuration :

1
2
3
4
5
6
7
iface eth0 inet static
        address xxx.xxx.xxx.16
        netmask 255.255.255.0
        network xxx.xxx.xxx.0
        broadcast xxx.xxx.xxx.255
        gateway xxx.xxx.xxx.254
        dns-nameservers 213.186.33.99

Dans le cas des IP RIPE, OVH vous indiquera les informations à mettre à l’exception du serveur DNS, vous pouvez utiliser celui de Google (8.8.8.8).

Redémarrez votre service réseau et vous devriez avoir accès à internet et votre VM est maintenant accessible depuis l’extérieur !

Convertir Un Entier en Char* Avec Des Macros

Quoi de plus rageant que de se retrouver avec un entier quand on à besoin d’une chaine de caractères? Et c’est encore plus vrai quand il s’agit d’un define qui est utiliser pour des fichiers .log.

Heureusement, les macros peuvent vous éviter une conversion lourde. Dans notre cas, il s’agit du préprocesseur __LINE__ qui indique le numéro de la ligne actuelle dans le fichier source, bref, exactement le type de valeur utile dans un fichier .log en cas de crash. Malheureusement, celle-ci est sous forme d’entier… Mais pas pour longtemps :

1
2
3
4
#define CONVSTR(x) #x
#define STRING(x)  CONVSTR(x)

#define WHERE_I_AM   __FILE__":"STRING(__LINE__)

Et voilà! Fini le méchant petit entier…

Cacher Des Processus Sous Windows

L’un de derniers projets réalisé l’année dernière concerne un élément important de la sécurité informatique : les Root-Kit ! Durant ce projet, nous avons vu comment mettre en place un root-kit sous Windows affin que celui-ci masque la présence de processus dans l’arborescence des processus lancés (tasklist) en utilisant la méthode DKOM (Direct Kernel Object Manipulation).

Pour ce faire, la première chose à réaliser est de télécharger les outils nécessaires WinDDK (http://msdn.microsoft.com/fr-fr/windows/hardware/gg487428/) et un bon éditeur de texte pour coder. Maintenant que vous avez les outils adéquats, place à la théorie !

Squelette du driver

Au final notre root-kit sera un magnifique driver (fichier .sys) avec lequel on dialoguera via IOCTL. Pourquoi un driver? Tout simplement car le driver n’est pas assujetti aux règles de sécurité une fois qu’il est exécuté : il pourra allez et venir comme il le souhaite dans des processus qui ne sont pas à lui. Bien, le template d’un tel projet et relativement simple, il est composé d’un fichier SOURCES (équivalent du Makefile Linux) et d’au moins 1 fichier .c.

Voici un exemple de fichier SOURCES utilisé par le projet :

SOURCES
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
TARGETNAME=DEADLANDS
TARGETPATH=OBJ
TARGETTYPE=DRIVER
SOURCES=deadlands_driver.c \
          deadlands_dkom.c

!if ($(_NT_TARGET_VERSION) == $(_NT_TARGET_VERSION_WINXP))
C_DEFINES=$(C_DEFINES) -D_NT_TARGET_VERSION_WINXP=1
!            message BUILDMSG: CHECK: _NT_TARGET_VERSION=$(_NT_TARGET_VERSION) -> XP
!else if ($(_NT_TARGET_VERSION) == $(_NT_TARGET_VERSION_VISTA))
C_DEFINES=$(C_DEFINES) -D_NT_TARGET_VERSION_VISTA=1
!            message BUILDMSG: CHECK: _NT_TARGET_VERSION=$(_NT_TARGET_VERSION) -> VISTA
!else if ($(_NT_TARGET_VERSION) == $(_NT_TARGET_VERSION_LONGHORN))
C_DEFINES=$(C_DEFINES) -D_NT_TARGET_VERSION_VISTA=1
!            message BUILDMSG: CHECK: _NT_TARGET_VERSION=$(_NT_TARGET_VERSION) -> LONGHORN
!else if ($(_NT_TARGET_VERSION) == $(_NT_TARGET_VERSION_WIN7))
C_DEFINES=$(C_DEFINES) -D_NT_TARGET_VERSION_SEVEN=1
!            message BUILDMSG: CHECK: _NT_TARGET_VERSION=$(_NT_TARGET_VERSION) -> SEVEN
!endif

Et maintenant, voilà à quoi ressemble le fichier driver.c de base :

driver.c
1
2
3
4
5
6
#include "ntddk.h"

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
{
  return (STATUS_SUCCESS);
}

Voilà, maintenant, il reste plus qu’à définir quelques fonction de votre driver histoire qu’il soit “compliant” avec l’OS (si le driver n’implémente pas un minimum de fonctions (Major Function), il risque de crasher/freezer votre machine à son chargement). Parmi ces fonctions obligatoires, on trouve Read/Write/Open et Close.

Structures des processus dans la mémoire

En Kernel Land, il est possible d’obtenir la liste des processus lancés depuis n’importe qu’elle application (Ben oui, on a tous les droits xD). Donc autant le faire simple, on va demander son propre processus avec la fonction :

1
PEPROCESS IoGetCurrentProcess(void);

Comme le montre ce diagramme, EPROCESS contient un élément nommé LIST_ENTRY qui donne accès à une liste doublement chainées qui permet de se promener de processus en processus et donc de pouvoir rechercher le processus que l’on souhaite masquer. Pour effectuer se masquage, il suffit de le retirer de la liste doublement chainée.

Attention : Vous vous apercevrez très rapidement que suivant l’OS sur lequel vous êtes, les offsets pour passer de l’EPROCESS à la LIST_ENTRY changent. Vous pourrez les retrouver en utilisant WinDBG.

Pour finir

Par manque de temps, je n’ai pas encore implémenté le spinlock pour éviter des petits soucis quand mon driver modifie cette liste de processus.

Si vous souhaitez tester ce projet, rendez-vous sur la page GitHub suivante : http://0xbaadf00d.github.com/deadlands-windows-dkom/

Installer Django Sous Windows

Avant de commencer quoi que ce soit, il vous faudra récupérer PyWin (http://sourceforge.net/projects/pywin32/files/pywin32/). PyWin est un package qui s’occupe d’installer toutes les extensions nécessaires. Faites attentions à prendre le package qui correspond à votre version de Python.

Pour connaitre la version que vous possédez, rendez vous dans votre explorer de fichiers et regarder le répertoire nommé PythonXX (XX représente la version)

Une fois PyWin téléchargé puis installé, ajoutez les répertoires suivants, s’ils n’y sont pas déjà, dans votre variable d’environnement PATH.

1
2
C:\Python27\
C:\Python27\Scripts

A ce point là, votre installation de Python est prête. Il ne vous reste plus qu’a installer l’outil easy_install. Pour ce faire, téléchargez le fichier setuptools-0.6c11.win32-pyX.Y.exe (http://pypi.python.org/pypi/setuptools#files) puis installez le.

Ouvrez une invite de commandes puis tapez la commandes suivantes :

1
2
C:\>  easy_install virtualenv
C:\>  easy_install django
1
2
C:\> django-admin.py --version
1.4

Bravo, vous venez d’installer avec succès Django sur Windows. Vous allez pouvoir commencer à construire votre site web avec sérénité.

Optimisez Votre Serveur Avec Php-apc

Aujourd’hui, nous allons voir comment gagner environ 45% de performance en plus sur votre serveur utilisant PHP (constaté avec l’outil AB). Pour cela, nous utiliserons l’extension PHP nommée APC.

Pour commencer, faisons une petite présentation: Le “Alternative PHP Cache” (APC) est un cache d’opcode pour PHP. Son objectif est de fournir un framework libre, ouvert et robuste pour la mise en cache et l’optimisation de code intermédiaire PHP. Pour installer cette extension, vous aurez besoin de PECL et du package de développement PHP.

1
root@0xbaadf00d> apt-get install php5-dev php-pear dh-make-php

maintenant, que vous avez le minimum vitale, installons l’extension:

1
root@0xbaadf00d> pecl install apc

Lors du processus de configuration, APC vous posera plusieurs questions, vous pouvez si vous le souhaitez les réponses par défaut. Une fois l’installation terminée, éditez votre fichier php.ini et ajoutez la ligne suivante :

1
extension = apc.so

Redémarrez PHP (ou apache si vous utilisez encore cette m….). Si vous souhaitez monitorer ou videz le cache APC, vous pouvez le faire en utilisant le script apc.php qui se trouve dans le répertoire /usr/share/php/. Il faut juste pensez à l’éditer pour modifier les lignes suivantes :

1
2
defaults('ADMIN_USERNAME', 'corvus');
defaults('ADMIN_PASSWORD', 'my_fkg_secret_password');

Et voilà, votre serveur va beaucoup mieux se porter maintenant.

Vérifier Le Numéro D’une Carte Bancaire

Avant de soumettre un numéro de carte bancaire (qu’un client aurait saisi sur votre boutique en ligne par exemple) à votre institution bancaire, il serait judicieux vérifier la véracité des informations. Il est possible de faire cette vérification simplement en analysant les numéros de la-dites carte bancaire.

Ce simple numéro permet d’obtenir facilement :
  • Le MII (Major Industry Identifier) qui représente la catégorie dans laquelle se trouve le fournisseur de la carte.
  • L’IIN (Issuer Identification Number) qui permet d’identifier l’institution qui a émise la carte.
La majorité des cartes bancaires (AMEX, VISA, MASTER CARD, …) utilisent l’algorithme de Luhn pour vérifier la validé du numéro de la carte. Pour reprendre Wikipedia : L’algorithme de Luhn ou la formule de Luhn, aussi connu comme l’algorithme “modulo 10”, fut développé dans les années 1960 comme une méthode de validation d’identification de nombres. C’est une simple formule de somme de contrôle (Checksum) utilisée pour valider une variété de numéros de comptes, comme les numéros de cartes bancaires, les numéros d’assurance sociale canadiens ainsi que pour le calcul de validité d’un numéro SIRET (Wikipedia.com).

Bien, maintenant que les présentations sont faites, passons à la partie programmation. Nous allons développez un script qui vérifie la validité du numéro de la carte :

Check Card Bank Number (check_bank_card.rb) download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/env ruby
##

#Check nb param
abort "Usage: #{$0} number" unless  ARGV.length > 0

#Check is numeric
card_num = ARGV[0].gsub ' ', ''
if /^[\d]+(\.[\d]+){0,1}$/.match card_num
  puts "Card Number: #{card_num}"

  #Get Card Type - http://en.wikipedia.org/wiki/Bank_card_number
  CARD_TYPE = [
               {:name => 'AMERICAN EXPRESS', :regex => /^3[4|7][0-9]{13}$/},
               {:name => 'VISA', :regex => /^4[0-9]{12}$|^4[0-9]{15}$/},
               {:name => 'MASTER CARD', :regex => /^5[1-5][0-9]{14}$/},
               {:name => 'UNKNOWN', :regex => /(.*)/}
              ]
  CARD_TYPE.each do |t|
    puts "Card Type  : #{t[:name]}" or break if t[:regex].match card_num
  end

  #Check Card Number - http://en.wikipedia.org/wiki/Luhn
  index = 1
  checksum = 0
  card_num.reverse.each_char do |c|
    if index % 2 == 0
      c = (c.to_i * 2)
      c.to_s.each_char {|n| checksum += n.to_i}
    else
      checksum += c.to_i
    end
    index += 1
  end
  puts "Checksum   : #{checksum}"
  puts "Card Check : " + (checksum % 10 == 0 ? "VALID" : "INVALID")
else
  puts 'Format error...'
  puts 'Please respect this format XXXXXXX... or XXXX XXXX XXXX...'
end
Le fait de passer cette vérification ne veut pas dire que les informations bancaire fournies sont justes. Ca veut juste dire que l’utilisateur n’a pas fait d’erreur en entrant le numéro de sa carte bancaire.
 

Créez Votre Gem Ruby From Scratch

Vous êtes un fervent utilisateur de Ruby ou simplement un utilisateur occasionnel et vous souhaitez apporter votre contribution à l’annuaire d’extensions Ruby ? Ce billet est fait pour vous. Nous allons voir comment créer une gem sans utiliser de template. Pour commencer, mettez à jour rubygems avec la commande suivante :

1
root@0xbaadf00d.com> gem update --system

Une fois le processus de mise à jour effectué, créez le squelette de votre gem :

1
2
3
4
meyer_t@0xbaadf00d.com> mkdir ionisauthenticator
meyer_t@0xbaadf00d.com> mkdir ionisauthenticator/lib
meyer_t@0xbaadf00d.com> touch ionisauthenticator/lib/ionisauthenticator.rb
meyer_t@0xbaadf00d.com> cd ionisauthenticator

Attention: Le fichier d’entrée de votre gem doit avoir le même nom que la gem (ici: ionisauthentication).

Créez ensuite le fichier qui contiendra les informations sur votre gem. Le nom du fichier n’a pas d’importance, vous devez seulement respecter l’extension .gemspec. Parmi les informations contenues dans ce fichiers nous pouvons citez l’auteur, la description, le site internet, les dépendances, les fichiers à utiliser…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Gem::Specification.new do |s|
  s.name         = 'ionisauthentication'
  s.version      = '0.0.3'
  s.date         = '2012-03-13'
  s.summary      = "IONIS Authentication"
  s.description  = "A Ruby Class to get informations about students in Ionis group"
  s.authors      = ["Thibault MEYER"]
  s.email        = 'email@domain'
  s.files        = ["lib/ionisauthentication.rb", "lib/ionisexceptions.rb", "README.rdoc"]
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "IONIS", "--main", "README.rdoc"]
  s.homepage     = 'https://github.com/corbeau-web/Ruby-IONIS-Info-Class'
  s.add_dependency('net-ssh', '>= 2.3.0')
  s.add_dependency('net-scp', '>= 1.0.4')
  s.add_dependency('bcrypt-ruby', '>= 3.0.1')
end

Dès à présent, vous pouvez coder votre gem dans le répertoire lib. Une fois cela fait, il suffit de générer la gem puis de l’installer.

1
2
meyer_t@0xbaadf00d> gem build my_own_gem.gemspec
meyer_t@0xbaadf00d> gem install ionisauthentication-0.0.3.gem

Et voilà, vous venez de créer votre première gem, il ne vous reste plus qu’à la tester et, si vous le souhaitez, la publier sur rubygems.

Surveillez Les Fichiers Log Sous Linux

Quand vous possédez un ou plusieurs serveurs vous aimeriez bien être tenu au courant tout de suite quand quelque chose ne passe pas bien et non pas être pris au dépourvu le jour ou vous vous décidez enfin à lire les fichiers de log qui sont barbant à consulter.

Il existe un logiciel qui répond au nom de “logcheck” qui à pour rôle de vous prévenir par mail dès que quelque chose cloche sur le système: Comme par exemple, un programme qui plante, une tentative de connexion échouée, …

Logcheck est présent dans les dépôts de la plupart des distributions. Après l’avoir installé, éditez le fichier /etc/logcheck/logcheck.conf pour ajouter votre adresse mail au champ SENDMAILTO.

1
SENDMAILTO="thibault.meyer@0xbaadf00d.com"

Voici un exemple de mail que vous pouvez recevoir avec logcheck

1
2
3
4
5
6
7
8
9
10
11
12
This email is sent by logcheck. If you no longer wish to receive
such mail, you can either deinstall the logcheck package or modify
its configuration file (/etc/logcheck/logcheck.conf).

System Events
=-=-=-=-=-=-=
Mar  9 16:13:55 ks25076 krb5kdc[2620]: preauth (timestamp) verify failure: Decrypt integrity check failed
Mar  9 16:13:55 ks25076 krb5kdc[2620]: AS_REQ (7 etypes {18 17 16 23 1 3 2}) 163.5.141.29: PREAUTH_FAILED: 0xbaadf00d@CORBEAU-WEB.EU for krbtgt/CORBEAU-WEB.EU@CORBEAU-WEB.EU, Decrypt integrity check failed
Mar  9 16:14:00 ks25076 krb5kdc[2620]: preauth (timestamp) verify failure: Decrypt integrity check failed
Mar  9 16:14:00 ks25076 krb5kdc[2620]: AS_REQ (7 etypes {18 17 16 23 1 3 2}) 163.5.181.23: PREAUTH_FAILED: 0xbaadf00d@CORBEAU-WEB.EU for krbtgt/CORBEAU-WEB.EU@CORBEAU-WEB.EU, Decrypt integrity check failed
Mar  9 16:14:05 ks25076 krb5kdc[2620]: preauth (timestamp) verify failure: Decrypt integrity check failed
Mar  9 16:14:05 ks25076 krb5kdc[2620]: AS_REQ (7 etypes {18 17 16 23 1 3 2}) 163.5.141.16: PREAUTH_FAILED: 0xbaadf00d@CORBEAU-WEB.EU for krbtgt/CORBEAU-WEB.EU@CORBEAU-WEB.EU, Decrypt integrity check failed

Affichage VT100 Exporté Sur HTTP

Cette nuit je suis tombé sur un script super sympa en Python qui permet d’exporter l’affichage d’un émulateur de terminal sur HTTP. Le résultat est plutôt bluffant, je vous conseil de tester par vous même pour vous en faire une idée.

Le projet est hébergé sur github à l’adresse suivante : https://github.com/JulienPalard/ashttp

Introduction Aux Trainers Sous Windows

Qui ne s’est jamais posé la question de comment fait un trainer pour modifier les caractéristiques des votre personnage dans votre jeu préféré? Aujourd’hui, je vais essayer de vous montrer basiquement le processus de la conception d’un tel programme. Ce billet se découpera en 2 parties: dans la première, nous utiliserons Cheat Engine (http://www.cheatengine.org) pour fouiner un peu dans la mémoire du jeu et dans un second temps, nous coderons une petite application (C ou C++ avec API Windows) pour exploiter les résultats de la première étape. Comme il s’agit d’une introduction, nous utiliserons un jeu simple, nous utiliserons donc “Might and Magic VI : The Mandate of Heaven” disponible sur GoG en échange de quelques dollars.

0x01 - A la poursuite des adresses perdues

Might and Magic VI est parfait pour débuter car les adresses mémoire ne changent pas. J’entend par la que l’adresse d’un élément donnée ne change pas d’une partie à l’autre (contrairement à des jeux comme Killing Floor, où l’adresse mémoire des points de vie change à chaque partie). Avant de commencer quoi que ce soit, je vous conseil de suivre le tutorial de Cheat Engine histoire de vous familiariser à son maniement. Maintenant que vous maitrisez Cheat Engine, nous pouvons procédez à l’opération. Cette étape, bien que peu complexe, est relativement peu intéressante à faire. En fait, il faut trouver ou se trouve les éléments que l’on souhaite manipuler dans notre trainer. Might and Magic VI étant un RPG, nous rechercheront en priorité des éléments intéressants comme les points de vie des personnages et le nombre de pièce d’or du groupe.

1
2
3
4
5
6
7
8
================ MM6.EXE ================
MM6.exe+508D50    Pièces d.or du groupe
MM6.exe+508D54    Pièces d.or déposées à la Banque
MM6.exe+908D2C    Nourriture du groupe
MM6.exe+90A348    Points de vie du personnage #1
MM6.exe+90B964    Points de vie du personnage #2
MM6.exe+90CF80    Points de vie du personnage #3
MM6.exe+90E59C    Points de vie du personnage #4

0x02 - Développez un trainer basique

Bien, on a les adresses mémoire, il ne nous reste plus qu’a développez un petit programme qui va modifier les valeurs quand on le souhaite. Pour cela, voyons ce que propose l’API Windows comme fonctions qui sont bien de les connaître tellement elles envoient du poney sur la lune:

  • FindWindow : Permet de récupérer un handle sur une application ouverte sur Windows
  • GetWindowThreadProcessId : Permet de récupérer le PID d’une application a partir de son handle
  • OpenProcess : Ouvre en lecture/écriture un processus en cours à partir de son PID
  • ReadProcessMemory : Lire dans la mémoire
  • WriteProcessMemory : Ecrire dans la mémoire
  • CloseHandle : Fermer un handle
  • GetAsyncKeyState : Pour savoir les touches clavier appuyées

Ces fonctions sont extrêmement bien documentés sur le MSDN, vous devriez y jeter un petit coup d’oeil pour vous familiariser avec. Pour commencer, nous allons récupérer le PID du jeu puis ouvrir le processus, pour cela il suffit d’utiliser FindWindow et GetWindowThreadProcessId.

1
2
3
4
5
6
7
8
9
10
m_hWindow = FindWindowA(NULL, "MM6.EXE");
if (m_hWindow) {
  retVal = GetWindowThreadProcessId(m_hWindow, (LPDWORD)&m_PID);
  if (retVal) {
    m_hProc = OpenProcess(PROCESS_ALL_ACCESS, NULL, m_PID);
    if (m_hProc) {
      // ok
    }
  }
}

Maintenant que le jeu est trouvé et que OpenProcess à retourné un handle valide, nous allons pouvoir commencer à lire et écrire dans la mémoire du programme. Voyons comment s’ajouter 2000 Pièces d’or en plus :

1
2
3
4
5
6
7
ULONG32  val = 0;
SIZE_T  nbReaded = 0;
SIZE_T   nbWritten = 0;

ReadProcessMemory(m_hProc, (LPCVOID) 0x908D50, (LPVOID)&val, 4, &nbReaded);
val += 2000;
WriteProcessMemory(m_hProc, (LPVOID) 0x908D50, (LPCVOID)&val, sizeof(ULONG32), &nbWritten);

Et voila, vous venez de gagner 2000 Pièces d’or en plus ! Utilisez GetAsyncKeyState pour ajouter la possibilité d’utiliser votre trainer in-game en ajouter de nouveaux bindkey : F2 pour de l’argent, F3 pour de la nourriture, …

Par pitié, n’oubliez pas de fermer les handles ouvert à la fin avec la fonction CloseHandle.