Problema sobre inyección de DLL desde shellcode

Iniciado por Kaxperday, 8 Septiembre 2016, 21:30 PM

0 Miembros y 2 Visitantes están viendo este tema.

Kaxperday

Buenas gente,

Estoy haciendo pruebas con una DLL inyectandola en un proceso pero lo que quiero hacer es hacer esa inyección pasando los bytes de la dll a una shellcode y utilizar esa shellcode en otro programa para realizar la inyección en el proceso objetivo, pero el programa me crashea en la inyección, sin embargo para otras shellcodes si que funciona, por lo tanto creo que puede ser problema de la generación de la shellcode desde la dll, ¿tengo que pasar todos los bytes de la dll a la shellcode?, si es así es lo que he hecho y esbozé un programa algo chapucero para automatizarlo que se encarga de generar un txt con la shellcode pasandole el path de la dll:

Código (cpp) [Seleccionar]


{
       WCHAR filePath[MAX_PATH];

wcout << "Introduce el path del archivo que quieres pasar a shellcode: " << endl;
wcin >> filePath;
fflush(stdin);

       HANDLE hFile;

if ((hFile = CreateFile(filePath, GENERIC_READ, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_HIDDEN, NULL)) != INVALID_HANDLE_VALUE)
{
DWORD fileSize;

if ((fileSize = GetFileSize(hFile, NULL)) != INVALID_FILE_SIZE)
{
CHAR *buffer = new CHAR[fileSize]();

if (ReadFile(hFile, buffer, fileSize, NULL, NULL))
{
FILE *a;

a = fopen("shellcode.txt", "wt");

for (DWORD i = 0; i < fileSize; i++)
{
fprintf(a, "%s", "\\x%.2X", (UCHAR)buffer[i]);
if (i % 20 == 0 && i != 0)
fprintf(a, "\"\n\"");
}

                                delete[] buffer;

fclose(a);

cout << "ok";
}
               }
               CloseHandle(hFile);
       }

       return 0;
}


Luego  procedo a declarar la shellcode como una variable static CHAR* en otro programa desde donde quiero inyectarla en otro proceso, pero crashea, sin embargo para otras shellcodes no lo hace, luego ese código parece estar bien.

¿Falla en algo la generación del payload, debo copiar todos los bytes o ignorar algunos casos?

Saludos y gracias.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

ivancea96

Código (cpp) [Seleccionar]
fprintf(a, "%s", "\\x%.2X", (UCHAR)buffer[i]);

Quita ese "%s" al principio. Eso está generando "\\x%.2X" sin más.
El cast a (UCHAR) sobra. El tipo de argumento sobra en una función con argumentos variables.

No deberías poner "fflush(stdin)". Usa getline si quieres coger una linea completa.

Kaxperday

Hola ivancea un placer verte por aqui, pues vaya se ve que edite mal el codigo y me equivoque en el fprintf, ya que es como dices, sobra el %s de hecho deberia haber generado error de compilador, sin embargo respecto a la conversion a UCHAR la hago para que no me salgan bytes negativos de la forma de 0xFFFFFFAB como me ocurrio que luego generan error en la declaracion de la shellcode, de esta manera ahorro esos problemas con el casteo. Sin embargo la autentica duda es: si cojo una dll de un messagebox por ejemplo y paso todos sus byte a una shellcode e inyecto la shellcode ¿deberia de inyectarse la dll sin problemas no?. La dll que uso para la shellcode hace un messagebox y la he inyectado en procesos sin problemas pero a la hora de inyectarla como shellcode surgen los problemas y crashea el proceso objetivo, soy nuevo en esto y aun no he encontrado algo bueno que me explique como funciona esto de las dll las shellcode etc, asi que investigando y a mi ritmo.

Daludos y gracias.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

BloodSharp

#3
Cita de: Kaxperday en  9 Septiembre 2016, 04:09 AMsin embargo respecto a la conversion a UCHAR la hago para que no me salgan bytes negativos de la forma de 0xFFFFFFAB como me ocurrio que luego generan error en la declaracion de la shellcode, de esta manera ahorro esos problemas con el casteo.

Puedes ahorrarte ese problema ya con declarar el buffer como PUCHAR en lugar de PCHAR...

Cita de: Kaxperday en  9 Septiembre 2016, 04:09 AMSin embargo la autentica duda es: si cojo una dll de un messagebox por ejemplo y paso todos sus byte a una shellcode e inyecto la shellcode ¿deberia de inyectarse la dll sin problemas no?. La dll que uso para la shellcode hace un messagebox y la he inyectado en procesos sin problemas pero a la hora de inyectarla como shellcode surgen los problemas y crashea el proceso objetivo

