2

I'm currently studying binary heap exploitation (mainly the glibc (ptmalloc2) implementation), for CTF competitions. The problem I'm facing is debugging challenges designed for a certain glibc version. I know there are some differences between (for example) libc 2.27 and libc 2.31 that can make the exploitation of certain vulnerabilities harder (or impossible) to exploit on newer versions.

This is a template script I usually like to use (with pwntools):

#!/usr/bin/env python3

from pwn import *

BINARY = ""
LIBC = ""
HOST = ""
PORT = 9999

exe = ELF(BINARY)
if LIBC != "":
    libc = ELF(LIBC, checksec=False)

rop = ROP(exe)

context.binary = exe
context.log_level = "debug"


if "remote" in sys.argv:
    io = remote(HOST, PORT)
else:
    io = gdb.debug([BINARY], gdbscript="""
         b main
    """
    )


io.interactive()

This makes debugging locally extremely easy and fast IMO.

I'd like to have a method to easily be able to debug programs using the same (or kind of the same) script as above and using the right glibc (and ld as both are required to be the same version) version without messing with my system's library.

How do I do that?

schroeder
  • 123,438
  • 55
  • 284
  • 319
  • I'm confused about how the script helps you and what you mean by "using the right glibc". You want to be able to call and run different versions of glibc? You want to know how to determine the correct version? – schroeder Sep 22 '20 at 14:40
  • Sorry for not being clear enough, I'm not used to asking questions on StackExchange. I want to run the given binary with the same libc (and ld) version of the CTF server. If, for example, i know the CTF server uses libc 2.11 I'd like to be able to debug the binary locally using libc 2.11. – Z. Alessandro Sep 22 '20 at 15:38
  • This isn't about asking questions *here*, this is just about clarity. Step me through what you want and what you have. So, you know the libc version and you want to run that version on your local machine? And you have that version? Is this really about CTFs at all or just about running different versions of glibc? – schroeder Sep 22 '20 at 16:17
  • I'm sorry I wasn't clear, thought I was :(. I know the libc version. I may not have it though. It's for CTF purposes but it's about running different versions of glibc, at the end of the day. I'd like to avoid changing the symlink from the default libc of my system (2.31) to a different one as that could cause problems, but I have no idea how. – Z. Alessandro Sep 22 '20 at 17:02

1 Answers1

1

If you know the libc version, it is possibly to find a dynamic linker (ld) through a package database and download it. To run the binary with a linker and libc that aren't your system defaults, you can use the environment variable LD_PRELOAD to specify the library and pass the binary as an argument to the linker.

For example, if given the files libc-2.27.so and vuln, you would find a ./ld-2.27.so online to match the libc version.

Then, to run the binary with the correct libc, you could use:

$ LD_PRELOAD=/path/to/libc-2.27.so ./ld-2.27.so ./vuln

It is possible to use this in pwntools with:

#!/usr/bin/env python3

from pwn import *

bin = ELF("./vuln")
libc = ELF("./libc-2.27.so")
ld = ELF("./ld-2.27.so")

context.binary = bin

io = process([ld.path, bin.path], env={"LD_PRELOAD": libc.path})

I would also recommend looking at pwninit, which will automatically find and download a linker for your libc and write the pwntools stub.