首页
论坛
课程
招聘
[原创] 关于不同版本glibc强行加载的方法(附上代码)
2018-4-10 15:13 26847

[原创] 关于不同版本glibc强行加载的方法(附上代码)

2018-4-10 15:13
26847
2018/6/11 更新:https://github.com/matrix1001/welpwn 已集成

各路大佬看到这题目就知道我说的是个困扰pwn选手多年的问题,不知道大家有没有解决这个问题,反正我是强行解决了。
TODO:
1. 自行下载glibc 2.23/2.24/2.25/2.26 源码并编译
2. 将所需要使用到版本的ld.so放在pwn题目录下
3. 跑这个代码
def change_ld(binary, ld):
    """
    Force to use assigned new ld.so by changing the binary
    """
    if not os.access(ld, os.R_OK): 
        log.failure("Invalid path {} to ld".format(ld))
        return None

        
    if not isinstance(binary, ELF):
        if not os.access(binary, os.R_OK): 
            log.failure("Invalid path {} to binary".format(binary))
            return None
        binary = ELF(binary)


    for segment in binary.segments:
        if segment.header['p_type'] == 'PT_INTERP':
            size = segment.header['p_memsz']
            addr = segment.header['p_paddr']
            data = segment.data()
            if size <= len(ld):
                log.failure("Failed to change PT_INTERP from {} to {}".format(data, ld))
                return None
            binary.write(addr, ld.ljust(size, '\0'))
            if not os.access('/tmp/pwn', os.F_OK): os.mkdir('/tmp/pwn')
            path = '/tmp/pwn/{}_debug'.format(os.path.basename(binary.path))
            if os.access(path, os.F_OK): 
                os.remove(path)
                info("Removing exist file {}".format(path))
            binary.save(path)    
            os.chmod(path, 0b111000000) #rwx------
    success("PT_INTERP has changed from {} to {}. Using temp file {}".format(data, ld, path)) 
    return ELF(path)
#example
elf = change_ld('./pwn', './ld.so')
p = elf.process(env={'LD_PRELOAD':'./libc.so.6'})
用法很简单,参数第一个可以是ELF,可以是路径,第二个必须是ld.so的路径(最好放在当前文件夹,原因后面讲)。返回值我自己方便用所以是ELF,不喜欢的自己改成path,这个不会改变你原来的文件,只是建立一个修改的副本放在/tmp/pwn里面
4. 不用LD_PRELOAD则加载 源码级 libc(调libc=调源码? 存在的) 或者 使用LD_PRELOAD加载给定的libc

原理:
PT_INTERP这是个神秘的东西,这个是编译的时候就硬编码好的东西,值是'/lib/ld-linux.so.2' ,其实这个就是万恶的ld了,程序加载的时候,首先进去的不是_start处的代码,而是先加载执行PT_INTERP指向的程序,ld在加载后会给程序加载libc,最后再执行程序的代码。
但是在改的时候,是有长度限制的,代码已经写好了,所以将ld.so放当前文件夹就不会出错。
所以说,利用LD_PRELOAD直接加载不同版本的libc,会由于libc和ld匹配不上而出错。

望各路大佬指正。

看雪论坛2020激励机制:能力值、活跃值和雪币体系!会员积分、权限和会员发帖、回帖活跃程度关联!

最后于 2018-6-11 11:52 被matrixIOOI编辑 ,原因:
收藏
点赞1
打赏
分享
最新回复 (13)
雪    币: 685
活跃值: 活跃值 (79)
能力值: ( LV9,RANK:240 )
在线值:
发帖
回帖
粉丝
sakura零 活跃值 4 2018-4-10 19:14
2
0
问个问题,假设我在ubuntu12.04上要运行libc2.26,这种方法能解决么?
雪    币: 217
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
matrixIOOI 活跃值 2018-4-10 21:16
3
0

大佬这是刚刚在trusty上面测试的,而且这个libc和ld还不是这里编译的。12.04我没有用,我觉得如果不是什么内核不兼容,应该没问题。
雪    币: 235
活跃值: 活跃值 (24)
能力值: ( LV7,RANK:116 )
在线值:
发帖
回帖
粉丝
TacXingXing 活跃值 2018-4-21 17:55
4
0
$  ./libc.so.6
./libc.so.6:  relocation  error:  ./libc.so.6:  symbol  _dl_starting_up,  version  GLIBC_PRIVATE  not  defined  in  file  ld-linux-x86-64.so.2  with  link  time  reference
报这个问题可以解决吗
雪    币: 4
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
JuicyBoy 活跃值 2018-5-18 17:05
5
0
最后于 2018-5-18 17:06 被JuicyBoy编辑 ,原因:
雪    币: 25
活跃值: 活跃值 (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qazgzz 活跃值 2018-9-5 10:52
6
1
太麻烦了,
先把ld.so cp到/lib64/Ld-linux-x86-64.so.2
把程序内的/lib64/ld-linux-x86-64.so.2改为/lib64/Ld-linux-x86-64.so.2
然后设置LD_PRELOAD加载libc就可以了
雪    币: 205
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
dqy行者 活跃值 2018-9-18 20:56
7
0
export LD_LIBRARY_PATH=`pwd`
export LD_PRELOAD=你的libc

最后不用了在:unset LD_PRELOAD
雪    币: 1602
活跃值: 活跃值 (600)
能力值: ( LV9,RANK:220 )
在线值:
发帖
回帖
粉丝
iddm 活跃值 4 2019-3-24 19:54
8
0
师傅也太低调了吧。。。
雪    币: 25
活跃值: 活跃值 (18)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qazgzz 活跃值 2019-6-22 10:53
9
0
话说我发现了更好的方法,有个工具叫patchelf,直接指定要是用的ld和libc就可以了
雪    币: 15
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
Mask6asok 活跃值 2019-7-15 20:22
10
0
你好,我想问下,利用这个方法加载其他版本的libc,gdb里面缺少libc debug symbols该如何解决
雪    币: 892
活跃值: 活跃值 (69)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
TopGreen 活跃值 2019-8-26 11:42
11
0
qazgzz 话说我发现了更好的方法,有个工具叫patchelf,直接指定要是用的ld和libc就可以了
运行那个后,程序都运行不起来了?
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
bree2e 活跃值 2019-12-1 11:06
12
0
Mask6asok 你好,我想问下,利用这个方法加载其他版本的libc,gdb里面缺少libc debug symbols该如何解决
你的libc没有调试符号,重新编译一个带符号的
雪    币: 4990
活跃值: 活跃值 (2739)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
0x2l 活跃值 3 2020-5-1 18:29
13
0

mark

最后于 2020-5-6 21:13 被0x2l编辑 ,原因: 修改
雪    币: 23
活跃值: 活跃值 (25)
能力值: ( LV3,RANK:36 )
在线值:
发帖
回帖
粉丝
violet陈 活跃值 2020-6-4 18:16
14
0
bree2e 你的libc没有调试符号,重新编译一个带符号的
https://github.com/matrix1001/glibc-all-in-one下载对应版本的lib
指定加载的方式:
pwn_file="./2.23-0ubuntu10_amd64/ld-2.23.so --library-path ./2.23-0ubuntu10_amd64/ ./SleepyHolder"
p = process(pwn_file.split())
游客
登录 | 注册 方可回帖
返回