1:题目:warmup_csaw_2016
下载附件得到一份64位ELF文件
checksec检查都开启了哪些防护措施
shift+f12查看字符串,发现cat flag.txt字眼。双击,发现其压栈的地址为0x40060D,call system调用 cat flag.txt
接着查看main函数
查看s,发现其距离返回地址为0x40+8
故可编写exp拿到flag
本题所涉及的sprintf知识点
上代码:
2:题目:ciscn_2019_n_1
下载附件,一个64位的ELF文件。
checksec检查开启哪些防护措施
拖进IDA分析,shift+f12查看字符串发现cat flag字眼。
双击此cat flag 找到其压栈位置地址0x4006BE
然后查看main函数
思路一:栈溢出覆盖返回地址。
双击v1发现其距离返回地址位0x30+8
所以exp编写如下,运行拿到flag。
思路二:覆盖局部变量
编写exp拿到flag。
3:题目:pwn1_sctf_2016
拿到附件,先查看文件类型,为32位ELF文件,checksec 检查保护措施,没有开启栈保护措施。
拖进IDA32分析,shift+f12查看字符串寻找敏感字眼,找到敏感字眼cat flag。
双击找寻其地址,并记住其地址。
找到main函数,分析可以利用的漏洞,发现调用了vuln函数。
尝试编写exp
本题涉及的知识点:
fgets函数的原型为
include <stdio.h>
char *fgets(char *s, int size, FILE *stream)
fgets函数相比gets更安全,但也比gets函数更麻烦,其有三个参数,功能是从 stream 流中读取 size 个字符存储到字符指针变量 s 所指向的内存空间。它的返回值是一个指针,指向字符串中第一个字符的地址。s 代表要保存到的内存空间的首地址,可以是字符数组名,也可以是指向字符数组的字符指针变量名。size 代表的是读取字符串的长度。stream 表示从何种流中读取,可以是标准输入流 stdin,也可以是文件流,即从某个文件中读取,这个在后面讲文件的时候再详细介绍。标准输入流就是前面讲的输入缓冲区。所以如果是从键盘读取数据的话就是从输入缓冲区中读取数据,即从标准输入流 stdin 中读取数据,所以第三个参数为 stdin。
如代码:
4:题目:jarvisoj_level0
下载附件,die检查为ELF64位文件,checksec检查开启了哪些保护
拖进IDA分析,shift+f12查看敏感字眼,看见bin/sh后门函数
接着查看main函数查找漏洞函数,可以看出调用了vulnerable_function函数,
于是编写exp,运行拿到flag
5:题目:[第五空间2019 决赛]PWN5 (格式化字符串漏洞)
下载附件,die查看,是一个ELF32位文件。
checksec查看都开启了哪些保护措施。
6:题目:rop_test (典型栈溢出--基础ROP之ret2text 32位ELF文件)
拿到附件,die查看为ELF32文件。(第7道题是64位文件,可以对比这俩题目EXP有何不同)
checksec检查下都开启了哪些保护。
试着编写exp,运行获取flag
[栈溢出--基础ROP相关文章]((27条消息) ret2xx----- Pwn中常见的CTF模板命题_Greeety的博客-CSDN博客_pwn中常见的ctf模板命题) ((27条消息) 栈溢出----基础rop_xiaoyuyulala的博客-CSDN博客)
7:题目:[HarekazeCTF2019]baby_rop (典型栈溢出 ROP之ret2text 64位文件)
拿到文件,检查为ELF64位文件。(第6道题是32位文件,可以对比这俩题目EXP有何不同)
checksec检查开启了哪些保护措施。
查找pop rdi ;ret的地址
exp如下:
8:题目:pwn_string (格式化字符串漏洞之ret2shellcode)
拿到附件,die查看为ELF64位文件。
checksec检查开启了哪些保护。
拖进IDA,查看敏感字眼,并未发现什么,但不难看出该程序是个小游戏
直接在main函数中分析代码:
在printf(有格式化字符串漏洞)测试字符串偏移位置,可以看出是第八位0x6161616161616161,但前边还有输入v2的值,占了一个偏移,所以wish是print的第八个参数,格式化字符串的第七个参数。
编写exp
9:题目:ciscn_2019_n_8 (覆盖局部变量)
下载附件,检查为ELF32位文件,再检查开启了哪些保护。
exp如下
10:题目 :bjdctf_2020_babystack
拿到附件,die检查为64位ELF,checksec检查开启了哪些保护措施。
拖进ida分析,先查看字符串有无敏感字眼。
点击buf
exp
11:题目:pwn04 (栈溢出之Carry绕过)
拿到附件,检查为ELF32位文件,再检查开启了哪些保护,
exp如下:
12:题目:pwn03(ret2libc -32)
下载附件,检查为32ELF文件,checksec检查开启哪些保护
exp如下
13:题目:get_started_3dsctf_2016 (无ebp寻址)
拿到附件,检查为32位ELF文件,checksec,
但是发现若没有flag返回地址的话程序就没法正常打印flag,于是改payload,payload = ‘a’ * 垃圾数据 + get_flag的地址 + exit_addr + get_flag的第一个参数 + get_flag的第二个参数,
exp如下:
14:BJDCTF2020 题目: babyrouter(ret2libc-64)
检查附件,64位elf,checksec开启哪些保护措施
拖进ida分析,查看字符串表无binsh,无system,
查找一下gadgets
点击main函数
先构造ROP链利用putsplt表泄露readgot表的地址然后根据readgot表的真实地址计算出system与binsh的地址,第一个payload为p=flat(b'a'*(0x20+8),poprdi,readgot,putsplt,main,word_size=64)。
然后利用计算出的system,binsh构造第二个payload,p2=flat(b'a'*(0x20+8),ret,poprdi,bin,system,word_size=64)。
exp如下:
15: 1024杯 题目 1024_happy_checkin(ret2libc 64)
拿到附件,die检查为64位elf文件,checksec检查
拖进ida分析
查看main函数
s缓冲区的溢出大小为0x370+8,
ROPgadget找我们需要用到的gadgets
泄露之后先recvline接收程序puts的s,再接收泄露的libc地址,addr=u64(r.recv(6).ljust(8,b'\x00'),然后计算system与binsh
的地址,接着利用计算得到的system与binsh构造第二个payload来getshell,p2=flat(b'a'(0x370+8),ret,rdi,bin,system,word_size=64)
exp如下:
16:题目:ciscn_2019_n_5 (法1:ret2libc-64) 17题为本题的ret2shellcode解法
拿到附件,die检查为64位程序,checksec检查保护措施
拖进ida分析,可以看到没有system,没有binsh,
再查看main函数,
查找我们需要的gadgets
先构造一个payload通过read函数,这个payload随便都可以,主要目的就是传进去一个name好让程序继续执行。p1=flat(b'aaaa') ,然后构造第二个payload,利用puts函数的plt表泄露read函数got表的真实地址,然后计算system与binsh的地址,p2=flat(b'a'*(0x20+8),poprdi,readgot,putsplt,main,word_size=64),接收泄露的libc ,addr=u64(r.recv(6).ljust(8,b'\x00')),因为p2的返回地址填的是main函数,程序会再次执行,需要再构造payload通过read函数,p3=flat(b'aaaa') ,然后根据计算出的system与binsh构造payload来getshell,p4=flat(b'a'*(0x20+8),ret,poprdi,bin,system,word_size=64)
exp如下:
exp如下
18:题目:ciscn_2019_ne_5(ret2text-32)
拿到附件,die检查为32位elf文件,checksec检查开启哪些保护。
拖进ida分析,未直接给出binsh,但程序有system函数。
查看main函数
exp如下:
19:题目:ciscn_2019_c_1(ret2libc-64)
拿到附件,检查为64位elf文件。
checksec检查开启哪些保护
没有binsh没有system函数,需要自己构造ROP链了。
查看main函数
分析完毕,开始构造第一个payload泄露libc,p=flat(b'\x00',b'a'*(0x50+7),rdi,putsgot,putsplt,main,word_size=64),计算system与binsh地址,再构造第二个payload获得shell,p1=flat(b'\x00',b'a'*(0x50+7),ret,rdi,bin,system,word_size=64),
exp如下:
20:题目:[HarekazeCTF2019]baby_rop2(ret2libc-64加设置printf参数)
checksec 检查
ida分析。
利用printf泄露函数地址,参数类型为printf(“%s”,address),由于64位程序前六个参数不直接使用栈,先使用寄存器RDI、RSI、RDX、RCX、R8、R9,传递,其余参数才通过栈传递。
第一个参数我们利用程序自带的’Welcome …,%s’字符串
第二个参数我们选择打印read函数的真正地址来泄露libc
查找用到的gadgets
构造payload1:
rsi,readgot:设置寄存器rsi的内容为readgot,printf的第二个参数,r15因为没用到,随意设置。
printfplt:执行ret指令后,返回到printf在plt表中的地址,相当于执行printf函数
main:printf函数的返回地址,得到read真正地址后返回程序开始,重新执行
打通后发现没有flag
21:题目:repeater
checksec
64位小端序ELF程序
没有敏感字眼
main函数:
由于程序开启了pie保护,地址只剩下了后三位,我们需要先找到基地址才能继续解题。所以先要满足if判断来打印出main函数真实地址。
我们需要先第一次溢出使if判断相等打印出main函数地址,构造第一个payload来覆盖局部变量:p=flat(b'a'*(0x20),0x321321,word_size=64),然后接收main地址。
r.recvuntil("But there is gift for you :\n")
mainaddr=int(r.recvuntil("\n"),16)
然后mainaddr减去随机化的main后三位即为基地址
然后0x202040加上基地址即为真实地址,
这个地址可以读入shellcode,然后在溢出点的时候把返回地址覆盖为读入shellcode的地址即可getshell。构造第二个payload:p= b'a'*(0x30+8)+ p64(base + 0x202040)
exp如下: