Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - ghastlyX

#131
WarZone / Re: Misc_Spoof
20 Julio 2008, 01:13 AM
Averiguad cómo detecta la página lo que os pide y como tenerlo o al menos hacedle creer que lo tenéis.

Un saludo de ghastlyX ;)
#132
Cita de: LordKevin en  9 Junio 2008, 06:17 AM
Cita de: ghastlyX en 30 Agosto 2007, 14:53 PM
Para que los resultados sean lo más fiables posibles, se despega la anterior encuesta y se pone esta, con muchos más antivirus, para que la opción "Otros" no se tenga que utilizar casi nada. Todos a votar y dar su opinión ;D

Un saludo de ghastlyX ;)

Es absurdo, decir cual es el mejor antivirus, tal vez decir cual es el que mas detecta virus sea mas objetivo.

Esta encuesta es subjetiva.
Toda encuesta es subjetiva, por algo recoge opiniones de la gente. Lo que si veo absurdo es decir qué antivirus detecta más virus, es mejor ver como basan su detección mejor que ver lo grande que es su base de firmas.


Cita de: V1rk4N en 11 Junio 2008, 02:28 AM
:o x lo que e estado viendo .. hay tecnikas que se  le aplikan a los antivirus.. para que no detecte al virus o troyano.. modificando su Kernel del antivirus.. principalmente .. eso me ha pasdo con el KASPERSKY ... un troyano ..se lo pasaba por el huevo al kaspersky.. ya que modifico la integridad del antivirus..  y bueno.. tube que darle un buen formateo.. pero.. eso me asombro.. veia como el antivirus se cabreaba..  jajja.. lo actializaba..  si creen que era un rootkit al S.O. x sika no-.!! xq.. ya les pase varios anti-rootkits,,.. al.. S.O no!!  se la isieron al antivirus.,.  a el le aplikaroin la tecnika del Rootkit.. y Bum,.. cayo el antivirus. x mas fuerte que apreca.. .. bueno yo confio ..en la THE HACKER ANTIVIRUS.. lo maximo.. 100% HEURISTICO. .ese se viola cualquier amenaza.. solo su interfas grafica es un poco monse.. pero lo que vale es su calidad ..  pruebenlo.. !!2.
-----------------------------------------------
?¿como apliko tecnikas de root-kits al antivirus.. !??¿¿?.. si he visto.. pero.. me gustaria aprender +++
tanks-- opinen
¿Kaspersky atacado por un troyano? Mucho dudo eso, no es imposible, pero dudo que un troyano que pulule por ahí consiga neutralizar el Kaspersky. Sobre lo de los rootkits, muchos antivirus han incorporado ya sistemas de detección de rootkits.

Un saludo de ghastlyX ;)
#133
Abrir cerraduras sin tener la llave, explicado rápidamente y simplificando mucho :P

Un saludo de ghastlyX ;)
#134
Si queréis crear un grupo de traducción, haz lo que ha dicho T0rete pero veo básica una cosa, en el tema que hagáis en este mismo subforo, tendríais que especificar de qué idiomas podéis traducir y qué temas domináis, porque por mucho que alguien sepa una lengua, si traduce un texto técnico de algo que no domina, no sale una traducción igual de fiel que si la hace alguien que sí domine.

Un saludo de ghastlyX ;)
#135
Las series de Numb3rs y los 4400 las tengo a medias, a ver si alguno las tiene.

Un saludo de ghastlyX ;)
#136
Criptografía / Re: RSA para no iniciados
28 Marzo 2008, 15:16 PM
Primero factorizas n y obtienes p = 173 y q = 409.

Calculas d, tal que d * e (mod phi(n)) = 1. Recuerda que phi(n) = (p - 1) * (q - 1). Para calcular d hice este código en C:
#define E 19
#define PHI_N 70176 //(p - 1) * (q - 1)

#include <stdio.h>

int main()
{
    int i;
    for(i = 0; i < 70757; i++)
    {
          if(((i * E) % PHI_N) == 1) printf("d = %d\n", i);
    }
    return 0;
}


