安装

使用的是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

  1. 修改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 = ""
  1. 修改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')
最后修改:2023 年 08 月 27 日
如果觉得我的文章对你有用,请随意赞赏