Make Perl segfault on one line

Introduction

Because it seems to be popular these days.

So I tried it with Perl. The environment is a suitable x86_64 Linux.

how can I do?

You see, it's that easy!

image.png

** No, not that **

take heart.

shell-session:WSL/Ubuntu18/Perl5.26.Run on 1


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

When I try it with a shell art bot, it looks like this. I'm happy to have a segfault here.

image.png

What are you doing?

If you make this a little easier to see, it looks like this.

Former story


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

In other words, the one-liner I mentioned earlier was to issue mprotect system calls endlessly starting from a certain address value.

The effect of this is to change the protection attribute of the specified memory area. Since 0 in the third argument is equivalent to PROT_NONE, all permissions for reading, writing, and executing programs for that memory area are lost. Therefore, the moment the memory is accessed, SEGV will fly.

Note that 0x800000000000, which is the start address, is determined because the end of the memory (heap, stack, vdso) of the 64-bit process is located approximately immediately before here.

Check memory map


$ 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
(Abbreviation)
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]

More dangerous

I was looking for a way to make it more interesting or shorter, and found a bad one.

python


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

I wondered what it was, so I looked it up.

First, ʻunpack is a built-in function that is paired with pack, which is simply responsible for serializing (pack) and deserializing (ʻunpack) data. This is used to combine single or multiple data into a character string so that it can be carried around, and conversely, to retrieve data from the character string.

Where p is the string'p' specified naked. This represents the type of data to be summarized / summarized, but according to the manual:

From pack manual:

p A pointer to a null-terminated string.

… ** Pointer ?? Did you say "pointer" !? **

What is the hidden function for using a bare pointer in such a place? ** As expected Perl **. Where do you use it?

take heart. When used with pack, it seems that the internal address value that holds the string data is serialized and converted to a string. If you look at it in the debugger as follows, it matches perfectly.

Peek into memory with 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
…(Abbreviation)…
(gdb) attach 1066
…(Abbreviation)…
(gdb) x/s 0x00007fffbc94a320
0x7fffbc94a320: "angel_p_57"

This means that if you use it with ʻunpack, it will ** deserialize the string and interpret it as an address value ** to generate a duplicate of the string there. Therefore, if you specify a random character string, it will be an illegal memory access immediately. However, probably x86_64-Linux Perl seems to require 8 characters to deserialize the address value, so I'm using the string 11111111 in 1x8. (X` is a string repetition operator)

No, I didn't know that ** pack had such a function. I couldn't help thinking that Perl is still deep **.

in conclusion

Surprisingly, I struggled to create unauthorized memory access, and this was the method I came up with. ** The memory area itself should be treated illegally **. After that, I learned about unpack, which felt like touching the abyss of Perl. If there is any other interesting way, please.

In addition, it is a list of articles that are segfaulted.

Recommended Posts

Make Perl segfault on one line
Make python segfault in one line
Make Python segfault on one line without using ctypes
Make a rock-paper-scissors game in one line (python)
Make a parrot return LINE Bot on AWS Cloud9
Make LINE BOT (Echolalia)
Fizzbuzz in Python (in one line)
Make iPython available on OSGeo4W
Make Cython available on Windows.
Make a LINE BOT (chat)
Make python segfault in 2 lines
Broadcast on LINE using python