Copy Link
Add to Bookmark
Report

7Sk1: Carahack : Carapopup, c'est-y comment que ça marche ?

eZine's profile picture
Published in 
Seven SYnKoP Mag
 · 2 years ago

Introduction

Cet article s'adresse à tout les amis codeurs qui font partie de cette grande communauté les carahackeur. Qu'ils soient codeurs de clients chat, pop, ou analyseurs de cookie ils s'attaquent tous à un système extrèmement interressant à attaquer j'ai nommé : Caramail. Faisant partie de cette communauté je voudrait vous faire découvrir un outil proposé par notre gentil service mail pour voir si on a de nouveaux messages : Carapopup. Allez, allez, on me telecharge ça let's go !


Carapopup

Notre carapopup a nous pèse 85 ko, hum ... voyons voir si ya du cryptage d'exe, on lance tout d'abord procdump > PE Editor > notre exe carapopup et là on va regarder les sections : UPX0, UPX1, .rsrc ok carapopup est compréssé par UPX bon là la meilleur solution pour décomprésser facilement et sans pertes de données un exe ayant subit cette compression il suffit d'utiliser UPX avec l'option -d et voilà le tour est joué on se retrouve nez a nez avec un carapopup de 280 ko rhaa est qui plus est totalement désassemblale avec W32ASM, c'est y pas bô tout ça ?

Bon désassemblons le monstre est trions quelques string references intérressantes :

Voilà pourquoi j'ai choisis ces str. ref. :

Ca ça ma l'air super interressant mais je ne le traiterai pas ici donc si qqun veux s'affairer a cette tache ...

Il me semble que ça pourait etre une possibilité de carahack superbe, la procedure de changement de mot de passe étant une procédure très à risque dans n'importe quel système :)

Bon ben go on va s'atthacker a ce carapopup je vais tout d'abord créer sous cara l'utilisateur "mojegtemp" avec le mot de passe "theorie" et là pour annalyser le protocole échangé j'ai deux solution. La première est de créer un proxy et de faire passer toutes les requêtes caramail par celui là pour les étudier, la seconde est de changer avec un editeur hexadécimal la str ref "carapop.caramail.com" en "127.0.0.1", puis de faire une ptite application serveur qui ouvrira le port 80 et affichera à l'écran ce qu'on lui envoie. Pour cause d'une soudaine montée de flemmardise je décide d'opter pour la seconde solution. Bon bé ... let's go !

Alors avec l'héditeur héxa on cherche dans notre bô carapopup décompréssé o˘ se trouve la chaine de carctère carapop.caramail.com puis on la remplace par 127.0.0.1 puis un caractère nul(le zéro, pour montrer la fin de la chaine de caractère), vient maintenant la programmation du mini serveur. Bon on va pas se faire chier on va faire ça en VB. Déposez sur la feuille un contrôle texte puis un contrôle winsock.

Ne modifiez pas leurs noms et pastez ce code (comprenez le avant ça peut servir :) :

'------------------------------------------------------------------------------------------> 
Private Sub Form_Load()
Text1.Text = ""
Winsock1.Bind 80
Winsock1.Listen
End Sub

Private Sub Winsock1_ConnectionRequest(ByVal requestID As Long)
If Winsock1.State <> sckClosed Then Winsock1.Close
Winsock1.Accept requestID
End Sub

Private Sub Winsock1_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
Winsock1.GetData strData, vbString
Text1.Text = Text1.Text & strData
End Sub
'<------------------------------------------------------------------------------------------


Ce code est assez simple a comprendre donc je ne fournirait pas d'expliquation.

Bon voilà deux essais et leurs résultats avec login/pass : "mojegtemp"/"theorie" :

GET /cgi-bin/clogin?login1=mojegtemp&password1=MCLGMIOEDLEFKCPAMMPDDNMCAAHGEDNE&rand1=1030209428 HTTP/1.0 
GET /cgi-bin/clogin?login1=mojegtemp&password1=MCLGMIOEDLEFKCPAMMPDDNMCAAHGEDNE&rand1=1030209486 HTTP/1.0