Una vez tenemos d = 7387, desciframos cada letra. Si llamamos c a la letra a descifrar y m la letra original, m = (c ^ d) (mod n). Así ya tendrás el mensaje descifrado en números:
{19, 20, 1, 20, 5, 13, 1, 14, 21, 9, 5, 14, 5, 20, 5, 7, 22, 19, 16, 17, 1, 19, 1, 17, 19, 9, 13, 16, 20, 20, 22, 6, 9, 3, 9, 3, 9, 5, 14, 21, 5, 13, 5, 14, 21, 5, 20, 7, 19, 1, 14, 4, 5, 20}

Así tan sólo te queda sustituirlo por las letras, que no tiene mucho misterio xDD. Hice este programa para que me lo hiciera solo si no te apetece hacerlo a mano:
#include <stdio.h>

int main()
{
    int i;
    char abc[] = " ABCDEFGHIJKLMNÑOPQRSTUVWXYZ";
    int cifrado[] = {19, 20, 1, 20, 5, 13, 1, 14, 21, 9, 5, 14, 5, 20, 5, 7, 22, 19, 16, 17, 1, 19, 1, 17, 19, 9, 13, 16, 20, 20, 22, 6, 9, 3, 9, 3, 9, 5, 14, 21, 5, 13, 5, 14, 21, 5, 20, 7, 19, 1, 14, 4, 5, 20};
    for(i = 0; i < 54; i++) printf("%c", abc[cifrado[i]]);
    return 0;
}


Para hacer el paso de descifrar tendrás problemas con elevar a d según qué métode utilices. La calculadora de Windows sorprendentemente parece que lo realiza bien, yo utilizo un sistema de cadenas para estas cuentas tan bestias.

Un saludo de ghastlyX ;)
#137
Criptografía / Re: RSA para no iniciados
27 Marzo 2008, 21:40 PM
Descifrado: RSASEMANTIENESEGUROPARAPRIMOSSUFICICIENTEMENTESGRANDES

Con números:
{19, 20, 1, 20, 5, 13, 1, 14, 21, 9, 5, 14, 5, 20, 5, 7, 22, 19, 16, 17, 1, 19, 1, 17, 19, 9, 13, 16, 20, 20, 22, 6, 9, 3, 9, 3, 9, 5, 14, 21, 5, 13, 5, 14, 21, 5, 20, 7, 19, 1, 14, 4, 5, 20}

Datos:

d = 7387

p = 173

q = 409

Un saludo de ghastlyX ;)
#138
Seguridad / Re: Creación de vacunas en C/C++
18 Marzo 2008, 00:50 AM
CitarY una duda que hasta ahora no he podido resolver es cómo matar un proceso inmortal mediante vacunas, por ejemplo algunos troyanos que vienen con opción de persistencia y que cuando matamos el proceso, éste vuelve a aparecer en unos segundos. A esos no los puedo eliminar mas que en modo a prueba de fallos, pero yo no quiero eso, sino matarlos como lo hacen los antivirus que así sean inmortales, el antivirus igual lo mata. Hay alguna forma para hacer eso?
Yo es que tengo el problemilla que nunca he usado troyanos porque no me gustan nada, así que todo lo que he trabajado con ellos ha sido para cargármelos xDD. Dime alguno que haga eso y me lo miro, seguro que se pueden matar, ya miraré el sistema de autoprotección que tienen.

CitarY otra duda... hay algunos virus que toman el nombre de procesos conocidos como explorer.exe o lsass.exe y que no se dejan matar así nomas porque windows piensa que son procesos esenciales. Con el código que has puesto se dejan matar estos procesos?.
Con ese código te va a dar problemas para eso, dime lo de los troyanos que dices y para el próximo capítulo a ver si hago un código que mate ambas cosas.

Y para todos en general, a ver quién le ve el fallo que comentaba en el primer post a la función de matar procesos xDD

Un saludo de ghastlyX ;)
#139
Seguridad / Creación de vacunas en C/C++
17 Marzo 2008, 15:33 PM
Últimamente cada vez abundan más los gusanos que se propagan por MSN, por lo que me he decidido a escribir este manual sobre como programar vacunas específicas para este tipo de malware (aunque se puede extrapolar a otros). Mi objetivo es que haya más gente con capacidad de lanzar vacunas para estos gusanos cutres pero que se propagan como la espuma.

