
Offusca API specifiche di Windows con API diverse
Oscura (nascondi) le importazioni PE dagli strumenti di analisi statica/dinamica.
È abbastanza semplice, supponiamo di aver usato VirtualProtect e vogliamo oscurarlo con Sleep, lo strumento manipolerà l'IAT in modo che il thunk che punta a VirtualProtect punti invece a Sleep, ora all'esecuzione del file, il caricatore di Windows caricherà Sleep invece di VirtualProtect, e sposta l'esecuzione al punto di ingresso, da lì l'esecuzione verrà reindirizzata allo shellcode, posizionato prima dallo strumento, per trovare l'indirizzo di VirtualProtect e usarlo per sostituire l'indirizzo di Sleep assegnato in precedenza dal caricatore.
#include <cobf.hpp>
int main() {
cobf obf_file = cobf("sample.exe");
obf_file.load_pe();
obf_file.obf_sym("kernel32.dll", "SetLastError", "Beep");
obf_file.obf_sym("kernel32.dll", "GetLastError", "GetACP");
obf_file.generate("sample_obfuscated.exe");
obf_file.unload_pe();
return 0;
};
config.ini).cobf.exe <file input> <file output> [file config]; Template per il file di configurazione:
; * Le sezioni possono essere scritte come:
; [nome_dll]
; vecchio_simbolo=nuovo_simbolo
; * Il nome della dll non è sensibile alle maiuscole, ma
; il vecchio e il nuovo simbolo lo sono.
; * Puoi usare il carattere jolly sia sul
; nome della dll che sul vecchio simbolo.
; * Puoi usare '#' all'inizio di
; il vecchio o il nuovo simbolo per contrassegnare
; un ordinale.
; * Il nuovo simbolo deve essere esportato
; dalla dll affinché il caricatore di Windows possa risolverlo.
; Per esempio:
; * Oscurare tutti i simboli
; importati da user32.dll con ordinale 1600.
[user32.dll]
*=#1600
; * Oscurare i simboli importati sia da
; kernel32.dll che da kernelbase.dll con Sleep.
[kernel*.dll]
*=Sleep
; * Oscurare fprintf con exit.
[*]
fprintf=exit
Compila questo esempio di codice
#include <windows.h>
#include <stdio.h>
int main() {
SetLastError(5);
printf("Last error is %d\n", GetLastError());
return 0;
};
Dopo averlo compilato, ecco come appaiono le importazioni di kernel32

Ora oscuriamo sia SetLastError che GetLastError con Beep e GetACP (in realtà qualsiasi api da kernel32 andrà bene anche se non è importata affatto).
Le configurazioni utilizzate sono
[kernel32.dll]
SetLastError=Beep
GetLastError=GetACP
Ecco l'output (puoi anche usare la libreria direttamente come mostrato sopra).

Ancora, diamo un'occhiata alle importazioni di kernel32

Non c'è traccia di SetLastError o GetLastError
Una conferma che i due file funzioneranno correttamente

IDA HexRays Decompiler

IDA Debugger

Ghidra

ApiMonitor

Questo perché tutti gli strumenti di analisi statica dipendono dal nome dell'api scritto nell'IAT, che può essere manipolato come mostrato.
Per ApiMonitor, a causa dell'uso dell'hooking dell'IAT, esiste lo stesso problema.
D'altra parte, per strumenti come x64dbg, i nomi delle api mostrati dipenderanno solo da ciò che viene effettivamente chiamato (non da ciò che è scritto nell'IAT).

.cobf per contenere lo shellcode e gli altri dati necessari.git clone https://github.com/d35ha/CallObfuscator.