Nous voyons donc le mot de passe est crypté et que l'argument passé en variable rand1 n'est pas dutout aléatoire mais qu'elle semble plus être un truc style les secondes, ou qqchose du genre, le login lui reste en clair.


Maintenant nous allons voir se qui se passe lorsque nous soumettons cette requete au vraie serveur.

Voilà ce qu'il nous renvoi :

JGKEPBLMMLBDFKEIMAGHBAPPKDOHEJCNHJOCOJJPCBLPOOAL 1.0 1

JGKEPBLMMLBDFKEIMAGHBAPPKDOHEJCNHJOCOJJPCBLPOOAL : un hash de session ?
1.0 : un numéro de version ?
1 : ??? le niveau de l'utilisateur (admin ou pas ?) -> supposition

second éssais avec la même requete que précédament :

HNHIAKGHHOEFAOBBDKAECJNANOPINKDMOJAIBIJIDNDOPDBM 1.0 1

Nous savons donc que la valeur de rand1 n'est absolument pas importante pour le déroulement de l'identification rand1 doit juste être composé de 10 chiffres, que nous sommes vraiment en présence d'un hash et pour le reste rien est sûr.

En suivant la logique du prog je vais effectuer la requete suivante envers le serveur:

/cgi-bin/cmail?key=<LE HASH>&rand1=<LA VALEUR PSEUDOALEATOIRE> HTTP/1.0


soit :

/cgi-bin/cmail?key=HNHIAKGHHOEFAOBBDKAECJNANOPINKDMOJAIBIJIDNDOPDBM&rand1=1030209428 HTTP/1.0


et je vois un bo zero qui saffiche ... ben oui, aucun nouveaux messages. Alors je m'envois un message a partir de mon adresse an-mojeg@caramail.com avec comme sujet "test test test", je recommence la requete et là ... réponse du serveur :


1 141233452 An-Mojeg test test test

hem hem hem :
1 : nombre de nouveaux messages
141233452 : numéro du message ?
An-Mojeg : expéditeur - moi
test test test : sujet du message.

Esske 141233452 est le numéro du message ? une seul manière de le vérifier :
http://www56.caramail.lycos.fr/cgi-bin/AfficheBody?IDMAIL=141233452

... bingo ... très fort ... wouawouuuu !!!

Huh un petit détail reste choquant ... comment il nous crypte le mot de passe ?

Cryptage du mot de passe

Alors comment se fait-il que notre password : theorie se transforme subitement en MCLGMIOEDLEFKCPAMMPDDNMCAAHGEDNE ???

Que se passe-t-il si theorie se transforme en aaaa ?, abjzkelb ?

résultats :
pour "aaaa" :
HELIHDDHEFECAANENDDPIAMEGGDNMFOF
pour "abjzkelb" :
IINGOGNFEHODDLBFKJOGPCFNNJIGHAOE

ok ok ok j'ai compris il s'agit d'un hash. ( hmmmm ouaouuuuuuuuuuuuuuuuuu ! )

Bon ben on va tracer le programme avec softice en foutant un breakpoint a l'appel de la fonction GetDlgItemTextA donc bpx GetDlgItemTextA on fait une fois F10 (pour passez outre la prise du login) Et puis après tout vous cherchez j'en ai marre.

Nan en fait ça serait trop sadique puissque moi j'ai mis environ une après-midi pour me rendre compte que ces ... connard ... apliquaient un algorythme MD5 puis un ptit changement tout bête.
Le code source est situé dans la partie data du zine (VC++ 6), je vous lache ici le petit changement qu'ils effectuent au hash :

//----------------------------------------------------------------------------- 
unsigned char digest[16]; // le hash
unsigned char final[50]; // le resultat

int i=0,x1=0,x2=0; // un compteurs et des variables temporaires.

for(i=0;i<16;i++){
x1 = x2 = digest[i];

x1 >>= 4;
x1 += 65;

x2 &= 15;
x2 += 65;

final[j] = x1;
j++;
final[j] = x2;
j++;
}
//-----------------------------------------------------------------------------


