Core Dump

Created On 26. Jun 2021

Updated: 2021-06-26 23:34:20.169055000 +0000

Created By: acidghost

Coredumps can be useful in various ways, mainly in finding the causes for why a program misbehaved. One way to list coredumps is with coredumpctl. If you don't have it, you can install coreutils package. List the last coredump with coredumpctl -1 -o=core or just coredumpctl -1. See some information with coredumpctl info -1. You should also get there its location. In my case it was in /var/lib/systemd/coredump/. This pattern is specified in /proc/sys/kernel/core_pattern/. On my Ubuntu VM it was | /lib/systemd/systemd-coredump %P %u %g %s %t 9223372036854775808 %h. However, whatever changes are made in these locations, this will be return to its initial state after a restart. See
To enable coredumps set the limit to unlimited with ulimit -c unlimited. Then view it with ulimit -c. Since I need to work with the core in an easy and fast way, I made a little script that does not mess with anything and removes the old cores and keeps the newest one in the current directory.

rm core
sudo cp /var/lib/systemd/coredump/core* $PWD
sudo lz4 core.*
sudo rm core .*.lz4
sudo chmod 777 core.*
cp core.* core
rm core.*

Now let's get started! Let's work on the example below:

int main() {
	char name[16];
	read(0, name, 128);
int win(int tricky) {
	if (tricky != 1337) return;
	sendfile(1, open("/flag", 0) 0, 1024);

Compile it with

gcc -g -fno-stack-protector -no-pie -o jump_to_win jump_to_win.c

In Memory Errors, we jumped to the win function to get the flag. Here, just jumping there won't yield us the flag, since it's protected by a tricky function inside that requires the 1337 argument to be passed for it to open the flag. Let's inspect it first. Launch it in pwntools and overflow it with a cyclic pattern:

import pwn
process = pwn.process('./jump_to_win')

after that launch the bash script above and in pwntools you can load up the core

coredump = pwn.Coredump('./core')

Now we have full control of the core :sunglasses:. You should see now upon the first load some information about why the file crashed. In my case, I found the pattern 0x6161616861616167 at fault.
It can be launched in gdb as well with with gdb ./jump_to_win core. Another way to launch the last file from the journal in gdb is with coredumpctl -1 --debugger=gdb debug. In the --debugger option, a optional debugger can be passed, however otherwise can be used with just coredumpctl gdb -1. It can be insepcted in gdb this way gdb jump_to_win core.

The -g flag during compilation will allow us to see the code part of the file. Just by launching it in gdb with the core, we can see on which line the file crashed and the value in rsp. Looks familiar doesn't it? We can find the exact location of the pattern with pwn.cyclic_find("gaaah"). With the core in pwntools we can make it calculate for us the exact same and output the pattern to us:
This will output the first 8 bytes of the pattern in rsp. See more on how to work with corefiles in pwntools here
Alright, this was a very brief, but hopefully a very useful intro to what can be achieved with coredumps. As for the problem above, we saw how easy it is with the core file to find out the distance towards the return address and look for reasons why a program might seg fault. As to how to solve the problem above, this is a problem for whoever might be reading this. Ok, here is a hint, just jump over it :monkey: :cyclone:


Section: Binary Exploitation (PWN)