J'essaie d'effectuer un appel système sur 32 bits, mais il y a un problème.

J'avais à l'origine une fonction nue comme stub et j'utilisais un assemblage en ligne, mais lorsque j'ai essayé de la transformer en shellcode, bien qu'il s'agisse d'une copie 1 à 1 de la fonction nue (en la regardant dans le désassemblage de Visual Studio), il ne fonctionne pas (violation d'accès en cours d'exécution NULL).

Cela fonctionnait parfaitement avec la fonction nue, d'ailleurs.

Voici le shellcode que j'ai écrit :

0:  b8 26 00 00 00        mov    eax,0x26
5:  64 ff 15 c0 00 00 00  call   DWORD PTR fs:0xc0
c:  c3                           ret

Et voici le code : Tout fonctionne bien. La mémoire est allouée avec succès, le problème est chaque fois que j'essaie d'appeler NtOpenProcess : il tente d'exécuter un pointeur null, ce qui entraîne une violation d'exécution d'accès.

typedef NTSTATUS(NTAPI * f_NtOpenProcess)(PHANDLE, ACCESS_MASK, OBJECT_ATTRIBUTES *, CLIENT_ID *);
 
INT
main(
    VOID
)
{
    HANDLE            hProcess  = NULL;
    OBJECT_ATTRIBUTES oaAttributes;
    memset(&oaAttributes,
           NULL,
           sizeof(oaAttributes));
    oaAttributes.Length         = sizeof(oaAttributes);
 
    CLIENT_ID        ciClient;
    ciClient.UniqueProcess      = GetCurrentProcessId();
    ciClient.UniqueThread       = NULL;
    
    BYTE Stub[] = { 0xB8, 0x00, 0x00, 0x00, 0x00, 0x64, 0xFF, 0x15, 0x0C, 0x00, 0x00, 0x00, 0xC3 };
    *(DWORD*)(Stub + 1) = 0x26;
    PVOID Mem = VirtualAlloc(NULL, sizeof(Stub), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    memcpy(Mem, &Stub, sizeof(Stub));
    DWORD Old = NULL;
    VirtualProtect(Mem, sizeof(Stub), PAGE_EXECUTE, &Old);
 
    f_NtOpenProcess NtOpenProcess = (f_NtOpenProcess)Mem;
 
    DWORD Status = NtOpenProcess(&hProcess,
                                 PROCESS_ALL_ACCESS,
                                 &oaAttributes,
                                 &ciClient);
 
    printf("Status: 0x%08X\nHandle: 0x%08X\n",
           Status,
           hProcess);
 
    getchar();
 
    return NULL;
}

Si quelqu'un se demande pourquoi je fais ça, je m'ennuie vraiment et j'aime jouer avec le code quand je le fais :)

1
Yung Lew 15 nov. 2020 à 18:30

1 réponse

Meilleure réponse

Comme l'a noté Micheal Petch, le shellcode était erroné. Je n'ai manqué qu'un octet (0x0C) qui devrait être 0xC0.

Si quelqu'un tente un jour quelque chose d'aussi stupide et inutile que je l'ai fait, vérifiez d'abord votre shellcode !

1
Yung Lew 15 nov. 2020 à 18:36