Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add offline parameter for search_by_hash series function #2360

Merged
merged 3 commits into from
Mar 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ The table below shows which release corresponds to each branch, and what date th

## 4.14.0 (`dev`)

- [#2360][2360] Add offline parameter for `search_by_hash` series function
- [#2356][2356] Add local libc database provider for libcdb

[2360]: https://github.com/Gallopsled/pwntools/pull/2360
[2356]: https://github.com/Gallopsled/pwntools/pull/2356

## 4.13.0 (`beta`)
Expand Down
46 changes: 34 additions & 12 deletions pwnlib/libcdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,12 @@ def provider_local_database(hex_encoded_id, hash_type):

return None

PROVIDERS = [provider_local_system, provider_local_database, provider_libcdb, provider_libc_rip]
PROVIDERS = {
"offline": [provider_local_system, provider_local_database],
"online": [provider_libcdb, provider_libc_rip]
}

def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True):
def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True, offline_only=False):
assert hash_type in HASHES, hash_type

# Ensure that the libcdb cache directory exists
Expand All @@ -157,8 +160,12 @@ def search_by_hash(hex_encoded_id, hash_type='build_id', unstrip=True):
if cache is None:
return None

providers = PROVIDERS["offline"]
if not offline_only:
providers += PROVIDERS["online"]

# Run through all available libc database providers to see if we have a match.
for provider in PROVIDERS:
for provider in providers:
data = provider(hex_encoded_id, hash_type)
if data and data.startswith(b'\x7FELF'):
break
Expand Down Expand Up @@ -603,7 +610,7 @@ def search_by_symbol_offsets(symbols, select_index=None, unstrip=True, return_as
selected_libc = _handle_multiple_matching_libcs(matching_libcs)
return search_by_build_id(selected_libc['buildid'], unstrip=unstrip)

def search_by_build_id(hex_encoded_id, unstrip=True):
def search_by_build_id(hex_encoded_id, unstrip=True, offline_only=False):
"""
Given a hex-encoded Build ID, attempt to download a matching libc from libcdb.

Expand All @@ -612,6 +619,10 @@ def search_by_build_id(hex_encoded_id, unstrip=True):
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.
offline_only(bool):
Both offline and online providers are used by default. When pass
`offline_only=True`, libcdb enable an exclusive offline search mode,
which will disable online providers.

Returns:
Path to the downloaded library on disk, or :const:`None`.
Expand All @@ -627,9 +638,9 @@ def search_by_build_id(hex_encoded_id, unstrip=True):
>>> hex(ELF(filename).symbols.read)
'0xeef40'
"""
return search_by_hash(hex_encoded_id, 'build_id', unstrip)
return search_by_hash(hex_encoded_id, 'build_id', unstrip, offline_only)

def search_by_md5(hex_encoded_id, unstrip=True):
def search_by_md5(hex_encoded_id, unstrip=True, offline_only=False):
"""
Given a hex-encoded md5sum, attempt to download a matching libc from libcdb.

Expand All @@ -638,6 +649,10 @@ def search_by_md5(hex_encoded_id, unstrip=True):
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.
offline_only(bool):
Both offline and online providers are used by default. When pass
`offline_only=True`, libcdb enable an exclusive offline search mode,
which will disable online providers.

Returns:
Path to the downloaded library on disk, or :const:`None`.
Expand All @@ -653,9 +668,9 @@ def search_by_md5(hex_encoded_id, unstrip=True):
>>> hex(ELF(filename).symbols.read)
'0xeef40'
"""
return search_by_hash(hex_encoded_id, 'md5', unstrip)
return search_by_hash(hex_encoded_id, 'md5', unstrip, offline_only)

def search_by_sha1(hex_encoded_id, unstrip=True):
def search_by_sha1(hex_encoded_id, unstrip=True, offline_only=False):
"""
Given a hex-encoded sha1, attempt to download a matching libc from libcdb.

Expand All @@ -664,6 +679,10 @@ def search_by_sha1(hex_encoded_id, unstrip=True):
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.
offline_only(bool):
Both offline and online providers are used by default. When pass
`offline_only=True`, libcdb enable an exclusive offline search mode,
which will disable online providers.

Returns:
Path to the downloaded library on disk, or :const:`None`.
Expand All @@ -679,10 +698,9 @@ def search_by_sha1(hex_encoded_id, unstrip=True):
>>> hex(ELF(filename).symbols.read)
'0xeef40'
"""
return search_by_hash(hex_encoded_id, 'sha1', unstrip)

return search_by_hash(hex_encoded_id, 'sha1', unstrip, offline_only)

def search_by_sha256(hex_encoded_id, unstrip=True):
def search_by_sha256(hex_encoded_id, unstrip=True, offline_only=False):
"""
Given a hex-encoded sha256, attempt to download a matching libc from libcdb.

Expand All @@ -691,6 +709,10 @@ def search_by_sha256(hex_encoded_id, unstrip=True):
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.
offline_only(bool):
Both offline and online providers are used by default. When pass
`offline_only=True`, libcdb enable an exclusive offline search mode,
which will disable online providers.

Returns:
Path to the downloaded library on disk, or :const:`None`.
Expand All @@ -706,7 +728,7 @@ def search_by_sha256(hex_encoded_id, unstrip=True):
>>> hex(ELF(filename).symbols.read)
'0xeef40'
"""
return search_by_hash(hex_encoded_id, 'sha256', unstrip)
return search_by_hash(hex_encoded_id, 'sha256', unstrip, offline_only)



Expand Down