为什么Pwn题要注意libc版本?这个困扰了我许久的问题,今天就来解释一下
前言
之前做Pwn题目retlibc的时候,一直不懂为什么老是打不通本地。后门发现是libc版本的问题,但是为什么libc版本不同就打不通呢?今天我来解释一下
原因
libc版本不同的话,函数的偏移地址在也会不同。我们先要知道这句话。
在本地运行可执行程序的时候,默认使用的是当前系统自带的libc版本
而常常retlibc题目,会给我们一个附件libc.so.6,这是远程靶机的libc版本
在我们写exp时,我们必然会用到以下语句:
libc= ELF('./libc.so.6')
puts_libc_addr = libc.sym['puts']
libc.sym['函数']
表示在是在libc中,获得指定函数的偏移地址。注意这里的libc表示的是ELF(‘./libc.so.6’),也就是远程靶机的libc
而我们如果打本地的程序时,系统会使用的是本机默认的libc,函数的偏移量也是取决于本机默认libc
如果当远程靶机的libc版本和本地libc的版本不一样的时候:
由于 libc基址=函数真实地址-函数的偏移地址
一旦libc版本不同,函数的偏移地址也不同,最终求出来的libc基址也必然不同。
假设我们求通过puts函数求基址:
puts_libc_addr = libc.sym['puts'](用题目附件给的libc查找puts函数移地址)
libc_base(基址) = puts_addr(puts函数实际地址) - puts_libc_addr(puts函数偏移地址)
由于程序实际运行的puts_libc_addr(puts函数偏移地址)
和题目附件libc.so.6查找到的puts_libc_addr(puts函数偏移地址)
不一样
这就使得通过exp求出来的libc基址与实际运行时的libc基址是不对应的
换句话说,就是程序实际运行的libc基址,与远程靶机的libc基址不同
这一系列的连锁反应,也影响到后面求出的后门函数地址
如:system_addr = libc_base+system_libc_addr
后门函数在本地实际运行的地址,根本就和你通过exp求出来的后门函数地址不同,那你想打通本地,当然不可能了啊!
所以这时,就会出现远程打得通,本地打不通的情况。
结语
所以做retlibc题目出现远程打得通,本地打不通的原因,就是因为系统默认的libc版本和题目附件给的(远程靶机)libc版本不同
什么?问我这么看libc版本一不一样?
别急,马上写出来给看。