❤️0xgame2023
2024-3-5
| 2024-10-13
0  |  Read Time 0 min
type
status
date
slug
summary
tags
category
icon
password
 

week 1

shellcode

week 2

week 3

没了溢出,你能秒我?

这道题很有意思,是利用了程序自带的leave 指令,同时也是一道在栈范围的off-by-one问题。这个思路我觉得很值得介绍。感觉应该在栈范围是对我有点启发的。
程序源码大概是这样:
notion image
notion image
看到这里,就需要想到第一个注重的点:我们这个程序在退回时经历了两次leave指令,这很重要,如果我们要涉及到关于栈迁移到思路的时候,这里就是天然的栈迁移。
如果我们可以修改到栈中rbp的值,那么在两次函数返回的时候,rsp指令就会直接指向被修改的rbp的值加8的地址。
然后我们进入custom_gets_off_by_one_or_null 这个函数
notion image
这里有一个很明显的off-by-one漏洞,这个漏洞可以让我们修改rbp的值,当然,只能修改到最低的一位
我们只能赌一下,赌我们将rbp最后一位变成零之后,经过两次leave指令后被修改的rsp指针会指向v1 的中间位置,这个位置也就是我们修改以后的地方。
同时要保证我们的payload最大可能性的被利用,方法就是在我们输入的payload的前端全部变成ret 指令,然后在最后才进行我们的payload的输入。也就是这样
这个思路和之前week 1 中的shellcode那个题很像,只不过那个题是添加了nop 指令,由此看来,这个思路是真的在栈漏洞方面比较通用的。
notion image
本题的exp如下:

关于one_gadget

one_gadget的指令我偶尔会用,但是总是意识不到他的限制点是可以直接通过人工进行绕过的
例如:
notion image
这个地方,这个地方的0xe3afe的one gadget,限制条件是r15和r12的值需要等于0
这个应该还是有点熟悉的,这两个寄存器同时存在的时候,直接用payload将0输入进去即可
这样就可以直接让one-gadget可以被使用了!

fmt3

notion image
我自己的代码如下:
疑问:
  • 关于格式化字符串到底是怎么进行漏洞利用的?为什么fmtstr_payload(8,{ret_addr : one_gadget_addr}) 不能利用?在offset正常的情况下
  • 如果是不满足one_gadget_addr 限定的条件下,那为什么fmtstr_payload(8,{printf_got: system_addr}) 也不是正确的?
以下是官方wp的代码:
这个代码主要涉及到的是关于fmtstr_payload函数的使用,以及关于one_gadget的限制突破,结合起来其实理论上是将fmtstr_payload中的值,化为一个ROP的链。
这个链可以将one_gadget的限制进行绕过,但是我不知道怎么用fmtstr_payload函数实现。
fmtstr_payload函数的原型是有write_size 参数,这个参数理论上是针对单个参数更改的时候可以很方便的进行,但是在针对像是ROP链的时候,就实现不了了
例如我想将返回地址设置成以下的样子:
那就代表我必须进行,将所有的地址都按照 write_size='long' 这样的规格进行,但是在64位修改地址的时候,地址数字太大了不能进行修改,搞得我目前也不知道该怎么办
不过我找寻了其他的payload,以下payload应该可以实现:
使用场景(以本题为例):

all-in-one-file

直接没看懂什么意思,文件1被关闭了那我该怎么办?
解答:
使用脚本即可,输入时的回车键在程序判断的时候会形成干扰,导致不能够被执行

week 4

srop

关于过滤器
notion image
这个SROP让我真正地大致明白了什么是具体的SROP解法,其实相对来说很简单:
就是利用sigreturn 系统调用,其他的说什么都是空的,就是利用这个系统调用就行了
首先构造一个frame:
这个frame用来作为srop中sigreturn系统调用返回之后的改变寄存器的模版,他甚至可以实现栈迁移,因为我们的rsp可以直接被改。
在同时也可以把执行的代码(rip)修改,改变此时程序的调用方向。
然后在我们本就熟悉的ROP链的构造的基础上,再进行srop的调用
这道题只是在同时结合了orw,用open、read、write的方法输出了flag而已

结束了?

这道题我真的学到了!!!
栈迁移原来是可以这样写。
我们将文件放到ida中,发现
notion image
有个sandbox,所以不能进行exec,那就进行orw就行
然后因为有个格式化字符串函数,可以泄露内存地址
重点来了,重点,我们发现栈溢出的地方很短,也就到返回地址处,也就是刚刚溢出两个栈帧长度
那么肯定就要考虑栈迁移。
我以前对栈迁移的理解基本上就是迁移到栈中我们可以写的变量的原本位置,再继续输入ROP链。
但是这个题不一样,这个题因为如果只迁移到局部变量开始处,哪怕修改了内容为ROP链,因为执行不了exec 函数,只有orw但是orw的ROP链太长了,根本塞不下。
所以该怎么弄呢?那就是利用函数自带的leave指令,通过修改rbp值的方式将rsp、rbp俩寄存器的值进行调用。
首先修改返回地址到偏移量0x148D
notion image
巧妙地利用了原本就存在的read函数,同时也可以更改rbp的值,这次返回到0x148D的同时,rbp也转到了elf.address + 0x4400 + 0x40 的位置
然后这次read函数需要send一个字符串,这个字符串就是要被写在rbp-0x40 的地址上。
然后这次main函数结束,rbp转为elf.address + 0x4400rsp转到原来的rbp+8 ,也就是leave_ret的地方。
执行它,rbp重新变为elf.address + 0x4400 + 0x40rsp变为指向pop rdx这里,进行这一串ROP链的执行,因为之前的rdi、rsi寄存器都没变,所以直接写rdx的值,将我们下次可以输入的ROP长度变大。
然后重新在elf.address + 0x4400 的地址上进行ROP链的输入即可,注意此时rsp的值其实是指向elf.address + 0x4400+0x20了,所以我们在进行重写的时候需要将之前的几个位置用字符填满,或者是将其进行ret来将其“滑”到+0x20的地址
整体代码:
 
  • CTF-WP
  • NewStar2023四川大学网络空间安全学院考研经验贴
    • Giscus
    • Cusdis
    Catalog