type
status
date
slug
summary
tags
category
icon
password
上个星期的时候在打有个比赛SCTF的时候,遇到一道栈题,算是这个比赛的签到题。
整体来说并不难,但当时并没有写出来,导致这个比赛颗粒无收。赛后知道看了wp才明白这道题目的解法,也算是自己学艺不精,连这种题都没能做出来。这里就写这篇文章记录一下这道题目。
这道题是个典型的数组越界的题目,在一开始先确定要输入的数有几个,最大可以输入40
之后会进入到distribute函数之中,
之后会更具我们输入的数据进行循环,每一次循环的次数都记录在
i
这个地址中我们看这里可以知道这个i的地址是在距离rbp的0x30的距离上面,现在我们调试一下
我们现在已经循环过一次,我们第一次输入的数据为1,于是在
0x7ffc5966c860
这里存放的就是我们的1这个数据,我们之前说过我们循环的次数要被放在距离rbp为-0x30的地方,便是0x7ffc5966c910
这里,刚好这里面的数据为1这里我们变会发现一个问题,我们循环放入的数据起始在
0x7ffc5966c860
,而存放循环次数的i放在0x7ffc5966c910
,其中的距离不过才22个字节长度,但是我们之前输入的循环大小为40,结合之前的函数可知这里,其实要满足的条件当i的值小于40时就会一直从0x7ffc5966c860
开始循环读入数据。于是这里便会出现一个问题,那就是当我们在第23次循环时输入的数会直接修改
0x7ffc5966c910
里面的内容,同时也会修改i的内容,导致程序的i不在是我们循环的次数而是更具我们输入的数确定,同时这里i的数被修改,但程序并没有检测的条件,于是无论我们怎么修改程序都会认可这个值,然后在下次循环时通过这个值去寻找要读入数的地方。这里我们找到这个思路后就可以按照一般的栈溢出的来作,
这里我们前22次循环都随便输入一个数,但第23次循环我们要输入的数为28。这样我们修改i的值为28,那么程序便会更具这个28,直接从第一个循环开始读入数据的第30位(在修改后的i,程序会有两次+1的过程然后在寻找那个位置)刚好是rbp的下一位这里读入数据
于是这里我们就可以向用这个泄露libc地址,然后使程序重新开始一遍,然后执行system(/bin/sh)
就这样拿到libc地址然后在从main开始执行。
exp
这道题还是出在对数据存放地址的不敏感,导致的问题,在做的时候都发现问题,但没有解决导致这道题不能解决。这是不应该出现的情况。
- 作者:wgiegie
- 链接:https://tangly1024.com/article/1183ecc9-5160-8062-be16-d987c9ea7e31
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。