Table des matières

Astuces dans la pratique de Reverse avec outils embarqués pour OSINT

La rétro-ingénierie est la pratique de chercher à comprendre ce que contient un fichier, ce que fait un logiciel, ou les clés d'entrée dans un système, dont l'information, le code source n'est pas clairement disponible. La rétro-ingénierie ne pas donner tous les détails exacts du fichier, du logiciel, ou sur un système. Mais vous pourrez comprendre assez précisément comment un système, logiciel a été implémenté.

La rétro-ingénierie comprend quatre étapes de base suivantes :

L'investigation par source ouverte, ou renseignement par source ouverte, comprend « les activités et méthodes de collecte et d'analyse de l'information de sources ouvertes, c'est-à-dire des informations accessibles publiquement »

Nous entendons ici « outils embarqués » comme ceux fournis de base dans une distribution Linux ainsi que certains autres de conception légère téléchargeable, donc embarquables, configurables et utilisables via un terminal puis utilisables hors connexion internet.

Commandes Basiques

cat

La commande cat pour concatener un ou des fichiers sur une sortie standard

Peut être, par exemple, utilisée dans ∕etc

cat passwd
root:x:0:0:root:/root:/bin/bash
[...]
less pagine le fichier et permet la recherche. Combiner cat avec pipe | la commande less permet de paginer la sortie. Ceci est utile avec beaucoup des manipulation suivantes.

paste

> cat test_leak.txt 
ID:Jean 
password:1234
ID:Pierre 
password:5678
ID:Pernault
password:9012
> paste - - -d, < test_leak.txt 
ID:Jean ,password:1234
ID:Pierre ,password:5678
ID:Pernault,password:9012

Voir également : https://www.quennec.fr/trucs-astuces/syst%C3%A8mes/gnulinux/programmation-shell-sous-gnulinux/les-commandes-filtres/traitement-de-donn%C3%A9es/paste

comm & sort

Déterminer les lignes et contenu que deux fichiers différents ont en commun.

> comm -12 <(sort names1.txt) <(sort names2.txt)

Aussi possible

> cat names1.txt names2.txt | sort | uniq -c

file

file permet de regarder un fichier et aide à deviner ce qu'il contient. La méthode qu'il utilise est simple. file fera la différence entre un fichier compréssé et un fichier.jpg lorsque vous n'avez pas d'extension. Il vous indiquera également l'architecture d'un binaire ELF.

file permet de voir les propriétés exécutables, à savoir :

> file Figure_1-1.png     
Figure_1-1.png: PNG image data, 1299 x 679, 8-bit/color RGBA, non-interlaced

dépôt de fichiers utilisables en exercice : https://github.com/ianare/exif-samples/tree/master/jpg

Prenons par exemple dans cette liste le Pentax_K10D.jpg

> file Pentax_K10D.jpg 
Pentax_K10D.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), 
density 350x350, segment length 16, Exif Standard: [TIFF image data, little-endian,
 direntries=19, manufacturer=PENTAX Corporation , model=PENTAX K10D
        , orientation=upper-left, xresolution=282, yresolution=290, resolutionunit=2, software=GIMP 2.4.5, datetime=2008:07:31 15:56:49, 
        copyright=Laitche (This file is in the public domain.)], baseline, precision 8, 100x72, components 3

Nous pouvons enlever l'extension .jpg puis voir que nous allons obtenir le même résultat.

> file Pentax_K10D
Pentax_K10D: JPEG image data, JFIF standard 1.01, resolution (DPI), density 350x350,
 segment length 16, Exif Standard: [TIFF image data, little-endian, direntries=19, manufacturer=PENTAX Corporation , model=PENTAX K10D
        , orientation=upper-left, xresolution=282, yresolution=290, resolutionunit=2,
         software=GIMP 2.4.5, datetime=2008:07:31 15:56:49, 
         copyright=Laitche (This file is in the public domain.)], baseline, precision 8, 100x72, components 3

Pour les question des EXFI : https://www.media.mit.edu/pia/Research/deepview/exif.html

> file libgraph-1.0.2.tar.gz 
libgraph-1.0.2.tar.gz: gzip compressed data, last modified: Wed Apr  5 18:25:15 2006, max compression, from Unix
> file indigo-gh-pages.zip 
indigo-gh-pages.zip: Zip archive data, at least v1.0 to extract

Exemples

> file busybox
busybox: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), 
statically linked, for GNU/Linux 3.2.0, 
BuildID[sha1]=⋅⋅⋅⋅⋅********************⋅⋅⋅⋅⋅⋅⋅, stripped

Lorsque data est rendu en sortie, c'est que file ne sait pas de quoi il s'agit

> file /opt/duniter/snapshot_blob.bin
/opt/duniter/snapshot_blob.bin: data

sur une micro-image d'un enregistruer de vidéo surveillance

https://support.zositech.com/hc/en-us/articles/360006626692-08ZN-M-V1-4-5-Upgrade-file-rootfs-3520dv300

> file rootfs-3520dv300 
rootfs-3520dv300: u-boot legacy uImage, hirootfs, Linux/ARM, Filesystem Image (any type) (Not compressed), 
8698364 bytes, Thu Mar  7 02:55:43 2019, 
Load Address: 0x00000000, Entry Point: 0x00000000, 
Header CRC: 0xB8071B27, Data CRC: 0x86BA3C18

stat

Affiche l'état d'un fichier ou d'un système de fichiers.

> stat perroquet
  Fichier : perroquet
   Taille : 8512      	Blocs : 24         Blocs d'E/S : 4096   fichier
Périphérique : 804h/2052d	Inœud : 2231065     Liens : 1
Accès : (0777/-rwxrwxrwx)  UID : ( 1000/       x)   GID : (  998/   wheel)
 Accès : 2020-11-01 11:21:14.140197000 +0100
Modif. : 2019-04-06 14:26:52.000000000 +0200
Changt : 2020-11-01 11:21:14.140197342 +0100
  Créé : 2020-11-01 11:21:14.140197342 +0100

stat –help

strings

strings écrit chaque chaîne de texte printable à partir d'un fichier binaire vers la sortie standard sdout

