buuctf-pwn-rip

先用checksec看一下保护情况

红色表示没有保护,绿色则表示有相应的保护
关于每种保护会在之后的做题中遇到,也有相应的应对措施,这次就不过多深入

打开ida64分析附件

发现高危函数gets,这个函数不会检查输入的长度,直到用户输入换行符为止
我们可以利用它修改函数的返回地址,从而执行后门函数

请先自行了解函数调用的过程,以及函数调用过程中栈是如何变化的


找到后门函数了,可以通过这个获取shell,然后拿到flag

在程序界面按tab切换到图形化汇编窗口,再按空格切换到普通汇编窗口
由于程序没有开启PIE(地址空间随机化),可以直接利用ida中后门函数的地址(有PIE后地址会变,每次运行地址不固定)

看看输入"abcdefghijklmnoonmlkjihgfedcba"之后栈的情况

前面"abcdefghijklmno"这15个字符填充了s字符数组,可以换成任意字符,这里是为了方便看出gets函数填充s数组的顺序
后面8个字符"onmlkjih"填充了rbp,这个也是任意的,因为执行system函数拿到shell后rbp指向什么位置都和我们无关了
后面就是ret的位置了,我们要让它返回到后门函数的位置,这里可以使用pwntools中的p64打包后门函数的地址,将p64打包的地址加到payload后面

所以exp

from pwn import *

p = remote("node5.buuoj.cn",27174)

payload = b'a'*15+b'b'*8+p64(0x40118A)

p.sendline(payload)

p.interactive()

flag{48545090-76f7-4fc7-9cf8-0855ca560508}

15个a填充s字符数组,8个b填充rbp,之后加上返回地址

这里解释一下为什么要跳到0x40118A这个位置,其实是为了不破坏堆栈平衡
我们正常ret之后指向的应该是一个正常的栈帧,它的rsp是对齐的
所以在ret之后不能执行push rbp这条指令,这条指令会改变rsp的值,破坏堆栈平衡
导致程序在执行system函数时用到的一个指令报错
所以需要跳过push这条指令,所以直接跳到0x40118A这里了,其实0x401187也可以

可以看看这篇文章,讲的比较详细 https://zhuanlan.zhihu.com/p/611961995

posted @ 2024-04-26 01:54  zzkkk1h  阅读(60)  评论(0)    收藏  举报