Parce qu'il semble être populaire ces jours-ci.
Alors je l'ai essayé avec Perl. L'environnement est un Linux x86_64 approprié.
Vous voyez, c'est aussi simple que cela!
** 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.
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]
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"
x / s
est l'adresse d'origine de la chaîne de caractères générée par pack
, et la sortie est visualisée en hexadécimal par ʻod -tx8`. Voilà pourquoi.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 **.
É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