note
思路是通过say中的格式化字符串漏洞,改topchunk,改完后,减小topchunk,然后分配一个大于topchunk的堆,得到main_arena,
再使用两次say改malloc_hook以及realloc_hook(调整栈,打og)
realloc_og调整栈:https://blog.csdn.net/qq_39869547/article/details/104587504
house of orange:https://www.cnblogs.com/L0g4n-blog/p/14217309.html
1 | from pwn import * |
PassWordBox_FreeVersion
64位保护全开,add函数中存在off-by-null,并且在输入数据后会对数据进行加密,加密算法如下
1 | __int64 __fastcall cry(__int64 a1, int a2)//a1为堆content的地址,a2为输入的size |
已知初始数据a,异或后的数据b,a ^ qword_4040 = b ,b ^ a = qword_4040
本题环境是ubuntu18,而ubuntu18中需要注意tcache的影响不能像ubuntu16那样overlapping,思路是先创建三个堆chunk0,chunk1,
chunk2,将0x100的tcache填满后,将chunk0放到unsortedbin,并将chunk2的pre_size改为前两个堆的大小,此时再free2就能触发chunk2和chunk0合并,然后分配一个0xf8的堆,main_arena就会到chunk1的fd,
而此时chunk1不是free状态,这样就可以泄露libc了,泄露了libc之后,因为之前分配的chunk1并没有free,再分配一个堆,堆9就会与
堆1重合,此时bss段上有两个同样的指针一个索引是1,一个是9,然后就可以乱写了(不是
1 | from pwn import * |
PassWordBox_ProVersion
strings看一下支持的版本,是2.31,malloc大小限制为largebin
通过largebin将tcache_max_bytes和tcache_bins改大
可以看到此时tcache_max_bytes和tcache_bins非常大(反正比0x600大)
free掉10此时10这个堆是当tcachefree掉的,然后edit(0,把对应地址改成free_hook,再add得到这个堆填入system就可以了)
1 | from pwn import * |
JigSaw‘sCage
检查,64位保护全开,前面存在一个整数溢出,如下
1 | unsigned __int64 sub_15F0() |
第一次必须保证v1为0,但是按道理来说不应该只要第一次溢出了,然后再输入0也可以v2不变,结果v2变0了(盲猜与scanf有关)
然后注意看test功能
1 | unsigned __int64 sub_1B9E() |
思路大致出来了,创建4个堆,然后分别填上合适的shellcde就可以了(真的良心给了0x50的空间,另外还有一种shellcode是通过改free_hook为system挺短的)
1 | from pwn import * |
LifeSimulation
c++现在不太会,以后再补充
lemon_pwn
这个题有两种方法做,在程序开始有一个地方满足条件能把flag读到bss段上,如下
1 | __int64 sub_DF3() |
这个地方由于rand()函数未设置种子,因此rand()为固定值,v1那个地方要算一下,我算出来buf
为p32(0x783d9e5e)+p32(0x1),应该也有其它值能满足条件
然后看color函数
1 | int sub_1295() |
这个函数是本题最关键的地方(没有检查下标)通过这个函数有两种做法,一种为栈上的做法,一种为堆的做法
栈的做法如下,思路是得到flag后三位地址后,通过功能color来将栈./lemon那个的地址改成flag地址,有一位不确定
需要爆破,然后调用功能1,就会报错,输出flag
1 | from pwn import * |
堆的做法如下,堆的做法有亿点点复杂,在add函数中会先分配一个0x30的堆,然后在判断输入的size的,>=0x400就
free掉,但是0x30那个堆没有free,并且写在bss段上了,此时再调用free函数就能double free
先分配几个堆
1 | add(3,"a",0x10,p64(0)+p64(0x31)) |
此时的堆如图
然后仔细看这一部分
1 | now_ad = heap_ad -0x10 |
此时的堆如图
1 | add(0,"a1",0x3c0,"aaaaa")#此时堆2那个0x60的堆被写入main_arena |
后面的思路是分配到栈上把./lemon_pwn那个地址改成flag(环境有问题,都分配到stdout上面了,就是写不进去…
1 | from pwn import * |
还有一个ez_pwn和baby_null太阴间了,0解还是1解就不复现了