BUUCTF PWN
rip
checksec分析一下,发现没有开NX,PIE。栈段可执行,还有RWX的段
看了一下main函数存在栈溢出,然后有一个fun函数很奇怪跟进看一下,发现是后门,很简单的ret2text,但是做64位题的时候要注意堆栈平衡
warmup_csaw_2016
看了一下,发现main函数中存在栈溢出,然后我们开始排查一下左边的函数,发现了这个函数。发现这题又是简单的ret2text,还是注意堆栈平衡
但是这题需要注意一下,他跟其他的题不一样,它不需要去堆栈平衡,所以后面做题我们需要去确认一下
ciscn_2019_n_1
checksec看看开启了啥保护,发现是64位程序开启了NX保护
通过查看main函数中发现了func函数,然后跟进一下func函数,看到了gets函数造成的栈溢出,然后还有我们需要的system("cat /flag"),但是通过阅读代码发现调用system函数是有要求的,发现需要v2等于11.28125才可以,但是上面已经将v2赋值为了0.0
然后我看到了system函数和cat /flag这两个,我已经有了思路就是自己去构造一下,通过栈溢出直接溢出到sytem函数的位置,然后将cat /flag参数传入,而要将参数传入需要用到pop rdi;ret这个命令,我们可以通过ROPgadget来看找到这个的地址,然后构造payload就行了,现在我们需要知道system函数的plt地址,cat /flag地址,pop rid;ret地址,就可以完成这个栈溢出。
然后要注意队堆栈平衡,这题需要考虑所以我们加了一个ret的地址在system前面
当做到这里我以为我已经完成了,但是我看到了别人的payload,我才发现我原来多做了很多的步骤
首先我们看一下他的代码,发现他只用了一个地址,我就好奇去看了一下这个地址
我发现他溢出的这个地址是fun阐述的其中一部分,他并不是直接溢出到system函数,而是溢出到他的上面的位置,通过这里的代码往下看,我发现他这里mov edi其实已经开始给edi赋值了,然后下面调用了system函数,就完成了整个的攻击过程,这个攻击过程和我们上面写的攻击过程原理其实是一样的,但是我们是通过手动完成了这个步骤,他是通过溢出到这个地址,然后下面的代码刚好把我们后面的步骤完成了,其实想一下
他这个地方其实已经就是把值传入了,以后我们做题看到如果我们需要的参数已经在函数体内了,我们就可以通过上述的方法来完成
jarvisoj_level0
发现打开了NX保护,但是canary和pie还有relro保护都没有开
通过跟进ida发现这是一个很简单的ret2text
[第五空间2019 决赛]PWN5
首先开始还是简单的checksec一下
发现开启了canary保护,这个时候我就在想他可能会考到canary的绕过,也可以不用到栈溢出,然后ida跟进一下
跟进主函数看一下,整体代码的逻辑就是
- 定义了一些变量,包括用于存储输入的字符数组
nptr
和buf
,以及用于存储随机数生成器种子的v1
。 - 使用
setvbuf
函数设置stdout
(标准输出)的缓冲区,使其不进行缓冲。 - 获取当前时间作为随机数生成器的种子,并通过
srand
函数设置随机数种子。 - 打开
/dev/urandom
设备文件,从中读取4个字节到dword_804C044
变量中。/dev/urandom
是一个提供伪随机数的设备文件。 - 通过
printf
函数提示用户输入他们的名称,然后使用read
函数从标准输入读取最多 99 个字节到buf
数组。 - 再次使用
printf
函数提示用户输入密码。 - 使用
read
函数从标准输入读取最多 15 个字节到nptr
数组。 - 将
nptr
数组的内容转换为整数,并与dword_804C044
进行比较。如果它们相等,程序将执行system("/bin/sh")
,这将启动一个 shell 提示符,允许用户执行命令。 - 如果密码不正确,程序将打印 "fail"。
- 最后,程序检查是否有安全违规,如果没有,返回0。
这个时候我看可以看到我们只需要输入一个数(nptr)和dword_804C044相等就可以运行获取shell的代码了,但是这是一个随机数我们该如何输入一个一样的呢?
这里考察的是格式化字符串的漏洞
我看可以看到这两地方,我们向buf输入数据,然后下面printf会把buf给输出出来,这里就存在漏洞,通常printf会将第一个参数当作格式化字符串,但是格式化字符串应该是在编写代码的时候给写好的,这里我们可以控制就可以通过格式化字符串输出我们想到的东西,这个漏洞通常运用在泄露栈内存,泄露任意地址内存,篡改栈内存,篡改任意代码内存,这四个方面。我们知道了他有这四个用途,我们好好想想,我们可以篡改任意代码内存了,那是不是就可以篡改随机值,将他改成我们输入进去的数字,所以payload如下
这里是解释为什么我们是10$了
然后%n的含义是,前面输出了多少的字节数据,然后他就给这个地方赋值多少,比如输出了4字节的数据,那这个地方就被篡改成4了
然后因为p32(addr),是将地址转为32位,32位为4字节,所以这个随机数这个地方就被我们篡改成了4了,现在只需要我们输入4就可以跟随机值正确匹配了
这个就是完整的exp了
jarvisoj_level2
checksec
发现没有canary,可能存在栈溢出
ida跟进
发现是一道非常简单的ROP构造
exp:
bjdctf_2020_babystack
checksec
ida跟进
发现他是很简单的ret2text,整体代码的逻辑就是scanf向nbytes读入,然后nbytes当成read的第三个参数,给buf赋值。所以我们给nbytes赋值大一点,不然不够造成栈溢出
exp:
这里要注意栈平衡
[NewStarCTF 2023]ret2text
最基本的ret2text
ciscn_2019_n_8
判断var[13]的值是不是17,只需要输入的时候在第18位填写17就行了,因为下标是从0开始的
get_started_3dsctf_2016
很简单的ret2text,32位栈传参,所以只需要把满足的值写入栈中就行了
jarvisoj_level2_x64
很明显的栈溢出,然后系统调用过system函数,所以可以调用system_plt,因为是64位程序,所以是寄存器传参,前六个整数或指针参数通常使用寄存器RDI, RSI, RDX, RCX, R8, 和 R9来传递,后面的参数还是会放到栈中进行传参,程序本身还存在/bin/sh,所以构造system(/bin/sh)
[HarekazeCTF2019]baby_rop
跟上题的思路差不多,但是64位程序都需要注意一下堆栈平衡
others_shellcode
链接即有shell
[OGeek2019]babyrop
32位程序,RELRO保护全开还有NX保护
main
sub_80486BB函数是一个初始化函数,然后下面打开了/dev/urandom获取了随机值然后将他赋值给buf,然后再将buf传入sub_804871F并且将返回值给到v2
sub_804871F
清空s和buf变量,然后将传入进来的随机值转换成长整型然后传给s,然后需要我们传入一些值给到buf,并将值传入的长度给到v5,并且将buf的最后一个读取的字符设置位0,这是移除换行符的操作。然后算出buf的长度给到v1,接下来判断buf和s的值是否相同,如果不相同退出程序,相同就输出,然后返回buf第八个字符,回到主函数中,v2接收返回值,然后v2当作sub_80487D0的参数
sub_80487D0
判断传入进来的值是否等于127,如果相等就可以输入0xc8大小的值,如果不相等就可以输入a1的大小的值,这里0xc8并不能造成栈溢出,所以得从a1的值下手
整理思路
整体思路很简单,这里我们需要绕过sub_804871F函数的判断,因为如果判断不相同的话就会退出程序,这里需要绕过,让判断相同,这里改如果绕过呢?我们如果让v1等于0的话,那是不是就是判断buf和s的前0个字符,那这里就会恒相同,那么该如何让v1等于0呢?由于v1是通过strlen计算buf字长的,但是strlen字长判断是通过\x00截断的,所以让buf的最开始为\x00的话这里的v1就会等于0了。
第二步我们需要修改a1的值,让他足够的大,因为这里的a1实际上就是sub_804871F中buf的第八个参数,这里需要用到转义字符
\为转义字符,而’\xhh‘表示ASCII码值与’hh’这个十六进制数相等的符号,例如’\xff’表示ASCII码为255的符号
所以我们就需要将buf[7]这个地方改为\xff,这样就可以使得a1的值大,导致我们可以栈溢出
然后就是泄露libc那一套了
not_the_same_3dsctf_2016
简单的rop
铁人三项(第五赛区)_2018_rop
简单rop
别问为什么我直接知道偏移,因为我到LibcSearcher有问题,上网找到的偏移
bjdctf_2020_babystack2
这题就是整数溢出,然后ret2text
bjdctf_2020_babyrop
checksec
发现开启了NX保护
ida分析
vuln:
这里存在栈溢出漏洞,然后并没有在plt表发现system函数,也没有/bin/sh字符串,所以我们这题用ret2libc,构造ROP链来完成
jarvisoj_fm
checksec
32位程序开启了Canary保护和NX保护
通过题目看到这,我认为应该是通过格式化字符串来泄露Canary的值,然后再去进行栈溢出
通过对main函数的分析,发现了prinrt(buf)
这个地方存在格式化字符串漏洞,然后在往下分析,我们知道需要满足x==4就可以获取到shell了,没有我们想的那么复杂,只是通过格式化字符串漏洞造成修改任意地址的值的目的
现在只需要知道x变量的地址,和我们格式化字符串漏洞在栈上是第几个写入我们的字符串位置就行了
通过看栈的布局结构可以知道实在第11个参数位置,x_addr=0x0804A02C
jarvisoj_tell_me_something
checksec
64位程序,只开了NX保护
main:
通过main函数的分析发现明显的栈溢出
good_name:
还有一个后门函数
所以这题很简单,就是ret2text,但是有一个地方要注意,这里的栈溢出只需要溢出0x88,不需要再加上0x8了
可以看到最后的地方只有一个ret,并没有leave命令,所以这里就并没有父函数的rbp,所以这里就不需要加上0x8了
__EOF__

本文链接:https://www.cnblogs.com/Q1Sec/p/18253806.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)