Mattez le code source entier et analysez le bien.

Conclusion

J'espère que cet article aura bien servi au carahackeurs et qu'il aura aussi su faire de futurs carahackeur parmis les lecteurs. Bon ben voilà maintenant vous pouvez me coder un ptit client POP ou un bruteforcer de comptes cara ( foutez moi dans les greetz, ça coute rien ! j'ai passé du temps a faire cette article ) et sendez moi les sources de vos progr ! ;)

Bon ben rendez vous au prochain zine pour un autre article du même style.

An-Mojeg [ an-mojeg@mail-developpeur.com ]

sources et prog du hasheur de mot de passe de carapopup

genpwd.cpp

#include <windows.h> 

#include "resource.h"
#include "MD5.h"

LRESULT CALLBACK MDlgproc (HWND,UINT,WPARAM,LPARAM);

HINSTANCE hInst = NULL;

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
MSG msg;
WNDCLASSEX dlgclass;

hInst = hInstance;

dlgclass.cbSize = sizeof(WNDCLASSEX);
dlgclass.style = CS_HREDRAW | CS_VREDRAW;
dlgclass.lpfnWndProc = (WNDPROC) MDlgproc;
dlgclass.cbClsExtra = NULL;
dlgclass.cbWndExtra = DLGWINDOWEXTRA;
dlgclass.hInstance = hInst;
dlgclass.hbrBackground = (HBRUSH)COLOR_BTNFACE+1;
dlgclass.lpszMenuName = NULL;
dlgclass.lpszClassName = "DLGCLASS";
RegisterClassEx(&dlgclass);

if(!CreateDialogParam(hInst,MAKEINTRESOURCE(IDD_MAIN),NULL,(DLGPROC)MDlgproc,NULL)){
MessageBox(NULL,"CreateDialogParam()","Erreur",0);
return 0;
}

while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

return msg.wParam;
}


LRESULT CALLBACK MDlgproc (HWND hDlg,UINT uMsg,WPARAM wParam, LPARAM lParam)
{
char motdepasse[100];
unsigned char digest[16];
unsigned char final[50];

int i=0,j=0,x1=0,x2=0,longeur;

switch(uMsg)
{
case WM_INITDIALOG:
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BTHASH:
GetDlgItemText(hDlg,IDC_TXTMDP,motdepasse,100);
if((longeur=strlen(motdepasse))>8){
MessageBox(hDlg,"Mot de passe trop long (maxi. 8).","Erreur",0);
break;
} else if(longeur<4){
MessageBox(hDlg,"Mot de passe trop court (mini. 4).","Erreur",0);
break;
}

StrMD5((unsigned char*)motdepasse,digest);

for(i=0;i<16;i++){
x1 = x2 = digest[i];

x1 >>= 4;
x1 += 65;

x2 &= 15;
x2 += 65;

final[j] = x1;
j++;
final[j] = x2;
j++;
}

final[j] = 0;

SetDlgItemText(hDlg,IDC_TXTRESULT,(const char*)final);
break;
default:
break;
}
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return false;
}
return true;
}


resource.h

//{{NO_DEPENDENCIES}} 
// Microsoft Developer Studio generated include file.
// Used by ressrc.rc
//
#define IDD_MAIN 101
#define IDC_TXTMDP 1000
#define IDC_BTHASH 1001
#define IDC_TXTRESULT 1002

// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif


MD5.h

// 
// Algorithme MD5
//
//
// An-Mojeg
//
// ##########################################################################
// Fonctions de bases :
// --------------------
#define F(X,Y,Z) (((X) & (Y)) | ((~X) & (Z)))
#define G(X,Y,Z) (((X) & (Z)) | ((Y) & (~Z)))
#define H(X,Y,Z) ((X) ^ (Y) ^ (Z))
#define I(X,Y,Z) ((Y) ^ ((X) | (~Z)))
// Fait tourner les bits :)
// ------------------------
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
// Fonctions dÈveloppÈes :
// -----------------------
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
// Constantes pour la fonction de hashcore (lol)
// ---------------------------------------
#define UINT4 unsigned int
#define POINTER char*

