O Melhor Fórum de Segurança da Web

[Tutorial]Fazendo o seu Code Injection

Área destinada a componentes, sources, funções, exemplos.

Mensagempor R0Dr1g0 » 25 Abr 2009, 17:34

Visto que é algo muito util e um pouco complicado estarei postando como fazer passo a passo.
Então vamos começar.

Dica:
Para quem não esta acostumado e sequer sabe sobre manipulação de memória recomendo que de uma boa lida em artigos sobre manipulação de memória para que haja uma facilidade de entendimento ao seguir a leitura do tutorial.

O que é Code Injection?
Code injection nada mais é do que injetar uma DLL e fazer com que o processo remoto execute a tal função.
Para fazer isso precisaremos de uma DLL que a função em seja exportada
Ex:no delphi o fim do código seria
Código: Selecionar tudo
exports
FazerExitProcess;


Outro detalhe importante é que precisaremos de privilégios necessários.Para evitar quaisquer eventuais problemas, definiremos o privilégio como o de debug e tambem depois de executada a rotina, não temos mais porque deixar os parametros utilizados na execução da mesma no target, isso só iria ocupar espaço, então nós liberaremos toda a memória escrita no processo remoto.

Preparando um Code Injection

Antes de mais nada precisaremos de uma estrutura para os parametros do nosso Code Injection então declare
a seguinte type no seu form
Código: Selecionar tudo
type
  TInjectParams = record
    LoadLibrary: function (lpLibFileName: PAnsiChar): Cardinal; stdcall;
    LibName: PAnsiChar;
    GetProcAddress: function (hModule: Cardinal; lpProcName: PAnsiChar): Pointer; stdcall;
    ProcName: PAnsiChar;
  end;
  PInjectParams = ^TInjectParams;

Com essa estrutura,o usuário no final do code injection só precisará de pegar o Process ID(PID) do processo,Portanto declare na uses da sua unit a biblioteca TlHelp32 e nas funções declare a seguinte função
Código: Selecionar tudo
function GetProcess(proc: string): Cardinal;
var
Snap: THandle;
pe: TProcessEntry32;
begin
Snap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if Snap = 0 then Exit;
if Process32First(Snap,pe) then
  begin
  repeat
    if proc = pe.szExeFile then
      begin
      Result:=pe.th32ProcessID;
      break;
      end;
  until not Process32Next(Snap,pe)
  end
end;


Como ja foi dito,nos precisaremos de escrever na memória do processo remoto,portanto é necessário alocar a memória para a escrita,para facilitar vamos declarar as funções
Código: Selecionar tudo
function WriteString(Process: Cardinal; s: string): Pointer;
var
bytes: Cardinal;
begin
Result:=VirtualAllocEx(Process, nil, length(s) + 1, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Process, Result , pchar(s), length(s) + 1, bytes);
end;

function WriteData(Process, dwSize: Cardinal; RemoteData: pointer): pointer;
var
bytes: Cardinal;
begin
Result:=VirtualAllocEx(Process, nil, dwSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(Process, Result, RemoteData, dwSize, bytes);
end;



Com quase tudo pronto nós precisaremos de uma função para executar o código no processo remoto então declare mais essa função tambem
Código: Selecionar tudo
procedure RemoteFunction(Parametros: PInjectParams); stdcall;
var
proc: procedure; stdcall;
begin
proc:=Parametros^.GetProcAddress(Parametros^.LoadLibrary(Parametros^.LibName),Parametros^.ProcName);
proc;
end;


Agora precisaremos de um método para saber o tamanho dessa rotina descrita acima, pois na hora de escrevê-la no target é necessário por o tamanho. Para isso faremos outro método logo abaixo desse, e depois é só pegar o endereço dele e subtrair do endereço da rotina "RemoteFunction".
Então declare o procedimento :
Código: Selecionar tudo
procedure RemoteFunctionEnd; stdcall;
begin;
end;


E como ja foi dito nos preciaremos de privilégios de DEBUG então declare a função
Código: Selecionar tudo
procedure ChangePrivilege(szPrivilege: PChar; fEnable: Boolean);
var
  NewState: TTokenPrivileges;
  luid: TLargeInteger;
  hToken: THandle;
  ReturnLength: DWord;
begin
  OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, hToken);
  LookupPrivilegeValue(nil, szPrivilege, luid);

  NewState.PrivilegeCount := 1;
  NewState.Privileges[0].Luid := luid;
  if (fEnable) then
    NewState.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
  else
    NewState.Privileges[0].Attributes := 0;

  AdjustTokenPrivileges(hToken, False, NewState, SizeOf(NewState), nil, ReturnLength);
  CloseHandle(hToken);
end;

Pronto, agora só falta montar a função final, mas depois de tudo isso, para quem realmente entendeu a lógica fica fácil.
Código: Selecionar tudo
pprocedure Inject(process, dll, code: string);
var
PID, hProcess, ThreadId, ThreadHandle: Cardinal;
RemoteData,RemoteFunc,LibFileName,ProcName: pointer;
Parametros: TInjectParams;
begin
//Pega o Handle do processo
PID:=GetProcess(Process);

//Seta o privilégio de debug
ChangePrivilege('SeDebugPrivilege', True);

//Abre o processo
hProcess := OpenProcess(PROCESS_ALL_ACCESS, False, PID);

//Define os parâmetros que serão usados para executar a procedure
LibFileName:=WriteString(hProcess, dll);
ProcName:=WriteString(hProcess, code);
Parametros.LoadLibrary:=GetProcAddress(GetModuleHandle('kernel32'), 'LoadLibraryA');
Parametros.LibName:=LibFileName;
Parametros.GetProcAddress:=GetProcAddress(GetModuleHandle('kernel32'), 'GetProcAddress');
Parametros.ProcName:=ProcName;

//Abre um novo espaço de memória para guardar os parâmetros
RemoteData:=WriteData(hProcess, sizeof(Parametros), @Parametros);

//Abre um novo espaço de memória para guardar a procedure
RemoteFunc:=WriteData(hProcess, integer(@RemoteFunctionEnd) - integer(@RemoteFunction), @RemoteFunction);

//Cria a thread que executará a procedure
ThreadHandle:=CreateRemoteThread(hProcess, nil, 0, RemoteFunc, RemoteData, 0, ThreadId);
WaitForSingleObject(ThreadHandle, 3000);

//Libera as alocações de memórias criadas
VirtualFreeEx(hProcess,LibFileName,0,MEM_RELEASE);
VirtualFreeEx(hProcess,ProcName,0,MEM_RELEASE);
VirtualFreeEx(hProcess,RemoteFunc,0,MEM_RELEASE);
VirtualFreeEx(hProcess,RemoteData,0,MEM_RELEASE);
end;




Agora chegou a parte que você ira realizar o code injection.
Como ja foi dito precisaremos de uma DLL com uma função que seja exportada então salve todo o seu projeto e crie um novo projeto de DLL.vou mostrar como ficou a minha dll de testes
Código: Selecionar tudo
library testdll;

uses
  Windows,
  SysUtils,
  Classes;

{$R *.res}

procedure MsgBox;
begin
MessageBox(0,'Funcionou','Code Injection bem sucedido',MB_OK+MB_ICONINFORMATION);
end;
exports
MsgBox;
begin

end.


Então agora é só no seu projeto do Injector você usar a função
Código: Selecionar tudo
Inject('notepad.exe','C:\Dev\CodeInjection\testdll\testdll.dll','MsgBox');


Agora pra quem não entendeu direito,ou não quer nem ler e quer tudo pronto eu coloquei um link com a source do injector e da testdll
http://www.4shared.com/file/101714263/6 ... ction.html
senha :by_R0Dr1g0


Bom proveito
Avatar de usuário
R0Dr1g0
Estudante
Estudante
 
Mensagens: 223
Data de registro: 22 Set 2006, 18:08
Localização: Somewhere in arizona

Mensagempor R0Dr1g0 » 25 Abr 2009, 17:37

Ops postei na area errada,algum mod ou admin poderia mover pra area certa
Abraços!
Avatar de usuário
R0Dr1g0
Estudante
Estudante
 
Mensagens: 223
Data de registro: 22 Set 2006, 18:08
Localização: Somewhere in arizona

Mensagempor Otávio Ribeiro » 25 Abr 2009, 19:02

Cara,

Movido para a área correta.

]['s, Otávio Ribeiro
Avatar de usuário
Otávio Ribeiro
Invasão Administrador
Invasão Administrador
 
Mensagens: 1080
Data de registro: 01 Ago 2006, 18:39
Localização: Goiás

Mensagempor log_22 » 25 Abr 2009, 19:04

Obrigado Rodrigo por tar compartilhando esse codigo.


Até mais.
Dúvidas apenas por forum, para entrar em contato comigo me mande uma MP
Avatar de usuário
log_22
Estudante
Estudante
 
Mensagens: 112
Data de registro: 15 Nov 2006, 19:32
Localização: FindWindow(nil, 'You are owned by log_22!');

Mensagempor rafapa23 » 09 Set 2009, 15:30

Muito bom este tutorial ! Pàrabéns
rafapa23
Iniciante
Iniciante
 
Mensagens: 20
Data de registro: 13 Mai 2009, 20:28

Mensagempor aldoduju » 08 Dez 2009, 20:35

rodrigo eu so nao entendi a parte de (função que sera injetada no processo ) .. pode me explicar ?
aldoduju
Iniciante
Iniciante
 
Mensagens: 1
Data de registro: 08 Dez 2009, 20:19


Retornar para Delphi/Pascal

Login Form