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

Sécurité Discussion :

Injection de bibliothéque dynamique


Sujet :

Sécurité

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 7
    Points : 4
    Points
    4
    Par défaut Injection de bibliothéque dynamique
    Bonjour,

    J'ai suivis ce tutoriel pour comprendre l'injection de bibliothèque sous Linux : https://tiger-222.fr/?d=2013/04/09/1...random-crackme
    Voici le code de mon hook qui est le même que sur le site :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <dlfcn.h>
     
    int strcmp(const char *str1, const char *str2) {
      printf("[Hook strcmp] str1 = %s\n", str1);
      printf("              str2 = %s\n", str2);
      typeof(strcmp)* function;
      function = dlsym(RTLD_NEXT, "strcmp");
      return (*function)(str1, str2);
    }
    Je bloque donc à l'étape 4. Quand il s'agit de lancer le crackme.
    J'obtiens l'erreur suivante :
    ERROR: ld.so: object '/tmp/libstrcmp.so' from LD_PRELOAD cannot be preloaded: ignored.
    Pourtant, j'ai bien lancer la commande : export LD_PRELOAD=/tmp/libstrcmp.so
    Par contre, quand je fais la commande : ls /tmp
    Mon hook semble fonctionner, car j'obtiens les printf contenus dans le code précédent.

    J'ai également fais un autre programme en C pour tester mon hook :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include<stdio.h>
    #include<stdlib.h>
     
    int main(){
      if(strcmp("test", "test")){
        printf("Test1\n");
      }
      else{
        printf("Test2\n");
      }
      return 0;
    }
    Quand je lance ce code, je n'ai aucun message d'erreurs, et j'obtiens tout le temps "Test2", sans pour autant avoir les printf de mon hook.

    J'ai aussi fais un autre hook sur la fonction printf :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <stdlib.h>
     
    int printf(const char *format, ...){
      exit(0);
    }
    Qui ne fonctionne pas non plus...

    Si quelqu'un pouvait m'éclaircir, je débute sur le sujet.

  2. #2
    Membre expérimenté
    Homme Profil pro
    Recherche du travail
    Inscrit en
    Août 2004
    Messages
    561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Recherche du travail

    Informations forums :
    Inscription : Août 2004
    Messages : 561
    Points : 1 320
    Points
    1 320
    Par défaut
    Trois cas possible :
    * Il trouve pas la librairie
    * Les permissions ne sont pas bonne
    * Les en-tête elf sont mauvaise
    Avoir un regard neutre sur notre vie dénuée de sens, c'est la voir tel un ignorant
    ------------------------------------------------------------------------------------------------------

  3. #3
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Les en-tête doivent être bon et l'emplacement de la lib aussi, étant donné que comme je l'ai dis dans mon message précédent, cela fonctionne quand je lance la commande :
    ls /tmp
    Au niveau des permissions, il me faut quoi ?
    J'ai tenté de lancer mon application avec les droit root, mais j'ai toujours le même problème.

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Dans le programme de test que vous avez fait, je verrai bien les cas suivants :
    • le compilateur a utilisé sa propre définition de strcmp() (il n'y a pas le bon fichier d'entêtes d'inclus, entre autre) ;
    • le compilateur a optimisé le strcmp(), vu qu'il est full statique et que l'on peut déterminer le résultat à la compilation (foutu compilateur, n'est ce pas .)
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre expérimenté
    Homme Profil pro
    Recherche du travail
    Inscrit en
    Août 2004
    Messages
    561
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Recherche du travail

    Informations forums :
    Inscription : Août 2004
    Messages : 561
    Points : 1 320
    Points
    1 320
    Par défaut
    Effectivement c'est fort possible, je viens d'essayé avec le compilateur gcc est effectivement il fait une optimisation par défaut. Alors que avec mon compilateur habituel clang ne le fait pas.

    J'ai comparé les en-tête, la table de symboles .dynsym ne contient pas strcmp dans gcc.

    Pour GCC:
    Table de symboles « .dynsym » contient 4 entrées:
    Num: Valeur Tail Type Lien Vis Ndx Nom
    0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
    1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND puts@GLIBC_2.2.5 (2)
    2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
    3: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
    Pour Clang, optimisation par défaut:
    Table de symboles « .dynsym » contient 8 entrées:
    Num: Valeur Tail Type Lien Vis Ndx Nom
    0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
    1: 0000000000000000 0 FUNC GLOBAL DEFAULT UND strcmp@GLIBC_2.2.5 (2)
    2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND printf@GLIBC_2.2.5 (2)
    3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND __libc_start_main@GLIBC_2.2.5 (2)
    4: 0000000000000000 0 NOTYPE WEAK DEFAULT UND __gmon_start__
    5: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_deregisterTMCloneTab
    6: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _ITM_registerTMCloneTable
    7: 0000000000000000 0 NOTYPE WEAK DEFAULT UND _Jv_RegisterClasses
    Donc les en-tête elf sont mauvaises.

    Donc gcc doit surement injecter directement strcmp dans le code du programme. Se qui semble confirmer l'assembleur généré:

    Pour Clang, optimisation par défaut
    .file "test.c"
    .text
    .globl main
    .align 16, 0x90
    .type main,@function
    main: # @main
    .cfi_startproc
    # BB#0:
    pushq %rbp
    .Ltmp2:
    .cfi_def_cfa_offset 16
    .Ltmp3:
    .cfi_offset %rbp, -16
    movq %rsp, %rbp
    .Ltmp4:
    .cfi_def_cfa_register %rbp
    subq $16, %rsp
    movl $0, -4(%rbp)
    movl $.L.str, %eax
    movl %eax, %ecx
    movq %rcx, %rdi
    movq %rcx, %rsi
    callq strcmp
    cmpl $0, %eax
    je .LBB0_2
    # BB#1:
    leaq .L.str1, %rdi
    movb $0, %al
    callq printf
    movl %eax, -8(%rbp) # 4-byte Spill
    jmp .LBB0_3
    .LBB0_2:
    leaq .L.str2, %rdi
    movb $0, %al
    callq printf
    movl %eax, -12(%rbp) # 4-byte Spill
    .LBB0_3:
    movl $0, %eax
    addq $16, %rsp
    popq %rbp
    ret
    .Ltmp5:
    .size main, .Ltmp5-main
    .cfi_endproc

    .type .L.str,@object # @.str
    .section .rodata.str1.1,"aMS",@progbits,1
    .L.str:
    .asciz "test"
    .size .L.str, 5

    .type .L.str1,@object # @.str1
    .L.str1:
    .asciz "Test1\n"
    .size .L.str1, 7

    .type .L.str2,@object # @.str2
    .L.str2:
    .asciz "Test2\n"
    .size .L.str2, 7


    .ident "clang version 3.4 (tags/RELEASE_34/final)"
    .section ".note.GNU-stack","",@progbits
    Pour gcc:

    .file "test.c"
    .section .rodata
    .LC0:
    .string "Test2"
    .text
    .globl main
    .type main, @function
    main:
    .LFB2:
    .cfi_startproc
    pushq %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq %rsp, %rbp
    .cfi_def_cfa_register 6
    movl $.LC0, %edi
    call puts
    movl $0, %eax
    popq %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
    .LFE2:
    .size main, .-main
    .ident "GCC: (GNU) 4.9.0"
    .section .note.GNU-stack,"",@progbits
    Avoir un regard neutre sur notre vie dénuée de sens, c'est la voir tel un ignorant
    ------------------------------------------------------------------------------------------------------

  6. #6
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Décembre 2013
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 7
    Points : 4
    Points
    4
    Par défaut
    Je vous remercie, j'arrive a faire fonctionner mes deux hooks sur mon programme de test.
    En revanche pour le crackme, j'ai toujours une erreur lors du lancement du binaire.
    J'ai vérifié la table de symbôle qui contient strcmp, printf...
    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
    51
    52
    53
    54
    55
    56
    57
    58
    0804af20 d _DYNAMIC
    0804aff4 d _GLOBAL_OFFSET_TABLE_
    08048f5c R _IO_stdin_used
             w _Jv_RegisterClasses
    0804af10 d __CTOR_END__
    0804af0c d __CTOR_LIST__
    0804af18 D __DTOR_END__
    0804af14 d __DTOR_LIST__
    0804907c r __FRAME_END__
    0804af1c d __JCR_END__
    0804af1c d __JCR_LIST__
    0804b064 A __bss_start
    0804b05c D __data_start
    08048f10 t __do_global_ctors_aux
    08048800 t __do_global_dtors_aux
    0804b060 D __dso_handle
             U __errno_location@@GLIBC_2.0
             w __gmon_start__
    08048f0a T __i686.get_pc_thunk.bx
    0804af0c d __init_array_end
    0804af0c d __init_array_start
    08048ea0 T __libc_csu_fini
    08048eb0 T __libc_csu_init
             U __libc_start_main@@GLIBC_2.0
             U __stack_chk_fail@@GLIBC_2.4
    0804b064 A _edata
    0804b074 A _end
    08048f3c T _fini
    08048f58 R _fp_hw
    08048620 T _init
    080487d0 T _start
    08048e4c T clean
    0804b06c b completed.6625
    0804b05c W data_start
    0804b070 b dtor_idx.6627
             U exit@@GLIBC_2.0
             U fgets@@GLIBC_2.0
             U fputc@@GLIBC_2.0
    08048860 t frame_dummy
             U free@@GLIBC_2.0
             U fwrite@@GLIBC_2.0
             U getchar@@GLIBC_2.0
             U getpid@@GLIBC_2.0
    08048884 T main
             U malloc@@GLIBC_2.0
             U memset@@GLIBC_2.0
             U printf@@GLIBC_2.0
             U ptrace@@GLIBC_2.0
             U puts@@GLIBC_2.0
             U rand@@GLIBC_2.0
             U sprintf@@GLIBC_2.0
             U srand@@GLIBC_2.0
    0804b064 B stderr@@GLIBC_2.0
    0804b068 B stdin@@GLIBC_2.0
             U strchr@@GLIBC_2.0
             U strcmp@@GLIBC_2.0
             U strlen@@GLIBC_2.0
             U time@@GLIBC_2.0
    J'ai toujours l'erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ERROR: ld.so: object '/tmp/libstrcmp.so' from LD_PRELOAD cannot be preloaded: ignored.
    Je ne comprends vraiment pas d'où cela peut venir étant donné que mes lib fonctionnent.

  7. #7
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Je pense simplement une incompatibilité 32/64 bits. En effet, un programme 32 bits, ne chargera pas la bibliothèque en 64 bits. L'inverse est vrai aussi. Du coup, je tenterai un -m32 durant la compilation, pour m'assurer de la chose.
    Note : ma théorie peux se vérifier avec un 'file' sur le crackme
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

Discussions similaires

  1. Bibliothèques dynamiques et multithreading!
    Par vonemya dans le forum Visual C++
    Réponses: 2
    Dernier message: 25/10/2007, 17h55
  2. creation bibliothéque dynamique
    Par scorpion06 dans le forum C++
    Réponses: 4
    Dernier message: 19/04/2007, 14h09
  3. Question sur les bibliothques dynamiques
    Par inh40 dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 11/04/2007, 15h16
  4. Chargement bibliothèques dynamiques
    Par Snark dans le forum C++
    Réponses: 3
    Dernier message: 15/12/2006, 15h49
  5. Problème avec la "Gestion des bibliothèques dynamiques"
    Par GoustiFruit dans le forum Delphi
    Réponses: 15
    Dernier message: 31/05/2006, 09h54

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