#define S11 7
#define S12 12
#define S13 17
#define S14 22

#define S21 5
#define S22 9
#define S23 14
#define S24 20

#define S31 4
#define S32 11
#define S33 16
#define S34 23

#define S41 6
#define S42 10
#define S43 15
#define S44 21

static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
// Ma classe context :
// -------------------
class MD5_CTX
{
public:
void MD5Init();
void MD5Transform(unsigned char tbuffer[64]);
void MD5Update(unsigned char* data, unsigned int len);
void MD5Final(unsigned char digest[16]);
private:
unsigned long state[5];
unsigned long count[2];
unsigned char buffer[64];
};
// Fonctions scpÈciales
// --------------------
void Decode (UINT4 *output, unsigned char *input, unsigned int len);
void MD5_memcpy (POINTER output, POINTER input, unsigned int len);
void MD5_memset (POINTER output, int value, unsigned int len);
void Encode (unsigned char *output, UINT4 *input, unsigned int len);
// -------------------
void MD5_CTX::MD5Init()
{
count[0] = count[1] = 0;

state[0] = 0x67452301;
state[1] = 0xefcdab89;
state[2] = 0x98badcfe;
state[3] = 0x10325476;
}

// -------------------

void MD5_CTX::MD5Transform(unsigned char tbuffer[64])
{
UINT4 a = state[0];
UINT4 b = state[1];
UINT4 c = state[2];
UINT4 d = state[3];
UINT4 x[16];

Decode (x, tbuffer, 64);

/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */

state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;

/* Zeroize sensitive information.*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}

void MD5_CTX::MD5Update(unsigned char* data, unsigned int len)
{
unsigned int i, index, partLen;

// Compute number of bytes mod 64
index = (unsigned int)((count[0] >> 3) & 0x3F);

// Update number of bits
if ((count[0] += ((UINT4)len << 3)) < ((UINT4)len << 3))
count[1]++;

count[1] += ((UINT4)len >> 29);

partLen = 64 - index;

// Transform as many times as possible.
if (len >= partLen) {
MD5_memcpy ((POINTER)&buffer[index], (POINTER)data, partLen);
MD5Transform (buffer);

for (i = partLen; i + 63 < len; i += 64)
{
MD5Transform (&data[i]);
}

index = 0;
} else {
i = 0;
}

// Buffer remaining input
MD5_memcpy ((POINTER)&buffer[index], (POINTER)&data[i], len-i);
}

void MD5_CTX::MD5Final(unsigned char digest[16])
{
unsigned char bits[8];
unsigned int index, padLen;

/* Save number of bits */
Encode (bits, (UINT4*)count, 8);

/* Pad out to 56 mod 64.*/
index = (unsigned int)((count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (PADDING, padLen);

/* Append length (before padding) */
MD5Update (bits, 8);

/* Store state in digest */
Encode (digest, (UINT4*)state, 16);

/* Zeroize sensitive information.*/
// MD5_memset ((POINTER)context, 0, sizeof (*context));
}

// -------------------

void Decode (UINT4 *output, unsigned char *input, unsigned int len)
{
unsigned int i, j;

for (i = 0, j = 0; j < len; i++, j += 4)
{
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
}

void MD5_memcpy (POINTER output, POINTER input, unsigned int len)
{
unsigned int i;

for (i = 0; i < len; i++)
{
output[i] = input[i];
}
}

void MD5_memset (POINTER output, int value, unsigned int len)
{
unsigned int i;

for (i = 0; i < len; i++)
{
((char *)output)[i] = (char)value;
}
}

void Encode (unsigned char *output, UINT4 *input, unsigned int len)
{
unsigned int i, j;

for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}

// -------------------

// ##########################################################################

int StrMD5(unsigned char *string,unsigned char digest[16])
{
MD5_CTX context;
int lenght = strlen((char*)string);

context.MD5Init();

context.MD5Update(string, lenght);

context.MD5Final(digest);

return 0;
}

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT