This is a write-up for the misc challenge of the problem Linker Chess from OMH CTF 2021
In this problem, we are required to craft a linker script which spawns a shell. We can't manipulate anything from the compilation process, as the source code of the challenge is fixed as the problem script below.
#!/bin/sh
set -ev
sed '/^EOF/Q' > script.ld
cat > hello.c << EOF
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("Hello, world!\n");
exit(0);
}
EOF
gcc -c hello.c -o hello.o
ld -T script.ld hello.o -o hello /usr/lib/x86_64-linux-gnu/libc.so -dynamic-linker /lib64/ld-linux-x86-64.so.2
./hello
They provide a sample linker script, which properly -provided that you think allocating .code
at 0x1337000
and .data
at 0x31337000
is actually "proper"- links and makes a valid executable.
As it was the first time ever that I played with GNU linker scripts, there were roughly two hurdles that I had to overcome.
- How can we insert arbitrary bytes into the program?
- How can we make the resulting program execute those arbitrary bytes?
After some googling and a lot of trial and error, I found out that we can put any arbitrary bytes with the BYTE()
directive. But somehow making new section for those bytes and changing the entry point to it didn't work. At last I managed to execute the shellcode by inserting them just before the *(.text)
directive.
For the detailed exploit, please refer to the attached file.