Il trouvera toutes les chaînes ASCII contiguës dans un fichier et les imprimera. C'est un bon moyen de voir ce que fait un binaire et de découvrir les API endpoints, les mots de passe codés en dur, etc.

Si trop de données, utilisez l'option d sur les chaînes pour ne filtrer que les données initialisées et chargées, ce qui réduit à 24 le nombre d'options pour le mot de passe enregistré.
> man strings
[...]
       -d
       --data
           Only print strings from initialized, loaded data sections in the
           file.  This may reduce the amount of garbage in the output, but it
           also exposes the strings program to any security flaws that may be
           present in the BFD library used to scan and load sections.  Strings
           can be configured so that this option is the default behaviour.  In
           such cases the -a option can be used to avoid using the BFD library
           and instead just print all of the strings found in the file.

strings peut être utile pour visualiser des messages d'erreur textuels qui donnent des indications sur les fonctionnalités binaires. C'est aussi un moyen simple pour détecter les binaires compressés comme dans l'exemple (fréquent avec les binaires malveillants) :

> strings exe_file
UPX!
...
PROT_EXEC|PROT_WRITE failed.
$Info: This file is packed with the UPX executable packer http://upx.sf.net $
$Id: UPX 3.91 Copyright (C) 1996-2013 the UPX Team. All Rights Reserved. $
...
UPX!

disons que nous cherchons une informations dans l'APk d'un application android

> strings ICI-RENNES_v1.0.6_apkpure.com.apk | less | grep user 
HH545060458628-5ibshj43h14g53d9q2ukvmlh14jmb31h.apps.googleusercontent.com

ldd

ldd « certaines versions de ldd tentent d'obtenir les bibliothèques logicielles partagées du programme en l'exécutant. Ainsi, la page de manuel de ldd recommande de ne jamais employer ldd sur des exécutables non-sûrs. Le manuel propose l'alternative suivante, utilisant les utilitaires objdump et grep »

objdump

objdump produit la liste de désassemblage d'un exécutable ELF

Soit, pour exemple, un programme perroquet en langage C qui répète ce qui est écrit en entrée

> ./perroquet
Entrez une ligne et validez avec Entrée
chante, chante...
Vous avez écrit : 'chante, chante...'

Nous aurons avec l'option d pour désassembler :

> objdump -d perroquet
 
perroquet:     format de fichier elf64-x86-64
 
 
Déassemblage de la section .init :
 
00000000000005d0 <_init>:
 5d0:	48 83 ec 08          	sub    $0x8,%rsp
 5d4:	48 8b 05 0d 0a 20 00 	mov    0x200a0d(%rip),%rax        # 200fe8 <__gmon_start__>
 5db:	48 85 c0             	test   %rax,%rax
 5de:	74 02                	je     5e2 <_init+0x12>
 5e0:	ff d0                	callq  *%rax
 5e2:	48 83 c4 08          	add    $0x8,%rsp
 5e6:	c3                   	retq   
 
Déassemblage de la section .plt :
 
00000000000005f0 <.plt>:
 5f0:	ff 35 b2 09 20 00    	pushq  0x2009b2(%rip)        # 200fa8 <_GLOBAL_OFFSET_TABLE_+0x8>
 5f6:	ff 25 b4 09 20 00    	jmpq   *0x2009b4(%rip)        # 200fb0 <_GLOBAL_OFFSET_TABLE_+0x10>
 5fc:	0f 1f 40 00          	nopl   0x0(%rax)
 
0000000000000600 <puts@plt>:
 600:	ff 25 b2 09 20 00    	jmpq   *0x2009b2(%rip)        # 200fb8 <puts@GLIBC_2.2.5>
 606:	68 00 00 00 00       	pushq  $0x0
 60b:	e9 e0 ff ff ff       	jmpq   5f0 <.plt>
 
0000000000000610 <printf@plt>:
 610:	ff 25 aa 09 20 00    	jmpq   *0x2009aa(%rip)        # 200fc0 <printf@GLIBC_2.2.5>
 616:	68 01 00 00 00       	pushq  $0x1
 61b:	e9 d0 ff ff ff       	jmpq   5f0 <.plt>
 
0000000000000620 <fgets@plt>:
 620:	ff 25 a2 09 20 00    	jmpq   *0x2009a2(%rip)        # 200fc8 <fgets@GLIBC_2.2.5>
 626:	68 02 00 00 00       	pushq  $0x2
 62b:	e9 c0 ff ff ff       	jmpq   5f0 <.plt>
 
0000000000000630 <exit@plt>:
 630:	ff 25 9a 09 20 00    	jmpq   *0x20099a(%rip)        # 200fd0 <exit@GLIBC_2.2.5>
 636:	68 03 00 00 00       	pushq  $0x3
 63b:	e9 b0 ff ff ff       	jmpq   5f0 <.plt>
 
Déassemblage de la section .plt.got :
 
0000000000000640 <__cxa_finalize@plt>:
 640:	ff 25 b2 09 20 00    	jmpq   *0x2009b2(%rip)        # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
 646:	66 90                	xchg   %ax,%ax
 
Déassemblage de la section .text :
 
0000000000000650 <_start>:
 650:	31 ed                	xor    %ebp,%ebp
 652:	49 89 d1             	mov    %rdx,%r9
 655:	5e                   	pop    %rsi
 656:	48 89 e2             	mov    %rsp,%rdx
 659:	48 83 e4 f0          	and    $0xfffffffffffffff0,%rsp
 65d:	50                   	push   %rax
 65e:	54                   	push   %rsp
 65f:	4c 8d 05 4a 02 00 00 	lea    0x24a(%rip),%r8        # 8b0 <__libc_csu_fini>
 666:	48 8d 0d d3 01 00 00 	lea    0x1d3(%rip),%rcx        # 840 <__libc_csu_init>
 66d:	48 8d 3d 6c 01 00 00 	lea    0x16c(%rip),%rdi        # 7e0 <main>
 674:	ff 15 66 09 20 00    	callq  *0x200966(%rip)        # 200fe0 <__libc_start_main@GLIBC_2.2.5>
 67a:	f4                   	hlt    
 67b:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
 
0000000000000680 <deregister_tm_clones>:
 680:	48 8d 3d 89 09 20 00 	lea    0x200989(%rip),%rdi        # 201010 <stdin@@GLIBC_2.2.5>
 687:	55                   	push   %rbp
 688:	48 8d 05 81 09 20 00 	lea    0x200981(%rip),%rax        # 201010 <stdin@@GLIBC_2.2.5>
 68f:	48 39 f8             	cmp    %rdi,%rax
 692:	48 89 e5             	mov    %rsp,%rbp
 695:	74 19                	je     6b0 <deregister_tm_clones+0x30>
 697:	48 8b 05 3a 09 20 00 	mov    0x20093a(%rip),%rax        # 200fd8 <_ITM_deregisterTMCloneTable>
 69e:	48 85 c0             	test   %rax,%rax
 6a1:	74 0d                	je     6b0 <deregister_tm_clones+0x30>
 6a3:	5d                   	pop    %rbp
 6a4:	ff e0                	jmpq   *%rax
 6a6:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 6ad:	00 00 00 
 6b0:	5d                   	pop    %rbp
 6b1:	c3                   	retq   
 6b2:	0f 1f 40 00          	nopl   0x0(%rax)
 6b6:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 6bd:	00 00 00 
 
00000000000006c0 <register_tm_clones>:
 6c0:	48 8d 3d 49 09 20 00 	lea    0x200949(%rip),%rdi        # 201010 <stdin@@GLIBC_2.2.5>
 6c7:	48 8d 35 42 09 20 00 	lea    0x200942(%rip),%rsi        # 201010 <stdin@@GLIBC_2.2.5>
 6ce:	55                   	push   %rbp
 6cf:	48 29 fe             	sub    %rdi,%rsi
 6d2:	48 89 e5             	mov    %rsp,%rbp
 6d5:	48 c1 fe 03          	sar    $0x3,%rsi
 6d9:	48 89 f0             	mov    %rsi,%rax
 6dc:	48 c1 e8 3f          	shr    $0x3f,%rax
 6e0:	48 01 c6             	add    %rax,%rsi
 6e3:	48 d1 fe             	sar    %rsi
 6e6:	74 18                	je     700 <register_tm_clones+0x40>
 6e8:	48 8b 05 01 09 20 00 	mov    0x200901(%rip),%rax        # 200ff0 <_ITM_registerTMCloneTable>
 6ef:	48 85 c0             	test   %rax,%rax
 6f2:	74 0c                	je     700 <register_tm_clones+0x40>
 6f4:	5d                   	pop    %rbp
 6f5:	ff e0                	jmpq   *%rax
 6f7:	66 0f 1f 84 00 00 00 	nopw   0x0(%rax,%rax,1)
 6fe:	00 00 
 700:	5d                   	pop    %rbp
 701:	c3                   	retq   
 702:	0f 1f 40 00          	nopl   0x0(%rax)
 706:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 70d:	00 00 00 
 
0000000000000710 <__do_global_dtors_aux>:
 710:	80 3d 01 09 20 00 00 	cmpb   $0x0,0x200901(%rip)        # 201018 <completed.7696>
 717:	75 2f                	jne    748 <__do_global_dtors_aux+0x38>
 719:	48 83 3d d7 08 20 00 	cmpq   $0x0,0x2008d7(%rip)        # 200ff8 <__cxa_finalize@GLIBC_2.2.5>
 720:	00 
 721:	55                   	push   %rbp
 722:	48 89 e5             	mov    %rsp,%rbp
 725:	74 0c                	je     733 <__do_global_dtors_aux+0x23>
 727:	48 8b 3d da 08 20 00 	mov    0x2008da(%rip),%rdi        # 201008 <__dso_handle>
 72e:	e8 0d ff ff ff       	callq  640 <__cxa_finalize@plt>
 733:	e8 48 ff ff ff       	callq  680 <deregister_tm_clones>
 738:	c6 05 d9 08 20 00 01 	movb   $0x1,0x2008d9(%rip)        # 201018 <completed.7696>
 73f:	5d                   	pop    %rbp
 740:	c3                   	retq   
 741:	0f 1f 80 00 00 00 00 	nopl   0x0(%rax)
 748:	f3 c3                	repz retq 
 74a:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)
 
0000000000000750 <frame_dummy>:
 750:	55                   	push   %rbp
 751:	48 89 e5             	mov    %rsp,%rbp
 754:	5d                   	pop    %rbp
 755:	e9 66 ff ff ff       	jmpq   6c0 <register_tm_clones>
 
