Créer un segfo Perl en une seule ligne

introduction

Parce qu'il semble être populaire ces jours-ci.

Alors je l'ai essayé avec Perl. L'environnement est un Linux x86_64 approprié.

Comment puis-je faire?

Vous voyez, c'est aussi simple que cela!

image.png

** Non pas ça **

prendre le coeur.

shell-session:WSL/Ubuntu18/Perl5.26.Courir sur 1


$ perl -e 'syscall 10,$m-=4096,4096,0 while$m||=1<<47'
Segmentation fault (core dumped)

Quand je l'essaye avec un robot d'art de coquille, cela ressemble à ceci. C'est devenu un joyeux Segfo ici.

image.png

Que faites-vous?

Si vous rendez cela un peu plus facile à voir, cela ressemble à ceci.

Ancienne histoire


require 'syscall.ph';
$m=0x800000000000;
while ( 1 ) {
  $m-=0x1000;
  syscall &SYS_mprotect,$m,0x1000,0;
}

En d'autres termes, la ligne unique mentionnée précédemment était d'émettre l'appel système mprotect sans fin à partir d'une certaine valeur d'adresse.

Cela a pour effet de modifier l'attribut de protection de la zone mémoire spécifiée. Puisque 0 dans le troisième argument équivaut à PROT_NONE, toutes les autorisations de lecture, d'écriture et d'exécution de programmes pour cette zone de mémoire sont perdues. Par conséquent, le SEGV volera au moment où vous accédez à la mémoire.

Notez que 0x800000000000, qui est l'adresse de début, est déterminé car la fin de la mémoire (tas, pile, vdso) du processus 64 bits se trouve approximativement juste avant ici.

Vérifier la carte mémoire


$ perl -e 'system "cat","/proc/$$/maps"'
7f11879f0000-7f11879f9000 r-xp 00000000 00:00 121160             /lib/x86_64-linux-gnu/libcrypt-2.27.so
7f11879f9000-7f11879fa000 ---p 00009000 00:00 121160             /lib/x86_64-linux-gnu/libcrypt-2.27.so
7f11879fa000-7f1187bf8000 ---p 0000000a 00:00 121160             /lib/x86_64-linux-gnu/libcrypt-2.27.so
(Abréviation)
7f1188c00000-7f1188df7000 r-xp 00000000 00:00 135847             /usr/bin/perl
7f1188df7000-7f1188df8000 r-xp 001f7000 00:00 135847             /usr/bin/perl
7f1188ff8000-7f1188ffe000 r--p 001f8000 00:00 135847             /usr/bin/perl
7f1188ffe000-7f1189000000 rw-p 001fe000 00:00 135847             /usr/bin/perl
7fffbe41b000-7fffbe45d000 rw-p 00000000 00:00 0                  [heap]
7fffc523e000-7fffc5a3e000 rw-p 00000000 00:00 0                  [stack]
7fffc6124000-7fffc6125000 r-xp 00000000 00:00 0                  [vdso]

Plus dangereux

Je cherchais un moyen de le rendre plus intéressant ou plus court, et j'en ai trouvé un mauvais.

python


$ perl -e 'unpack p,1x8'
Segmentation fault (core dumped)

Je me suis demandé ce que c'était, alors je l'ai recherché.

Premièrement, ʻunpack est une fonction intégrée qui est associée à pack, qui est simplement responsable de la sérialisation des données (pack) et de la désérialisation (ʻunpack). Ceci est utilisé pour combiner des données simples à multiples dans une chaîne de caractères afin qu'elle puisse être transportée, et inversement, pour récupérer des données à partir de la chaîne de caractères.

Où «p» est la spécification nue de la chaîne «p». Cela représente le type de données à résumer / résumer, mais selon le manuel:

À partir du manuel du pack:

p Un pointeur vers une chaîne qui se termine par un caractère nul.

… ** Pointeur ?? Avez-vous dit "pointeur"!? **

Quelle est la fonction cachée pour utiliser un pointeur nu dans un tel endroit? ** Comme prévu Perl **. Où l'utilisez-vous?

prendre le coeur. Lorsqu'il est utilisé avec pack, il semble que la valeur d'adresse interne qui contient les données de la chaîne de caractères est sérialisée et convertie en chaîne de caractères. Si vous le regardez dans le débogueur comme suit, il correspond parfaitement.

Jetez un œil en mémoire avec gdb


$ perl -e '$x="angel_p_57";print pack "p",$x;close STDOUT;sleep 1200'|od -tx8 & sleep 1
[2] 1067
0000000 00007fffbc94a320
0000010
$ ps -fC perl
UID        PID  PPID  C STIME TTY          TIME CMD
angel     1066    12  0 23:53 pts/0    00:00:00 perl -e $x="angel_p_57";print pack "p",$x;close STDOUT;
$ sudo gdb perl
…(Abréviation)…
(gdb) attach 1066
…(Abréviation)…
(gdb) x/s 0x00007fffbc94a320
0x7fffbc94a320: "angel_p_57"

Au contraire, lorsqu'il est utilisé dans ʻunpack, cela signifie que ** la chaîne de caractères est désérialisée et interprétée comme une valeur d'adresse ** pour y générer un double de la chaîne de caractères. Par conséquent, si vous spécifiez une chaîne de caractères aléatoire, ce sera immédiatement un accès mémoire illégal. Cependant, probablement x86_64-Linux Perl semble nécessiter 8 caractères pour désérialiser la valeur d'adresse, donc j'utilise la chaîne 11111111 dans 1x8`. («X» est un opérateur de répétition de chaîne)

Non, je ne savais pas que ** pack avait une telle fonction. Je ne pouvais pas m'empêcher de penser que Perl est encore profond **.

en conclusion

Étonnamment, j'ai eu du mal à créer un accès mémoire non autorisé, et c'est la méthode que j'ai proposée. ** La zone mémoire elle-même doit être traitée illégalement **. Après cela, j'ai appris à déballer, ce qui me donnait l'impression de toucher les profondeurs de Perl. S'il y a un autre moyen intéressant, s'il vous plaît.

De plus, c'est une liste d'articles qui sont faits à Segfo.

Recommended Posts

Créer un segfo Perl en une seule ligne
Segfo python en une ligne
Laissez Python segfo sur une ligne sans utiliser de ctypes
Créez un jeu Janken en une seule ligne (python)
Créer un robot LINE de retour de perroquet avec AWS Cloud9
Créer un LINE BOT
Fizzbuzz en Python (en une ligne)
Rendre iPython disponible sur OSGeo4W
Rendre Cython disponible sur Windows.
Créer un LINE BOT (chat)
Segfo python en 2 lignes
Diffusion sur LINE en utilisant python