pwnlib.libcdb — Libc Database

Fetch a LIBC binary based on some heuristics.

pwnlib.libcdb.download_libraries(str, bool) str[source]

Download the matching libraries for the given libc binary and cache them in a local directory. The libraries are looked up using libc.rip and fetched from the official package repositories if available.

This commonly includes the ld-linux-x86-64.so.2 and libpthread.so.0 binaries which can be used to execute the program locally when the given libc is incompatible with the local dynamic loader.

Note: Only .deb and .pkg.tar.* packages are currently supported (Debian/Ubuntu, Arch).

Parameters
  • libc_path (str) – The path the libc binary.

  • unstrip (bool) – Try to fetch debug info for the libc and apply it to the downloaded file.

Returns

The path to the cached directory containing the downloaded libraries.

Example

>>> libc_path = ELF(which('ls'), checksec=False).libc.path
>>> lib_path = download_libraries(libc_path)
>>> lib_path is not None
True
>>> os.path.exists(os.path.join(lib_path, 'libc.so.6'))
True
>>> os.path.exists(os.path.join(lib_path, 'ld-linux-x86-64.so.2'))
True
pwnlib.libcdb.get_build_id_offsets()[source]

Returns a list of file offsets where the Build ID should reside within an ELF file of the currently selected architecture.

pwnlib.libcdb.search_by_build_id(hex_encoded_id, unstrip=True)[source]

Given a hex-encoded Build ID, attempt to download a matching libc from libcdb.

Parameters
  • hex_encoded_id (str) – Hex-encoded Build ID (e.g. ‘ABCDEF…’) of the library

  • unstrip (bool) – Try to fetch debug info for the libc and apply it to the downloaded file.

Returns

Path to the downloaded library on disk, or None.

Examples

>>> filename = search_by_build_id('fe136e485814fee2268cf19e5c124ed0f73f4400')
>>> hex(ELF(filename).symbols.read)
'0xda260'
>>> None == search_by_build_id('XX')
True
>>> filename = search_by_build_id('a5a3c3f65fd94f4c7f323a175707c3a79cbbd614')
>>> hex(ELF(filename).symbols.read)
'0xeef40'
pwnlib.libcdb.search_by_md5(hex_encoded_id, unstrip=True)[source]

Given a hex-encoded md5sum, attempt to download a matching libc from libcdb.

Parameters
  • hex_encoded_id (str) – Hex-encoded md5sum (e.g. ‘ABCDEF…’) of the library

  • unstrip (bool) – Try to fetch debug info for the libc and apply it to the downloaded file.

Returns

Path to the downloaded library on disk, or None.

Examples

>>> filename = search_by_md5('7a71dafb87606f360043dcd638e411bd')
>>> hex(ELF(filename).symbols.read)
'0xda260'
>>> None == search_by_md5('XX')
True
>>> filename = search_by_md5('74f2d3062180572fc8bcd964b587eeae')
>>> hex(ELF(filename).symbols.read)
'0xeef40'
pwnlib.libcdb.search_by_sha1(hex_encoded_id, unstrip=True)[source]

Given a hex-encoded sha1, attempt to download a matching libc from libcdb.

Parameters
  • hex_encoded_id (str) – Hex-encoded sha1sum (e.g. ‘ABCDEF…’) of the library

  • unstrip (bool) – Try to fetch debug info for the libc and apply it to the downloaded file.

Returns

Path to the downloaded library on disk, or None.

Examples

>>> filename = search_by_sha1('34471e355a5e71400b9d65e78d2cd6ce7fc49de5')
>>> hex(ELF(filename).symbols.read)
'0xda260'
>>> None == search_by_sha1('XX')
True
>>> filename = search_by_sha1('0041d2f397bc2498f62aeb4134d522c5b2635e87')
>>> hex(ELF(filename).symbols.read)
'0xeef40'
pwnlib.libcdb.search_by_sha256(hex_encoded_id, unstrip=True)[source]

Given a hex-encoded sha256, attempt to download a matching libc from libcdb.

Parameters
  • hex_encoded_id (str) – Hex-encoded sha256sum (e.g. ‘ABCDEF…’) of the library

  • unstrip (bool) – Try to fetch debug info for the libc and apply it to the downloaded file.

Returns

Path to the downloaded library on disk, or None.

Examples

>>> filename = search_by_sha256('5e877a8272da934812d2d1f9ee94f73c77c790cbc5d8251f5322389fc9667f21')
>>> hex(ELF(filename).symbols.read)
'0xda260'
>>> None == search_by_sha256('XX')
True
>>> filename = search_by_sha256('5d78fc60054df18df20480c71f3379218790751090f452baffb62ac6b2aff7ee')
>>> hex(ELF(filename).symbols.read)
'0xeef40'
pwnlib.libcdb.search_by_symbol_offsets(symbols, select_index=None, unstrip=True, return_as_list=False)[source]

Lookup possible matching libc versions based on leaked function addresses.

The leaked function addresses have to be provided as a dict mapping the function name to the leaked value. Only the lower 3 nibbles are relevant for the lookup.

If there are multiple matches you are presented with a list to select one interactively, unless the select_index or return_as_list arguments are used.

Parameters
  • symbols (dict) – Dictionary mapping symbol names to their addresses.

  • select_index (int) – The libc to select if there are multiple matches (starting at 1).

  • unstrip (bool) – Try to fetch debug info for the libc and apply it to the downloaded file.

  • return_as_list (bool) – Return a list of build ids of all matching libc versions instead of a path to a downloaded file.

Returns

Path to the downloaded library on disk, or None. If the return_as_list argument is True, a list of build ids is returned instead.

Examples

>>> filename = search_by_symbol_offsets({'puts': 0x420, 'printf': 0xc90}, select_index=1)
>>> libc = ELF(filename)
>>> libc.sym.system == 0x52290
True
>>> matched_libcs = search_by_symbol_offsets({'__libc_start_main_ret': '7f89ad926550'}, return_as_list=True)
>>> len(matched_libcs) > 1
True
>>> for buildid in matched_libcs: # doctest +SKIP
...     libc = ELF(search_by_build_id(buildid)) # doctest +SKIP
pwnlib.libcdb.unstrip_libc(filename)[source]

Given a path to a libc binary, attempt to download matching debug info and add them back to the given binary.

This modifies the given file.

Parameters

filename (str) – Path to the libc binary to unstrip.

Returns

True if binary was unstripped, False otherwise.

Examples

>>> filename = search_by_build_id('69389d485a9793dbe873f0ea2c93e02efaa9aa3d', unstrip=False)
>>> libc = ELF(filename)
>>> 'main_arena' in libc.symbols
False
>>> unstrip_libc(filename)
True
>>> libc = ELF(filename)
>>> hex(libc.symbols.main_arena)
'0x219c80'
>>> unstrip_libc(pwnlib.data.elf.get('test-x86'))
False
>>> filename = search_by_build_id('d1704d25fbbb72fa95d517b883131828c0883fe9', unstrip=True)
>>> 'main_arena' in ELF(filename).symbols
True