安装
使用的是lieanu/LibcSearcher: glibc offset search for ctf. (github.com)
git clone https://github.com/lieanu/LibcSearcher.git
cd LibcSearcher
python setup.py develop
示例
from LibcSearcher import *
#第二个参数,为已泄露的实际地址,或最后12位(比如:d90),int类型
obj = LibcSearcher("fgets", 0X7ff39014bd90)
obj.dump("system") #system 偏移
obj.dump("str_bin_sh") #/bin/sh 偏移
obj.dump("__libc_start_main_ret")
更新LibcSearcher的libc-database
更具体可以看niklasb/libc-database: Build a database of libc offsets to simplify exploitation (github.com)
我们只需要
cd LibcSearcher
rm -r libc-database
git clone https://github.com/niklasb/libc-database.git
cd libc-database
./get # List categories
./get ubuntu debian # Download Ubuntu's and Debian's libc, old default behavior
./get all # Download all categories. Can take a while!
修改LibcSearcher
目的是为了在Multi Results时不用手动选择
修改clone下来的LibcSearcher.py
- 修改
class LibcSearcher
的__init__
def __init__(self, func=None, address=None,choose=None):
self.condition = {}
self.chosen= choose
if func is not None and address is not None:
self.add_condition(func, address)
self.libc_database_path = os.path.join(
os.path.realpath(os.path.dirname(__file__)), "libc-database/db/")
self.db = ""
修改
decided
函数len(result)>1
时的结果实际上就是在
while True:
前加上判断chosen
def decided(self):
if len(self.condition) == 0:
print("No leaked info provided.")
print("Please supply more info using add_condition(leaked_func, leaked_address).")
sys.exit(0)
res = []
for name, address in self.condition.items():
addr_last12 = address & 0xfff
res.append(re.compile("^%s .*%x" % (name, addr_last12)))
db = self.libc_database_path
files = []
# only read "*.symbols" file to find
for _, _, f in os.walk(db):
for i in f:
files += re.findall('^.*symbols$', i)
result = []
for ff in files:
fd = open(db + ff, "rb")
data = fd.read().decode(errors='ignore').split("\n")
for x in res:
if any(map(lambda line: x.match(line), data)):
result.append(ff)
fd.close()
if len(result) == 0:
print("No matched libc, please add more libc or try others")
sys.exit(0)
if len(result) > 1:
print("Multi Results:")
for x in range(len(result)):
print("%2d: %s" % (x, self.pmore(result[x])))
print("Please supply more info using \n\tadd_condition(leaked_func, leaked_address).")
if(self.chosen!=None):
self.db = result[self.chosen]
print("[+] %s be chosen." % self.pmore(self.db))
return
while True:
in_id = input(
"You can choose it by hand\nOr type 'exit' to quit:")
#print(in_id)
if in_id == "exit\n" or in_id == "quit\n":
sys.exit(0)
try:
in_id = int(in_id)
self.db = result[in_id]
break
except:
continue
else:
self.db = result[0]
print("[+] %s be chosen." % self.pmore(self.db))
之后初始化的时候只要
libc = LibcSearcher('puts',puts_addr,0) #选择序号为0的libc
libc.dump('system')