000000000000075a <lire_clavier>:
 75a:	55                   	push   %rbp
 75b:	48 89 e5             	mov    %rsp,%rbp
 75e:	48 83 ec 20          	sub    $0x20,%rsp
 762:	48 89 7d e8          	mov    %rdi,-0x18(%rbp)
 766:	89 75 e4             	mov    %esi,-0x1c(%rbp)
 769:	48 8b 15 a0 08 20 00 	mov    0x2008a0(%rip),%rdx        # 201010 <stdin@@GLIBC_2.2.5>
 770:	8b 4d e4             	mov    -0x1c(%rbp),%ecx
 773:	48 8b 45 e8          	mov    -0x18(%rbp),%rax
 777:	89 ce                	mov    %ecx,%esi
 779:	48 89 c7             	mov    %rax,%rdi
 77c:	e8 9f fe ff ff       	callq  620 <fgets@plt>
 781:	8b 45 e4             	mov    -0x1c(%rbp),%eax
 784:	48 98                	cltq   
 786:	48 8d 50 ff          	lea    -0x1(%rax),%rdx
 78a:	48 8b 45 e8          	mov    -0x18(%rbp),%rax
 78e:	48 01 d0             	add    %rdx,%rax
 791:	c6 00 00             	movb   $0x0,(%rax)
 794:	c7 45 fc 00 00 00 00 	movl   $0x0,-0x4(%rbp)
 79b:	eb 2a                	jmp    7c7 <lire_clavier+0x6d>
 79d:	8b 45 fc             	mov    -0x4(%rbp),%eax
 7a0:	48 63 d0             	movslq %eax,%rdx
 7a3:	48 8b 45 e8          	mov    -0x18(%rbp),%rax
 7a7:	48 01 d0             	add    %rdx,%rax
 7aa:	0f b6 00             	movzbl (%rax),%eax
 7ad:	3c 0a                	cmp    $0xa,%al
 7af:	75 12                	jne    7c3 <lire_clavier+0x69>
 7b1:	8b 45 fc             	mov    -0x4(%rbp),%eax
 7b4:	48 63 d0             	movslq %eax,%rdx
 7b7:	48 8b 45 e8          	mov    -0x18(%rbp),%rax
 7bb:	48 01 d0             	add    %rdx,%rax
 7be:	c6 00 00             	movb   $0x0,(%rax)
 7c1:	eb 18                	jmp    7db <lire_clavier+0x81>
 7c3:	83 45 fc 01          	addl   $0x1,-0x4(%rbp)
 7c7:	8b 45 fc             	mov    -0x4(%rbp),%eax
 7ca:	48 63 d0             	movslq %eax,%rdx
 7cd:	48 8b 45 e8          	mov    -0x18(%rbp),%rax
 7d1:	48 01 d0             	add    %rdx,%rax
 7d4:	0f b6 00             	movzbl (%rax),%eax
 7d7:	84 c0                	test   %al,%al
 7d9:	75 c2                	jne    79d <lire_clavier+0x43>
 7db:	8b 45 fc             	mov    -0x4(%rbp),%eax
 7de:	c9                   	leaveq 
 7df:	c3                   	retq   
 
00000000000007e0 <main>:
 7e0:	55                   	push   %rbp
 7e1:	48 89 e5             	mov    %rsp,%rbp
 7e4:	48 83 ec 60          	sub    $0x60,%rsp
 7e8:	64 48 8b 04 25 28 00 	mov    %fs:0x28,%rax
 7ef:	00 00 
 7f1:	48 89 45 f8          	mov    %rax,-0x8(%rbp)
 7f5:	31 c0                	xor    %eax,%eax
 7f7:	48 8d 3d ca 00 00 00 	lea    0xca(%rip),%rdi        # 8c8 <_IO_stdin_used+0x8>
 7fe:	e8 fd fd ff ff       	callq  600 <puts@plt>
 803:	48 8d 45 a0          	lea    -0x60(%rbp),%rax
 807:	be 50 00 00 00       	mov    $0x50,%esi
 80c:	48 89 c7             	mov    %rax,%rdi
 80f:	e8 46 ff ff ff       	callq  75a <lire_clavier>
 814:	48 8d 45 a0          	lea    -0x60(%rbp),%rax
 818:	48 89 c6             	mov    %rax,%rsi
 81b:	48 8d 3d cf 00 00 00 	lea    0xcf(%rip),%rdi        # 8f1 <_IO_stdin_used+0x31>
 822:	b8 00 00 00 00       	mov    $0x0,%eax
 827:	e8 e4 fd ff ff       	callq  610 <printf@plt>
 82c:	bf 00 00 00 00       	mov    $0x0,%edi
 831:	e8 fa fd ff ff       	callq  630 <exit@plt>
 836:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 83d:	00 00 00 
 
0000000000000840 <__libc_csu_init>:
 840:	41 57                	push   %r15
 842:	41 56                	push   %r14
 844:	49 89 d7             	mov    %rdx,%r15
 847:	41 55                	push   %r13
 849:	41 54                	push   %r12
 84b:	4c 8d 25 4e 05 20 00 	lea    0x20054e(%rip),%r12        # 200da0 <__frame_dummy_init_array_entry>
 852:	55                   	push   %rbp
 853:	48 8d 2d 4e 05 20 00 	lea    0x20054e(%rip),%rbp        # 200da8 <__init_array_end>
 85a:	53                   	push   %rbx
 85b:	41 89 fd             	mov    %edi,%r13d
 85e:	49 89 f6             	mov    %rsi,%r14
 861:	4c 29 e5             	sub    %r12,%rbp
 864:	48 83 ec 08          	sub    $0x8,%rsp
 868:	48 c1 fd 03          	sar    $0x3,%rbp
 86c:	e8 5f fd ff ff       	callq  5d0 <_init>
 871:	48 85 ed             	test   %rbp,%rbp
 874:	74 20                	je     896 <__libc_csu_init+0x56>
 876:	31 db                	xor    %ebx,%ebx
 878:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)
 87f:	00 
 880:	4c 89 fa             	mov    %r15,%rdx
 883:	4c 89 f6             	mov    %r14,%rsi
 886:	44 89 ef             	mov    %r13d,%edi
 889:	41 ff 14 dc          	callq  *(%r12,%rbx,8)
 88d:	48 83 c3 01          	add    $0x1,%rbx
 891:	48 39 dd             	cmp    %rbx,%rbp
 894:	75 ea                	jne    880 <__libc_csu_init+0x40>
 896:	48 83 c4 08          	add    $0x8,%rsp
 89a:	5b                   	pop    %rbx
 89b:	5d                   	pop    %rbp
 89c:	41 5c                	pop    %r12
 89e:	41 5d                	pop    %r13
 8a0:	41 5e                	pop    %r14
 8a2:	41 5f                	pop    %r15
 8a4:	c3                   	retq   
 8a5:	90                   	nop
 8a6:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
 8ad:	00 00 00 
 
00000000000008b0 <__libc_csu_fini>:
 8b0:	f3 c3                	repz retq 
 
Déassemblage de la section .fini :
 
00000000000008b4 <_fini>:
 8b4:	48 83 ec 08          	sub    $0x8,%rsp
 8b8:	48 83 c4 08          	add    $0x8,%rsp
 8bc:	c3                   	retq   

Afficher le contenu de l'en-tête du fichier global à l'aide de l'option -f

> objdump -f perroquet
 
perroquet:     format de fichier elf64-x86-64
architecture: i386:x86-64, fanions 0x00000150:
HAS_SYMS, DYNAMIC, D_PAGED
adresse de départ 0x0000000000000650

Avec l'option -p

> objdump -p perroquet
 
perroquet:     format de fichier elf64-x86-64
 
En-tête de programme:
    PHDR off    0x0000000000000040 vaddr 0x0000000000000040 paddr 0x0000000000000040 align 2**3
         filesz 0x00000000000001f8 memsz 0x00000000000001f8 flags r--
  INTERP off    0x0000000000000238 vaddr 0x0000000000000238 paddr 0x0000000000000238 align 2**0
         filesz 0x000000000000001c memsz 0x000000000000001c flags r--
    LOAD off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**21
         filesz 0x0000000000000a78 memsz 0x0000000000000a78 flags r-x
    LOAD off    0x0000000000000da0 vaddr 0x0000000000200da0 paddr 0x0000000000200da0 align 2**21
         filesz 0x0000000000000270 memsz 0x0000000000000280 flags rw-
 DYNAMIC off    0x0000000000000db0 vaddr 0x0000000000200db0 paddr 0x0000000000200db0 align 2**3
         filesz 0x00000000000001f0 memsz 0x00000000000001f0 flags rw-
    NOTE off    0x0000000000000254 vaddr 0x0000000000000254 paddr 0x0000000000000254 align 2**2
         filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
EH_FRAME off    0x000000000000090c vaddr 0x000000000000090c paddr 0x000000000000090c align 2**2
         filesz 0x0000000000000044 memsz 0x0000000000000044 flags r--
   STACK off    0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
         filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
   RELRO off    0x0000000000000da0 vaddr 0x0000000000200da0 paddr 0x0000000000200da0 align 2**0
         filesz 0x0000000000000260 memsz 0x0000000000000260 flags r--
 
Section dynamique:
  NEEDED               libc.so.6
  INIT                 0x00000000000005d0
  FINI                 0x00000000000008b4
  INIT_ARRAY           0x0000000000200da0
  INIT_ARRAYSZ         0x0000000000000008
  FINI_ARRAY           0x0000000000200da8
  FINI_ARRAYSZ         0x0000000000000008
  GNU_HASH             0x0000000000000298
  STRTAB               0x00000000000003c8
  SYMTAB               0x00000000000002c0
  STRSZ                0x000000000000009a
  SYMENT               0x0000000000000018
  DEBUG                0x0000000000000000
  PLTGOT               0x0000000000200fa0
  PLTRELSZ             0x0000000000000060
  PLTREL               0x0000000000000007
  JMPREL               0x0000000000000570
  RELA                 0x0000000000000498
  RELASZ               0x00000000000000d8
  RELAENT              0x0000000000000018
  FLAGS                0x0000000000000008
  FLAGS_1              0x0000000008000001
  VERNEED              0x0000000000000478
  VERNEEDNUM           0x0000000000000001
  VERSYM               0x0000000000000462
  RELACOUNT            0x0000000000000003
 
Références de version:
  requis par libc.so.6:
    0x09691a75 0x00 02 GLIBC_2.2.5

objdump permet aussi de connaître le compilateur utilisé pour compiler l'exécutable binaire et l'OS dans lequel cette opération a eu lieu :

> objdump -s --section .comment perroquet
 
perroquet:     format de fichier elf64-x86-64
 
Contenu de la section .comment :
 0000 4743433a 20285562 756e7475 20372e33  GCC: (Ubuntu 7.3
 0010 2e302d32 37756275 6e747531 7e31382e  .0-27ubuntu1~18.
 0020 30342920 372e332e 3000               04) 7.3.0. 

readelf

readelf est un programme permettant d'afficher diverses informations sur les fichiers objets sur les systèmes de type Unix tels que objdump. Il fait partie des binutils de GNU.

readelf -x .rodata exe_file : lists static strings

readelf -h exe_file gets ELF header information

readelf -s exe_file displays symbols

readelf affiche des informations sur un ou plusieurs fichiers objets au format ELF. Les options contrôlent les informations particulières à afficher.

Les fichiers ELF 32 bits et 64 bits sont supportés, tout comme les archives contenant des fichiers ELF

binwalk

Binwalk utilise la bibliothèque libmagic, il est donc compatible avec les signatures créées pour l'utilitaire de fichiers Unix.

Il comprend également un fichier de signature magic personnalisé qui contient des signatures améliorées pour les fichiers que l'on trouve couramment dans les microprogrammes tels que les fichiers compressés/archivés, les en-têtes de microprogrammes, les noyaux Linux, les chargeurs d'amorçage, les systèmes de fichiers, etc.

>  binwalk Pentax_K10D.jpg 
 
DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, JFIF standard 1.01
30            0x1E            TIFF image data, little-endian offset of first image directory: 8
802           0x322           JPEG image data, JFIF standard 1.01
7399          0x1CE7          Copyright string: "Copyright (c) 1998 Hewlett-Packard Company"

hexdump

hexdump vous montrera une représentation hexadécimale d'un fichier. Utile pour voir la structure. Le paramètre -C montre également la représentation ASCII.

(~/.cache/gstreamer-1.0)
`--> hexdump -C registry.x86_64.bin | less | grep keys
00039a40  69 67 61 74 69 6f 6e 5c  20 6b 65 79 73 5c 20 6c  |igation\ keys\ l|

Reprenons notre exemple depuis la photo Pentax_K10D dans la section file ci-avant

$ hexdump Pentax                                                         1 ↵
0000000 d8ff e0ff 1000 464a 4649 0100 0101 5e01
0000010 5e01 0000 e1ff 5108 7845 6669 0000 4949
0000020 002a 0008 0000 0013 010f 0002 0014 0000
0000030 00f2 0000 0110 0002 0014 0000 0106 0000
0000040 0112 0003 0001 0000 0001 0000 011a 0005
0000050 0001 0000 011a 0000 011b 0005 0001 0000
0000060 0122 0000 0128 0003 0001 0000 0002 0000
0000070 0131 0002 000b 0000 012a 0000 0132 0002
0000080 0014 0000 0136 0000 8298 0002 002d 0000
0000090 014a 0000 8769 0004 0001 0000 0198 0000
00000a0 9c9d 0001 0020 0000 0178 0000 a401 0003
00000b0 0001 0000 0000 0000 a402 0003 0001 0000
 
------SNIP------
 
0002f20 54d6 ab21 ced3 a25d b6e4 ff7f 00d9     
0002f2d

Une information intéressante, parmi d'autres, dans l'ensemble des spécifications est que les “marqueurs” commencent par 0xFF. Il existe plusieurs marqueurs statiques connus, tels que

  1. le marqueur “Start of Image” (SOI) : 0xFFD8, 0000000 d8ff ici en début de sortie de donnée
  2. le marqueur “Fin d'image” (EOI) : 0xFFD9 00d9 ici en fin de sortie de données
  3. Marqueur APP1 : 0xFFE1
  4. Marqueurs génériques : 0xFFXX

hexdiff

hexdiff permet de comparer à des fichiers au niveau de l'octet.

« hexdiff affiche, après le lancement, deux fenêtres montrant un dump hexadécimal et ascii du début des deux fichiers. Deux barres d’état donnent le nom du fichier, sa taille et l’offset courant. La fenêtre courante est marquée par ** à gauche de l’écran. A l’aide de diverses touches du clavier, vous pouvez vous déplacer simultanément dans les deux fichiers, et le dump vous montrera alors, en vidéo inverse, les octets qui sont différents entre les deux fichiers. »
> hexdiff file1.bin file2.bin

Téléchargeons deux pdf censés identiques à un court instant d'interval depuis le site du ministère de l'intérieur de France https://www.interieur.gouv.fr/Actualites/L-actu-du-Ministere/Attestation-de-deplacement-derogatoire-et-justificatif-de-deplacement-professionnel

Puis

> hexdiff attestation-deplacement-fr.pdf attestation-deplacement-fr1.pdf

Ensuite I pour afficher les données fstat des documents en parallèle

La touche ? ouvre une popup d'aide expliquant les commandes de base.

la touche n pour se rendre à la prochaine différence entre les deux fichiers.

diff

pour vérifier si un différence existe ou n'existe pas on peut utiliser la commande diff. (qui est en quelque sorte l'inverse de comm vue ci-dessus)

toujours avec nous 2 pdf en exemple

> diff -y <(xxd  attestation-deplacement-fr.pdf) <(xxd attestation-deplacement-fr\(1\).pdf) | colordiff
  1. -y montre les différences côte à côte
  2. xxd une commande pour créer une sortie hexadump du fichier binaire
  3. colordiff va coloriser la sortie diff, nous connectons diff et colordiff grâce un pipe |.
  4. Si les fichiers sont trop longs, ajouter une limite (par exemple, -l 1000 ou -l 10000 ) pour chaque xxd
exemple de fin de sorti de données pour la commande prescrite ci-avant

find

find « commande UNIX permettant de chercher des fichiers dans un ou plusieurs répertoires selon des critères définis par l'utilisateur.  » est utilisée pour rechercher des fichiers par nom, autorisations, etc.

La commande suivante recherche dans le répertoire courant (.) les fichiers correspondant au nom insensible à la casse de *.sh

> find . -iname '*.sh'
[...]
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/build6.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/debug.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/build.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/restyle.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/restyle-all.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/build1.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/ci/build_package.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/ci/host_test.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/ci/style_check.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/ci/build_boards.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/ci/install_astyle.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/ci/build_docs.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/run_CI_locally.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/common.sh
./Esp8266-Arduino-Makefile/esp8266-2.5.2/tests/platformio.sh
[...]

Ou autre exemple

> find ~/ -iname '*eric*.jpg' -mtime -365

Pour trouver dans un sytème de fichiers Où est la photo contenant le nom Eric. Utilisez -iname pour les recherches de noms de fichiers insensibles à la casse. Utilisez -mtime -365 pour les fichiers modifiés il y a moins d'un an.

grep

grep programme en ligne de commande de recherche de chaînes de caractères, est utilisé pour rechercher le contenu des fichiers. Option -r signifie recherche récursive dans les répertoires, et -i signifie recherche insensible à la casse.

Ici, On cherche n'importe quel fichier contenant le mot « password ».

pour cet exemple nous allons dans pwndb

(~/pwndb)
`--> grep -ri password * | less
[...]
chu.gml:_sub_ds1[? "password"] = "ambrinebel99";
chu.gml:_sub_ds2[? "password"] = "pierre";
chu.gml:_sub_ds3[? "password"] = "IDJVVEOZ";
chu.gml:_sub_ds4[? "password"] = "hugo5";
chu.gml:_sub_ds5[? "password"] = "JMRAFUPK";
chu.gml:_sub_ds6[? "password"] = "leguerrier007";
chu.gml:_sub_ds7[? "password"] = "086603685cb18746e05c";
chu.gml:_sub_ds8[? "password"] = "086603685cb18746e05c29244f524123";
chu.gml:_sub_ds9[? "password"] = "giraffes";
chu.gml:_sub_ds10[? "password"] = "54139464";
chu.gml:_sub_ds11[? "password"] = "chouchoune";
chu.gml:_sub_ds12[? "password"] = "cesson1";
[...]

agrep

agrep grep par approximation.

En se basant sur les distances de Levenshtein1), il est possible de rechercher des mots ou une chaîne de caractères qui se ressemblent.

.-(~/pwndb)-----------------------------------------------------
`--> agrep -1 086603685 pwndb_dump.json 
    "password": "086603685cb18746e05c"
    "password": "086603685cb18746e05c29244f524123"
-1 retourne les résultats avec 1 différence par rapport à la recherchce demandée
-2, résultats avec 2 différences
.-(~/pwndb)----------------------------------------------------
`--> agrep -2 08660 pwndb_dump.json         
    "password": "086603685cb18746e05c"
    "password": "086603685cb18746e05c29244f524123"
    "password": "860452932746608"
-l : N'imprime que le nom de chaque fichier d'entrée qui contient au moins une correspondance, en supprimant la sortie normale. L'analyse de chaque fichier s'arrêtera à la première correspondance.

voir également

Pour des enjeux sur Edit distance

> tre-agrep -s -9 -w ACTGGGTAAACTA dna.file
 
4:ACTGGGAAAATAAACTA
4:ACTAAACTA
0:ACTGGGTAAACTA
-s, --show-cost	    print match cost with output
      --colour, --color     use markers to distinguish the matching strings
      --show-position       prefix each output record with start and end
                            position of the first match within the record
from fuzzysearch import find_near_matches
 
with open('path/to/file', 'r') as f:
    data = f.read()
 
# 1. search allowing up to 3 substitutions
matches = find_near_matches("ACTGGGTAAACTA", data, max_substitutions=3)
 
# 2. also allow insertions and deletions, i.e. allow an edit distance
#    a.k.a. Levenshtein distance of up to 3
matches = find_near_matches("ACTGGGTAAACTA", data, max_l_dist=3)

dmesg

dmesg « (pour l'anglais “display message”, “afficher message” en français) est une commande sur les systèmes d'exploitation de type Unix qui affiche la mémoire tampon de message du noyau. »

Là on peut voir si les périphériques USB ont été correctement énumérés, et comment ils sont appelés. Sur un périphérique, le tampon de messages peut contenir beaucoup d'informations utiles - cartes mémoire, matériel supporté, et bien plus.

« La quantité d'indications données par dmesg peut requérir plus que la taille de l'écran, aussi pour cette raison la sortie de dmesg est généralement consultée par des outils de manipulation de texte comme less, tail ou grep. Les sorties de dmesg sont également souvent conservées de manière permanente dans des fichiers de log à l'aide de daemon comme syslog. » Wikipedia
> dmesg
[...]
[44252.790090] ata1: SATA link up 3.0 Gbps (SStatus 123 SControl 300)
[44252.792550] ata1.00: configured for UDMA/133
[44255.311810] usb 2-1.4: USB disconnect, device number 9
[44255.317649] IPv6: ADDRCONF(NETDEV_UP): wlp2s0: link is not ready
[44255.438525] ACPI: \_SB_.PCI0.PEG0.PEGP: failed to evaluate _DSM
[44255.534190] usb 2-1.4: new full-speed USB device number 10 using ehci-pci
[44260.668407] usb 2-1.4: New USB device found, idVendor=0cf3, idProduct=3004
[44260.668413] usb 2-1.4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[44260.668417] usb 2-1.4: Product: Bluetooth USB Host Controller
[44260.668420] usb 2-1.4: Manufacturer: Atheros Communications
[44260.668423] usb 2-1.4: SerialNumber: Alaska Day 2006
[44266.484676] IPv6: ADDRCONF(NETDEV_UP): enp3s0: link is not ready
[44266.623978] r8169 0000:03:00.0 enp3s0: link down
[...]

Les empreintes de hash d'un fichier

md5sum, sha1sum, sha256sum, sha224sum, sha384sum et sha512sum

> md5sum monfichier.pdf
le format du fichier peut aussi être .bin ou tout autre

Voir aussi Have I Been Pwned Checker Check if a password (hash) is present in the HIBP database

exemple possible de mitigation par charge utile

« Les signatures basées sur la charge utile détectent des modèles dans le contenu du fichier plutôt que des attributs, tels qu'un hachage, ce qui leur permet d'identifier et de traiter fichiers intègres ou modifiés, pouvant possiblement contenir des actions malveillantes. »
> sha1sum fichier-1.bin
38762cf7f55934b34d179ae6a4c80cadccbb7f0a fichier-1.bin
> sha1sum fichier-2.bin 
38762cf7f55934b34d179ae6a4c80cadccbb7f0a  fichier-2.bin
> echo "payload" > payload
> cat playload fichier-1.bin | sha1sum
02f7808168af17eece0d9cd9d69846c51a65f395 -
> cat playload fichier-2.bin | sha1sum
02f7808168af17eece0d9cd9d69846c51a65f395 -
> cat playload fichier-1.bin | sha1sum
41c418591ea08fa9c535bf71efb3b902a7928d53 -
> cat palyload chichier-2.bin | sha1sum
6820b0b4dd1dcbaa79a5b1155be98ee6ca5b8203  -
Le hash seul ne permet pas forcément de prouver que deux fichiers sont identiques dans le cas où l'algorithme de hash a été compromis.

Par conséquent changer l’algorithme de hash ou ajouter un payload sûr « avant » le fichier permet de vérifier si le hash a été compromis ou non

Les récentes actions dans une section user

> loginctl session-status | tee session.status

Déterminer le comportement d'un programme

ltrace

ltrace trace les appels à la fonction de bibliothèque. Elle exécute le programme dans ce processus.

« ltrace est un utilitaire de débogage sous Linux, utilisé pour afficher les appels qu'une application en espace utilisateur fait aux bibliothèques partagées. Il fait cela en se connectant au système de chargement dynamique, lui permettant d'insérer des cales qui affichent les paramètres que l'application utilise lors de l'appel, et la valeur de retour que l'appel à la bibliothèque rapporte. ltrace peut aussi tracer les appels système sous Linux. Parce qu'il utilise le mécanisme d'accrochage dynamique des bibliothèques, ltrace ne peut pas tracer les appels aux bibliothèques qui sont statiquement liées directement au binaire cible. Depuis la version 0.7.3, ltrace peut aussi tracer les appels aux bibliothèques qui sont chargées en utilisant dlopen(). » wikipedia
setlocale(LC_TIME, nil)                                                      = "fr_FR.UTF-8"
utmpxname(0x557dcdcfcf74, 0x7fffbd7f4ed8, 0x7fffbd7f4ee0, 1)                 = 0
setutxent(0x557dcdcfcf74, 0x7f7b7452cf20, 0, 1)                              = 1
getutxent(3, 0, 0x7f7b7475c720, 0x7f7b74482217)                              = 0x557dcf9d4400
realloc(0, 384)                                                              = 0x557dcf9d4590
getutxent(0x557dcf9d4710, 0x557dcf9d4580, 0, 0)                              = 0x557dcf9d4400
realloc(0x557dcf9d4590, 768)                                                 = 0x557dcf9d4590
getutxent(0x557dcf9d4890, 0x557dcf9d4580, 0, 0)                              = 0x557dcf9d4400
kill(1940, 0)                                                                = 0
realloc(0x557dcf9d4590, 1536)                                                = 0x557dcf9d4590
getutxent(0x557dcf9d4a10, 0x557dcf9d4580, 0, 0)                              = 0
endutxent(14, 0x7fffbd7f4b40, 0, 0)                                          = 0x7f7b7475c6e0
[...]

Nous avons comme information intéressante : langue et horodatage de la machine

vous trouverez également le nom d'utilist⋅rice⋅eur enregistré pour la session machine inspectée

[...]
strlen("bob    :0           2019-12-20"...)                                = 47
puts("bob    :0           2019-12-20"...)                                  = 44

Vous pouvez observer qu'il existe un ensemble d'appels à getutxent et sa famille de fonction de bibliothèque. Vous pouvez également noter que ltrace donne les résultats dans l'ordre dans lequel les fonctions sont appelées dans le programme. Maintenant nous savons que la commande who,qui permet d'avoir des informations sur les différents utilisat⋅rices⋅eurs connecté⋅e⋅s, fonctionne en appelant le getutxent et sa famille de fonctions pour obtenir la liste utilisat⋅rices⋅eurs connecté⋅e⋅s.

« la glibc sous Linux n’utilise pas de fichier utmpx en parallèle car sa structure utmp est déjà assez grande. Les fonctions getutxent() etc. sont des alias pour getutent() etc. » source

strace

La commande strace, outil de débogage, utilisée pour tracer les appels système effectués par le programme. Si un programme n'utilise aucune fonction de bibliothèque et qu'il n'utilise que des appels système, alors en utilisant ltrace simplement nous ne pouvons pas retracer l'exécution du programme.

> strace /usr/bin/who
.
.
.
brk(NULL)                               = 0x558fed465000
.
.
.
 
brk(NULL)                               = 0x558fed465000
brk(0x558fed486000)                     = 0x558fed486000
openat(AT_FDCWD, "/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=4270640, ...}) = 0
mmap(NULL, 4270640, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2699494000
close(3)                                = 0
access("/var/run/utmpx", F_OK)          = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/var/run/utmp", O_RDONLY|O_CLOEXEC) = 3
lseek(3, 0, SEEK_SET)                   = 0
alarm(0)                                = 0
.
.
.
fcntl(3, F_SETLKW, {l_type=F_RDLCK, l_whence=SEEK_SET, l_start=0, l_len=0}) = 0
read(3, "\7\0\0\0\224[...]"..., 384) = 384
fcntl(3, F_SETLKW, {l_type=F_UNLCK, l_whence=SEEK_SET, l_start=0, l_len=0}) = 0

vous pouvez observer que chaque fois qu'une fonction malloc3) est appelée, elle effectue l'appel système brk(). La fonction de la bibliothèque getutxent fait l'appel système open pour ouvrir /var/run/utmp et met un verrou en lecture et lit le contenu puis libère les verrous.

Maintenant nous avons confirmé que la commande qui lit le fichier utmp pour afficher la sortie sdout

strace et ltrace ont tous deux un ensemble de bonnes options qui peuvent être utilisées.
  • -p <pid> : S'attache au pid spécifié. Utile si le programme est déjà en cours d'exécution et que vous voulez connaître son comportement.
  • -n 2 : Indente chaque appel imbriqué de 2 espaces.
  • -f : Suivre le fork

déboguer, désassembler, fuite de données et mémoire, Retracer l'histoirique

Gdb + peda + voltron

Nous vous proposons ici de une composition sur la base de GNU Project Debugger avec PEDA - Python Exploit Development Assistance for GDB pour moins vous abimer les yeux, et enfin Voltron is an extensible debugger UI toolkit written in Python.

Exemple

Un exercice et une proposition de défi seront rédigés prochainement

Voir également Hitchikers Guide To The GDB

Radare 2

  1. Voir la page dédiée
  2. par exemple, usage de radre2 in bioinfo

Intercepter de l'information

Ces outils embarqués ou embarquables peuvent servir à l'analyse de données sur réseaux. Internet n'étant pas le seul et unique réseau, Internet étant un réseau de réseaux.

https://github.com/linux-can/can-utils

Can-utils

CAN est un protocole de réseau basé sur des messages, conçu pour les véhicules, créé à l'origine par Robert Bosch GmbH. SocketCAN est un ensemble de pilotes CAN à source ouverte et une pile de réseau. Contribution par la recherche Volkswagen au noyau Linux.

https://github.com/linux-can/can-utils

candump

candump permet de sniffer les paquets CAN d'une ou plusieurs interfaces CAN avec de nombreuses autres options utiles pour filtrer, rediriger les messages, etc.

Exemple :

$ candump vcan0
 vcan0  123   [4]  01 AA BB 22
 vcan0  123   [4]  01 AA BB 23
 vcan0  123   [4]  01 AA BB 24

cansniffer

cansniffer est un outil qui organise les informations sur les CAN par ID d'arbitrage et permet de déterminer les valeurs qui changent. Par défaut, si un ID d'arbitrage ne reçoit pas d'informations « différentes » dans le paquet après 5 secondes, les données seront effacées de l'écran.

$ cansniffer can0

hping

netstat

nmap

tcpdump

xprobe2

wireshark

mitmproxy

Aller plus loin

Exemples d'exercice

linux_investigation.jpg

source : https://web.archive.org/web/20200225023508/https://www.brendangregg.com/index.html

Pages liées

retro-ingé sur logiciel

Sources

Remerciements

1)
La distance de Levenshtein est une distance, au sens mathématique du terme, donnant une mesure de la différence entre deux chaînes de caractères. Elle est égale au nombre minimal de caractères qu'il faut supprimer, insérer ou remplacer pour passer d’une chaîne à l’autre. fr:Distance_de_Levenshtein
3)
Description des mécanismes d'allocation dynamique de mémoire en langage C https://rperrot.developpez.com/articles/c/allocationC/