El lenguaje de programación que usaremos será C/C++ con el compilador Dev-C++, utilizando APIs. Si no sabéis que son preguntad a Google o a Wikipedia. Empezaré desde cero y ya adelanto que no voy a hacer un tutorial demasiado avanzado, puesto que quiero que lo entienda todo el mundo. Las APIs que use las explicaré por encima, para una mayor explicación podéis consultar en MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/functions_in_alphabetical_order.asp

Análisis del código maligno
Bien, explicaré el método más sencillo. Este consiste en utilizar una máquina virtual y con un programa llamado Regshot mirar que cambios ha realizado en el sistema tras su ejecución. No es el mejor método porque un programa bien hecho puede evitar ser registrado por programas así, pero es mucho más sencillo que el otro método (desensamblarlo) y como este manual pretende ser básico, será el método que usaremos.

Lo primero de todo será instalar un programa para crear máquinas virtuales, yo personalmente uso para eso VMWare. No voy a explicar como se crea una máquina virtual, para eso mirad el siguiente enlace:
http://foro.elhacker.net/index.php/topic,158384.0.html

Una vez tenemos nuestra máquina virtual con el sistema operativo instalado (Windows) ya tan sólo hay que deshabilitar las conexiones (no queremos que se propague el malware ni que ataque a otros sitios mientras lo analizamos) y cerrar todo programa no imprescindible. Hacemos una primera foto con Regshot y luego otra después de haber ejecutado el malware. Entonces hacemos que compare y tendremos nuestra lista de cambios :)

Comencemos a programar
Antes que nada tenéis que tener instalado Dev-C++ o vuestro compilador si usáis otro, una vez hecho, vayamos al grano. Todo programa en C/C++ se divide en funciones, que son trozos de código a los que se puede llamar. Pueden devolver una salida o no (void). En C/C++ hay una función imprescindible que es main, aquella por la que empieza el programa cuando lo ejecutamos. Tiene la siguiente estructura:
Código (cpp) [Seleccionar]
int main()
{
    ...
}


La función main es la que menos utilizaremos, puesto que borraremos el gusano con funciones aparte, que llamaremos desde el main. Será necesario utilizar APIs, por lo que habrá que incluir el header (archivo de cabecera) que permite usarlas, que es windows.h. También queremos comunicarnos con el usuario, por lo que hace falta stdio.h (Standard Input/Output). También nos hará falta Tlhelp32.h y ctype.h (por la función toupper). Para incluir headers hay que poner las siguientes líneas al principio del código, antes que ninguna función:
Código (cpp) [Seleccionar]
#include <stdio.h>
#include <windows.h>
#include <Tlhelp32.h>
#include <ctype.h>


Matando procesos y eliminando archivos concretos
Para poder eliminar un archivo que se está ejecutando, es necesario matar antes su proceso. Para ello haremos una función que llamaremos KillProcess, que recibirá como entrada una cadena con el nombre del archivo al que hay que matar el proceso. Las funciones (excepto main) se declaran antes de poner el código de otra función y después de los headers incluidos.

Como salida nuestra función devolvera un entero (un número) indicando si ha tenido éxito o no. Para declarar la función habría que usar la sentencia siguiente:
Código (cpp) [Seleccionar]
int KillProcess(LPCTSTR lpfilename);

Luego también tendríamos que poner la función en sí, por lo que hasta ahora tendríamos que tener el código así:
Código (cpp) [Seleccionar]
#include <stdio.h>
#include <windows.h>
#include <Tlhelp32.h>
#include <ctype.h>

int KillProcess(LPCTSTR lpfilename);

int KillProcess(LPCTSTR lpfilename)
{
       ...
}

int main()
{
    ...
}


Ahora veamos como matar el proceso de un archivo. Hay que declarar una serie de variables que usaremos:
Código (cpp) [Seleccionar]
     WIN32_FIND_DATA Win32FindData;
     HANDLE handle;
     DWORD exitcode;
     PROCESSENTRY32 pe32;

