IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

x86 32-bits / 64-bits Assembleur Discussion :

null byte et exécution en c++


Sujet :

x86 32-bits / 64-bits Assembleur

  1. #1
    Invité
    Invité(e)
    Par défaut null byte et exécution en c++
    Bonjour,
    Je ne programme pas du tout en assembleur, j'ai vraiment besoin d'aide , a l'aide de windbg j'ai pu obtenir l'assembleur du programme ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    typedef BOOL (FAR PASCAL *BEEP)(DWORD, DWORD);
     
    int main(int argc, char* argv[])
    {
    	BEEP  Beep;
     
    	HINSTANCE kernel32 = LoadLibrary(L"Kernel32");
    	if (kernel32 != NULL)
    	{
    		Beep = (BEEP)GetProcAddress(kernel32, "Beep");
     
    		if (Beep != NULL)
    		{
    			(*Beep)(2000, 20000);
    		}
     
    	}
     
    	FreeLibrary(kernel32);
    J'ai ensuite mon shellcode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    \x0f\x99\xc1\x33\xc0\x89\x0f\x40\x5f\x5e\xc3\x90\x90\x90\x90\x90\x6a\x2c\x68\x88\x2b\x8f\x77\xe8\x38\xdb\xf8\xff\x8b\x1f\x64\x8b\x3d\x18\x00\x00\x00\x8d\x45\xe0\x50\x6a\x00\xff\x77\x08\x6a\xff\xe8\09\x93\xf8\xff\x85\xc0\x78\x61\x8b\x55\xc8\x81\xc2\x00\x30\x00\x00\x8b\x47\x04\x05\x00\xf0\xff\xff\x89\x45\xe4\x3b\xc6\x76\x08\x8b\xc8\x2b\xce\x3b\xca\x83\x65\xfc\x00\x3b\xc1\x72\x0f\x8b\x00
    Le premier problème c'est que j'ai plein de null bytes partout et que je ne sais pas comment les enlever

    Ensuite je n'arrive pas exécuté le code d'assembleur dans un bloc __asm{} en c++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    int main(int argc, char* argv[])
    {
    	__asm{
     
    		setns   cl
    			xor     eax, eax
    			mov     dword ptr[edi], ecx
    			inc     eax
    			pop     edi
    			pop     esi
    			ret
    			nop
    			nop
    			nop
    			nop
    			nop
    			push    2Ch
    			push    offset ntdll!LdrResolveDelayLoadsFromDll + 0xfcf (778f2b88)
    			call    ntdll!RtlInitializeCriticalSectionAndSpinCount + 0x3e (77880630)
    			mov     esi, ecx
    			mov     edi, dword ptr fs : [18h]
    			lea     eax, [ebp - 20h]
    			push    eax
    			push    1Ch
    			lea     eax, [ebp - 3Ch]
    			push    eax
    			push    0
    			push    dword ptr[edi + 8]
    			push    0FFFFFFFFh
    			call    ntdll!ZwQueryVirtualMemory(7787be20)
    			test    eax, eax
    			js      ntdll!LdrResolveDelayLoadsFromDll + 0xfc3 (778f2b7c)
    			mov     edx, dword ptr[ebp - 38h]
    			add     edx, 3000h
    			mov     eax, dword ptr[edi + 4]
    			add     eax, 0FFFFF000h
    			mov     dword ptr[ebp - 1Ch], eax
    			cmp     eax, esi
    			jbe     ntdll!LdrResolveDelayLoadsFromDll + 0xf82 (778f2b3b)
    			mov     ecx, eax
    			sub     ecx, esi
    			cmp     ecx, edx
    			ja      ntdll!LdrResolveDelayLoadsFromDll + 0xf84 (778f2b3d)
    			mov     ecx, edx
    			and     dword ptr[ebp - 4], 0
    			cmp     eax, ecx
    			jb      ntdll!LdrResolveDelayLoadsFromDll + 0xf9b (778f2b54)
    			mov     eax, dword ptr[eax]
    	}
    }
    De multiple warning et erreur :
    Avertissement 10 warning C4405: 'test'*: cet identificateur est un mot réservé
    Avertissement 16 warning C4405: 'mov'*: cet identificateur est un mot réservé
    etc

    Erreur 1 error C2400: erreur de syntaxe d'assembleur inline dans 'second opérande'*; trouvé 'bad token'
    Erreur 4 error C2400: erreur de syntaxe d'assembleur inline dans 'opcode'*; trouvé 'bad token'
    Erreur 20 error C2041: chiffre 'f' non conforme pour la base '2'
    Erreur 2 error C2041: chiffre 'f' non conforme pour la base '10'


    Merci pour votre aide.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Bonjour, et salut les amis depuis le temps.

    Ca fait un moment que je n'ai pas fait de shellcode, mais il y a énormément de site web qui en parle, tu trouveras toutes les réponses rapidement.

    Il y a par exemple la méthode des adresses négatives.
    J'ai posté sur le sujet:
    http://www.developpez.net/forums/d13...ttre-registre/

    C'est une des méthodes.
    Après tu peux aussi changer d'instruction. Donc remplacer une instruction par une autre ou plusieurs autres qui ne comporteront pas de null-byte.

  3. #3
    Invité
    Invité(e)
    Par défaut
    Merci pour ta réponse j'aurais le temps de regarder ça en fin de semaine mais pourquoi mon code C++ ne compile pas ? Ensuite j'imagine qu'il existe des moyens de faire ça sans connaître l'assembleur.
    Tu me propose de changer une instruction par une autre mais pour ça il faudrait que je recompile cela avec NASM (ou je pourrais le re-compiler directement avec visual studio avec le bloc asm?)et encore dé-compiler le binaire obtenu ?

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2013
    Messages
    397
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2013
    Messages : 397
    Points : 424
    Points
    424
    Par défaut
    Je connais peu le C++, mais ça ressemble à un problème de syntaxe.
    D'autres pourront mieux t'aider que moi.

    Pour ta deuxième question, tu peux voir ton code avec objdump par exemple.

  5. #5
    Membre confirmé Avatar de bifur
    passe le balais et l'aspirateur
    Inscrit en
    Mars 2008
    Messages
    314
    Détails du profil
    Informations personnelles :
    Âge : 38

    Informations professionnelles :
    Activité : passe le balais et l'aspirateur

    Informations forums :
    Inscription : Mars 2008
    Messages : 314
    Points : 550
    Points
    550
    Par défaut
    qu'est ce que tu souhaite faire exactement avec ton programme assembleur issue d'un programme C++?
    et pourquoi vouloir retirer les null byte du bytecode?

  6. #6
    Invité
    Invité(e)
    Par défaut
    Merci pour vos réponses,
    apparemment il est impossible d'éxécuter de l'asm win32 dans un asm{} en c++, maintenant j'ai essayé d’exécuter mon shellcode depuis un emplacement que j’alloue mais j'obtiens une violation d'accès ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    unsigned char shellcode[] = "\x0f\x99\xc1\x33\xc0\x89\x0f\x40\x5f\x5e\xc3\x90\x90"
    "\x90\x90\x90\x6a\x2c\x68\x88\x2b\x8f\x77\xe8\x38\xdb\xf8\xff\x8b\xf1"
    "\x64\x8b\x3d\x18\x00\x00\x00\x8d\x45\xe0\x50\x6a\x1c\x8d\x45\xc4\x50\x6a\x00\xff\x77\x08\x6a"
    "\xff\xe8\x09\x93\xf8\xff\x85\xc0\x78\x61\x8b\x55\xc8\x81\xc2\x00\x30"
    "\x00\x00\x8b\x47\x04\x05\x00\xf0\xff\xff\x89\x45\xe4\x3b\xc6\x76\x08"
    "\x8b\xc8\x2b\xce\x3b\xca\x77\x02\x8b\xca\x83\x65\xfc\x00\x3b\xc1\x72\x0f\x8b\x00";
     
    int main(int argc, char* argv[])
    {
    	typedef void(*fp)();
    	void * heap = (void *)VirtualAlloc(
    		NULL,
    		4096,
    		MEM_COMMIT | MEM_RESERVE,
    		PAGE_EXECUTE_READWRITE
    		);
    	CopyMemory(heap, shellcode, sizeof shellcode);
    	fp func = (fp)heap;
    	(*func)();
     
    	system("PAUSE");
    	return 0;
    }

  7. #7
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Bien le but premier du mode protégé est de fixer les limites du code et des données.
    Donc si tu essayes d'exécuter des données je trouve ça normal que ça coince

  8. #8
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Une piste ?

    dans un programme que j'ai sous la main, du code 386 est entré directement comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
     //386 instructions
        #define EMIT_DWORD(x) \
            __emit__((unsigned char)x);__emit__((unsigned char)(x>>8));\
            __emit__((unsigned char)(x>>16));__emit__((unsigned char)(x>>24))
     
        #define MOV_EAX(x) __emit__(0x66, 0xb8); EMIT_DWORD(x)
     
        #define MOV_VAR_EAX(x) __emit__(0x66); _asm mov WORD PTR x, ax
        #define MOV_VAR_EDX(x) __emit__(0x66); _asm mov WORD PTR x, dx
     
        #define MOV_EAX_VAR(x) __emit__(0x66); _asm mov ax, WORD PTR x
     
        #define OUT_EDX_EAX __emit__(0x66); _asm out dx, ax
        #define IN_EAX_EDX __emit__(0x66); _asm in ax, dx
     
        //#define RDTSC(x,y) __emit__(0x0f, 0x31); MOV_VAR_EAX(x); MOV_VAR_EDX(y)
    et utilisé plus loin comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
            _asm mov dx, WORD PTR addr
            MOV_EAX_VAR(val);
            OUT_EDX_EAX;

  9. #9
    Invité
    Invité(e)
    Par défaut
    Et comment je peut retirer ce mode protégé ? même en exécutant directement mon programme il plante

  10. #10
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    aucune chance que ca marche.

    ton shellcode ne correspond absolument à rien, mais tu ne peux pas le savoir puisque tu ne lis pas l'assembleur manifestement

    les nulbytes ne sont pas le seul problème, certaines instructions comme les jmp par exemple fonctionnent sur un mode d'adressage absolu, c'est à dire avec une adresse fixe en mémoire, une des caractéristiques d'un shellcode est d'être indépendant de l'endroit depuis lequel il est exécuté, des mécanismes de sécurité comme l'ASLR font en sorte également de compliquer le boulot des pirates, là encore il te manque les connaissances système et assembleur qui vont bien

    enfin pour ce qui est de faire exécuter du code assembleur en ligne avec visual studio il suffit de savoir quoi chercher, en l'occurence une recherche sur "visual studio inline assembly" donne dans les premiers liens les résultats qui expliquent comment faire

    quant à faire exécuter un shellcode mis directement dans un tableau de char, là encore divers mécanismes de sécurité aujourd'hui en standard sur windows empêchent l'exécution de code sur la stack directement, sinon dans l'absolu il suffit de déclarer un pointeur de fonction qui pointe sur ton shellcode, ça revient à connaitre le C++

    l'un dans l'autre j'ai le sentiment - assez clair - qu'il te manque un certain nombre de connaissances qui font office de prérequis indispensables pour se lancer dans l'exploitation de buffer overflows et autres joyeusetés du même genre
    par ailleurs il est communément admis que c'est un peu plus compliqué sous windows, ou en tous cas beaucoups mieux documenté sous linux, ça peut être un point de réflexion à envisager...

  11. #11
    Membre chevronné
    Avatar de Forthman
    Homme Profil pro
    conception mécanique
    Inscrit en
    Janvier 2005
    Messages
    702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : conception mécanique
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2005
    Messages : 702
    Points : 1 905
    Points
    1 905
    Par défaut
    Je viens d'aller voir sur http://www.flatland.tuxfamily.org/shellcodes.php
    car je n'avais aucune idée de ce qu'était du shellcode

    Le gros problème c'est que tu ne programmes pas en assembleur. en compilant en C , ce n'est pas toi qui décide

    Si tu veux tenter l’aventure en assembleur, il y a un décompilateur que j'aime bien, en ligne et gratuit ici : http://onlinedisassembler.com/odaweb/
    ça te permettra de faire des modifs dans ton shellcode et de voir en directement les changements du code

Discussions similaires

  1. Erreur d'exécution '94' Utilisation incorrecte du Null.
    Par zeine77 dans le forum VBA Access
    Réponses: 6
    Dernier message: 11/08/2008, 16h53
  2. Socket - Envoye une série de Byte Null à la fin
    Par deejay2221 dans le forum C#
    Réponses: 3
    Dernier message: 30/04/2008, 16h51
  3. Réponses: 4
    Dernier message: 04/03/2008, 12h17
  4. [windev 10] byte[] montableau=NULL pour .NET
    Par pagodas dans le forum WinDev
    Réponses: 13
    Dernier message: 20/07/2007, 11h02
  5. [SQL] Comment ne pas exécuter une clause WHERE si une var est nulle
    Par charlysquare dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 01/05/2006, 21h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo