Skip to content

Commit 27bc31e

Browse files
authored
Match against local system libc first in libcdb (#2325)
* Match against local system libc first in libcdb Don't do any requests if the libc currently in use on the system running the exploit matches already. This is a small short circuit optimization when the remote target uses the same libc as the local one. This looks at the libc loaded by the local shell binary. This appears more dynamic than hardcoding library paths. Refs #983 * Update CHANGELOG * Handle missing SHELL envvar * Fix hash lookup
1 parent 993f590 commit 27bc31e

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ The table below shows which release corresponds to each branch, and what date th
8585
- [#2189][2189] Explicitly define p64/u64 functions for IDE support
8686
- [#2339][2339] Fix: Allow setting attributes on gdb Breakpoints
8787
- [#2323][2323] Retry failed lookups after one week in libcdb
88+
- [#2325][2325] Match against local system libc first in libcdb
8889

8990
[2242]: https://github.com/Gallopsled/pwntools/pull/2242
9091
[2277]: https://github.com/Gallopsled/pwntools/pull/2277
@@ -101,6 +102,7 @@ The table below shows which release corresponds to each branch, and what date th
101102
[2189]: https://github.com/Gallopsled/pwntools/pull/2189
102103
[2339]: https://github.com/Gallopsled/pwntools/pull/2339
103104
[2323]: https://github.com/Gallopsled/pwntools/pull/2323
105+
[2325]: https://github.com/Gallopsled/pwntools/pull/2325
104106

105107
## 4.12.0 (`beta`)
106108

pwnlib/libcdb.py

+24-2
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,20 @@
1414
from pwnlib.log import getLogger
1515
from pwnlib.tubes.process import process
1616
from pwnlib.util.fiddling import enhex
17+
from pwnlib.util.hashes import sha1filehex, sha256filehex, md5filehex
1718
from pwnlib.util.misc import read
1819
from pwnlib.util.misc import which
1920
from pwnlib.util.misc import write
2021
from pwnlib.util.web import wget
2122

2223
log = getLogger(__name__)
2324

24-
HASHES = ['build_id', 'sha1', 'sha256', 'md5']
25+
HASHES = {
26+
'build_id': lambda path: enhex(ELF(path, checksec=False).buildid or b''),
27+
'sha1': sha1filehex,
28+
'sha256': sha256filehex,
29+
'md5': md5filehex,
30+
}
2531
DEBUGINFOD_SERVERS = [
2632
'https://debuginfod.elfutils.org/',
2733
]
@@ -104,7 +110,23 @@ def provider_libc_rip(hex_encoded_id, hash_type):
104110
return None
105111
return data
106112

107-
PROVIDERS = [provider_libcdb, provider_libc_rip]
113+
# Check if the local system libc matches the requested hash.
114+
def provider_local_system(hex_encoded_id, hash_type):
115+
if hash_type == 'id':
116+
return None
117+
shell_path = os.environ.get('SHELL', None) or '/bin/sh'
118+
if not os.path.exists(shell_path):
119+
log.debug('Shell path %r does not exist. Skipping local system libc matching.', shell_path)
120+
return None
121+
local_libc = ELF(shell_path, checksec=False).libc
122+
if not local_libc:
123+
log.debug('Cannot lookup libc from shell %r. Skipping local system libc matching.', shell_path)
124+
return None
125+
if HASHES[hash_type](local_libc.path) == hex_encoded_id:
126+
return local_libc.data
127+
return None
128+
129+
PROVIDERS = [provider_local_system, provider_libcdb, provider_libc_rip]
108130

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

0 commit comments

Comments
 (0)