Estas son las que necesitaremos para poder matar el proceso. No hace falta que los nombres de variable (la segunda palabra) sea la misma, estos son los que usaré yo aquí. Los tipos de variable no los podéis cambiar y tened en cuenta que C/C++ distingue mayúsculas de minúsculas.

Ahora tenemos que hacer como si fuera una foto de todos los procesos que se ejecutan, para ello usaremos la API CreateToolhelp32Snapshot, que tiene la siguiente forma:
Código (cpp) [Seleccionar]
HANDLE WINAPI CreateToolhelp32Snapshot(
  __in  DWORD dwFlags,
  __in  DWORD th32ProcessID
);


Luego recorremos los procesos con las APIs Process32First (para el primero) y Process32Next (para los siguientes). Tienen la siguiente forma:
Código (cpp) [Seleccionar]
BOOL WINAPI Process32First(
  __in     HANDLE hSnapshot,
  __inout  LPPROCESSENTRY32 lppe
);

BOOL WINAPI Process32Next(
  __in   HANDLE hSnapshot,
  __out  LPPROCESSENTRY32 lppe
);


Harán falta otras APIs:
Código (cpp) [Seleccionar]
//Cierra un handle abierto
BOOL WINAPI CloseHandle(
  __in  HANDLE hObject
);

//Abre un proceso
HANDLE WINAPI OpenProcess(
  __in  DWORD dwDesiredAccess,
  __in  BOOL bInheritHandle,
  __in  DWORD dwProcessId
);

//Devuelve el estado de finalización del proceso
BOOL WINAPI GetExitCodeProcess(
  __in   HANDLE hProcess,
  __out  LPDWORD lpExitCode
);

//Termina un proceso y sus threads
BOOL WINAPI TerminateProcess(
  __in  HANDLE hProcess,
  __in  UINT uExitCode
);

Para hacer todo esto, traducido a código hay que hacer lo siguiente:
Código (cpp) [Seleccionar]
     handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);  //Guardamos en nuestra variable de tipo HANDLE la "foto"
     if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;    //Si no es correcta la "foto" se acaba la funcion y se devuelve un error         
     pe32.dwSize = sizeof(PROCESSENTRY32); //Definimos la medida de nuestra estructura PROCESSENTRY32
     if(!Process32First(handle, &pe32)) //Si hay un error al mirar el primer proceso
     {
          CloseHandle(handle); //Cierra el HANDLE que usamos
          return ERROR_PROCESO; //Acaba la funcion devolviendo un error
     }
     int i; //Declaramos un par de variables más que hacen falta para pasar a mayusculas dos cadenas
     char lpfilename2[strlen(lpfilename) + 1];
     strcpy(lpfilename2, lpfilename);
     for(i = 0; pe32.szExeFile[i] != '\0'; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]); //Pasamos a mayúsculas las dos cadenas a comparar para que si no son exactamente iguales en cuanto a mayusculas o minusculas, también mate el proceso
     for(i = 0; lpfilename2[i] != '\0'; i++) lpfilename2[i] = toupper(lpfilename2[i]);
     while(strcmp(pe32.szExeFile,lpfilename2))  /Mientras el proceso no coincida con el que buscamos...
     {                                   
          if(!Process32Next(handle, &pe32))  //Va mirando el siguiente, acabando la funcion si hay errores
          {
                  CloseHandle(handle);
                  return ERROR_PROCESO;
          }
          for(i = 0; pe32.szExeFile[i] != '\0'; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]); //Pasa a mayusculas por lo que he dicho antes
     }
/**Una vez hemos encontrado el proceso**//
     handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);  //Abrimos el proceso
     if(handle == NULL) //Si sale mal, damos error y salimos de la funcion
     {
               CloseHandle(handle);
               return ERROR_PROCESO;
     }
     else           //Si no sale mal...                               
     {
          GetExitCodeProcess(handle, &exitcode); //Cogemos el exitcode del proceso y lo guardamos en nuestra variable destinada a ese cometido
          TerminateProcess(handle, exitcode); //Matamos el proceso
          CloseHandle(handle);  //Cerramos el HANDLE que habiamos usado
          return 0; //Devolvemos el valor 0, que es el que indicara que todo va bien y acaba la funcion
     }