Cada archivo PE tiene al inicio la cabecera DOS, la cabecera PE, secciones de información extras, si es libería/driver o utiliza ASLR seguro tiene secciones de reubicaciones (.reloc), secciones de datos globales (.*data), secciones de importaciones y exportaciones (.import / .export si mal no recuerdo), secciones de código ejecutable (.text / .code , etc...) y algunas veces secciones de recursos.
Si lo que quieres hacer es pasar todo a una secuencia de bytes y enviarselos directamente a un programa y redireccionar un hilo de ejecución al primer byte estás frito, dado que no está apuntando a código real sino a información del archivo PE.
Cuando inyectas con otros métodos por ejemplo hilo remoto con LoadLibrary, el API de dicho proceso se encarga de cargar y verificar si es un archivo PE, procesar los datos, cargar módulos dependientes, reubicar los datos del código a ejecutarse en caso de que esté ocupado la mismas direcciones virtuales del proceso por otro módulo y capaz algo más que se me olvide de momento.
Conclusión tendrías que no solamente inyectar el código sino que además realizar las mismas tareas que el PELoader a mano desde otro proceso lo cuál se vuelve una tarea demasiado tediosa y mucho más si además tienes que cargar dependencias...

EDIT: Capaz te sirva (como una sugerencia de una flasheada que se me ocurrió recién :xD) crear un ejecutable normal sin ASLR, lo cuál te evitarías la tabla de reubicaciones, evitar objetos o variables globales para la secciones de datos (usando únicamente locales), evitar llamar a APIs del SO directamente para evitar la secciones de import creando tus propias GetProcAddress, GetModuleHandle y LoadLibrary (en internet hay info) si necesitas APIs. En lugar de recopilar todos los bytes del PE solo obtienes los de la sección/es ejecutable/s y el offset de tu función inicializadora (main), creando primero un JUMP CALL al principio del payload hacia el main y luego metiendo todos los bytes recogidos de la/s sección/es ejecutable/s.


B#



Kaxperday

Ya veo es más complicado de lo que parecía, buscando por github encontré un proyecto que se supone que hacía lo que busco: "MakeCode", lo he probado y no ha funcionado, parece como que añade una cabecera a la shellcode y luego la dll del tirón separada por un flag (payload + flag + context según su código). El caso es que genera un txt que pasandolo a cadena hexadecimal para poner en la shellcode el resultado es que crashea el programa a inyectar, visto lo visto optaré por poner la dll en una shellcode byte a byte y generar el archivo dll con la shellcode e inyectar después, ahora mismo lo veo lo más simple ya que la dll sería un proyecto con numerosas dependencias llamadas a librerías etc.. ¿Que os parece?.

Gracias y un saludo.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.

BloodSharp

Cita de: Kaxperday en 10 Septiembre 2016, 18:25 PMvisto lo visto optaré por poner la dll en una shellcode byte a byte y generar el archivo dll con la shellcode e inyectar después, ahora mismo lo veo lo más simple ya que la dll sería un proyecto con numerosas dependencias llamadas a librerías etc.. ¿Que os parece?.

No entiendo cuál es el objetivo de hacer la shellcode, si ya puedes inyectar una dll en el "proceso objetivo" de la manera común y que el Windows te la cargue correctamente con sus dependencias... Además no te salvás de hacer la tarea de cargarla como el SO excepto que ya no tenés que parchear el shellcode desde el "proceso atacante" sino desde el "proceso objetivo"...


B#



Kaxperday

Buenas pues prefería crear una shellcode con todo el contenido de la DLL para poder inyectarla directamente sin necesidad de crear el archivo dll, ahorrar espacio y también para descifrar su payload cada vez que se vaya a inyectar y el código quede más protegido (sin exponer el archivo dll con el código al desnudo), pues la idea es crear un exe que inyecte una dll (un solo archivo).

Sin embargo, vistas las complicaciones de las que hablas creo que pondre la dll como shellcode byte a byte así pues crearé un archivo dll con su código para su posterior inyección, aunque tiene sus desventajas como dije, pero siendo una dll con mucho código y dependencias creo que será lo mejor. Cifraré su código en el payload del exe y lo descifraré cuando se ejecute el exe que creará la dll y la inyectará. :P

Saludos.
Cuando el poder económico parasita al político ningún partido ni dictador podrá liberarnos de él. Se reserva el 99% ese poder.