Como ya supongo que habréis supuesto, return se utiliza para terminar la función y devolver un valor. La doble barra sirve para introducir comentarios de una línea y también son comentario todo aquello entre /* y */. Además, también podéis ver que excepto el cero del final, los return devuelven cosas como ERROR_PROCESO. Esto sirve para llamar de una forma más recordable a una salida, en vez de usar un número. Para usar estos nombres, hay que definirlos antes,  en la zona de los headers. Veamos todo lo que llevamos de código, incluyendo estas definiciones:
Código (cpp) [Seleccionar]

#define ERROR_LISTAR 1
#define ERROR_PROCESO 2

#include <stdio.h>
#include <windows.h>
#include <Tlhelp32.h>
#include <ctype.h>

int KillProcess(LPCTSTR lpfilename);

int KillProcess(LPCTSTR lpfilename)
{
     WIN32_FIND_DATA Win32FindData;
     HANDLE handle;
     DWORD exitcode;
     PROCESSENTRY32 pe32;
     handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;             
     pe32.dwSize = sizeof(PROCESSENTRY32);
     if(!Process32First(handle, &pe32))
     {
          CloseHandle(handle);
          return ERROR_PROCESO;
     }
     int i;
     char lpfilename2[strlen(lpfilename) + 1];
     strcpy(lpfilename2, lpfilename);
     for(i = 0; pe32.szExeFile[i] != '\0'; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
     for(i = 0; lpfilename2[i] != '\0'; i++) lpfilename2[i] = toupper(lpfilename2[i]);
     while(strcmp(pe32.szExeFile,lpfilename2))
     {                                   
          if(!Process32Next(handle, &pe32))
          {
                  CloseHandle(handle);
                  return ERROR_PROCESO;
          }
          for(i = 0; pe32.szExeFile[i] != '\0'; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
     }
     handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
     if(handle == NULL)
     {
               CloseHandle(handle);
               return ERROR_PROCESO;
     }
     else                                         
     {
          GetExitCodeProcess(handle, &exitcode);
          TerminateProcess(handle, exitcode);
          CloseHandle(handle);
          return 0;
     }
}

int main()
{
    ...
}


Bueno, ahora que ya está hecha la función de matar el proceso, vayamos con la de borrar el archivo. Usaremos una función con la misma estructura, recibe como parámetro un archivo y de salida devuelve un entero. Para seguir poniendo de manifiesto mi gran originalidad, la llamaremos FileDelete. La declaración que habría que poner junto con la de la otra función, quedaría así:
Código (cpp) [Seleccionar]
int FileDelete(LPCTSTR lpfilename);

Para la función es muy sencillo, tan sólo hay que ver una API, que es DeleteFile:
Código (cpp) [Seleccionar]
BOOL WINAPI DeleteFile(
  __in  LPCTSTR lpFileName
);


El código de la función quedaría así:
Código (cpp) [Seleccionar]
int FileDelete(LPCTSTR lpfilename)
{
     return DeleteFile(lpfilename);
}


Y el código total por ahora:
Código (cpp) [Seleccionar]
#define ERROR_LISTAR 1
#define ERROR_PROCESO 2

#include <stdio.h>
#include <windows.h>
#include <Tlhelp32.h>
#include <ctype.h>

int KillProcess(LPCTSTR lpfilename);
int FileDelete(LPCTSTR lpfilename);

int KillProcess(LPCTSTR lpfilename)
{
     WIN32_FIND_DATA Win32FindData;
     HANDLE handle;
     DWORD exitcode;
     PROCESSENTRY32 pe32;
     handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;             
     pe32.dwSize = sizeof(PROCESSENTRY32);
     if(!Process32First(handle, &pe32))
     {
          CloseHandle(handle);
          return ERROR_PROCESO;
     }
     int i;
     char lpfilename2[strlen(lpfilename) + 1];
     strcpy(lpfilename2, lpfilename);
     for(i = 0; pe32.szExeFile[i] != '\0'; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
     for(i = 0; lpfilename2[i] != '\0'; i++) lpfilename2[i] = toupper(lpfilename2[i]);
     while(strcmp(pe32.szExeFile,lpfilename2))
     {                                   
          if(!Process32Next(handle, &pe32))
          {
                  CloseHandle(handle);
                  return ERROR_PROCESO;
          }
          for(i = 0; pe32.szExeFile[i] != '\0'; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
     }
     handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
     if(handle == NULL)
     {
               CloseHandle(handle);
               return ERROR_PROCESO;
     }
     else                                         
     {
          GetExitCodeProcess(handle, &exitcode);
          TerminateProcess(handle, exitcode);
          CloseHandle(handle);
          return 0;
     }
}

int FileDelete(LPCTSTR lpfilename)
{
     return DeleteFile(lpfilename);
}

int main()
{
    ...
}


Realmente la función FileDelete es inútil, podríamos llamar directamente a la API, que es lo único que hace la función. Si no hago esto es porque más adelante (en próximos capítulos xD) ampliaremos esta función.


Borrando valores del registro
Este será el último apartado de este capítulo, el borrado de valores del registro, para por ejemplo borrar una entrada que pueda usar un gusano para autoejecutarse al inicio. Llamaremos a nuestra función RegKill, que será así:
Código (cpp) [Seleccionar]
long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName);

Devolverá un entero largo y como parámetros recibe un HKEY, que será en este caso  HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE o HKEY_USERS, que son valores predefinidos; como segundo parámetro una cadena que indica la ruta de la clave donde está el valor a borrar y como tercer parámetro otra cadena que indica el nombre del valor a borrar.

Usaremos tres APIs para esta función. La primera es RegOpenKeyEx, que abre una clave del registro y tiene la siguiente forma:
Código (cpp) [Seleccionar]
LONG WINAPI RegOpenKeyEx(
  __in        HKEY hKey,
  __in_opt    LPCTSTR lpSubKey,
  __reserved  DWORD ulOptions,
  __in        REGSAM samDesired,
  __out       PHKEY phkResult
);


La segunda API es RegDeleteValue, que elimina un valor de una clave del registro y tiene la siguiente forma:
Código (cpp) [Seleccionar]
LONG WINAPI RegDeleteValue(
  __in      HKEY hKey,
  __in_opt  LPCTSTR lpValueName
);


La última es RegCloseKey, que cierra el handle abierto y tiene esta forma:
Código (cpp) [Seleccionar]
LONG WINAPI RegCloseKey(
  __in  HKEY hKey
);


El código de la función quedaría así:
Código (cpp) [Seleccionar]
long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
     HKEY hregkey; //Definimos la variable donde guardaremos la ruta entera de la clave
     long vuelta; //Definimos la variable donde guardaremos el valor a devolver
     if(RegOpenKeyEx(hkey, lpSubKey, 0, KEY_ALL_ACCESS, &hregkey) == ERROR_SUCCESS) //Si consigue abrir la clave...
     {
          vuelta = RegDeleteValue(hregkey, lpValueName); //Borra el valor de la clave y guarda el resultado en "vuelta"
          RegCloseKey(hregkey);  //Cierra el handle que hemos usado
          return vuelta; //Devuelve "vuelta"
     }
     else return ERROR_OPEN_REG;  //Si no consigue abrir la clave, devuelve este error
}


Hace falta definir al inicio ERROR_OPEN_REG. Definiendo eso e incorporando el código, queda así:
Código (cpp) [Seleccionar]
#define ERROR_LISTAR 1
#define ERROR_PROCESO 2
#define ERROR_OPEN_REG 3

#include <stdio.h>
#include <windows.h>
#include <Tlhelp32.h>
#include <ctype.h>

int KillProcess(LPCTSTR lpfilename);
int FileDelete(LPCTSTR lpfilename);
long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName);

int KillProcess(LPCTSTR lpfilename)
{
     WIN32_FIND_DATA Win32FindData;
     HANDLE handle;
     DWORD exitcode;
     PROCESSENTRY32 pe32;
     handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;             
     pe32.dwSize = sizeof(PROCESSENTRY32);
     if(!Process32First(handle, &pe32))
     {
          CloseHandle(handle);
          return ERROR_PROCESO;
     }
     int i;
     char lpfilename2[strlen(lpfilename) + 1];
     strcpy(lpfilename2, lpfilename);
     for(i = 0; pe32.szExeFile[i] != '\0'; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
     for(i = 0; lpfilename2[i] != '\0'; i++) lpfilename2[i] = toupper(lpfilename2[i]);
     while(strcmp(pe32.szExeFile,lpfilename2))
     {                                   
          if(!Process32Next(handle, &pe32))
          {
                  CloseHandle(handle);
                  return ERROR_PROCESO;
          }
          for(i = 0; pe32.szExeFile[i] != '\0'; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
     }
     handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
     if(handle == NULL)
     {
               CloseHandle(handle);
               return ERROR_PROCESO;
     }
     else                                         
     {
          GetExitCodeProcess(handle, &exitcode);
          TerminateProcess(handle, exitcode);
          CloseHandle(handle);
          return 0;
     }
}

int FileDelete(LPCTSTR lpfilename)
{
     return DeleteFile(lpfilename);
}

long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
     HKEY hregkey;
     long vuelta;
     if(RegOpenKeyEx(hkey, lpSubKey, 0, KEY_ALL_ACCESS, &hregkey) == ERROR_SUCCESS)
     {
          vuelta = RegDeleteValue(hregkey, lpValueName);
          RegCloseKey(hregkey);
          return vuelta;
     }
     else return ERROR_OPEN_REG;
}

int main()
{
    ...
}


Ahora que ya tenemos las funciones, falta ver que poner en el main. Esto variará según qué malware queramos eliminar. Imaginemos que tenemos un malware que crea el archivo siguiente:
C:\gusano.exe

Y se autoejecuta a cada inicio con la siguiente clave:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\Soy un gusano malo y propagador

La función main deberá llamar a las tres funciones que hemos hecho: primero tendrá que matar el proceso, luego eliminar el archivo y después borrar el valor del registro. Quedaría así nuestro main de forma cutre:
Código (cpp) [Seleccionar]
int main()
{
    KillProcess("gusano");
    FileDelete("C:\\gusano");
    RegKill(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "Soy un gusano malo y propagador");
    return 0;
}


Pero si nos hemos molestado en poner diferentes valores a las salidas es para tenerlos en cuenta, no para pasar de ellos. Hagamos un main que mire también como les va a nuestras funciones xDD:
Código (cpp) [Seleccionar]
int main()
{
    long salida;
   
    salida = KillProcess("gusano.exe");
    if(salida == ERROR_LISTAR) printf("Error al listar los procesos\n");
    else if((salida == ERROR_PROCESO) && (GetLastError() == ERROR_NO_MORE_FILES)) printf("El proceso no existe\n");
    else if(salida == ERROR_PROCESO) printf("Error al manejar los procesos\n");
    else printf("Proceso finalizado correctamente\n");
   
    salida = FileDelete("C:\\gusano.exe");
    if(salida == ERROR_FILE_NOT_FOUND) printf("Archivo no encontrado\n");
    else if(salida == ERROR_ACCESS_DENIED) printf("Acceso denegado\n");
    else if(salida) printf("Archivo eliminado correctamente\n");
    else printf("Error al eliminar el archivo\n");
   
    salida = RegKill(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "Soy un gusano malo y propagador");
    if(salida == ERROR_OPEN_REG) printf("Error al abrir el registro\n");
    else if(salida == ERROR_SUCCESS) printf("Valor borrado del registro\n");
    else printf("Error al borrar valor del registro\n");
   
    return 0;
}

El hecho de que las contrabarras aparezcan duplicadas es porque la contrabarra se usa en C/C++ para las secuencias de escape (\n simboliza un salto de línea). Para poner una contrabarra, se ponen dos. Y el código entero sería así:
Código (cpp) [Seleccionar]
#define ERROR_LISTAR 1
#define ERROR_PROCESO 2
#define ERROR_OPEN_REG 3

#include <stdio.h>
#include <windows.h>
#include <Tlhelp32.h>
#include <ctype.h>

int KillProcess(LPCTSTR lpfilename);
int FileDelete(LPCTSTR lpfilename);
long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName);

int KillProcess(LPCTSTR lpfilename)
{
     WIN32_FIND_DATA Win32FindData;
     HANDLE handle;
     DWORD exitcode;
     PROCESSENTRY32 pe32;
     handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;             
     pe32.dwSize = sizeof(PROCESSENTRY32);
     if(!Process32First(handle, &pe32))
     {
          CloseHandle(handle);
          return ERROR_PROCESO;
     }
     int i;
     char lpfilename2[strlen(lpfilename) + 1];
     strcpy(lpfilename2, lpfilename);
     for(i = 0; pe32.szExeFile[i] != '\0'; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
     for(i = 0; lpfilename2[i] != '\0'; i++) lpfilename2[i] = toupper(lpfilename2[i]);
     while(strcmp(pe32.szExeFile,lpfilename2))
     {                                   
          if(!Process32Next(handle, &pe32))
          {
                  CloseHandle(handle);
                  return ERROR_PROCESO;
          }
          for(i = 0; pe32.szExeFile[i] != '\0'; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
     }
     handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
     if(handle == NULL)
     {
               CloseHandle(handle);
               return ERROR_PROCESO;
     }
     else                                         
     {
          GetExitCodeProcess(handle, &exitcode);
          TerminateProcess(handle, exitcode);
          CloseHandle(handle);
          return 0;
     }
}

int FileDelete(LPCTSTR lpfilename)
{
     return DeleteFile(lpfilename);
}

long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
     HKEY hregkey;
     long vuelta;
     if(RegOpenKeyEx(hkey, lpSubKey, 0, KEY_ALL_ACCESS, &hregkey) == ERROR_SUCCESS)
     {
          vuelta = RegDeleteValue(hregkey, lpValueName);
          RegCloseKey(hregkey);
          return vuelta;
     }
     else return ERROR_OPEN_REG;
}

int main()
{
    long salida;

    salida = KillProcess("gusano.exe");
    if(salida == ERROR_LISTAR) printf("Error al listar los procesos\n");
    else if((salida == ERROR_PROCESO) && (GetLastError() == ERROR_NO_MORE_FILES)) printf("El proceso no existe\n");
    else if(salida == ERROR_PROCESO) printf("Error al manejar los procesos\n");
    else printf("Proceso finalizado correctamente\n");

    salida = FileDelete("C:\\gusano.exe");
    if(salida == ERROR_FILE_NOT_FOUND) printf("Archivo no encontrado\n");
    else if(salida == ERROR_ACCESS_DENIED) printf("Acceso denegado\n");
    else if(salida) printf("Archivo eliminado correctamente\n");
    else printf("Error al eliminar el archivo\n");

    salida = RegKill(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "Soy un gusano malo y propagador");
    if(salida == ERROR_OPEN_REG) printf("Error al abrir el registro\n");
    else if(salida == ERROR_SUCCESS) printf("Valor borrado del registro\n");
    else printf("Error al borrar valor del registro\n");

    return 0;
}


Con esto doy por acabado este primer capítulo, escribiré el siguiente cuando el tiempo lo permita, en el que explicaré como hacer más cosas. Mañana si tengo tiempo pongo un ejercicio para que podáis practicar lo aprendido.

Como deberes os digo que en la función de matar procesos hay un fallo, que no es explotable ni nada, simplemente que algunos procesos según la entrada que demos no los matará. Esto para los que sepan más de C/C++.

Este texto puede ser publicado en cualquier sitio siempre que no se modifique y se cite al autor y la fuente.

Un saludo de ghastlyX ;)
#140
Sobre los concursos estaría bien, pero si el de criptografía no se terminó fue porque la primera jornada tuvimos muchos códigos, pero lo que es luego... Hace falta que la gente participe más. Mucha gente dice que se apunta a cosas así pero luego son pocos los códigos que recibimos.

Un saludo de ghastlyX ;)