<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>wgiegie’s Blog</title>
        <link>https://tangly1024.com/</link>
        <description>一个NotionNext搭建的博客</description>
        <lastBuildDate>Sat, 03 Aug 2024 09:18:50 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2024, wgiegie</copyright>
        <item>
            <title><![CDATA[周报8.2]]></title>
            <link>https://tangly1024.com/article/ae32075e-decd-4e4d-ab74-fbe46a9eee53</link>
            <guid>https://tangly1024.com/article/ae32075e-decd-4e4d-ab74-fbe46a9eee53</guid>
            <pubDate>Fri, 02 Aug 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-ae32075edecd4e4dab74fbe46a9eee53"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-3d2ac24e2ee143c1858167a4c7b6df78">先简单描述一下周的学习情况。</div><div class="notion-text notion-block-a6bd8e55b87144ef86a5c14649c832a0">这周的话依然是按照ctfwiki上的house of的顺序往下学习。</div><ol start="1" class="notion-list notion-list-numbered notion-block-2f7dc8166d78422982ed6c0df714ffcb"><li><b>house of lore </b></li></ol><div class="notion-text notion-block-9e72c439b8384a9aaade4d76681e03bd">这个手法由于在wiki上没有推荐的题目，于是就把这个手法的描述脚本详细的分析了一下，总体来说不是特别难得一种手法，在后面做题的时候遇到在详细在题目中分析。</div><div class="notion-text notion-block-be10cb8ef3344f3a8eedea527d10a6e3">有关于这个手法的分析可以下面这里的内容，我与其他的house of一起写的写成一个系列。</div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-e43270e1859d4b57afaf5d85825564f1" href="https://notion-next-pied-omega-95.vercel.app/article/68926489-6f75-42d4-93e7-9075e244d1b4#8ee6489db7f0460b8bea35cb740a17d0"><div><div class="notion-bookmark-title">house of系列 | wgiegie’s Blog</div><div class="notion-bookmark-description">一个NotionNext搭建的博客</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fnotion-next-pied-omega-95.vercel.app%2Ffavicon.ico?table=block&amp;id=e43270e1-859d-4b57-afaf-5d85825564f1&amp;t=e43270e1-859d-4b57-afaf-5d85825564f1" alt="house of系列 | wgiegie’s Blog" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://notion-next-pied-omega-95.vercel.app/article/68926489-6f75-42d4-93e7-9075e244d1b4#8ee6489db7f0460b8bea35cb740a17d0</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/images/page-cover/met_the_unicorn_in_captivity.jpg" alt="house of系列 | wgiegie’s Blog" loading="lazy" decoding="async"/></div></a></div><ol start="1" class="notion-list notion-list-numbered notion-block-06bb7e32ab3f4d2b9a8e77f22439a32e"><li><b>House of Rabbit</b></li></ol><div class="notion-text notion-block-70c57deb64fa4ba28dedc231e6fb8096">这个于是一个比较奇妙的堆的利用姿势，用于绕过堆块的地址随机化保护（ASLR）达到<b>任意</b>地址分配的目的。</div><div class="notion-text notion-block-4d81d7d965444f85b92edee94e07ba0f">这个手法具体的过程我是利用了这个手法里提供的那道题进行分析的。</div><div class="notion-text notion-block-850e5f20771e4af19c9110d90b8f275a">这道题目整体来说不是太难，基本就是这个手法的照搬，但对于我而问题不小，一会儿在下面具体分析</div><div class="notion-text notion-block-8fb85075bcf546ee89a897ecc2861dce">这个手法的分析在下面这里</div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-d3ead666ed614a20923336dee6f96068" href="https://notion-next-pied-omega-95.vercel.app/article/68926489-6f75-42d4-93e7-9075e244d1b4#441c5be09ed742db90e60ca25eeafc8d"><div><div class="notion-bookmark-title">house of系列 | wgiegie’s Blog</div><div class="notion-bookmark-description">一个NotionNext搭建的博客</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fnotion-next-pied-omega-95.vercel.app%2Ffavicon.ico?table=block&amp;id=d3ead666-ed61-4a20-9233-36dee6f96068&amp;t=d3ead666-ed61-4a20-9233-36dee6f96068" alt="house of系列 | wgiegie’s Blog" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://notion-next-pied-omega-95.vercel.app/article/68926489-6f75-42d4-93e7-9075e244d1b4#441c5be09ed742db90e60ca25eeafc8d</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/images/page-cover/met_the_unicorn_in_captivity.jpg" alt="house of系列 | wgiegie’s Blog" loading="lazy" decoding="async"/></div></a></div><ol start="1" class="notion-list notion-list-numbered notion-block-69aef3c766554fa68924f7459a503b02"><li><b>House of Roman（未完）</b></li></ol><div class="notion-text notion-block-ad66683465024642a1ffd34cf3ca351c">这个手法的大致学了，但这个手法依然是更具据其提供的题目来描述的，这个题我还没有全部整完，故这里先留下，与下周的一起记录。</div><div class="notion-blank notion-block-98feb039fc624fd7815ca438438e330a"> </div><div class="notion-text notion-block-39b9862548984f388518a331dd358fb4">这周的学习进度大致就到这里，相对来说，目标基本完成，但还是在学习的过程中出现了一定的1问题，下面分析一下</div><div class="notion-blank notion-block-b51a61b8ff3b4a8785eaf44a83e48949"> </div><ol start="1" class="notion-list notion-list-numbered notion-block-a83c765131ab465ca5e0343d0b396226"><li>程序语言能力不足</li></ol><div class="notion-text notion-block-3f9a4b27d54f47adb460b3d78d77800c">在上面的House of Rabbit这里面的那道题由于无法进行gdb调式，只能读程序，导致很长时间都花费在理解程序上面，甚至有的地方还没有完全理解。这是一个很严重的问题，基本功不够，</div><ol start="1" class="notion-list notion-list-numbered notion-block-9e66d538a7144f1a98968ffe0c116403"><li>做过的题目不足</li></ol><div class="notion-text notion-block-745f9d62e31647d4967d1d5e55a1daca">在遇到有的特别情况时反映不够，导致出现长时间卡住的情况，像上周的那道题由于全程没有输出的情况有的地方要加入时间暂停。</div><div class="notion-blank notion-block-2482e40f27ff49fbbcc74b3485703268"> </div><div class="notion-text notion-block-e1151ef6772b48478ca9e7a490117e25">这些都是在上周的过程中保露出来比较严重的问题，结合这些问题与学习进度，对下周的规划如下</div><ol start="1" class="notion-list notion-list-numbered notion-block-51109a489e154dc889bb29535190c2dd"><li>先是wiki上的house of的手法都要学完，并且把之前与后面的题目总结出来，把能做的<b><span class="notion-inline-underscore">独立完成</span></b></li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-dfcb71caebf24312a57e76770874a85b"><li>在找一点时间从新学一下c语言和汇编</li></ol><div class="notion-blank notion-block-6406493d425f44a19a0e5995b427a54b"> </div><div class="notion-text notion-block-05e8138ad8d240c19ac68d2105eefc6d">行吧这周的周报到此为止，下周的这个周报尽量在周3向学长汇报之前学完吧。</div><div class="notion-blank notion-block-f384e5d12c3642a1b1730555e5b9cd0d"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[house of系列]]></title>
            <link>https://tangly1024.com/article/68926489-6f75-42d4-93e7-9075e244d1b4</link>
            <guid>https://tangly1024.com/article/68926489-6f75-42d4-93e7-9075e244d1b4</guid>
            <pubDate>Sun, 28 Jul 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-689264896f7542d493e79075e244d1b4"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-callout notion-gray_background_co notion-block-758a1d55a2fc40eb97c5d0689c7640f8"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="😀">😀</span></div><div class="notion-callout-text">这里写文章的前言：
一个简单的开头,简述这篇文章讨论的问题、目标、人物、背景是什么？并简述你给出的答案。<div class="notion-text notion-block-7d7eebeefdf6474ca3321543618fbbdc">可以说说你的故事：阻碍、努力、结果成果，意外与转折。</div></div></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-a6400d2223d944f28669f3cdc380113a" data-id="a6400d2223d944f28669f3cdc380113a"><span><div id="a6400d2223d944f28669f3cdc380113a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a6400d2223d944f28669f3cdc380113a" title="house of系列"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">house of系列</span></span></h2><div class="notion-text notion-block-063226ad03fb4f1cbc3d14b030514868">之前在堆的基础解法那里简单说了一下有关于堆的利用，从这里开始新起一章，这章主要讲一讲有关于house of的各各系列的手法与对应的libc版本。</div><div class="notion-blank notion-block-3030cfaa3f8c4cfd929a2271603fa5f4"> </div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-84bbeedcca044881921bbed81d966047" href="http://github.com"><div><div class="notion-bookmark-title">GitHub: Let’s build from here</div><div class="notion-bookmark-description">GitHub is where over 100 million developers shape the future of software, together. Contribute to the open source community, manage your Git repositories, review code like a pro, track bugs and fea...</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fgithub.com%2Ffluidicon.png?table=block&amp;id=84bbeedc-ca04-4881-921b-bed81d966047&amp;t=84bbeedc-ca04-4881-921b-bed81d966047" alt="GitHub: Let’s build from here" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">http://github.com</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fgithub.githubassets.com%2Fassets%2Fcampaign-social-031d6161fa10.png?table=block&amp;id=84bbeedc-ca04-4881-921b-bed81d966047&amp;t=84bbeedc-ca04-4881-921b-bed81d966047" alt="GitHub: Let’s build from here" loading="lazy" decoding="async"/></div></a></div><div class="notion-text notion-block-ade4f58cc33445aea3958ac97961f1f2">关于这里的手法的具体例子可以再这里查看，下面我就开启有关我对这里面的各中手法的理解与在做题时遇到的问题做一个具体的说明。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3361ecd2efc049859f871a540ac6ba0f" data-id="3361ecd2efc049859f871a540ac6ba0f"><span><div id="3361ecd2efc049859f871a540ac6ba0f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3361ecd2efc049859f871a540ac6ba0f" title="House Of Einherjar"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>House Of Einherjar</b></span></span></h2><div class="notion-text notion-block-341430aca9dc454f82a9cad5123f385f">这种利用方法与之前的方法有所不同的在于，其用到了一个之前没有过多使用，并且尽可能规避的有个chunk，</div><div class="notion-blank notion-block-c03a3327928246e0b691c5b21d859bff"> </div><div class="notion-text notion-block-84f6596f57bf4a3d8b389f7b1bebb5f1">这个chunk就是我们之前有所提到的，在所有我们自行申请堆的chunk只外的有程序在malloc我们申请的一个chunk时会与这个chunk一起从程序中为我们产生的top chunk。不过在正常情况下产生的这个top chunk，并不能直接供我们使用，只是作为一个chunk的后备资源，在后面如果我们有再次malloc的时候程序可以直接从top chunk中取出对应的chunk大小，从而使我们能快速申请到对应的chunk，不必在从程序中拿取chunk。</div><div class="notion-blank notion-block-8122c2712c9b4c5da0808abbcfd728a5"> </div><div class="notion-text notion-block-d99bdba9fd964bdab51430bac6dee7cc">正常情况下程序中的top chunk都有在malloc函数执行后就固定产生的大小，这个大小是固定的，如果程序申请的新的chunk的大小小于这个top chunk的大小，程序便会直接先从top chunk中分配出来使用，如果大于这个top chunk的大小则会从新向程序申请。</div><div class="notion-blank notion-block-7459d846bd2c441e9f788b055daf88ba"> </div><div class="notion-text notion-block-7c855901e82548f786cbcb728b9a07e2">这里便是我们这种手法的关键所在，关于我们能从top chunk中申请到多大的chunk这个是由top chunk的size决定的， 那这样如果我们能在top chunk的前一个chunk中存在堆溢出，那我们就可以修改top chunk中的size的大小，然后再在程序的其他地方比如<b>栈或bss数据段</b>等地址伪造一个fake_chunk ，然后让这个伪造的chunk和之前的存在堆溢出的chunk，一同被释放，并吧我们伪造的chunk到存在堆溢出的chunk的这一段距离都当做之前fake_chunk的大小一同free进入到top chunk中（top chunk相近的chunk free掉会直接与top chunk合并），这样就能导致top chunk的大小被远远放大，导致其起始地址直接从我们伪造的chunk开始。那这样之后我们在向程序申请chunk，程序便会从我们之前伪造的chunk的地址开始申请，使得我们可以控制栈或bss的地址进行我们想要的操作。</div><div class="notion-blank notion-block-0bf43664a34b4ad4b018e6163fccd6ac"> </div><div class="notion-text notion-block-289878b5945e4865a203b1ee7def848f">大致的过程就是上面的内容，当重点在于如何操作下面便是这种方法的具体操作。</div><div class="notion-blank notion-block-644091d54a4f40499a8f9758a227e402"> </div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-fed9d2e948b744c1966468c976c56cb1"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F0c1a609f-6e92-44d8-aca4-973407bad560%2F8f1aa2d976405baa7dce4788d6596429.png?table=block&amp;id=fed9d2e9-48b7-44c1-9664-68c976c56cb1&amp;t=fed9d2e9-48b7-44c1-9664-68c976c56cb1&amp;width=2278&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-d16904b477d94f03ac2db3e964c87927">简单来说也就是这幅图的内容，</div><ol start="1" class="notion-list notion-list-numbered notion-block-e8af5c6b335a4b5d94376b018ef89081"><li>在栈或bss中（更具题目需要）构造fake_chunk</li></ol><div class="notion-row notion-block-fd39d9fc860c464cb94e9fd2f04ebb1a"><div class="notion-column notion-block-dfd1561fa88c430d8a84f13e102b0d6e" style="width:calc((100% - (1 * min(32px, 4vw))) * 0.5)"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-cc4e9437bbed41b5b9dc81c3d89f232a"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fc035fe07-9a83-451d-b5cc-a2adac438ff1%2F2db6cd43c182b120aebe76db0e73378e.png?table=block&amp;id=cc4e9437-bbed-41b5-b9dc-81c3d89f232a&amp;t=cc4e9437-bbed-41b5-b9dc-81c3d89f232a&amp;width=1732&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure></div><div class="notion-spacer"></div><div class="notion-column notion-block-ba590f8710c3469997acbcb210effa7f" style="width:calc((100% - (1 * min(32px, 4vw))) * 0.5)"><div class="notion-text notion-block-c73e3e9c63ac40dbbab411fea3c0a6d7">大致要像这个一样，prev_size随便，size后面要计算的可以先放放，之后的4个位置都要放的是我们构造的fake_chunk的头地址，</div><div class="notion-blank notion-block-b1600023fe014b41b3c78e3e011add01"> </div></div><div class="notion-spacer"></div></div><ol start="1" class="notion-list notion-list-numbered notion-block-b0462a91dec24b5aa0754fedf60597c5"><li>计算fake_chunk的size和靠近top chunk的chunk（下面叫chunk_b）的prev_size 大小（这两个大小相同），并修改chunk_b的size的最后一位为0</li></ol><div class="notion-text notion-block-70baae0389974d8c86789564140aab28">这里为了让从fake_chunk到我们的top chunk的内容都能被程序放入到top chunk中，就要把从fake_chunk到chunk_b的距离计算出来然后放入fake_chunk的size和chunk_b的prev_size位置。</div><div class="notion-blank notion-block-998250e39c6e47208c80fb445107239f"> </div><div class="notion-text notion-red notion-block-9b020e517f354482abe6a594c8fbca36"><b>距离=chunk_b的头地址-fake_chunk头地址</b></div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-2b716a76a81f4f31915927de0e498d5c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fccc0a914-56b2-415a-b0ac-fb3cf1903b6c%2F00b80539a36ea470a02c5e4c335a3a69.png?table=block&amp;id=2b716a76-a81f-4f31-9159-27de0e498d5c&amp;t=2b716a76-a81f-4f31-9159-27de0e498d5c&amp;width=2040&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-174e02491d744e15af4dc564fb332aaa"> </div><div class="notion-text notion-block-d10b2ca7d8f645c28104375ce6f6c070">这里要用小的地址-大的地址，得到的才是正确的地址，最后的结果要想上面的一样。</div><ol start="1" class="notion-list notion-list-numbered notion-block-69b611fd63f1467c974a120e10db3f6c"><li>free掉chunk_b</li><ol class="notion-list notion-list-numbered notion-block-69b611fd63f1467c974a120e10db3f6c"><div class="notion-text notion-block-37b5f53c73a64829b2feed178cecdb2e">将chunk_b释放之后，由于我们修改了chunk_b的size 和prev_size的大小，使得程序将它free后会仍为从这个chunk到我们伪造的chunk都是free_chunk，从而使程序开启chunk的合并机制。并导致从我们的fake_chunk开始的头地址被当做top chunk的头地址，然后便可以在下一次malloc时，就从我们fake_chunk的头地址开始分配，从而达到我们控制栈或bss段的地址。</div><div class="notion-blank notion-block-53259ac04850466bba97beb051db2fc8"> </div></ol></ol><div class="notion-text notion-block-bce9cf7a8e4d493bbb1034ec9e0cd4ac">以上便是这个手法的利用，相对来说是一个比较攻击力大的手法，在ctfwiki上有一题，一会可以供我们分析一下。</div><div class="notion-blank notion-block-5454d3e2c7ec49adb265538b6c0095d0"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-adee968e1ec54a2bafe70ea818d21bb1" data-id="adee968e1ec54a2bafe70ea818d21bb1"><span><div id="adee968e1ec54a2bafe70ea818d21bb1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#adee968e1ec54a2bafe70ea818d21bb1" title="2016 Seccon tinypad"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>2016 Seccon tinypad</b></span></span></h3><div class="notion-blank notion-block-2d12e23135ac4ff5b6f6ff093d9cd1a6"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-153d73e1a5ed491481978d191e8dce56" data-id="153d73e1a5ed491481978d191e8dce56"><span><div id="153d73e1a5ed491481978d191e8dce56" class="notion-header-anchor"></div><a class="notion-hash-link" href="#153d73e1a5ed491481978d191e8dce56" title="House Of Force"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>House Of Force</b></span></span></h2><div class="notion-blank notion-block-6fac28904d044a1c9d64fc581fbd2fe3"> </div><div class="notion-text notion-block-01d336b214c74594a4480abb639d2bc8">这种方法对于堆的利用相对来说过程是比较简单的一种，不过由于程序的条件实行条件比较苛刻，故利用的地方不算特别多，并且这种手法的使用相对来说也有一定复杂的地方，故这种手法具体将通过题目来进行详解。</div><div class="notion-blank notion-block-49408edbb4ac454ea24bcdd745ec4e87"> </div><div class="notion-text notion-block-fa42a074f9594e1c98a8e10482739535">这种手法简单来说就是，通过堆溢出，修改top chunk的size的值为0xffffffffffffffff/0xffffffff(64位或32位的-1)</div><div class="notion-blank notion-block-3ce5d0294ccf41439e15ff37d8ed51ed"> </div><div class="notion-text notion-block-8e4a7eeb3f5a4792bef8d9e27094d5c5">然后将可以向程序申请一个很大很大的chunk，由于top chunk被我们修改为这个在程序中被认为是无限大的数字，所以我们的申请一定会被满足，而对于超出程序中原本top chunk的大小的内容，程序便会从其他地方拿却使用，故这里我们便可以直接申请一个到我们目标地址的chunk，然后就可以对这个地址进行修改和输入数据，由于我们的申请的内容一定是从程序中去申请而不向内核申请（top chunk的大小被我们修改为程序的最大值），故我们甚至可以直接申请到栈或bss等其他地址。从而满足我们后门的操作。</div><div class="notion-blank notion-block-f63eee2e3dde4ffb9b89bc0b937c0187"> </div><div class="notion-text notion-block-fb8bd28b0c294100983b64df712ee26e">这个手法的利用相对来说比较简单，当条件比较苛刻</div><ul class="notion-list notion-list-disc notion-block-a14819b3bad748f98691b6967b537810"><li>首先，需要存在漏洞使得用户能够控制 top chunk 的 size 域。</li></ul><ul class="notion-list notion-list-disc notion-block-965c0adffa984ae98e1e91416e73d10b"><li>其次，<b>需要用户能自由控制 malloc 的分配大小</b></li></ul><ul class="notion-list notion-list-disc notion-block-aea5ff9106d145c9b0c53d154f9053b3"><li>第三，分配的次数不能受限制</li></ul><div class="notion-text notion-block-d3ba1e53ac7242e28bcdfbfe143ebd0f">只有能满足这3点才算能使用这种手法的题目。</div><div class="notion-blank notion-block-b0052e7eb63043d68c2139dbdf133327"> </div><div class="notion-text notion-block-93de338883774169be38977c2b062d29"><b>这里还有一个需要注意的地方，那就是这种手法只能</b><b><span class="notion-inline-underscore">在libc-2.23到libc-2.27这里面的版本使用</span></b><b>，像libc-2.29及以上的版本就不能使用这种攻击手法</b></div><div class="notion-blank notion-block-4f761108bea3400781748d471bc64e68"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-478b6be0f82e4f36a1fcdd7ff03cc245" data-id="478b6be0f82e4f36a1fcdd7ff03cc245"><span><div id="478b6be0f82e4f36a1fcdd7ff03cc245" class="notion-header-anchor"></div><a class="notion-hash-link" href="#478b6be0f82e4f36a1fcdd7ff03cc245" title="HITCON training lab 11"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>HITCON training lab 11</b></span></span></h3><div class="notion-blank notion-block-1bcd2c17d71e4da0ba8495b758325185"> </div><div class="notion-text notion-block-4cec70039842489b86baae3c47a2a87b">这道题是ctfwiki上的题目相对来说是一到，比较简单的题目，</div><div class="notion-blank notion-block-2d848d028d174c1ca779ad018f10cf7e"> </div><div class="notion-text notion-block-6c80cfb398fa455f92fa14b0e177a465">他的漏洞在于第3个选项时，用于修改堆的内容的函数。这里我们看下面的从18到21行，可以看出来，这里对于我们需要新输入到程序中的内容的大小，是由我们自行输入的，并且对大小并没有一个是非的检查，这里存在一个堆溢出的漏洞，我们可以先输入一个巨大的数字从而形成堆溢出，</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1e7ce6541c7347d0893d13a47d82186a"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F03642f02-36e8-4561-8c09-911294922b11%2Fimage-20240726132607140.png?table=block&amp;id=1e7ce654-1c73-47d0-893d-13a47d82186a&amp;t=1e7ce654-1c73-47d0-893d-13a47d82186a&amp;width=1192&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-da267e8179a341148b9c48b600a9f833"> </div><div class="notion-text notion-block-f96f33924b084d889ae9470a39df1eaf">再看其他的函数就是正常的一个show函数，一个malloc函数，一个change函数，一个free函数，整个程序的漏洞就在于我们刚刚说的堆溢出，并且这里有关于堆的大小申请是由我们自行输入决定的。并且在程序中还存在一个后门函数，于是我们的重点就在于如果使程序能够跳转执行我们的后门函数。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d7343a53942d4b7380130c564dead2c4"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fc453224d-da84-42a5-9857-9afc6d7cdade%2Fimage-20240726135153267.png?table=block&amp;id=d7343a53-942d-4b73-8013-0c564dead2c4&amp;t=d7343a53-942d-4b73-8013-0c564dead2c4&amp;width=810&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-c24fc7d531ce4581b9e6744936da0010"> </div><div class="notion-text notion-block-286d1731a3c7435e855bff68a6bf9700">这里回到主函数中就会有所发现，这个当我们选择5时，程序便会执行v4[1],而这个v4就是程序在一开始申请的第一个chunk的指针，故这里我们可以像是否能修改第一个chunk的内容为我们后门函数的地址然后执行5选项，那目的就打成了。</div><div class="notion-blank notion-block-da15fcaa450f46b89fcfda06cc0d55c3"> </div><div class="notion-text notion-block-3a57ef10b4f24bc2961adf23b1ca7277">现在我们的目标就是如果拿到第一个chunk_v4的控制权。结合之前的堆溢出漏洞，其实这里可以使用unlink的方法，不过既然我们已经学了House Of Force的手法，那这里就使用一下这种方法。</div><div class="notion-blank notion-block-38e5203ffcfd4d9fa0adcffb374ec2ff"> </div><div class="notion-text notion-block-75015f3e89374210be7533da30ede0cb">这里的思路简单讲一下就是</div><ol start="1" class="notion-list notion-list-numbered notion-block-c61e24b5b4b3472bbb7833fad70f1412"><li>先申请一个chunk（这里大小不限选0x30）</li></ol><div class="notion-blank notion-block-e0921fb59c764879ba17686b75200f86"> </div><ol start="1" class="notion-list notion-list-numbered notion-block-a1997cea26a74f03af30d4f25861cfc2"><li>通过堆溢出修改top chunk的size为0xffffffffffffffff</li></ol><div class="notion-blank notion-block-0353ca4e7f1e4b71b9a97853f5e63551"> </div><ol start="1" class="notion-list notion-list-numbered notion-block-d5190b6fe2044dc2a459622a3a8c1578"><li>计算从top chunk的头地址到到我们需要的chunk的头的地址的距离大小</li><ol class="notion-list notion-list-numbered notion-block-d5190b6fe2044dc2a459622a3a8c1578"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b1ae2997cc584193bdf9310bb2d4da13"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F44e85f89-80d9-441f-8d83-d8c6d13e5dc4%2Fimage-20240726140906823.png?table=block&amp;id=b1ae2997-cc58-4193-bdf9-310bb2d4da13&amp;t=b1ae2997-cc58-4193-bdf9-310bb2d4da13&amp;width=656&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure></ol></ol><div class="notion-text notion-block-3ac2a1b22ce94da897992411d88cfaa1"><div class="notion-text-children"><div class="notion-text notion-block-0dcb10027a284d0291981407d0f8de1e">这里为0x20+0x40</div></div></div><ol start="1" class="notion-list notion-list-numbered notion-block-ba552fe26390486ab60651178577301e"><li><b>使用 house of force 技巧，我们需要绕过 request2size(req) 宏，这里由于 -0x60 是16字节对齐的，所以只要减去 SIZE_SZ 和 MALLOC_ALIGN_MASK 大小即可得出需要 malloc 的大小，然后我们再次分配就能分配到 chunk_v4处。</b></li><ol class="notion-list notion-list-numbered notion-block-ba552fe26390486ab60651178577301e"><div class="notion-text notion-block-3bf7d70266e94315ac5d03d9a11019ad">故这里的真实要申请地址为</div><div class="notion-text notion-block-be89299190814bf09ae1a44fcd697a00">关于这个0x17的值，准确来说可以是0x8~0x17中的任意一个数字就可以</div><div class="notion-blank notion-block-df59812176c64da18b350b4697607956"> </div></ol></ol><ol start="2" class="notion-list notion-list-numbered notion-block-52e0e172d2c243039179f2a4a5dcaa94"><li>在决定这个数字后向程序申请这个大小的chunk（就是要负数），便可以将chunk_v4包裹其中</li></ol><div class="notion-blank notion-block-7f5cd70b55b1466ab2009869c460d723"> </div><ol start="1" class="notion-list notion-list-numbered notion-block-553b97ad2ace450db07f9770d57d4208"><li>在申请一个chunk输入后门函数的地址，然后执行5，变调用后门函数</li></ol><div class="notion-blank notion-block-7b7ebb6f646a441fbf55ba3d53031b03"> </div><div class="notion-text notion-block-2379e3d1b5974cc5804ebf6f7216d904">exp</div><div class="notion-text notion-block-8f02eb03cab349b1ab03e69479fd947d">关于这道题的重点在于修改top chunk的堆的申请，一定要注意是距离的负数-0x8，申请这个之后的在申请的就是我们要的目标地址。</div><div class="notion-blank notion-block-694e26b116aa4e5e83fe6e633408bd2a"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-4751dc8ae69b4f2ea6875036e1355d24" data-id="4751dc8ae69b4f2ea6875036e1355d24"><span><div id="4751dc8ae69b4f2ea6875036e1355d24" class="notion-header-anchor"></div><a class="notion-hash-link" href="#4751dc8ae69b4f2ea6875036e1355d24" title="2016 BCTF bcloud"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>2016 BCTF bcloud</b></span></span></h3><div class="notion-text notion-block-b348f17fb7914962a7a9dc9471716e65">这道题相对来说就是上一道题的翻版，不过这道题的难点在于对程序中的漏洞的修找，这里我就是在寻找漏洞的时候出了一定的问题，导致一开始做的时候并没有做出来，后面看了一下别人的分析+自己在仔细调试才把这道题的问题完整明白。看来对C语言的理解和汇编的理解还是有点差了，之后要找时间再重新学一下。</div><div class="notion-text notion-block-d837c8301eee4cc3a2da307191338af0">利用步骤如下:</div><div class="notion-blank notion-block-3db8c1c1d3504812a5cf2db72185f8b3"> </div><ul class="notion-list notion-list-disc notion-block-180f6b33b0254111a2f3bce45f615241"><li>1.通过名字leak堆地址</li></ul><ul class="notion-list notion-list-disc notion-block-e73115160d8441439814f6eddecd382f"><li>2.通过host and org 改大top_chunk-&gt;size</li></ul><ul class="notion-list notion-list-disc notion-block-08b8bb726b8a4bd797d088aa4a45d85b"><li>3.移动top_chunk</li><ul class="notion-list notion-list-disc notion-block-08b8bb726b8a4bd797d088aa4a45d85b"><li>让再申请的内存在覆盖到bss段中 list_len 和noet位置的内存</li><li>让noet指向函数的got表</li></ul></ul><ul class="notion-list notion-list-disc notion-block-5300225ccf2449319777793343db3204"><li>4.把free改成printf</li></ul><ul class="notion-list notion-list-disc notion-block-06685c70f7dc4dc39e21980695f25be4"><li>5.利用 假free 函数把atoi地址printf出来</li></ul><ul class="notion-list notion-list-disc notion-block-7c368f1107d44ea987b874b5e1ac8490"><li>6.利用 atoi 得到system地址</li></ul><ul class="notion-list notion-list-disc notion-block-7a07ba8429084937b107f935ade92a2d"><li>7.把atoi改成system</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-8ee6489db7f0460b8bea35cb740a17d0" data-id="8ee6489db7f0460b8bea35cb740a17d0"><span><div id="8ee6489db7f0460b8bea35cb740a17d0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8ee6489db7f0460b8bea35cb740a17d0" title="House Of Lore"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>House Of Lore</b></span></span></h2><div class="notion-text notion-block-5df4d91fc8a1487093f2e4f1e41b0c09">这种手法主要用于对libc-2.27及以下的版本中的small bin的机制中的漏洞从而进行攻击的一种手法，简单来说就是我们通过修改出在small bin中的chunk的bk位数据，使其指向我在栈或bss段中伪造的fake_chunk，然后由于在libc2.27及以下的libc版本中对这个chunk的检查不足，导致我们的这个fake_chunk会被程序认为是small bin上的一个free chunk。使得我们能在后面通过malloc将我们伪造的chunk申请出来供我们使用。</div><div class="notion-blank notion-block-e731c46c455f4cfa999fac4220820943"> </div><div class="notion-text notion-block-22c30f55a6f2468b9f3436a7a814cb11">基本原理</div><div class="notion-text notion-block-215d6d3d2bca4b4ba567ea123da92f8f">
如果在 malloc 的时候，申请的内存块在 small bin 范围内，那么执行的流程如下</div><div class="notion-text notion-block-7f4ea0e85817483bb7dcf0408de527fb">从下面的这部分我们可以看出</div><div class="notion-text notion-block-5a2f5acab7b34940a5824dcc5a867eed">如果我们可以修改 small bin 的最后一个 chunk 的 bk 为我们指定内存地址的 fake chunk，并且同时满足之后的 bck-&gt;fd != victim 的检测，那么我们就可以使得 small bin 的 bk 恰好为我们构造的 fake chunk。也就是说，当下一次申请 small bin 的时候，我们就会分配到指定位置的 fake chunk。</div><div class="notion-blank notion-block-0ec812b7227343539a7f0116a2d6cc64"> </div><div class="notion-text notion-block-7a235657851f4ea7a545ef573671c0fb">当然具体的利用条件必然不会这么简单，还是有很多要注意的地方，具体的跟具以下的这个脚本分析</div><div class="notion-blank notion-block-d39cea0187c8419d82ef204696a6094c"> </div><div class="notion-text notion-block-23a4db5e46e14ff2a4dba0efa6ce45da">这是一个C语言的脚本，我们将跟具这个具体分析一下有关于这个House of Lore手法的具体利用</div><div class="notion-blank notion-block-569ee9922d3d4bbe92ddd1c2b3a42632"> </div><div class="notion-text notion-block-db38b9ba9fa7469195e066f7240ff23f">最开始这里我们要申请一个大小在（0x80~0x390）,只有在这个范围的chunk才会进入到small bin中，这里我们申请0x100的大小的堆块，然后在申请一个比较大的堆块用于使0x100这个堆块在后面我们free时不会被top chunk合并</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-5fd9d39568984700a59eb38827c2494c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F2833458f-60c3-4963-ba1d-e8c5c09ae65e%2FUntitled.png?table=block&amp;id=5fd9d395-6898-4700-a59e-b38827c2494c&amp;t=5fd9d395-6898-4700-a59e-b38827c2494c&amp;width=853&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-c4b80fd3f1b8490ea4bd3304bdb2c0de"> </div><div class="notion-text notion-block-9ea716f2f9c5469184f1a9a4d56e0d01">之后我们便可以在栈或bss段上伪造我们的fake_chunk,</div><div class="notion-text notion-block-a634857346d345fda158d187e6f59c44">在这个手法中我们需要注意的就是这个fake_chunk，需要俩个不同地址的chunk相互结合才能形成有效的攻击，</div><div class="notion-text notion-block-4eb9775891234b59944334bfcdd26b85">这里我们假设这两个fake_chunk为<em><b>stack_buffer_1和stack_buffer_2</b></em></div><div class="notion-text notion-block-81e30daef5624781b544a3d82d7626d8">这里这两个的要求各不相同，<em><b>stack_buffer_1</b></em>至少要4个字节，而<em><b>stack_buffer_2</b></em>至少要3个字节</div><div class="notion-text notion-block-47ee917c38c94197a3dd875d0c4d80b4">在stack_buffer_1中要放入的数据为</div><div class="notion-blank notion-block-5163789acfae4972a2211dcbb6bf5989"> </div><div class="notion-text notion-block-dc4dc41fde87450b951146db021b5104">在stack_buffer_2中要放入的数据为</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-7560b7c1bab145c088744456ca62aae5"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F14e84fd9-a2b3-469f-8ad7-cc222907683b%2FUntitled.png?table=block&amp;id=7560b7c1-bab1-45c0-8874-4456ca62aae5&amp;t=7560b7c1-bab1-45c0-8874-4456ca62aae5&amp;width=863&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-c557ca52b1b54b40b27c710c41f08781">0x7fffffffddd0为stack_buffer_1，0x7fffffffddb0为stack_buffer_2</div><div class="notion-blank notion-block-69cb738f510e41a2b5c7291d9f46b1a6"> </div><div class="notion-text notion-block-7eab706fa6ba401c92752ac570702c03">在伪造完这两个fake_chunk后，我们在free那个0x100的chunk，使其进入unsortedbin中</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-a59fc8a53cea48d3b9b8b05623e21c75"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F2f80acee-25de-44c6-9712-8fa89af4366c%2FUntitled.png?table=block&amp;id=a59fc8a5-3cea-48d3-b9b8-b05623e21c75&amp;t=a59fc8a5-3cea-48d3-b9b8-b05623e21c75&amp;width=703.3229370117188&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-0e29926f1d724dd98154c8ac8cd4d2e7">然后在向程序申请一个比较大的chunk，使其进入smallbin中</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-792f7cd0dd8249e89b095975bea964a5"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F53e24935-34d0-4baa-b6c2-777b48a26db2%2FUntitled.png?table=block&amp;id=792f7cd0-dd82-49e8-9b09-5975bea964a5&amp;t=792f7cd0-dd82-49e8-9b09-5975bea964a5&amp;width=958&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-8bdf39c2ebbb47728bc30b3e5e71febd"> </div><div class="notion-text notion-block-0d4c3c7d5e844431b38d88869ddd213f">在完成这几步后就要修改这个smallbins中的chunk了，</div><div class="notion-text notion-block-4cd7d0df9b2b4066b39d81aeb227a19b">这是未修改的chunk</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-07448c1073da485391f86ec3212b6f28"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fda606545-eb1d-4e15-a901-caa12748b482%2FUntitled.png?table=block&amp;id=07448c10-73da-4853-91f8-6ec3212b6f28&amp;t=07448c10-73da-4853-91f8-6ec3212b6f28&amp;width=964&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-ffcfe403c11040c28138fcdb9355fbe1"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F2453adf0-2fc4-40bc-b092-84f1e94e8cce%2FUntitled.png?table=block&amp;id=ffcfe403-c110-40c2-8138-fcdb9355fbe1&amp;t=ffcfe403-c110-40c2-8138-fcdb9355fbe1&amp;width=861&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-6f75ae0625ac4ec8834c4ff45be9b09c">此时的chunk还在正常的smallbins chnk，而我们的目的就是要修改这个chunk的bk（第4个）指针为我们刚刚伪造的stack_buffer_1的头地址，修改，结果如下</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-f771663e840745e38fd68c659aba8e0c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F4fa664f3-7c80-42cc-8893-8692276f30e1%2FUntitled.png?table=block&amp;id=f771663e-8407-45e3-8fd6-8c659aba8e0c&amp;t=f771663e-8407-45e3-8fd6-8c659aba8e0c&amp;width=789&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-a48112c0c1fc40feac0e51700d4dd62d">对应的heap和bin中也有相应的变化</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-775678d81ff74de59c621013f474a86e"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fccf83564-12ae-4876-be27-17d8dec21fe1%2FUntitled.png?table=block&amp;id=775678d8-1ff7-4de5-9c62-1013f474a86e&amp;t=775678d8-1ff7-4de5-9c62-1013f474a86e&amp;width=1128&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-831b229db87443898bdecef661d46fcf">可以看到在smallbins中明显多了一行，并且这一行里面虽然0x603000依然为第一个但我们刚刚伪造的两个栈上的chunk也被放入了其中，这样我们的基本目的就完成了，成功吧我们伪造的chunk都放入了smallbins中，之后只要我们把这个栈上的地址申请出来，那这个攻击的目的就达到了。</div><div class="notion-text notion-block-77c8ea8eac6d479c8663e00322933f6d">我们首先把之前那个0x100的chunk mallc出来（通过malloc(0X100)），使得bin中为如下情况</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3e6fd34febea42d6a9110ee725b21b6d"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fadfe086f-a078-4a43-ba86-ef32652547d3%2FUntitled.png?table=block&amp;id=3e6fd34f-ebea-42d6-a911-0ee725b21b6d&amp;t=3e6fd34f-ebea-42d6-a911-0ee725b21b6d&amp;width=1019&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-e477c71f28fb4ebc8f70a28ec2e6008b">然后在malloc(0X100)，就可以使程序把stack_buffer_1（0x7fffffffddd0）当做新的chunk给我们使用</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b8e4062debcc43e6b67cbb19eaa414b0"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Ffa42a1db-5eb7-475f-af60-48202ed92b1d%2FUntitled.png?table=block&amp;id=b8e4062d-ebcc-43e6-b67c-bb19eaa414b0&amp;t=b8e4062d-ebcc-43e6-b67c-bb19eaa414b0&amp;width=831&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-a8c79aa53e624aae875e26e90257f94a">至此，这个手法的基本过程结束，后面的就是通过栈上的这个chunk，从而劫持程序的执行流。</div><div class="notion-blank notion-block-49b6f023d93b4f1390d3debac5f17075"> </div><div class="notion-text notion-block-c28e7312ac9a42aaa6c5429e6c939c1d">简单来讲这个手法通过伪造chunk1，和chunk2。</div><div class="notion-text notion-block-34fb2b7f451949898344e468f5790ebc">修改smallbins中的chunk使bk指针其指向chunk1的头地址，</div><div class="notion-text notion-block-17c2bd2945d244e28979dd64703e95d5">然后就把chunk1当做正常堆的chunk拿出来供我们使用。</div><div class="notion-blank notion-block-86f43b7a0d894e6889cc97efe3356dde"> </div><div class="notion-text notion-block-d4843adec5334d3cb7fa509f3534680e">这个手法虽然限制比较多</div><ul class="notion-list notion-list-disc notion-block-0ea44a1f68894905bfb4a27481925b71"><li>libc-2.27及以下</li></ul><ul class="notion-list notion-list-disc notion-block-9b997450dd284988a06c3df888012f55"><li>能修改free chunk的bk位，这个free chunk为smallbins</li></ul><ul class="notion-list notion-list-disc notion-block-5a5ca14ccb9640d29fca62d0d1b48bbf"><li>有足够的地方伪造chunk1和chunk2</li></ul><div class="notion-text notion-block-0e7c1a38b5af44d99144bed53fa7c462">不过攻击力还是比较强大</div><div class="notion-blank notion-block-641e2a582d2441918ca08025a51cacb7"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-441c5be09ed742db90e60ca25eeafc8d" data-id="441c5be09ed742db90e60ca25eeafc8d"><span><div id="441c5be09ed742db90e60ca25eeafc8d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#441c5be09ed742db90e60ca25eeafc8d" title="House Of Rabbit"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>House Of Rabbit</b></span></span></h2><div class="notion-text notion-block-216a45a1eae242999a67a104d6f2dd08">这是一个对堆的利用姿势，目的在于使用满足条件的情况，绕过堆块的地址随机化保护（ASLR）达到<b>任意</b>地址分配的目的。

使用这个手法需要3个条件</div><ol start="1" class="notion-list notion-list-numbered notion-block-fd7ea728a5264cc3b8682332a0691170"><li>可以分配任意大小的堆块并且释放，主要包括三类fastbin大小的堆块、smallbin大小的堆块、较大的堆块（用于分配到任意地址处）</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-fcce9a80fb8f411ab9f382b898d4fd96"><li>存在一块已知地址的内存空间，并可以任意写至少<b>0x20</b>长度的字节</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-06953d1c872e4ce18b70b1713f45cd26"><li>存在fastbin dup、UAF等漏洞，用于劫持fastbin的fd指针。</li></ol><div class="notion-text notion-block-814854ec064e4d84886a6b07da3a2de2">当存在上述三个条件时，即可使用House Of Rabbit攻击方法</div><div class="notion-blank notion-block-462ede1ca82247228e2eb0c523c6fb47"> </div><div class="notion-text notion-block-5db89bc2bc3e4f298b19207880cb442f">这里干脆直接把提出这个手法的那道题拿上来分析一下</div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-46f9e2c38aa04a789dfd09d70d13f690" data-id="46f9e2c38aa04a789dfd09d70d13f690"><span><div id="46f9e2c38aa04a789dfd09d70d13f690" class="notion-header-anchor"></div><a class="notion-hash-link" href="#46f9e2c38aa04a789dfd09d70d13f690" title="HITB CTF 2018 mutepig"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>HITB CTF 2018 mutepig</b></span></span></h3><div class="notion-text notion-block-9ae04fc27cdf4fa98200bf8c72a3f777">这道题怎么说呢，比较恶心，没有输出的内容，调试的时候太难受了，不能直接使用gdb调试，只能在脚本中调，确实不太容易。</div><div class="notion-text notion-block-3519e100c6f6458684e09c0aeadbfadf">简单讲一下这个题目的基本流程，是个选项题，还是基本的3个选项，</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-170371065e514780821fd8ec34cba779"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F687d7ee2-e264-4239-903d-1bfb9ca6b316%2FUntitled.png?table=block&amp;id=17037106-5e51-4780-821f-d8ec34cba779&amp;t=17037106-5e51-4780-821f-d8ec34cba779&amp;width=1035&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-e687e0fb21b64f45b171c38b0f684c3b">第一个选项用于创建chunk，但是</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-cc1c4ca681604ddfba03a097f262d423"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F8b3014dc-2c08-4115-a584-d22afbce4659%2FUntitled.png?table=block&amp;id=cc1c4ca6-8160-4ddf-ba03-a097f262d423&amp;t=cc1c4ca6-8160-4ddf-ba03-a097f262d423&amp;width=737&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-c4787aefe3f94581bda694a998a55593">这里用于创建chunk的大小是固定的，大小只能为1时的0x10,2时的0x80,3时的0xA00000以及0x3419时的0xFFFFFFFFFFFFFF70LL，并且这里的chunk的数量也只能是10个有以下。在创建好的同时还会直接向这个chunk里面读入数据，</div><div class="notion-text notion-block-1248cd4c5f71469c83cf8f3975f1ce3d">其次是选项2这个选项2的主要作用就是free chunk，同时这里也是存在UAF漏洞的</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-a863ff661caf4d1f9bac6f065540f9f9"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:616px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F051d9965-2cb5-40bd-a70c-c18186d54b15%2FUntitled.png?table=block&amp;id=a863ff66-1caf-4d1f-9bac-6f065540f9f9&amp;t=a863ff66-1caf-4d1f-9bac-6f065540f9f9&amp;width=616&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-d5c6dac09eb747669158a262f12d9d1b">其次是选项3，这里先读入一个序数，然后向这个序号的chunk读入最多8个字节的数据，然后又向bss段上的0x602120这里读入最多0x48字节的数据。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3dae5593000a42449116b2eab07b413e"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:608px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F9b4e7910-08fe-4c7d-94c0-1e951c04fa17%2FUntitled.png?table=block&amp;id=3dae5593-000a-4244-9116-b2eab07b413e&amp;t=3dae5593-000a-4244-9116-b2eab07b413e&amp;width=608&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-0203828e8dcf4406a504ebc5fc9160be"> </div><div class="notion-text notion-block-3d6f3be34c97474e8c452c8a1489781d">题目提供分配大小为0x10、0x80、0xa00000、0xffffffffffffff70大小的堆块，并且没有开启PIE保护，还存在UAF漏洞，完全满足该利用方法需求，通过将内存地址分配回bss段低地址部分的堆地址指针数组，覆写数组内容为free@got，利用编辑功能，将其内容改为system@plt，在free时可以拿到shell</div><div class="notion-text notion-block-415b49fcd18e4df29f58bfcd970b3253">那就具体看一下具体流程，</div><ol start="1" class="notion-list notion-list-numbered notion-block-bf39019e316244cf980194f77e771aaf"><li><b>增大malloc函数中 mmap分配阈值</b></li></ol><div class="notion-text notion-block-5f8aaaf4395a4053bca1694e4d2e277b">这里我们向程序申请0xa00000的堆块，堆块由mmap分配，并且mp_.max_mmaped_mem变成0xa10000，当free以后再次malloc(0xa00000)时，系统会首先通过sbrk扩大top块进行分配，当最后一次free后，top大小变成0xa20c31 &gt; 0xa00000，这样我们下次申请这个大小的chunk是程序会使用比较大的top chunk。</div><ol start="1" class="notion-list notion-list-numbered notion-block-f23168a9973e4f12a1d1b89d889fd5d7"><li><b>申请小堆块并放入fastbin</b></li></ol><div class="notion-text notion-block-4db6de9a6a824c50b19313cfabb803b0">首先malloc(0x20) ，再次malloc(0x80)，这两块都是由top直接切割得到，保证small bin大小的块挨着top。</div><ol start="1" class="notion-list notion-list-numbered notion-block-c002020665554c95a8d8e1c4f2747c2d"><li><b>伪造堆块并劫持至fastbin</b></li></ol><div class="notion-text notion-block-6d1d07e83e8a482a928de8de6ddf176c">在一个已知地址的内存处（如未开启PIE的程序BSS段）伪造两个连续的堆块，一个堆块大小是0x11，紧挨着是0xfffffffffffffff1，这样可以保证后续操作可以覆盖到任意地址。更重要的是这个0x11的小块即是大块的前块，也是大块的后块，可以保证在malloc中通过检查。</div><div class="notion-text notion-block-26b8e7fe5d7747228b7d79d012ff7a8a">利用漏洞劫持fastbin，将大小为0xfffffffffffffff1的堆块，挂到fastbin上去。</div><div class="notion-blank notion-block-537a6f56b9f1453ead7b8e983b692efc"> </div><ol start="1" class="notion-list notion-list-numbered notion-block-b044021f2b1c46458dfc8a5861e40c95"><li><b>利用malloc_consolidate使伪造堆块进入unsorted bin</b></li></ol><div class="notion-text notion-block-f9c4a31fca5443b6afebae582c3aded5">在free函数中，当释放的块大于 65536时，会触发malloc_consolidate，这个函数用于对fastbin合并，并放到unsorted bin中</div><div class="notion-text notion-block-85d79c32a1ec4ec6ac1accc734f1b6bd">而在malloc_consolidate()中，会循环处理各fastbin堆块，当堆块与top相邻时，与top合并。否则，将堆块放入unsorted bin中，并设置pre_size和pre_inuse位，此时较小的堆块变成 0xffffffffffffffff0 0x10</div><div class="notion-blank notion-block-dcf1b234e7504add9efb738e6a45d02e"> </div><div class="notion-text notion-block-3ffb8d57d3934102a00d5f5c83c183bc">将程序中的chunk全部与top chunk合并</div><div class="notion-text notion-block-9234cded7fca4c6a9419f5e343abccd5">使得将大小为0xfffffffffffffff1的堆块从fastbin中转到unsortedbin中</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b108ebcd279b4e39b81aa8bebe06f83e"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F5bdbb6a0-9eb6-4847-be77-53644fcb14a7%2FUntitled.png?table=block&amp;id=b108ebcd-279b-4e39-b81a-a8bebe06f83e&amp;t=b108ebcd-279b-4e39-b81a-a8bebe06f83e&amp;width=984&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-9a33339a54ab4394921f20653a8f21da"> </div><ol start="1" class="notion-list notion-list-numbered notion-block-d47a9d59496c476a9577e8ff25dd3a0a"><li><b>分配内存 使伪造堆块进入large bin</b></li></ol><div class="notion-text notion-block-c2de6b8455a44647bca906c917b5a7f7">当伪造的堆块进入unsorted bin时，并不能达到目的，需要进一步使堆块进入large bin，此时需要将伪造的堆块大小改为0xa00001，其目的有两个，1是绕过程序对unsorted bin中内存块大小小于av-&gt;system_mem的检测；2是使程序放入large bin的最后一块（&gt;0x800000)</div><ol start="1" class="notion-list notion-list-numbered notion-block-fedc7e3776e94d20b0f875d5d3b525ba"><li>任意内存分配</li></ol><div class="notion-text notion-block-062c00a779554785a106daebcfd2334d">当伪造堆块进入large bin最后一个队列时，将伪造堆块的大小改回0xfffffffffffffff1，此时在申请任意长度的地址，使堆块地址上溢到当前堆地址的低地址位置，从而可以分配到任意地址，达到内存任意写的目的。</div><div class="notion-blank notion-block-6a4aeaf3798143698bd635aeca6a7106"> </div><div class="notion-text notion-block-7df1f8110c75489e8b5d687cddb1326d">exp</div><div class="notion-blank notion-block-08e2cf524c8e4d74bb7e141d926ae5d2"> </div><div class="notion-text notion-block-3cd7a3f96ab04b36aede5ca6ec772690">这道题就是这个手法比较明显的使用，借助这种手法这道题的完整就如此，</div><div class="notion-text notion-block-652e54baa1bc4838a651f6a58ca86860">这里由于这道没有任何的输出导致我们在注入数据时要注意需要时间空格</div><div class="notion-text notion-block-e374d390b5c64ba49f99e72154260697">这里我当时最开始做的时候就是被这个问题卡了很久，想这种对于数据的注入如果没有注入成功的可以考虑，要么使用更具收到的数据在发送，或者就是这个加时间间隔。</div><div class="notion-blank notion-block-4ce92a35baca422cbf9feb46dd2a699a"> </div><div class="notion-text notion-block-f2c07d9d26e842f893472623a8869982">其次这道还有一个问题就是在选项3的向堆块注入数据时只能是8个字节但是在我们注入8个字节会把换行符一起读进去，因此要在那加上<code class="notion-inline-code">[:-1]</code> 防止读入的数据不对</div><div class="notion-blank notion-block-903a60e34a1e416ab8ffecba02140764"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-3b59883f674f42e49486700ec2d0dfbc" data-id="3b59883f674f42e49486700ec2d0dfbc"><span><div id="3b59883f674f42e49486700ec2d0dfbc" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3b59883f674f42e49486700ec2d0dfbc" title="House Of Roman"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>House Of Roman</b></span></span></h2><div class="notion-text notion-block-03883f8f0c8c41a28268532bd3140fa0">这种手法主要是关于堆的布局的一种比较奇妙的方法，</div><div class="notion-text notion-block-5125fb71dd12476d9f5c2898398b7bf5">主要特点是不需要 <code class="notion-inline-code">leak libc</code>的地址，通过 堆内存的布局 和 堆相关的漏洞（<code class="notion-inline-code">uaf</code> 等) 就可以 <code class="notion-inline-code">getshell</code></div><div class="notion-blank notion-block-cadec2fd921540fe9fae1ec84dfad1c2"> </div><div class="notion-text notion-block-d8253b6453e1401a95e05e0cccaae65d">这里还是以这个手法的提供者里的那道题来具体分析一下这种手法的思路和特点，</div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-f6e322238ba14e978999275d59d3dcf8" href="https://gist.github.com/romanking98/9aab2804832c0fb46615f025e8ffb0bc"><div><div class="notion-bookmark-title">House_of_Roman.md</div><div class="notion-bookmark-description">House_of_Roman.md · GitHub</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fgist.github.com%2Ffavicon.ico?table=block&amp;id=f6e32223-8ba1-4e97-8999-275d59d3dcf8&amp;t=f6e32223-8ba1-4e97-8999-275d59d3dcf8" alt="House_of_Roman.md" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://gist.github.com/romanking98/9aab2804832c0fb46615f025e8ffb0bc</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fgithub.githubassets.com%2Fassets%2Fgist-og-image-54fd7dc0713e.png?table=block&amp;id=f6e32223-8ba1-4e97-8999-275d59d3dcf8&amp;t=f6e32223-8ba1-4e97-8999-275d59d3dcf8" alt="House_of_Roman.md" loading="lazy" decoding="async"/></div></a></div><div class="notion-text notion-block-2bbd0b7590b64af392a6a0ee14f9b801">这里是这个提出者自己写的有关于这种手法的分析，</div><div class="notion-text notion-block-16d352849d5f48b1a7d82ca4a93321b9">具体的题目和exp可以再这里下载，</div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-e00d19712e4b4e0b99067d51d06645b2" href="https://github.com/romanking98/House-Of-Roman"><div><div class="notion-bookmark-title">GitHub - romanking98/House-Of-Roman: RCE through Leakless HeapFengShui, fastbin alloc anywhere.</div><div class="notion-bookmark-description">RCE through Leakless HeapFengShui, fastbin alloc anywhere. - romanking98/House-Of-Roman</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fgithub.com%2Ffluidicon.png?table=block&amp;id=e00d1971-2e4b-4e0b-9906-7d51d06645b2&amp;t=e00d1971-2e4b-4e0b-9906-7d51d06645b2" alt="GitHub - romanking98/House-Of-Roman: RCE through Leakless HeapFengShui, fastbin alloc anywhere." loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://github.com/romanking98/House-Of-Roman</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fopengraph.githubassets.com%2Fc1dd0d4ccc281c18d2d468a6ebb92ce1af96a46eb3f063c3f95da793da58c948%2Fromanking98%2FHouse-Of-Roman?table=block&amp;id=e00d1971-2e4b-4e0b-9906-7d51d06645b2&amp;t=e00d1971-2e4b-4e0b-9906-7d51d06645b2" alt="GitHub - romanking98/House-Of-Roman: RCE through Leakless HeapFengShui, fastbin alloc anywhere." loading="lazy" decoding="async"/></div></a></div><div class="notion-blank notion-block-af49004838bb44648fad5a4c5d168241"> </div><div class="notion-blank notion-block-d0a9cc6e52fe45dd82bafb57158a3deb"> </div><div class="notion-blank notion-block-9f89e81c33f443ada61d779415800b4a"> </div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[堆基础题解法及wp]]></title>
            <link>https://tangly1024.com/article/865b1101-0819-470d-aabe-41c304df9d64</link>
            <guid>https://tangly1024.com/article/865b1101-0819-470d-aabe-41c304df9d64</guid>
            <pubDate>Tue, 30 Jul 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-865b11010819470daabe41c304df9d64"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-e6a789bd3e4c4e6faf62b43d87456044" data-id="e6a789bd3e4c4e6faf62b43d87456044"><span><div id="e6a789bd3e4c4e6faf62b43d87456044" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e6a789bd3e4c4e6faf62b43d87456044" title="UAF漏洞"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>UAF漏洞</b></span></span></h2><div class="notion-text notion-block-238dbf247b5e434b95187c80e38fd835">这类漏洞的基础与原理就是在申请堆块后没有在使用free函数释放这个堆块的同时将在申请是用于指向这个堆块的指针一并清0，使得在后面的程序中还能使用这个指针对程序中的数据造成泄露或执行的操作。</div><div class="notion-blank notion-block-6a39e8245c0843ac9279ca252c827b62"> </div><div class="notion-text notion-block-5a38236eff944ad8b47fb7a6564428e9">(想自己写一个例子，发现能力不足，还是从网上抄一下算了)</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-c4411b5eb3964c888b884497405982ff"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:436px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fd3c243b5-8e4c-46df-92e7-d2f8639827dc%2FUntitled.png?table=block&amp;id=c4411b5e-b396-4c88-8b88-4497405982ff&amp;t=c4411b5e-b396-4c88-8b88-4497405982ff&amp;width=436&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-3ddccb27ef074423b5bc88e0df2347d6"> </div><div class="notion-text notion-block-c0e6582f98ce4e17aa2afb6b4c051cbf">如上代码所示，指针p1申请内存，打印其地址，值</div><div class="notion-text notion-block-abc911b39504463894746bd43084a32a">然后释放p1</div><div class="notion-blank notion-block-0ac7da65338a4f5d9657018b6827b81d"> </div><div class="notion-text notion-block-c0ce38c3266d4732aed0737cc5fd595f">指针p2申请同样大小的内存，打印p2的地址，p1指针指向的值</div><div class="notion-text notion-block-5bc8d3cc6ff8403b8b597e97157ef94f">Gcc编译，运行结果如下：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b7bdabe588ad4a0e974b80fd9a2740c9"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:337px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F81da5172-b28e-4e7e-8b71-71818d43526a%2FUntitled.png?table=block&amp;id=b7bdabe5-88ad-4a0e-974b-80fd9a2740c9&amp;t=b7bdabe5-88ad-4a0e-974b-80fd9a2740c9&amp;width=337&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-ba05c873e0bb4c7a9c5632da51cbfae1"> </div><div class="notion-text notion-block-a9afe43059d94084b12cd63e50c6bc83">p1与p2地址相同，p1指针释放后，p2申请相同的大小的内存，操作系统会将之前给p1的地址分配给p2，修改p2的值，p1也被修改了。</div><div class="notion-text notion-block-660c96a8a93245c492e66efa3001f147">由此我们可以知道：</div><div class="notion-blank notion-block-80da5911e1714d0985212f52ea039412"> </div><div class="notion-text notion-block-e94c06c6a5324a18a0d9ffd6852266d4">1.在free一块内存后，接着申请大小相同的一块内存，操作系统会将刚刚free掉的内存再次分配。</div><div class="notion-blank notion-block-501e25fbe262411fb2b13f3f74c1d9b3"> </div><div class="notion-text notion-block-1d7ad0e9913e4f60941ca07d3be403c9">根本原因是dllmalloc：</div><div class="notion-text notion-block-18667ce110024c248af65bdf76490525">参考资料：<a target="_blank" rel="noopener noreferrer" class="notion-link" href="http://blog.csdn.net/ycnian/article/details/12971863">http://blog.csdn.net/ycnian/article/details/12971863</a></div><div class="notion-blank notion-block-c3882c52f177416b91c3e0c4fb16f200"> </div><div class="notion-text notion-block-d5d977d41a714253899d5bb0f00c2b08">当应用程序调用free()释放内存时，如果内存块小于256kb，dlmalloc并不马上将内存块释放回内存，而是将内存块标记为空闲状态。这么做的原因有两个：一是内存块不一定能马上释放会内核（比如内存块不是位于堆顶端），二是供应用程序下次申请内存使用（这是主要原因）。当dlmalloc中空闲内存量达到一定值时dlmalloc才将空闲内存释放会内核。如果应用程序申请的内存大于256kb，dlmalloc调用mmap()向内核申请一块内存，返回返还给应用程序使用。如果应用程序释放的内存大于256kb，dlmalloc马上调用munmap()释放内存。dlmalloc不会缓存大于256kb的内存块，因为这样的内存块太大了，最好不要长期占用这么大的内存资源。</div><div class="notion-blank notion-block-df232ec4aff34e3c92c585adc9e686f1"> </div><div class="notion-text notion-block-b925e791c5f44f198e170c18a04054a7">2.通过p2能够操作p1，如果之后p1继续被使用（use after free），则可以达到通过p2修改程序功能等目的。</div><div class="notion-blank notion-block-7e0f3fdc7b724b89890f4a29fd1298c9"> </div><div class="notion-text notion-block-21ff0a4b278848a6923e6cfc44454565">大致便是如此，现在我们便来整一道题来练一练。</div><div class="notion-text notion-block-bb9df85587944a21a4088fabf05c1362"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://buuoj.cn/challenges#actf_2019_babyheap">BUUCTF在线评测 (buuoj.cn)</a></div><div class="notion-blank notion-block-2fbfc356616f408bad4f614f57cdc9cc"> </div><div class="notion-text notion-block-c746a2da8c8648f49df24221ebed720e">来自buuctf上的actf_2019_babyheap一道基础的uaf堆的题。</div><div class="notion-text notion-block-d8b7f71aa49b4ecab5f3b15829b076f7">老规矩先checksec一下，只差pie没开了。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-c282f02766a44ab5ac372dbfc77cccd0"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F902829e7-cefc-446a-bbf0-8c2035d8d34f%2FUntitled.png?table=block&amp;id=c282f027-66a4-4ab5-ac37-2dbfc77cccd0&amp;t=c282f027-66a4-4ab5-ac37-2dbfc77cccd0&amp;width=706&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-90942c1892da4e6ebd4627f983aafdc7"> </div><div class="notion-text notion-block-910f9feddc394426a11bd156c29c61e2">执行一下，经典的菜单题</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-ff30340d08e442f687fba878dee80cec"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:605px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F23535e1a-bfcd-4193-be03-35887cda7bce%2FUntitled.png?table=block&amp;id=ff30340d-08e4-42f6-87fb-a878dee80cec&amp;t=ff30340d-08e4-42f6-87fb-a878dee80cec&amp;width=605&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-002a1d73058f400f8a35921d5ef96db0"> </div><div class="notion-text notion-block-789231327feb43cb92f3b8c27a4e904f">那便放入ida中看一看。</div><div class="notion-text notion-block-8c08c301edcf4b86a1370c9f0defdb12">main函数，稍微修改了一下，没什么意义。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-54c410237c93441599c2e29933051164"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:646px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F5ac4827d-764e-4d9f-bcdb-e0fc774553c8%2FUntitled.png?table=block&amp;id=54c41023-7c93-4415-99c2-e29933051164&amp;t=54c41023-7c93-4415-99c2-e29933051164&amp;width=646&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-047f78cb929145c9b2702feda8a228cf"> </div><div class="notion-blank notion-block-76553eba4cdc4bcfa580ac97bae80dc9"> </div><div class="notion-text notion-block-a360d4a4a1ba4c19bc79ef155ea957eb">有4个选项，1是创建日志，2是清除日志，3是打印日志，4是结束程序。那边一个一个来看</div><div class="notion-text notion-block-d2235f1b459746379f954fcd88395504">关于这个创建日志的函数便有很多值得注意的地方，这里面ptr是个bss段的空地址，程序以这里作为申请堆的指针处，在一开始程序通过<code class="notion-inline-code">*(&amp;ptr + i) = malloc(0x10uLL);</code>申请0x10大小的堆，这句话简单来说就是，在ptr+i的地方放这申请的0x10堆的数据段的地址，也通过*(&amp;ptr + i)作为指针指向这个堆。</div><div class="notion-blank notion-block-c71b4f287fdc469a9294fb668172b4cd"> </div><div class="notion-text notion-block-559fee91ae1a48acb382bae0969fd2ce">下一句</div><div class="notion-text notion-block-d61eb780b4324357b92ad9812b3aa39a">,这里我们知道</div><div class="notion-text notion-block-fa2a5e64eea34493832b78255cac2e8d">指向的是0x10堆的数据区的起始地址，因此</div><div class="notion-text notion-block-9c0ae133ba8b4c89b904b61d9fb5ec2d">指的就是堆的数据区中的下一个字节（大小为0x10，实际就是两个字节），这句的本意是将</div><div class="notion-text notion-block-dcfbb2e06e9f4322820b9786b8ba25ae">这个作为指针指向sub_40098A函数，起始就是在一开始申请的堆的数据段的第二个字节处放入sub_40098A函数的起始地址。关于sub_40098A函数这个函数（在后文会有答案，用于打印内容）</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b7092d5b3f6342248d7daacfedd3c8bf"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:549px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F4b76f9b4-6a78-4c19-966e-f1733ff0ba2c%2FUntitled.png?table=block&amp;id=b7092d5b-3f63-4224-8d7d-aacfedd3c8bf&amp;t=b7092d5b-3f63-4224-8d7d-aacfedd3c8bf&amp;width=549&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-8a509b7b276b4008b838a4ddb981db3a"> </div><div class="notion-text notion-block-567c9543a33b4b3e9aa4463e2165e20e">接下来的几句大致意思也就是将输入的数作为数值去申请相应大小的堆，并输入数据进去。这理要注意的是这里用<code class="notion-inline-code">*v0</code>作为指针指向新申请堆块，在之前用<code class="notion-inline-code">v0 = *(&amp;ptr + i)</code>将最开始申请的堆块的数据区的第一个字节的地址赋给v0，这里的真正含义便是以最开始申请的堆块的数据区的第一个字节作为指针指向后面申请的堆，便是在第一个堆的数据区中放上第二个堆的数据区的起始地址。入图所示（虚线等多余的地方先不用管）。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-33d66edb6f5146ad92689b548e4914e8"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F55a835cc-cbcf-4b87-8d25-3d06f037ccea%2FUntitled.png?table=block&amp;id=33d66edb-6f51-46ad-9268-9b548e4914e8&amp;t=33d66edb-6f51-46ad-9268-9b548e4914e8&amp;width=836&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-1a621c7678924c6c91e118ccddff7352"> </div><div class="notion-text notion-block-46737a94fa1f48bcb8c792e991a1fa98">于此便完成了程序中日志创建的堆管理。在来看第二个选项，清理堆</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-dca51b8eb76044cb960f9cbed5df07a1"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:578px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fadb7c24d-5eb8-4dc0-be40-392e5424f4ac%2FUntitled.png?table=block&amp;id=dca51b8e-b760-44cb-960f-9cbed5df07a1&amp;t=dca51b8e-b760-44cb-960f-9cbed5df07a1&amp;width=578&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-d59b292b4e0b4fd48d1b2ed86c299a2c"> </div><div class="notion-text notion-block-5b8679af78a84a909bade229571a9dc9">这里会更具我们输入的数字从而清理第几个堆块，需要注意的是由于之前我们在创建堆的时候程序用来统计堆的个数的数据的起始是从0开始的，所以这里要清理第一个堆要输入的数，应该是0，后面的也要相应减一。</div><div class="notion-blank notion-block-01b9def85e6c4d2f8d38f8dfebbcaf3f"> </div><div class="notion-text notion-block-07e5542c504a4ae4b44531e31760bdc2">在知道要清理的堆块后，程序便会开始使用free函数清理堆块，这里的<code class="notion-inline-code">**(&amp;ptr + v1))</code>这个其实就是指<code class="notion-inline-code">*v0</code>用来指向由我们自己创建的堆的指针，而第二个<code class="notion-inline-code">*(&amp;ptr + v1)</code>则是用来指向在上一个函数中一开始就创建用来存放第二个堆块的指针的大小为0x10得堆块，这里一次性清理两个堆块，把我们使用创建日志的函数中创建的两个堆一次性清理，<b>但是我们可以注意到在清理了这个堆块的同时，并没有把指向这两个堆的指针同时清零</b>，我们可能还有再次调用这两个指针的可能，这里便出现的uaf漏洞的可能，至于能不能使用还要继续往下看。</div><div class="notion-blank notion-block-13029bdba6ab4ea4a61bcd682094d499"> </div><div class="notion-text notion-block-50b4c1a2c5614d4d87fcbeba9dc5b57b">突然想起来在这里差了一步，忘记查找程序中有没有后门函数。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-40ac19544a2242cfb1e182693c5e9547"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fe1a17ad4-a4e0-43ed-a648-6ee2fff41ac0%2FUntitled.png?table=block&amp;id=40ac1954-4a22-42cf-b1e1-82693c5e9547&amp;t=40ac1954-4a22-42cf-b1e1-82693c5e9547&amp;width=727&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-5785b372af0b4823b28f8c1f61378ef7"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F6d374042-417b-4f66-9c40-0c40ff993791%2FUntitled.png?table=block&amp;id=5785b372-af0b-4823-b28f-8c1f61378ef7&amp;t=5785b372-af0b-4823-b28f-8c1f61378ef7&amp;width=747&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-cbb926a2474041c099203acb800a40cd">那好，system函数和/bin/sh都有了，那我们只要能在后面使程序执行system(/bin/sh)便可以满足程序的需求。现在的问题就在与我们要如何才能使程序执行这个命令的问题了。</div><div class="notion-blank notion-block-fcd43dd0eefc4e239ad13feb014dbb6d"> </div><div class="notion-text notion-block-3ea30b2d384c490385275efb44b06e25">现在我们的选项函数还有两个函数没有看，第4个不用管，就是简单的退出函数。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-08b3bf4948414dbbb78d98a2c7fa6024"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:352px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F7bfbca23-53a8-4701-b6f0-ad48fa075ade%2FUntitled.png?table=block&amp;id=08b3bf49-4841-4dbb-b78d-98a2c7fa6024&amp;t=08b3bf49-4841-4dbb-b78d-98a2c7fa6024&amp;width=352&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4117461688d6480385b9eb1b9cdce4b2"> </div><div class="notion-text notion-block-15580b102ce84f5390fc21d25fa1f4c0">现在来重点看最后一个打印内容选项的函数。</div><div class="notion-text notion-block-2bcac05a541a4e299f7811e1cb7f4dad">根据用户输入的数判断要打印的堆块，然后重点来了。</div><div class="notion-text notion-block-0cca5beb76194579bca337d8839b3b7a">使用的打印函数并不是直接使用某个函数，而是使用两个指针从而完成函数调用的功能</div><ul class="notion-list notion-list-disc notion-block-5ab3103b033a45e0b26366c88a8978fa"><li><code class="notion-inline-code">(*(&amp;ptr + v1) + 1)</code>这里我们前文提过，<code class="notion-inline-code">(&amp;ptr + v1)</code>是程序自己申请的0x10大小的堆块的指针，而+1则代表他的下一字节。根据前文我们知道这里被放入了一个函数的起始地址（<code class="notion-inline-code">(*(&amp;ptr + i) + 1) = sub_40098A;</code>），而这个sub_40098A函数的内容</li></ul><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-eeee2ab37d57428f9f1b00bd01020055"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:606px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F57b1cbd0-d02e-4a17-9fae-6e4caf8090d6%2FUntitled.png?table=block&amp;id=eeee2ab3-7d57-428f-9f1b-00bd01020055&amp;t=eeee2ab3-7d57-428f-9f1b-00bd01020055&amp;width=606&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-7af63d3762174011b81eaef7954bebd7"> </div><div class="notion-text notion-block-cbf580797aaa4487b0a2c10264a9a702">其实就是完成一个打印的功能的函数，不过这里在程序中使用了一个指针指向他，并通过指针调用。而<code class="notion-inline-code">**(&amp;ptr + v1)</code>这个就是指向在之前根据我们自己输入的大小申请的相应大小的堆块。</div><div class="notion-blank notion-block-fd2b13eb7790494b932aa68c5646fef6"> </div><div class="notion-text notion-block-98a127c6e89b463789067619f1d01293">所以这里就用这两个指针完成了对堆内容的打印。并且这里的这两个指针是存放在同一个堆块之中，那我们便可以想是否能够修改这个堆块中的这两个指针的内容从而执行我们的后门函数，从而达到目的。</div><div class="notion-blank notion-block-fc5baf2ab3e849beb5672cdb2063ea1a"> </div><div class="notion-text notion-block-e88093e3f80c489ea369e0fb0b0ef6ba">在这里结合之前发现的uaf漏洞，会发现这里会出现一个致命的问题，在理论上我们之前申请堆块用的指针被存放在ptr及其后面的位置中，程序为了方便管理会依次使用ptr后的空间，并不是覆盖。然后在我们使用清理堆块的选项时，并没有将指针一同清零，因此，在ptr的地址中依然有指向堆块的指针存在，并没有被清理，然后我们在调用打印的函数时，依然能调用已经被free掉的堆块，并执行其中的内容，于是我们对本题的攻击便基本成型。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-9c4ee1bd0549490087e5588248c843b0"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fe91e0da5-80b9-4c92-b0a4-8bd58b11780e%2FUntitled.png?table=block&amp;id=9c4ee1bd-0549-4900-87e5-588248c843b0&amp;t=9c4ee1bd-0549-4900-87e5-588248c843b0&amp;width=1653&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-d23841b39a384323932bd98486097495"> </div><div class="notion-text notion-block-b5e353e605014a19b1ab75990810705e">大致的思路如图，根据这个来描述针对本题的攻击。</div><div class="notion-text notion-block-ffc4a312137048fb9ac39f67c59dc7b7">在程序中先使用创建日志的函数，申请一个大小&gt;0x18的堆（这里必须要让程序配一个与0x10大小不同的堆块，多的8可以输入到下一个chunk中的prev size字段，一旦超过8便只能从新申请更大的堆块），随便填一点内容就行，这样程序便会像上面的ptr指向的两个堆块一样出现这样的结构，然后在执行同样的操作，再申请一个大于0x18的堆，这样程序的ptr和ptr+1地段都会出现上文中的结构。</div><div class="notion-blank notion-block-815aaf7125d14a9b96a7c8e84b78d730"> </div><div class="notion-text notion-block-31663ca8a3784eaf90083b42736e7106">在之后我们通过程序中的清理函数的选项将我们刚刚申请的这4个堆块都free掉。于是程序中的fast bin中便会出现上面左边的结构，这4个堆依次连接，便于程序的下次快速调用，这里我们虽然将我们之前申请的堆块free掉了，但是ptr中的指针这些都没有被清零。</div><div class="notion-blank notion-block-10ea939f1ab048578721f41683e848ff"> </div><div class="notion-text notion-block-ce1d9e5c2e9a4c3b99fd84dba791deb8">然后我们在使用这个选项向程序在申请大小为0x10的堆块，这里程序为了快速分配会先从而fast bin中寻找有没有满足要求的chunk，于是之前最后进入fast bin中的原本ptr +1指向的chunk便会被分配出去，然后由于我们还需要一个大小为0x10的chunk，于是之前ptr指向的chunk，便会被分配出去（这里就是为了避免我们自己申请的堆被分配出去所以申请的必须要大于0x18），用于作为我们自己申请的堆存储我们填入的数据，于是程序便构成ptr+2中由虚线指向的结构。此时如果我们向我们自己申请的堆中填入system和/bin/sh的地址那么，便覆盖ptr指向的堆中的数据，</div><div class="notion-blank notion-block-8c78edb45cc74fa7a447c11433ab6a00"> </div><div class="notion-text notion-block-1a0aaca89faf4e79bc4532082ad59168">此时由于ptr中的指针并没用清零，于是我们再次使用打印的选项并想要打印第一个堆块中的内容时程序会开始执行ptr指向的堆块中的命令来用于打印（理论上来说，如果我们应该将ptr中的指针清零，从而使程序不能完成我们这个打印已经被free掉的堆的操作，但是由于ptr中指针没有被清零于是程序就认为那个堆依然存在从而去执行堆中的指针，从而打印内容），但是我们此时修改了这个堆的内容导致程序直接执行了system(/bin/sh)这个后门函数从而满足了我们的要求。</div><div class="notion-blank notion-block-233d375331d84692862681ad286450ab"> </div><div class="notion-text notion-block-245cd91488024d3ba12f14e94a1130e7">exp如下</div><div class="notion-text notion-block-c837269c26274c5aa8eb59167eebeeaa">这道题就是一个最基础的uaf漏洞的题，写的比较详细，往对以后的这种漏洞有所启迪。</div><div class="notion-blank notion-block-54128d788bb642c79f0f079b2691a0b3"> </div><div class="notion-text notion-block-bdd927c697ea4b86af05f655b9ed1a25">在libc版本为2.27的题目中，这种uaf漏洞，能使用tcachebins这样一种结构</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-37b16afe954a4343b528499528b3c689"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:434px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F04e6384d-0eba-40bd-86c7-50046c056089%2FUntitled.png?table=block&amp;id=37b16afe-954a-4343-b528-499528b3c689&amp;t=37b16afe-954a-4343-b528-499528b3c689&amp;width=434&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-c21c7f664c904ddcb5e02162090ff1d6"> </div><div class="notion-text notion-block-5555153912c0473e957d70e4b9112b82">这种结构出现在大小小于0x400的chunk在被free后链接而成（大于0x400的在free后会成为unsortedbin），在这种结构中，chunk的fd指针由于指向下一个chunk的原本的的数据段，现在的fd段（如果下面没有chunk了，这个fd指针将会指向0）。这里面的chunk在再次使用时遵循的是先进先出的规律，当再次malloc时，先吧上面一个满足大小的chunk拿出来使用，然后在将下面一个满足大小的chunk拿出来使用。</div><div class="notion-blank notion-block-cddfce62cb814ea1a8cb1f15beccaf89"> </div><div class="notion-text notion-block-b218d1018cc044cebc159a5380215009">这里如果我们便可以通过uaf漏洞，将chunk中fd指针的值修改为我们需要的地址空间然后，malloc到这块空间，便可以对其进行修改。</div><div class="notion-blank notion-block-a9e7a22a521c45119885265624c31afa"> </div><div class="notion-text notion-block-648ca4e4e8dd42199dabbababec18129">（这里好像不用在意要修改的地址空间上两位的值能不能构成chunk的prev size和size都可以，malloc到那里直接修改，但是在其他版本可能要满足条件）</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-d627f2a672a34f17bb225e2fdece3b8f" data-id="d627f2a672a34f17bb225e2fdece3b8f"><span><div id="d627f2a672a34f17bb225e2fdece3b8f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d627f2a672a34f17bb225e2fdece3b8f" title="unlink"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>unlink</b></span></span></h2><div class="notion-text notion-block-15b6d774b8dd469d91cbd2dd52528480">现简单说一下这一类题的大致问题在哪里，与一般的解决办法。</div><div class="notion-text notion-block-bf541b8f05864222978d063641f35151">要能使用这种解决办法的题，会以下的几种重要的东西是我们能够使用的，才能使用这种办法。</div><div class="notion-blank notion-block-6b6561db710d4dedb36bab1efc523fad"> </div><ol start="1" class="notion-list notion-list-numbered notion-block-5509210d85924dd7912d846f607c4cd8"><li>能连续申请几个连续的堆，</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-3a1687337f7f457180075a8e5ef34cd5"><li>对于指向申请的堆的指针，会在bss段上有一个固定且已知的地点存放，并且存放的方式是连续的。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-37d92041c3c64543bb8cbf1e5f2faba9"><li>必须在申请的堆中有堆溢出，用于修改下一个堆的prev size段空间</li></ol><div class="notion-blank notion-block-2f297c829c5446208d584e62895316ba"> </div><div class="notion-text notion-block-4c574f132d47436c82a1fdb5f538bfc8">对于这一类的题，最重要的就是在我们申请的堆中间，通过我们自己伪造一个fake chunk与bss段的存放对指针的地址，构成一个含有3个chunk的双向链表，然后在申请的宁外一个堆中使用堆溢出，从而修改下一个堆中的prev size段，并使大小为从要修改这个chunk的prev size一直到，我们伪造的fake chunk的prev size这两个地址的距离差大小，这样使得我们在后面free掉我们修改了prev size 的chunk时，程序会将从这个chunk一直到我们伪造的fake chunk的这一段地址都认为是之前已经free的chunk（prev size中记录的是上一个free chunk的大小），从而使这一个刚刚释放的free chunk，直接就把上面的一整段被识变为free chunk的地址合并了（连续的两个free chunk会被程序合并），但是我们在之前伪造的fake chunk已经与存放指针的地址，构成了一个双向链表，所以在这里fake chunk被下面的free chunk合并时，原本与之构成双项链表的那两个空间，由于与之相连的chunk被拿走了，使得那两个空间，会有一定的改变，而改变的结果就会使原本存放指针的地方存放其他地址空间，从而使用这个地址修改函数地址。</div><div class="notion-blank notion-block-0b694b3b81904ca1b4c6930a513d74df"> </div><div class="notion-text notion-block-63e9a6de801d47fe990a62f9070e136e"><b>注意一下，当这道题的libc版本为2.23时，我们用于free的chunk的大小必须要大于fastbin（大于等于0x80）的大小，否则不能出现unlink的情况</b></div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-78f6f49560934a4597282751cf4eae8c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F1c435dab-7f1b-4175-9562-56a54753d237%2FUntitled.png?table=block&amp;id=78f6f495-6093-4a45-9728-2751cf4eae8c&amp;t=78f6f495-6093-4a45-9728-2751cf4eae8c&amp;width=802&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-a6f63f869074487aa4931d0203411277"> </div><div class="notion-blank notion-block-485cea098e064ddcad6052d1d50e69b5"> </div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b6327b881452458791b0b4c2a6685afd"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fdfbca9d1-9d2f-48cc-bf42-ff24c7fc8ce4%2FUntitled.png?table=block&amp;id=b6327b88-1452-4587-91b0-b4c2a6685afd&amp;t=b6327b88-1452-4587-91b0-b4c2a6685afd&amp;width=999&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4f69140188e34644b528449a8247083e"> </div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-4b4f647d819e4cc28b3d1f91dfc6fa5a"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:683px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F7abda3be-ef52-4170-97d9-0901184edac6%2FUntitled.png?table=block&amp;id=4b4f647d-819e-4cc2-8b3d-1f91dfc6fa5a&amp;t=4b4f647d-819e-4cc2-8b3d-1f91dfc6fa5a&amp;width=683&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-f7c97cb777444ba18a6f4eb475990fbe"> </div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-52eaeadcfcb4407ca3b6a0d2e877cecb"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F86fbef63-13bc-4511-96f8-b5d456cfd882%2FUntitled.png?table=block&amp;id=52eaeadc-fcb4-407c-a3b6-a0d2e877cecb&amp;t=52eaeadc-fcb4-407c-a3b6-a0d2e877cecb&amp;width=1500&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-00fc8cd2085e4de2b808688bedd99420" data-id="00fc8cd2085e4de2b808688bedd99420"><span><div id="00fc8cd2085e4de2b808688bedd99420" class="notion-header-anchor"></div><a class="notion-hash-link" href="#00fc8cd2085e4de2b808688bedd99420" title="Off-By-One"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>Off-By-One</b></span></span></h2><div class="notion-text notion-block-8aa9b6b62fc442aabc8ebd0a26d91724">这个漏洞在很多的地方都算是比较常见的吧，不过在之前的栈的时候属于不太好利用的一种，不过在堆中由于堆的特殊性导致，这个漏洞难够在很多地方发挥出意想不到的作用。</div><div class="notion-blank notion-block-251ea31b6f854f3f878d21bfa0d3d7f7"> </div><div class="notion-text notion-block-b660cf470050406797b97a2966a3844b">这个漏洞的具体就是使用read等函数向某块地址写入数据时，如果使用了循环的方式，而循环的次数的大小与那块地址的大小相同，如我们有的是大小为16的数组，我们通过循环向这里写入数字，而我们的循环的次数是由我们数组的大小决定，这里简单的说就是对循环的次数没有进行严格的检查，像循环的次数由变量x决定，并且循环的此时就等于这个x的值，这里x=16，看起来好像没什么问题但是会发现，由于程序中的这些数组的起始都是从0开始，包括循环的+</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-a8a8f0d2f4404662af13a676f2997739"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fe261e184-f4b4-44e6-8139-354fbe82c1b0%2FUntitled.png?table=block&amp;id=a8a8f0d2-f440-4662-af13-a676f2997739&amp;t=a8a8f0d2-f440-4662-af13-a676f2997739&amp;width=1387&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-1f3f7c6593594475a5a2828d7447b116"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-af12f5c7fab94bb094ba2946ac9a1d85" data-id="af12f5c7fab94bb094ba2946ac9a1d85"><span><div id="af12f5c7fab94bb094ba2946ac9a1d85" class="notion-header-anchor"></div><a class="notion-hash-link" href="#af12f5c7fab94bb094ba2946ac9a1d85" title="unsortedbin泄露libc地址"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>unsortedbin泄露libc地址</b></span></span></h2><div class="notion-text notion-block-d1f7619f79b84013adbe27b24e636884">关于这种bin的具体结构等之后学会了在细讲，这里先讨论如何利用这种bin将libc的地址泄露。</div><div class="notion-text notion-block-2bb1a57eaa36431794fe818917b206fe">由于在不同的libc版本中unsortedbin的产生不同，这里将针对不同libc版本进行分别讲解。</div><div class="notion-blank notion-block-29cac8311b5140efaf14d1d06e9b8694"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-93ba2cd9ebdc48f3b96b49e65e6ebea6" data-id="93ba2cd9ebdc48f3b96b49e65e6ebea6"><span><div id="93ba2cd9ebdc48f3b96b49e65e6ebea6" class="notion-header-anchor"></div><a class="notion-hash-link" href="#93ba2cd9ebdc48f3b96b49e65e6ebea6" title="一，libc-2.27"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><em><b>一，libc-2.27</b></em></span></span></h4><div class="notion-text notion-block-20736cbad0c64219a3fcc7ca23abb474">在2.27的libc版本中又一种tcachebins的存在，这会导致数据区小于0x400，整体小于0x410的chunk在free后被放入tcachebins这里面，供下次使用，因此我们这里首先要先malloc一块大小大于0x400的chunk，同时这个chunk还不能与top chunk相邻，否则在free后会被top chunk直接合并，因此我们必须保证这个大于0x400的chunk与top chunk中间还有一个chunk用于隔离这两个chunk。就像满足这样的条件</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-38580f3e59fa4eeebd7cb94738881673"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:447px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F8b030857-96b4-4d60-bd4f-50018e4b4617%2FUntitled.png?table=block&amp;id=38580f3e-59fa-4eee-bd7c-b94738881673&amp;t=38580f3e-59fa-4eee-bd7c-b94738881673&amp;width=447&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-f1c943408b6340a8ab80b7deb0b6be6f"> </div><div class="notion-text notion-block-f5b04300251c447f808edfa4aaae8414">然后我们将大于0x400的这块chunk，free掉，就会得到一块被放置在unsortedbin中，且满足条件的free</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-30bb92875ff945509a0e8b32657d7794"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:624px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F780f5674-ac75-4e1b-9c9b-1ce298a90a8c%2FUntitled.png?table=block&amp;id=30bb9287-5ff9-4550-9a0e-8b32657d7794&amp;t=30bb9287-5ff9-4550-9a0e-8b32657d7794&amp;width=624&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-cff3bcdd82554c008df4348e89572fca"> </div><div class="notion-text notion-block-33a3b0696e804930ac74283a54a64666">而此时这个free掉的chunk中的fd和bk指针由于只有这一个chunk在unsortedbin中，所以他们同时指向的都是main_arena+96的地址</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-bfad1b48ae5241ba94509b1f91987323"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fabcb1cd1-59e7-4adb-9cff-5902c7001fd4%2FUntitled.png?table=block&amp;id=bfad1b48-ae52-41ba-9450-9b1f91987323&amp;t=bfad1b48-ae52-41ba-9450-9b1f91987323&amp;width=793&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-559b4926e86c42149ba47a0e5272fd59"> </div><div class="notion-text notion-block-b4825ccd7b724167bd686b4841628ea5">并且这个地址在程序中与libc的基地址的距离是始终保持相同的，只要能泄露这个便可以知道程序中的libc的基地址，在其他版本中其实也如此，不过在有的地方也有不同。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-c846e219c71c486783966db3327221af" data-id="c846e219c71c486783966db3327221af"><span><div id="c846e219c71c486783966db3327221af" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c846e219c71c486783966db3327221af" title="house of orange"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>house of orange</b></span></span></h2><div class="notion-text notion-block-a712ba9d7cf549adaca3df4d731a1ff8">今天做题的时候刚好遇到这个知识点，那就现在把他写一下。</div><div class="notion-blank notion-block-c9baeb9da6844b169e71ed38afdd281d"> </div><div class="notion-text notion-block-b0c5b304009343cba963e4100d067f42">这个的作用并不能直接作用于程序上实现shell，这个漏洞的作用只是在于特殊情况下泄露libc的地址，其实这里用到也就是创造unsortedbin，从而泄露libc的地址，我们知道在上面的使用unsortedbin泄露libc地址的方法前提是要能创造一个大小满足free后进入unsortedbin的大小的chunk并且这个chunk还不能与top chunk相邻的的条件的chunk，并且还要能将这个chunk，free掉使得它进入到unsortedbin中，然后在将fd指针的值打印出来，这样才能泄露libc的值，而这里我们就是在面对没有free函数的情况下，依然能产生unsortedbin从而泄露libc的值。</div><div class="notion-blank notion-block-19dbad59f5eb43eb9c5b2f2cabcd1690"> </div><div class="notion-text notion-block-ff5a4c428a4349978c225985a3ab732c">具体的不细将，直接将做法。</div><div class="notion-blank notion-block-e1dd6d341a4f448c973ce575bf1c7fb0"> </div><div class="notion-text notion-block-83244334e416480db6f9970cac43c525">关于这种做法目前我之在libc-2.23上做过，关于其他的libc可能有所不同，请注意。这里也是按在libc-2.23上来讲。</div><div class="notion-blank notion-block-34c60024fb2d4beaaf48733f049d04fe"> </div><div class="notion-text notion-block-d48574ef4692483094d2cbf159f401fc"><em>一，第一步堆溢出，修改top chunk的size值</em></div><div class="notion-text notion-block-3a117aeaa1fa43789d81d5aed7de476b">这里必须有一个靠近top chunk的chunk能被我们写入数据进去，同时这个chunk要能进行溢出，溢出的大小要能刚好修改到top chunk的size段。</div><div class="notion-text notion-block-03066991d0b1419787e66d8191e18ce2">关于修改的这个top chunk的size的大小并不是随意的，也是有要求的，</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-0a3dc5cd95054a62a2b45a83e2d8ffa2"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:606px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F253dbc18-95e0-4719-98ee-205c7383e957%2FUntitled.png?table=block&amp;id=0a3dc5cd-9505-4a62-a2b4-5a83e2d8ffa2&amp;t=0a3dc5cd-9505-4a62-a2b4-5a83e2d8ffa2&amp;width=606&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-b9a6e0496bc14aa4a86efb2c5cad5625"> </div><div class="notion-text notion-block-f0f11fb166074760a1569e5c4959f33c">这是未修改的top chunk的大小，size段的大小为0x20fe0，这里我们要修改成0xfe1，如下图，从而使程序能将top chunk的大小识别为0xfe0（那一个字节用于放数据，不计入总大小）</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-37d4ca1eafa7493980fab2b460b978dd"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:590px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fb8e826ff-c465-47bd-9f9b-c025c14188a5%2FUntitled.png?table=block&amp;id=37d4ca1e-afa7-4939-80fa-b2b460b978dd&amp;t=37d4ca1e-afa7-4939-80fa-b2b460b978dd&amp;width=590&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-8e7304f31179404bae1bd9c7f66d20d7"> </div><div class="notion-text notion-block-84dbc1d2525a4418958ba01acdaf3e47">关于为什么要修改top  chunk的大小为这个数据，我解释不好，有兴致的可以参考一下这篇文章<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://ctf-wiki.org/pwn/linux/user-mode/heap/ptmalloc2/house-of-orange/?h=of+orange">House of Orange - CTF Wiki (ctf-wiki.org)</a></div><div class="notion-text notion-block-83b6ea21a14b4d79981649d8605b0eb7">什么是对齐到内存页呢？我们知道现代操作系统都是以内存页为单位进行内存管理的，一般内存页的大小是 4kb。那么我们伪造的 size 就必须要对齐到这个尺寸。在覆盖之前 top chunk 的 size 大小是 20fe1，通过计算得知 0x602020+0x20fe0=0x623000 是对于 0x1000（4kb）对齐的。</div><div class="notion-text notion-block-9ff3814208aa46d6b93eb70a83372d6e">因此我们伪造的 fake_size 可以是 0x0fe1、0x1fe1、0x2fe1、0x3fe1 等对 4kb 对齐的 size。</div><div class="notion-text notion-block-a5ea1468c8794588ab5ace1c46aeb360">以上便是引用那里面的话，这里关于修改的大小我目前使用0x0fe1是成功的，使用了0x1fe1不能成功，原因未知。有时间研究一下。</div><div class="notion-blank notion-block-aab03030bf11423e8abffb764c4f5655"> </div><div class="notion-blank notion-block-07698085c36d492581f95d27e26ef1ab"> </div><div class="notion-text notion-block-d2177407200441c9a0ab9496c90b2d46"><em>二，申请一个大小大于这个top chunk的堆块</em></div><div class="notion-text notion-block-9f91765a3cef4f26b38c6e45385f8020">这里我申请的大小为0xff0，这是申请后的样子</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-2550bf2ea1a2477b94074bf9f13440d2"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:598px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fe0f5feb5-262a-4f27-85ad-a5afb57bc41d%2FUntitled.png?table=block&amp;id=2550bf2e-a1a2-477b-9407-4bf9f13440d2&amp;t=2550bf2e-a1a2-477b-9407-4bf9f13440d2&amp;width=598&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-b768c1d042864fb3b6d39c4015d5596b"> </div><div class="notion-text notion-block-67410dde54284766821861d949081f76">就是这样我们便能够在没有使用free函数的情况下也能产生一个unsortedbin,并且其中fd和bk指针都指向main_arena+88的地址空间。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-531eeb39e4f2494b813b5fd99f2ae522"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fd818b197-5df8-4d69-8e90-40d9f9a4fc17%2FUntitled.png?table=block&amp;id=531eeb39-e4f2-494b-813b-5fd99f2ae522&amp;t=531eeb39-e4f2-494b-813b-5fd99f2ae522&amp;width=941&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-775765ac85e74d939ae0ba1a4fee8fd8"> </div><div class="notion-text notion-block-8a2bb33caa0e4935bd10d4addd32d369">现在虽然产生了unsortedbin但是我们会发现，此时我们如果只有一个用于存放最近的指针的空间，会发现这个指针指向的chunk时是下面的的那个chunk，所以这个没有用。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-9ce6a06a6cd84bec960e09ff24b61e19"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:649px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F7c3a05d0-655d-4c17-aef1-6218fcfbbc33%2FUntitled.png?table=block&amp;id=9ce6a06a-6cd8-4bec-960e-09ff24b61e19&amp;t=9ce6a06a-6cd8-4bec-960e-09ff24b61e19&amp;width=649&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-5c9864abecf14dbe83420ef3a24d8910"> </div><div class="notion-text notion-block-504e962eb42f4d40b46f2a37cb1cb9b2"><em>三，再申请一个chunk</em></div><div class="notion-text notion-block-9c0bcf0e934240299152c51527fb4e8e">这个新申请的chunk的大小，没什么限制，别太大太小就行，这里我申请的大小为0x40</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-f56e7993645146049fc8fe5c52f01764"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F942c2ee5-2afc-4f2e-943d-a324dee18625%2FUntitled.png?table=block&amp;id=f56e7993-6451-4604-9fc8-fe5c52f01764&amp;t=f56e7993-6451-4604-9fc8-fe5c52f01764&amp;width=785&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-a1cd14d3073c4697b061570384151a8f"> </div><div class="notion-text notion-block-56a1b00f090c4d128eec5fadfad15e5b">申请之后会发现存放指针的地址空间，存放的新的chunk指针为unsortedbin上面的新chunk，并且这个新chunk的内容也大有搞头，这里按理论来说这个新chunk的数据段前两个字节存放的都是<b>0x00007614787c4188</b>这个数据，（这里因为这道题在申请chunk时，必须要输入数据，所以这里的数据段第一个字节，不能使用，只能使用第二个字节的数据），这个地址指向的为main_arena+1640，这个地址与libc基地址的距离是固定的。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1820bf58b23a403da8b0bb5b6f7b2f4b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F975665e4-bb83-456e-9981-652c7c708498%2FUntitled.png?table=block&amp;id=1820bf58-b23a-403d-a8b0-bb5b6f7b2f4b&amp;t=1820bf58-b23a-403d-a8b0-bb5b6f7b2f4b&amp;width=883&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-bbcd46c0835c4d9aa5e54ced854277b6"> </div><div class="notion-text notion-block-3885cf1a614445229f6631c64e687cfc">同时这个chunk的第3，第4字节存放的数据时这个chunk的头地址。</div><div class="notion-blank notion-block-b7ad92796dbf473580a49c755fba024e"> </div><div class="notion-text notion-block-4b416bb1bba542759f4a7b43c189ca02">就这样只要我们能将这个新chunk的内容打印出来，接收第2字节的main_arena+1640的地址，第3字节的chunk的头地址，那就可以跟具这个地址与libc基地址的差得到基地址的大小（这个差值是固定不变的），还有chunk的地址也能拿到</div><ul class="notion-list notion-list-disc notion-block-260605e2bc4d498cb5fe74208c89d808"><li>修改top chunk的size大小为0xfe1</li></ul><ul class="notion-list notion-list-disc notion-block-17753a4f69594a689c35b1048fa41d42"><li>申请一个大小大于0xfe0的chunk</li></ul><ul class="notion-list notion-list-disc notion-block-108de4ee4e8b4ddc97c0bdbc14982e2b"><li>在申请一个0x20的chunk</li></ul><ul class="notion-list notion-list-disc notion-block-a373e0dad4d34bebb81852adb1f84d9e"><li>打印并接收新chunk的内容（注意如果一定要输入数据，注意不要过多，影响第二字节的内容）</li></ul><ul class="notion-list notion-list-disc notion-block-ee694bdb9d4d45acb56c2b9e13e896ac"><li>减去相应的差值得到libc基地址。</li></ul><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-aaf98ec51a4e4d32a4357aa01ca57b9c" data-id="aaf98ec51a4e4d32a4357aa01ca57b9c"><span><div id="aaf98ec51a4e4d32a4357aa01ca57b9c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#aaf98ec51a4e4d32a4357aa01ca57b9c" title="Fastbin Attack"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>Fastbin Attack</b></span></span></h2><div class="notion-text notion-block-9d6e0498d6f344c580cd4916dd06015f">这一类有四种小类，这里将分批讲解。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-2a1d9e4fe15c4e94871f9bf7a14c3290" data-id="2a1d9e4fe15c4e94871f9bf7a14c3290"><span><div id="2a1d9e4fe15c4e94871f9bf7a14c3290" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2a1d9e4fe15c4e94871f9bf7a14c3290" title="Fastbin Double Free"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><em><b>Fastbin Double Free</b></em></span></span></h4><div class="notion-text notion-block-4387b07aa53e4c9da83978b213e40111">这是一种利用比较多的漏洞，这种漏洞的实现的条件比较苛刻，但其攻击的效果也属于比较明显的便于利用的一种，这种的攻击的手段需要的有uaf漏洞，只有在有uaf漏洞的基础上以及比较早的比如libc2.23这些比较早期的版本下才能实现这种攻击的手段，具体的现在来讲。</div><div class="notion-blank notion-block-79fa1971600d4c8ea2a720a41bd5a446"> </div><div class="notion-text notion-block-1e90e8ed51ff4a2c9d671719a471e834">既然是Double Free，那就必须要进行双重释放，对同一个堆块进行两次free，中间必须要free得有一个或多个chunk这样才能实现对同一个chunk进行两次释放，</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d5d9fd62effa40feaac57a7fca877dd1"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:693px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fbc25379d-4cd0-4edc-8cdf-6dabd97ee5eb%2FUntitled.png?table=block&amp;id=d5d9fd62-effa-40fe-aac5-7a7fca877dd1&amp;t=d5d9fd62-effa-40fe-aac5-7a7fca877dd1&amp;width=693&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-29d8016acf434ec5a74f757e2ee3c381"> </div><div class="notion-text notion-block-97ef887f68de424481a8df52d797c38d">这里借用一下之前文章中的图片讲解一下，在fastbin中的结构是用chunk中的fd指针指向之前一个free的指针的头地址，然后bin的指针指向最近free的chunk的头地址，对于最后一个chunk中的fd指针则为0，就这样可以再fastbin中构成由最开始的bin中的指针开始依次由fd指针相连的chunk链，就这样在malloc相同的大小的chunk时便可以在直接从这个fastbin中依次取出来用就行。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-58142211c7a74e309bd687e9b5c28def"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F27224b56-9958-477c-a963-d843ca68166a%2FUntitled.png?table=block&amp;id=58142211-c7a7-4e30-9bd6-87e9b5c28def&amp;t=58142211-c7a7-4e30-9bd6-87e9b5c28def&amp;width=863&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-bf7e798f5c76442f9729a2c3507aeb5e"> </div><div class="notion-text notion-block-a7cca9ac1d204e1492909b6446717d4b">就这样我们先free两个chunk这时bin指向第二个free的malloc，这个malloc的fd指针指向第一个chunk的头地址，第一个chunk的fd指针为0。</div><div class="notion-blank notion-block-d561ac1173344f2e9ce01536068cc558"> </div><div class="notion-text notion-block-bc8cf324bb2f4079ab58c8a6aec93e3d">这时我们就对第一个free的chunk进行二次free，于是bin中的指针就会回到第一个chunk的头地址，同时这个chunk的fd指针也会因为在之前有已经free掉的chunk，从而指向第二个chunk的头地址，</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-e7a33f51cd66455e963d821cd536afaa"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F15a3bcfc-5c36-41d9-9d16-8c40816ce416%2FUntitled.png?table=block&amp;id=e7a33f51-cd66-455e-963d-821cd536afaa&amp;t=e7a33f51-cd66-455e-963d-821cd536afaa&amp;width=942&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-0653e5dfd687441f921a6a5206ba4c08"> </div><div class="notion-text notion-block-102454b304874f008c124d7adeabb5d1">就这样原本的fastbin中的结构，由<code class="notion-inline-code">bin--&gt;第二个chunk--&gt;第一个chunk</code>，变成</div><div class="notion-text notion-block-8cce54c523944fecba149416895857fe"><code class="notion-inline-code">bin--&gt;第一个chunk--&gt;第二个chunk--&gt;第一个chunk</code>这样的双重free结构，</div><div class="notion-text notion-block-1f1de2507c794584babf4805e55bb0eb">这样当我们向程序再申请一个相同大小的chunk时，程序会先从bin的指向中取出第一个chunk以供使用，但是由于之前的双重释放从而使得bin中的结构即使取出第一个chunk后依然有第一个chunk的存在，</div><div class="notion-text notion-block-d0d41d2cc4e442cda30501ed65772aab"><code class="notion-inline-code">bin--&gt;第二个chunk--&gt;第一个chunk</code></div><div class="notion-text notion-block-7bd8a6331d904e349a6282f476e9679f">是这样的结构，虽然第一个chunk被我们取了出来但是在bin中依然有他的存在，并且此时第一个chunk中的fd指针在fastbin中由于是有用的指向了第二个chunk的头地址。</div><div class="notion-blank notion-block-eeeae81e5692410dba291287d5446ece"> </div><div class="notion-text notion-block-745c81f1fd3a44398ac380d13a59c7ce">这里如果我们在程序的其他地方构造一个fake_chunk（这个地方可以是bss段上，甚至可以是栈上的地址）,并使得第一个chunk中fd指针就指向这个fake_chunk的头地址，而这个fake_chunk的构造很简单，就是确保size段的大小和前两个chunk的size一样，同时其他的保持为0就行，然后在修改了chunk中的fd段后bin中的结构就会改变为如下的结构。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d52f608954234819b46848f003537065"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F4a90f9df-f69b-45c2-9f81-dbe4cba58456%2FUntitled.png?table=block&amp;id=d52f6089-5423-4819-b468-48f003537065&amp;t=d52f6089-5423-4819-b468-48f003537065&amp;width=1212&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-c0e1658115504008afe2f242aa8cce93">这样之后，我们再向程序连续申请两个大小相同的chunk后bin就会指向我们fake_chunkde1,然后在申请一个就会使我们刚刚伪造的fake_chunk,被我们申请为一个新的chunk，从而可以修改这个地址的内容。</div><div class="notion-blank notion-block-f59d6a961f7f44eaacbe857f19120f51"> </div><div class="notion-blank notion-block-9f18ca42f25a458daa6d7af73bfbb4a5"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-b46101df1c754a499a091659cab0af91" data-id="b46101df1c754a499a091659cab0af91"><span><div id="b46101df1c754a499a091659cab0af91" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b46101df1c754a499a091659cab0af91" title="House Of Spirit"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><em><b>House Of Spirit</b></em></span></span></h4><div class="notion-text notion-block-111594a044ea41e498d15fb66538afea">这个方法我个人感觉很奇妙，虽然这种方法有种脱裤子放屁的感觉（在更多的地方感觉使用fd修改可能更多，不过这种方法的思想还很值得学习的）。</div><div class="notion-blank notion-block-bc7d9778860341af992d653a5847a893"> </div><div class="notion-text notion-block-6b1704f57b2c4450bbdbbdef7cf28f6a">这种方法的主要过程就是在使用free函数释放某一个chunk，我们通过在bss段或其他的地址伪造一段chunk，在使用于释放的那个指针指向的就是我们伪造的这个chunk，通过这样使得我们这伪造的这个chunk被挂入进fastbin中的单项链表中，被程序识别为一个free掉的chunk，在后期我们在向程序申请相同大小的chunk时，能直接将那块地址作为chunk以供我们要使用，从而是我们能修改那块区域和使用其中的数据段。</div><div class="notion-blank notion-block-62721441df5b4a0cb6bbe853a2994c12"> </div><div class="notion-text notion-block-e2edd8e0f08c46afbbcfdffd8c8be79e">我之前说的脱裤子放屁的感觉就是在这里，我们本可以直接修改fastbin中的bk段直接指向伪造的chunk，但我们却要将那块伪造的chunk释放来挂入fastbin中，这不是脱裤子放屁，这是什么。不过并不是所有题都能直接修改free chunk的，所以这种方法的出现以可以理解。</div><div class="notion-blank notion-block-75919083caa94c258844832c57eba5bc"> </div><div class="notion-text notion-block-a978a56f1d174483be4747f246c78a3c">关于这种方法在伪造chunk时有几个需要注意的点，这里我直接吵ctfwiki上了，原文在这里</div><div class="notion-text notion-block-6992ceac86fa41d28c810b2e8b8de89a"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://ctf-wiki.org/pwn/linux/user-mode/heap/ptmalloc2/fastbin-attack/#house-of-spirit">Fastbin Attack - CTF Wiki (ctf-wiki.org)</a></div><div class="notion-text notion-block-f09e7368db2444dea1e77dbfb7922ed4">要想构造 fastbin fake chunk，并且将其释放时，可以将其放入到对应的 fastbin 链表中，需要绕过一些必要的检测，即</div><ul class="notion-list notion-list-disc notion-block-30d11a67cd5445e1810590a2cf99d339"><li>fake chunk 的 ISMMAP 位不能为 1，因为 free 时，如果是 mmap 的 chunk，会单独处理。</li></ul><ul class="notion-list notion-list-disc notion-block-5af8d8f1edb34696b0d97093fc0c7cf2"><li>fake chunk 地址需要对齐， MALLOC_ALIGN_MASK</li></ul><ul class="notion-list notion-list-disc notion-block-ad2f24f6ced24afbafe09531d941e377"><li>fake chunk 的 size 大小需要满足对应的 fastbin 的需求，同时也得对齐。</li></ul><ul class="notion-list notion-list-disc notion-block-bc3e40acac7046368f959351e21b5bc8"><li>fake chunk 的 next chunk 的大小不能小于 <code class="notion-inline-code">2 * SIZE_SZ</code>，同时也不能大于<code class="notion-inline-code">av-&gt;system_mem</code> 。</li></ul><ul class="notion-list notion-list-disc notion-block-b0552fe0c32f44419846385c836be38a"><li>fake chunk 对应的 fastbin 链表头部不能是该 fake chunk，即不能构成 double free 的情况。</li></ul><div class="notion-blank notion-block-8f11d248f66a4790b30dc9f1d949d01c"> </div><div class="notion-text notion-block-133a3e15ae4d4f5dae7224a1e86d8e01">在借用一篇大佬写的解释<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://blog.csdn.net/qq_41202237/article/details/109284167">好好说话之Fastbin Attack（2）：House Of Spirit_fastbin attack house of spirit-CSDN博客</a>（这个是真的nb大佬，写的文章都太好了）</div><div class="notion-blank notion-block-2f9dde4cd23e4caab324aa498a8437e6"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-8871b843d22942de8b76a3a437927c2e" data-id="8871b843d22942de8b76a3a437927c2e"><span><div id="8871b843d22942de8b76a3a437927c2e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8871b843d22942de8b76a3a437927c2e" title="1、fake chunk 的 ISMMAP 位不能为 1，因为 free 时，如果是 mmap 的 chunk，会单独处理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>1、fake chunk 的 ISMMAP 位不能为 1，因为 free 时，如果是 mmap 的 chunk，会单独处理</b></span></span></h4><div class="notion-text notion-block-500ba00061c34835a4963abb455c1275">IS_MAPPED，记录当前 chunk 是否是由 mmap 分配的，这个标志位位于size低二比特位</div><div class="notion-blank notion-block-1160f47df5cb4c848f56facce5ae6a73"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-320c438825ed4284957899dd73469b1e" data-id="320c438825ed4284957899dd73469b1e"><span><div id="320c438825ed4284957899dd73469b1e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#320c438825ed4284957899dd73469b1e" title="2、fake chunk 地址需要对齐， MALLOC_ALIGN_MASK"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>2、fake chunk 地址需要对齐， MALLOC_ALIGN_MASK</b></span></span></h4><div class="notion-text notion-block-d763f82774a949878e613be5c92a7581">因为fake_chunk可以在任意可写位置构造，这里对齐指的是地址上的对齐而不仅仅是内存对齐，比如32位程序的话fake_chunk的prev_size所在地址就应该位<code class="notion-inline-code">0xXXXX0</code>或<code class="notion-inline-code">0xXXXX4</code>。64位的话地址就应该在<code class="notion-inline-code">0xXXXX0</code>或<code class="notion-inline-code">0xXXXX8</code></div><div class="notion-blank notion-block-db020aad92154437906a4bcf71a77ec5"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-0c4c3cd6c2254a18804c947fac82b1b7" data-id="0c4c3cd6c2254a18804c947fac82b1b7"><span><div id="0c4c3cd6c2254a18804c947fac82b1b7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0c4c3cd6c2254a18804c947fac82b1b7" title="3、fake chunk 的 size 大小需要满足对应的 fastbin 的需求，同时也得对齐"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>3、fake chunk 的 size 大小需要满足对应的 fastbin 的需求，同时也得对齐</b></span></span></h4><div class="notion-text notion-block-3fc701f1cbed4bbab8bda6d779163940">fake_chunk如果想挂进fastbin的话构造的大小就不能大于<code class="notion-inline-code">0x80</code>，关于对齐和上面一样，并且在确定prev_size的位置后size所在位置要满足堆块结构的摆放位置</div><div class="notion-blank notion-block-f88835342bd046f4a904c57adefc121d"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-364ba55e50994a80bb234855525ca1d0" data-id="364ba55e50994a80bb234855525ca1d0"><span><div id="364ba55e50994a80bb234855525ca1d0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#364ba55e50994a80bb234855525ca1d0" title="4、fake chunk 的 next chunk 的大小不能小于 2 * SIZE_SZ，同时也不能大于av-&gt;system_mem"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>4、fake chunk 的 next chunk 的大小不能小于 2 * SIZE_SZ，同时也不能大于av-&gt;system_mem</b></span></span></h4><div class="notion-text notion-block-2bf869df24b846ea9262c4d1bed059a9">fake_chunk 的大小，大小必须是 2 * SIZE_SZ 的整数倍。如果申请的内存大小不是 2 * SIZE_SZ 的整数倍，会被转换满足大小的最小的 2 * SIZE_SZ 的倍数。32 位系统中，SIZE_SZ 是 4；64 位系统中，SIZE_SZ 是 8。最大不能超过av-&gt;system_mem，即128kb。next_chunk的大小一般我们会设置成为一个超过fastbin最大的范围的一个数，但要小雨128kb，这样做的目的是在chunk连续释放的时候，能够保证伪造的chunk在释放后能够挂在fastbin中main_arena的前面，这样以来我们再一次申请伪造chunk大小的块时可以直接重启伪造chunk</div><div class="notion-blank notion-block-f7d9505eb08a4a0286d4dbf872ce4f19"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-ed6e2846fb254560a0eccdf1c397a81f" data-id="ed6e2846fb254560a0eccdf1c397a81f"><span><div id="ed6e2846fb254560a0eccdf1c397a81f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ed6e2846fb254560a0eccdf1c397a81f" title="5、fake chunk 对应的 fastbin 链表头部不能是该 fake chunk，即不能构成 double free 的情况"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>5、fake chunk 对应的 fastbin 链表头部不能是该 fake chunk，即不能构成 double free 的情况</b></span></span></h4><div class="notion-text notion-block-fef02da55ba64fbc89df1af881907b8b">这个检查就是fake_chunk前一个释放块不能是fake_chunk本身，如果是的话_int_free函数就会检查出来并且中断。可以参考篇文章<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://blog.csdn.net/qq_41202237/article/details/109199077">好好说话之Fastbin Attack（1）：Fastbin Double Free</a></div><div class="notion-blank notion-block-1caaa46a91fe497ebcfa5773fe032cb2"> </div><div class="notion-text notion-block-2deb3c15e8d24f7c88ad88e9bae8523d">这里在讲讲我的自己的简单补充，伪造的chunk最好如下，fake_prev_size的值为0，fake_size可以根据自己的需求来调整，但不能超过fastbin的要求，还有这里填的是0x几0不用加1。在整个fake_chunk结束的下一行便要是宁一个fake chunk，这个只要整prev_szie 和size段就好，这个的prev szie是之前伪造的那个chunk的整体大小，然后size这个的大小在32位系统我使用了0x100是可行的，不知道在64位的系统中可以不，到时候在仔细研究一下。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-e0ce2a2323b84d669ab3bfcd66d8a5a6"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:549px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F12e27d14-80fa-4ee6-aab6-2e4aff4ae094%2FUntitled.png?table=block&amp;id=e0ce2a23-23b8-4d66-9ab3-bfcd66d8a5a6&amp;t=e0ce2a23-23b8-4d66-9ab3-bfcd66d8a5a6&amp;width=549&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-b355c4346f134a908c538f7156a60d85"> </div><div class="notion-text notion-block-822f1861c11149b48b6d98798f399f32">就这样我们伪造一个chunk然后把这个chunk的数据段起始地址，当做这个chunk的指针放入free函数中，这样这个chunk变回被程序当做free chunk挂入fastbin中，然后我们在申请这个大小的chunk，便可以把这个地址当做新被chunk，被我们使用。</div><div class="notion-blank notion-block-01f0c656bb3248bc9d5e9b08862a0e28"> </div><div class="notion-text notion-block-885e4185f6b94876b8ea878555901cc3"><em>Alloc to Stack</em></div><div class="notion-text notion-block-6e97b4dbce204377b5496ea4583af776"><em>Arbitrary Alloc</em></div><div class="notion-text notion-block-2c19abd301724db7971376a693bc9ced">这还有两种方法，这两种方法的大致差别不大，都是在程序中寻找一块可用的地址然后修改fastbin的bk指针使其指向这个地址，在fastbin中增加这块地址，在之后将这块地址申请出来作为一个新chunk使用。</div><div class="notion-blank notion-block-e4d1ca94289847e3a90e49a998d4704e"> </div><div class="notion-text notion-block-8fd17fd6d3404e1e80e7781236889043">关于这块这地址的检查，不需要多的就一个对size段的大小检查，因此我们这可以在malloc_hook的地址上面通过偏移地址使得size只有0x7几，这样只要我们申请的chunk大小为0x70，程序就会直接把那块区域分配给我们使用。</div><div class="notion-blank notion-block-25c404b6fb4f4252bac9c22af104ed4a"> </div><div class="notion-blank notion-block-9f3b2fb55bd94027a6163a72e685892a"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-d4ec7d695f6b4296bbe2084639b4f1ea" data-id="d4ec7d695f6b4296bbe2084639b4f1ea"><span><div id="d4ec7d695f6b4296bbe2084639b4f1ea" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d4ec7d695f6b4296bbe2084639b4f1ea" title="2017 0ctf babyheap"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://github.com/ctf-wiki/ctf-challenges/tree/master/pwn/heap/fastbin-attack/2017_0ctf_babyheap">2017 0ctf babyheap</a></b></span></span></h4><div class="notion-text notion-block-83be43c3de484b8cb61ca0fd8de69da9">这里讲一个泄露libc手法，是在做这道题时遇到的，这个手法还是比较可以的。</div><div class="notion-text notion-block-9be5b4e55afc4b5faa181796f2fabde1">关于这种手法的使用条件，为</div><ul class="notion-list notion-list-disc notion-block-17b7aeb8760b49d0a5dac4bed7b3aa7a"><li>可以申请多个chunk大小不一</li></ul><ul class="notion-list notion-list-disc notion-block-c1af4161a5134ecc96a5c5063a5d3a66"><li>每一个chunk都可以进行堆溢出</li></ul><ul class="notion-list notion-list-disc notion-block-261fd086f9d847cf9e4a9c28ab9f9afe"><li>可以打印chunk中的内容</li></ul><div class="notion-text notion-block-84b6453af37441abb0d366e30d9439cf">其实有这些条件这道题就可以用这种泄露的办法将libc地址泄露。</div><div class="notion-blank notion-block-98428f886fa242c5913e18b16b1921d5"> </div><div class="notion-text notion-block-74ae863444ec4f4490cbbfd72e6fa01c">这里就拿这道题的条件分析，（这里面的图我从大佬的博客里面偷的，写的太好的这个大佬，强推！！！原文在这里<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://blog.csdn.net/qq_41202237/article/details/112320919">好好说话之Fastbin Attack（4）：Arbitrary Alloc_好好说话 ctf-CSDN博客</a>，和上面的那篇是同一个作者，膜拜大佬。）</div><div class="notion-blank notion-block-05151bba2b3e4845b2bcfd7fb15f11bb"> </div><div class="notion-text notion-block-40c8d917de254cb0bdf1b192255a4203">这道题我们不知道堆的指针在哪，同时也没有uaf漏洞给我们使用，那我们要泄露libc的地址，虽然这里我们能创造unsortbin，但我们并不知道这个chunk的地址故不能直接泄露他，这里便可以用这个方法泄露libc的地址</div><div class="notion-blank notion-block-f02b55f633da4c8ebed54e079a8a1033"> </div><div class="notion-text notion-block-60928c571bdb40b195aa3ed957879233">这里我们先申请5个chunk前4个大小为0x20，最后一个0x90，申请后的样子如下</div><div class="notion-blank notion-block-309de3a973f643bd8678ce03e1681348"> </div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-a24b54ff017a47709431632b331b6034"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fb8d3b452-3d49-4b20-9bb4-dabda04905a5%2FUntitled.png?table=block&amp;id=a24b54ff-017a-4770-9431-632b331b6034&amp;t=a24b54ff-017a-4770-9431-632b331b6034&amp;width=2482&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-1b87c5d19c9843f3a532f60c73bbb838">形成这样的结构后，我们在依次free掉chunk3和chunk2这两个chunk，使得在fastbin中能形成一个链表，为什么要先free chunk3在chunk2，这里是为了在chunk2中出现bk指针执向chunk3头地址（fastbin的结构使后free的chunk中的bk指向前一个free的chunk的头地址），然后我们在利用chunk1的堆溢出，从而直接修改chunk2中的bk指针，使其指向chunk5的头地址。</div><div class="notion-blank notion-block-1e27f2887ffe42268711aa73f173f83e"> </div><div class="notion-text notion-block-ef1b09c4b1f7447f90b57ca3b0d07e96">这里虽然我们并不知道chunk5的准确头地址，但这里因为堆的对齐导致堆块的地址即使在每一次程序的加载都会有变化，但末尾的后3位是固定，这里我们只需要将chunk2的bk指针的后两位数字覆盖为chunk5的头地址的后两位，这样就可以改变fastbin中的结构使得chunk2后直接是chunk5的地址</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-79e18738f9a74669a54c96c1d68265ae"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F130d753b-2651-4400-bf21-8b12b22f0d6c%2FUntitled.png?table=block&amp;id=79e18738-f9a7-4669-a54c-96c1d68265ae&amp;t=79e18738-f9a7-4669-a54c-96c1d68265ae&amp;width=1598&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-f1f5fdb9a6674c76ab38f12dcd70e7a8"> </div><div class="notion-text notion-block-a3809f40996f45bbaf000ad1e2b49138">这里我们还需要做的就是再利用chunk4中的堆溢出将chunk5的size段改为0x21，这里修改是为使chunk5的大小与chunk2的大小保持一致，这样我们能在之后的申请中将chunk再一次申请出来被程序再次记录下，</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b0bdb3c40e5340aeb18f0aaa6ab3686b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F6014727a-41fc-4e3c-8f39-6c874cf8ffc3%2FUntitled.png?table=block&amp;id=b0bdb3c4-0e53-40ae-b18f-0aaa6ab3686b&amp;t=b0bdb3c4-0e53-40ae-b18f-0aaa6ab3686b&amp;width=1598&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-0ace5a325eb94b6ba9cf9e31e1d70fb0">修改后的结构如上，这样chunk2和chunk5的大小一致，我们可以直接向程序申请这个大小的堆块从而使得程序中的第3个指针的位置存放的也是第5个chunk的指针，也就是chunk5的重启</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-8a970fe7d2034456966881f2f02bcd8c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fa53e0bd1-f344-4a5e-9015-2b5718bd3b97%2FUntitled.png?table=block&amp;id=8a970fe7-d203-4456-9668-81f2f02bcd8c&amp;t=8a970fe7-d203-4456-9668-81f2f02bcd8c&amp;width=703.3333740234375&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4eb274067e244d63a2d5d842ff685daf"> </div><div class="notion-text notion-block-2908ccb0b97546939df86bdd5c4a93a8">再这样之后再程序中就有两个地址同时记录则chunk5的地址，分别为地址空间为3和5的指针，不过由于这个地址我们并不知道但并不影响我们对其的引用。其实到这里剩下的就很简单了，我们再一次利用chunk4的堆溢出修改chunk5的size段的数据恢复为0x91，然后我们在申请一个chunk块，这个会从top chunk分出来，用以避免chunk5 free时直接与top chunk合并，之后我们直接free掉chunk5这样，chunk5就回进入unsortbin中，产生指向main_arena的fd指针，这里我们知道程序在free掉后会同时清楚相应位置存放的指针，但是这里由于我们之前的操作导致在程序中不只有记录chunk5的位置有指向chunk5的指针，还有记录chunk3的位置有指向chunk5的指针，这样就到导致我们可以通过打印chunk3的方法从而打印出chunk5中的内容，这样就可以通过unsortbin的bk指针得知libc的地址。</div><div class="notion-blank notion-block-84bad69a189f49f69055015bd96e7fe0"> </div><div class="notion-text notion-block-7c06799679774fb3ae2a4bc149e44ee2">补充一下图，恢复chunk5的大小</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-fd3f83e5190c4fe09228ccfd83c11e1c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fed89b202-9261-4bf6-a719-983690dd0ea3%2FUntitled.png?table=block&amp;id=fd3f83e5-190c-4fe0-9228-ccfd83c11e1c&amp;t=fd3f83e5-190c-4fe0-9228-ccfd83c11e1c&amp;width=1858&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-63c3724ba6954707a8354884a9fc2d6e">free chunk5，产生unsortbin</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-8a3f9abdeb1440a08f9d156713916e42"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F0dfcf115-b04c-4062-ba1b-a9d54f3185e6%2FUntitled.png?table=block&amp;id=8a3f9abd-eb14-40a0-8f9d-156713916e42&amp;t=8a3f9abd-eb14-40a0-8f9d-156713916e42&amp;width=2004&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-d89eb69bfc0f4bcd807acccef553b049"> </div><div class="notion-text notion-block-8e81e9d6355b460e9d0d6d05edd6f95d">在次感谢holk大佬的博客，跪谢！</div><div class="notion-text notion-block-897cecd44c854ee99c7763f5fd394d0e">其实这种方法的主要目的就在与使用堆溢出修改fastbin中fd的指向，在申请相同chunk区域，使得程序中两个地址同时记录着同一块chunk的指针，然后利用这块chunk产生unsortbin，在利用后面存放这块chunk的指针打印chunk中的内容，从而实现libc地址的泄露。</div><div class="notion-text notion-block-418efc21300f4750b3c1edca1974d350">巧妙的方法，感觉要长脑子了。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-a907abe188a64b12af3c32d7041ea54f" data-id="a907abe188a64b12af3c32d7041ea54f"><span><div id="a907abe188a64b12af3c32d7041ea54f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a907abe188a64b12af3c32d7041ea54f" title="Unsorted Bin Attack"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>Unsorted Bin Attack</b></span></span></h2><div class="notion-text notion-block-0d7b1e9b3bdb470c92876c6155f56a7c">这个手法咋说呢，感觉有点鸡肋，单独使用的作用并不是那么的大，可能在大部分时候要配和着其他的手法来使用才算可以发挥作用，或许可以用来在有的时候用于泄露libc的地址，但条件感觉要的有点多，在没有在实际的题目的使用过。并且这种攻击的手法之前好像看见有人说从libc2.28开始就不能再使用，在系统中多了对Unsorted Bin 的大小检测的函数，这种攻击的方式便不能再使用所以对题目的要求也较高，就有点鸡肋。不过既然有种手法就还是学一下，至少知道这种漏洞的存在。</div><div class="notion-blank notion-block-52a31463e8d0475aa6167c229bbed21e"> </div><div class="notion-text notion-block-7d47c49808dd45c0b9af23730836e5c6">前话到此为止，现在开始讲有关这种手法的操作。</div><div class="notion-blank notion-block-945307936318411b909d0455e7b5eee5"> </div><div class="notion-text notion-block-d04dbb8c9bc24daab5bb67452d264292">关于Unsorted Bin这是一个神奇的bin，我们知道有的chunk由于大小限制所以在释放后会被放入的Unsorted Bin中作为其中的一部分free chunk以供下次申请时快速使用，但是其实在没有chunk进入到unsorted bin的时候他自己本身就是一个单独的chunk结构，不过不参与到chunk的分配只作用来作为unsorted bin的基础机构，如下图</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1f2c3b8abaca4db5a2d2a3bfdf5cb38f"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:473px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fc1579dfd-1f53-48e9-9db6-72e5fb4f5c86%2FUntitled.png?table=block&amp;id=1f2c3b8a-baca-4db5-a2d2-a3bfdf5cb38f&amp;t=1f2c3b8a-baca-4db5-a2d2-a3bfdf5cb38f&amp;width=473&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-31f826cd976e4f23883c0718e3933b1c"> </div><div class="notion-text notion-block-3345ec8c5ff04bdbabd3fa65342e96fb">（这个图还是偷的csdn的大佬holk，再次跪谢大佬，跪谢大佬无私，原文链接<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://blog.csdn.net/qq_41202237/article/details/112589899">好好说话之Unsorted Bin Attack_unsortedbin attack-CSDN博客</a>）</div><div class="notion-text notion-block-b5cae7352d3d4b518780cae6af7dba59">这个就是unsorted bin结构，而当有free chunk进入到unsorted bin中时这两个的结构变回发生新的变化，</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-abf0f665bc004545933ae31f3b9264cf"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:671px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F310e5cad-9d8c-4d84-ad18-aa2a0989cd5f%2FUntitled.png?table=block&amp;id=abf0f665-bc00-4545-933a-e31f3b9264cf&amp;t=abf0f665-bc00-4545-933a-e31f3b9264cf&amp;width=671&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4d39e24bb140475a964464e222dfbd9b"> </div><div class="notion-blank notion-block-951add13c4864f9b891cd182897e7e39"> </div><div class="notion-text notion-block-e25c907319fb4c658916f6ff67482649">此时chunk_400是我们程序中由free从而进入到unsorted bin中chunk，这个chunk的fd和bk指针都会指向unsorted bin的结构chunk的头地址，而我们知道unsorted bin的结构在程序中的位置在main_arena+88的地方，这就是为什么我们能通过泄露unsorted bin的fd和bk指针从而获取到程序的libc地址。</div><div class="notion-blank notion-block-ca7902d611074a558462f0badfcf81fb"> </div><div class="notion-text notion-block-cf95653aa0944f8b9fd37dca4a89a960">我们关于这个漏洞的手法就正式从这里开始，这里我们如果修改了我们free进unsorted bin中的这个chunk的bk指针，使其指向宁一个地址那么程序便会直接将那个地址默认为一个新free进unsorted bin中的chunk，从而形成一个新的结构。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-09295c10b5264560891889825cf1dbe1"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F3a0953e5-e70f-4cf6-960d-7d365c80373b%2FUntitled.png?table=block&amp;id=09295c10-b526-4560-8918-89825cf1dbe1&amp;t=09295c10-b526-4560-8918-89825cf1dbe1&amp;width=911&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-dc3293b67fef4358a4a127c9732d9dbb"> </div><div class="notion-text notion-block-5a1e6667b91b4323b6bac9965dd3d58a">这里的bk指向的chunk中对任何一个的数值没有要求只要修改bk的指向，程序就会默认这个地址为一个新的chunk被收录进unsorted bin（这个在libc2.23中是如此其他版本还不知道），但是这里在个填入的地址后期并不会被申请出来。这里还有一个重要的点，就是在我们堆溢出修改chunk_400时我们不必保存fd指针的指向一直指向unsorted bin的头地址，我们可以直接覆盖为0。这样也不影响后面的操作。</div><div class="notion-blank notion-block-47262c61e9d946b6918eaefe8555363c"> </div><div class="notion-text notion-block-1ee7be0d519a4bd6884988155845bc31">现在便是这种方法的最后一步，由于在unsorted bin中对free chunk的申请保持的是一种<code class="notion-inline-code">FIFO</code>（先进先出）的利用手法，所以即使在这里我们将一个新的地址作为新的free chunk挂入unsorted bin中，只要我们能在申请到与chunk_400同样大小的chunk那程序依然会先从unsorted bin中将chunk_400拿出给我们使用，而在这里一旦将chunk_400拿出来unsorted bin中变回对结构有新的变化，变化的结果如下</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d8c9fe50f55a43fea909dec19a6ee110"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Ff2245ad4-53dd-478c-9c3c-42b2791815f0%2FUntitled.png?table=block&amp;id=d8c9fe50-f55a-43fe-a909-dec19a6ee110&amp;t=d8c9fe50-f55a-43fe-a909-dec19a6ee110&amp;width=956&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-79e5814dd969455da5ee9e9819a4ea9a"> </div><div class="notion-text notion-block-cfb6e4e1867546e184647c160660776d">变化之后unsorted bin的fd指针指向chunk_400的头地址，bk指针指向我们创造的fake chunk的头地址，而对我们来说最终要的便是我们的fake chunk的bk指针被修改为指向unsorted bin的头地址。</div><div class="notion-blank notion-block-a920211969e9429b87b217ee5f7204be"> </div><div class="notion-text notion-block-1e60d901fb3a4cf384078f3c386f0121">就这样我们成功做到将我们写入chunk_400中的地址的下两位修改为unsorted bin的头地址，但是由于这个地址在程序中随机化的，所以我们并不能保证这个数值的大小。虽然这个地址是main_arena+88，与libc的距离是固定不变的，但我们并不知道具体的大小，所以这里是有一点鸡肋的存在，但或许可以通过打印修改的这里的地址获取到libc的地址，但这并不好用。</div><div class="notion-blank notion-block-db199cae03c64e2da10e33a6abe22095"> </div><div class="notion-text notion-block-ce22ea476e5b43cf8c9a329aa09d8094">好，到这里这种手法就差不多结束了，总结一下，这种手法能做的就是将程序中的某一块地址的内容修改为main_arena+88的地址， 是一个比较大的数。</div><ol start="1" class="notion-list notion-list-numbered notion-block-966797c175404190aedda5ca64b37344"><li>产生unsorted bin</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-68eb81accb224dd988218959d7eb38da"><li>修改这个unsorted bin的bk指针指向我们要修改的地址-0x10的地址</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-755f116a1a7a4f468aa8c7c924146aa1"><li>重新通过malloc启用unsorted bin中的那个chunk</li></ol><div class="notion-blank notion-block-db987231534f40df8ebbc3c3b5d2d979"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-faef034d02db49eaa71ac510c15c1e63" data-id="faef034d02db49eaa71ac510c15c1e63"><span><div id="faef034d02db49eaa71ac510c15c1e63" class="notion-header-anchor"></div><a class="notion-hash-link" href="#faef034d02db49eaa71ac510c15c1e63" title="关于unsorted bin"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><em><b>关于unsorted bin</b></em></span></span></h4><div class="notion-text notion-block-3d4fd04faac54a9ebdcf82c83675fd79">这里讲一下有关于unsorted bin中的chunk的分配有关的事情，我们知道除了再有tcache bin的情况下一般只要大于fastbin的范围（0x80）的free chunk会被放入到unsorted bin中，但unsorted bin并不会长期存放，只会作为一个暂时的chunk存放地，在之后如果有需要malloc时，程序会先看fastbin中是否有符合要求的free chunk ，然后在在unsorted bin中寻找。</div><div class="notion-blank notion-block-1c17f75f8e784b6baed3ed60b53d4e79"> </div><div class="notion-text notion-block-ed9e89b63c054980819ad5ae23486c81">这里我们假设在unsorted bin中有两个chunk，一个为chunk(P1)0x390（&lt;0x3F0）,另一个为chunk(P2)0x410（&gt;0x3F0）这两个chunk，并且小的chunk在第一位大的在第二位。这时我们向程序申请1个0x90的chunk，程序会在unsorted bin中进行寻找，而寻找的过程并不简单。</div><div class="notion-blank notion-block-4aea7021a4f143dd95f273d1f633e941"> </div><ul class="notion-list notion-list-disc notion-block-aeb1f2bae38241eb988159e7c8434365"><li>从unsorted bin中拿出最后一个chunk(P1)</li></ul><ul class="notion-list notion-list-disc notion-block-df74726f9aa140438d38316ef03f06cf"><li>把这个chunk(P1)放进small bin中，并标记这个small bin中有空闲的chunk（小于0x3F0）</li></ul><ul class="notion-list notion-list-disc notion-block-981dc80d16e6480bb70bf71399f47dbc"><li>从unsorted bin中拿出最后一个chunk(P2)（P1被拿走之后P2就作为最后一个chunk了）</li></ul><ul class="notion-list notion-list-disc notion-block-8e85765c987e416d9359c1f1c41edbf1"><li>把这个chunk(P2)放进large bin中，并标记这个large bin有空先的chunk(大于0x3F0)</li></ul><ul class="notion-list notion-list-disc notion-block-6c7104bf8b2248718a9989550847b7b1"><li>现在unsorted bin中为空，从small bin中的P1中分割出一个小chunk，满足请求的P4，并把剩下的chunk(0x390 - 0xa0后记<code class="notion-inline-code">P1_left</code>)放回unsorted bin中</li></ul><div class="notion-blank notion-block-072b262d8c4f44359508d28d35827abf"> </div><div class="notion-text notion-block-d565deaede0043a1b4c116f1c1250f35">这个过程是比较复杂的，我这里讲的依然只是其中的一种情况，还有很多情况没有说。</div><div class="notion-blank notion-block-8ea17ef7db32462dbd4c4552e7eabee9"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-add8d6bbfe434b69849df764c966012b" data-id="add8d6bbfe434b69849df764c966012b"><span><div id="add8d6bbfe434b69849df764c966012b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#add8d6bbfe434b69849df764c966012b" title="malloc.c中从unsorted bin中摘除chunk完整过程代码"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>malloc.c中从unsorted bin中摘除chunk完整过程代码</b></span></span></h3><div class="notion-text notion-block-fb8eeb453d9e4516819a94464fcb0060">上面这是完整的原代码有时间再详细分析一下。</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-5a704e38ab514bd6a9e26564e06f1f20" data-id="5a704e38ab514bd6a9e26564e06f1f20"><span><div id="5a704e38ab514bd6a9e26564e06f1f20" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5a704e38ab514bd6a9e26564e06f1f20" title="tcache attack"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>tcache attack</b></span></span></h2><div class="notion-text notion-block-d93501dbbdbc4da2a3395c7f82d56846">fast bin=0~0x80</div><div class="notion-text notion-block-a722b1124f674f41ad77835dbbd68af5">small bin&lt;0x3F0</div><div class="notion-text notion-block-cd883342bbc74a5e9c98cee18a54b971">large bin&gt;0x3F0</div><div class="notion-text notion-block-6fbcde964fe64fe5aa440a14e3986393">tcache bin 最多有7个chunk，多的要放在其他bin中。</div><div class="notion-blank notion-block-404f6eda211a407eb89c2f38375410be"> </div><div class="notion-blank notion-block-fb081f954c8043de84d9e48a782a9de5"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-c936590120d8412baae1cae5a8a952ad" data-id="c936590120d8412baae1cae5a8a952ad"><span><div id="c936590120d8412baae1cae5a8a952ad" class="notion-header-anchor"></div><a class="notion-hash-link" href="#c936590120d8412baae1cae5a8a952ad" title="tcache poisoning"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><em><b>tcache poisoning</b></em></span></span></h4><div class="notion-text notion-block-cb21c207c59b470a842a28766e9fa461">这个漏洞的的利用是很方便的，同时效果也很强，不过这个漏洞的很大问题在于这个目前只能在libc2.27的版本上利用，在高一点的版本都对其有检测，不能利用，这是很重要的一点。</div><div class="notion-blank notion-block-3633b27d8b99478f893d0763c7d92685"> </div><div class="notion-text notion-block-aca6e88b148a465d993e2be18d3ed921">这个漏洞利用的是在tcache中的链表对chunk的检测不完全而到导致的，先来讲一下tcache bin中的chunk结构。</div><div class="notion-blank notion-block-dcd0911af62f440f8720cf20aad419f6"> </div><div class="notion-text notion-block-63c64620277742588f9239951996226e">当程序中有被free的程序进入到tcache bin中，当进入的数量大于两个后程序会将这里chunk通过他们的fd指针链接起来，而链接的过程是，由后一个进入tcache bin的chunk在fd中产生一个指向上一个chunk的数据段的指针，依次相连从而构成tcache bin，并且bin的记录的是新进入的chunk，在后面的程序有需要chunk时，程序变会从记录的第一个开始，依次分配chunk以供使用，所以其分配结构为<b>先进后出，后进先出</b>的结构。</div><div class="notion-blank notion-block-aac29e9d903844c1b7a42678cde51311"> </div><div class="notion-text notion-block-bd70627e4d574a279e372b91669384df">那么既然知道了tcache bin中的chunk链表结构，便会发现一个很严重的问题，这里tcache bin上的chunk是有fd指针指向下一个chunk的数据段，来相连的。并且在libc.2.27这个版本中有一个很大的问题，在于使用fd指向的下一个chunk，在上一个chunk没分配出去后，将这个fd指向的记录在bin中时，程序不会有任何检测，同样的在malloc那块地址时，也不会对那块地址有任何检测，因此这里我们的这个漏洞便出现了。</div><div class="notion-blank notion-block-c195da6fa38a48f2a0fb094308e92d3d"> </div><div class="notion-text notion-block-65470cf1deed4fd99d69c8b86634d395">到我们使用堆溢出或uaf将tcache bin中的chunk的fd指针，修改为一个我们需要修改的地址后（这里由于程序对那个地址没有一点检测，同时fd指针指向的是chunk的数据段，因此我们直接修改为要修改的地址就行），程序便会直接将那块地址记录在tcache bin中，我们一直申请向程序申请与之前的free chunk相同的chunk，那程序便会现将前面的chunk分出去,然后变会来到被我修改了的fd指针，并因为程序对chunk的不检查，从而导致我们输入到fd的地址被直接分配成我们需要的chunk以供我们使用，这样我们便可以修改那块地址。</div><div class="notion-blank notion-block-8f36fd5184e1480b9b867f9f3da835e4"> </div><div class="notion-text notion-block-6dfef82f4c134643bcb0e659a41e79d7">总结一下</div><ol start="1" class="notion-list notion-list-numbered notion-block-bc59c514d35d4c669132860bc2c0e5b4"><li>产生tcache bin中的chunk链表</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-fc94984ed1b348db95c0d820826c4155"><li>将tcache bin中的chunk的fd指针修改为我们要修改的地址</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-53f81efe6f964d30a7fd9a2416a70579"><li>申请大小与修改的chunk相同的chunk，一直申请到修改的fd指针被分配出去</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-691aa318a12e4e1fba1ed1c02c1f45fe"><li>我们要的地址被认作chunk分配给我们使用，从而修改那块地址</li></ol><div class="notion-text notion-block-4eeb938fbeaf472b9554e926af41434c">这个方法是很简单的一种，但限制也很大几乎只能在libc.2.27的条件下使用。</div><div class="notion-blank notion-block-091f2a4b1c514d1da636b97047bfcded"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-0087efc7d0ce4a119a945113e8067605" data-id="0087efc7d0ce4a119a945113e8067605"><span><div id="0087efc7d0ce4a119a945113e8067605" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0087efc7d0ce4a119a945113e8067605" title="tcache dup"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><em><b>tcache dup</b></em></span></span></h4><div class="notion-text notion-block-280a2f570b9046d6bbc392371261fd5d">这个漏洞也是一个几乎只能在libc.2.27使用的漏洞。</div><div class="notion-text notion-block-b19e8c56af25428a99ed74051d0765c3">这里利用的是在tcache bin对free进的函数没有然后检测从而利用的漏洞</div><div class="notion-blank notion-block-d93cc46a660540eda116db2b4b6e89bb"> </div><div class="notion-text notion-block-ff5dfd78b5a145f88878a9a727577d14">这个漏洞也算是一个比较离谱的漏洞，这个简单说就是对同一个chunk连续两次free，在连续两次申请相同大小的chunk，从而导致程序中的后面两个malloc的指针同时指向一个chunk。这里的由于程序对这个释放的过程并不会有检测从而导致，我们能同时连续对一块chunk释放两次。中间甚至不用free其他的chunk从而间隔。</div><div class="notion-blank notion-block-3957e6b4255c4c609fdf08b067c484b2"> </div><div class="notion-text notion-block-8dd7694684e046dc983e3e496270949e">所以这个漏洞就是对同一个chunk，free两次，然后在申请相同大小的chunk两次，这两次的指针会指向同一个chunk。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-a8583099a0984853834fc53519e270f8" data-id="a8583099a0984853834fc53519e270f8"><span><div id="a8583099a0984853834fc53519e270f8" class="notion-header-anchor"></div><a class="notion-hash-link" href="#a8583099a0984853834fc53519e270f8" title="tcache house of spirit"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><em><b>tcache house of spirit</b></em></span></span></h4><div class="notion-text notion-block-d7f9deab47ad4cc9bbd777d46fca116e">这个漏洞和上一个一样也是只能在libc.2.27的上使用的漏洞。</div><div class="notion-blank notion-block-e973ccd240b540c8b553a004fc709baa"> </div><div class="notion-text notion-block-d44e6e362f21441baff56f70b8757aa7">这个漏洞的利用很简单，只要我们在程序的某一个地方伪造一个fake_chunk然后将这个chunk直接free进tcache  bin中，在后面的malloc中申请我们fake_chunk的大小chunk，这样就可以把这个fake_chunk当做一个真正的chunk分配给我们使用。</div><div class="notion-blank notion-block-7fd8c689d6e74865a8fc8832155a0020"> </div><div class="notion-text notion-block-13701c3670d44b9aa51f17764c027e21">关于这个fake_chunk的伪造条件只有一个，就是要保证这个fake_chunk的size为一个相对正确的chunk大小，这样就可以满足要求了。</div><ul class="notion-list notion-list-disc notion-block-6c685987b6154794b83357d308015f42"><li>找到要伪造的chunk的地址，就这个地址的size为一个正确的地址。</li></ul><ul class="notion-list notion-list-disc notion-block-0160c395ad2f48a6bc5e3dd6e6a226d5"><li>将这个fake_chunk的数据段地址使用free函数将这个fake_chunk挂入tcache bin中</li></ul><ul class="notion-list notion-list-disc notion-block-52326189e5694a2bbd17cc56053a2519"><li>申请我们刚刚free的fake_chunk的大小的chunk</li></ul><div class="notion-text notion-block-2eeedbf5a77f4d658eb2f292040e1e7e">这样我们fake_chunk就会被当做chunk供我们使用。</div><div class="notion-blank notion-block-20e3bd658ba74ed0b83dcab92f47a09d"> </div><div class="notion-blank notion-block-313ed59a947b44739ea67904b4b86817"> </div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-3044a9cde87c418faccd65e56bddb40b" data-id="3044a9cde87c418faccd65e56bddb40b"><span><div id="3044a9cde87c418faccd65e56bddb40b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3044a9cde87c418faccd65e56bddb40b" title="tcache stashing unlink attack"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><em><b>tcache stashing unlink attack</b></em></span></span></h4><div class="notion-text notion-block-9913a7d23f784c9085c645d67b57e91f">这个漏洞的利用相较上面的几种就相对来说要复杂一点，并且利用的东西也多了很多，</div><ul class="notion-list notion-list-disc notion-block-8fd12625a59f4e668a4472c1ce9b6543"><li>当使用calloc分配的堆块时会从small bin中获取（不从tcache bin中拿）</li></ul><ul class="notion-list notion-list-disc notion-block-c614aadb579741e1aa4c2fd6a99aff87"><li>获取一次之后会将small bin中其余堆块挂进tcache中（前提tcache中有相同堆块的链表，且其中chunk大小相同有剩余）</li></ul><ul class="notion-list notion-list-disc notion-block-6546bc27c30b4d29b06187deaac42f40"><li>在将small bin中其余堆块挂进tcache中这个过程中只会对第一个挂进去的chunk进行完整性检查，后面的不做检查</li></ul><div class="notion-text notion-block-ac29db414dd940c9af470066553cbbb2">这里其实就已经很明显的告诉我们这里我们可以在程序中，产生small bin后在small bin中修改chunk的控制字段，从而使伪造的fake_chunk挂入small bin中，在使用calloc分配一个相同大小的chunk，从而使small bin的剩下的chunk挂入tcache bin中，这里注意一定要保证我们伪造的fake_chunk之前还有一个正常的chunk，只有这样才能保证我们的fake_chunk能顺利挂入tcache bin，然后被分配出来。</div><div class="notion-blank notion-block-e50e905bcaec4564b09ddf53fd5a9148"> </div><div class="notion-blank notion-block-4042dd4541154af1be28cb526f41bb23"> </div><div class="notion-text notion-block-37231d748a7a4b1c99eeec2346379d87">这里具体的根据这个案例来分析这种漏洞的利用（注意要使用libc.2.27来编译这个程序），</div><div class="notion-blank notion-block-33b507a6d5e74f849abc8c564b203427"> </div><div class="notion-blank notion-block-bbf51218eb43404a8a35b2b2e9188252"> </div><div class="notion-text notion-block-c26850a455004ac783339737f38d6ee7"><b>LCTF2018 PWN easy_heap</b></div><div class="notion-text notion-block-47eca5d4ce5a41de813f85aaed09ffc6">这个方向在wiki上的第一道题就是这个，这是一个极好的题目，其中对于如何泄露libc的手法很是奇妙，很值得仔细写一写。</div><div class="notion-blank notion-block-5738951130094cc3b8b0dfd5a3e8cf3a"> </div><div class="notion-text notion-block-27f669908e824e89801ac16829252995">先感谢hollk大佬的文章<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://blog.csdn.net/qq_41202237/article/details/113697892">（补题）LCTF2018 PWN easy_heap超详细讲解_lctftk-CSDN博客</a>写的很详细，膜拜大佬。</div><div class="notion-text notion-block-31f07c44fe2241c09857e9a42cacca55">这道题的整体逻辑还是比较简单的，就是可以申请10个chunk，这10个chunk的大小固定，都为0xf8（数据段大小）。然后这10个chunk的指针和大小都会被记录进最开始的一个chunk中，然后我们可以对这10个chun进行，free，puts，其中的内容在最开始申请的时候就会被输入其中，后期不能更改。</div><div class="notion-blank notion-block-8989f68f67574a37952a284b76290336"> </div><div class="notion-text notion-block-2373adc89b364dc9ab8b593f74901a38">整体看完程序会发现漏洞就一个，在chunk申请的时候能输入多少多少数据是由我们输入的大小决定的，这里由于我们这个chunk的大小为固定的0xf8，我们能输入的数据的最大大小也为0xf8，然后这里有个很大的问题在于用于向chunk读入的内容的函数，使用的是个循环函数，这里只要我们输入的大小为0xf8这个循环就会出现一个类似于<code class="notion-inline-code">off-by-one</code>漏洞的<code class="notion-inline-code">null-byte-overflow</code>漏洞(wiki上这么叫，虽然我感觉没什么差别)，这里会对下一个chunk的size的最后两个位址覆盖为<code class="notion-inline-code">\x00</code>，这里覆盖的这个位置正好是chunk中由于检测上一个chunk是否为free chunk的inuse标志位，当程序检测到这个chunk的上一个chunk为free chunk时，这个位址的值为0，否则为1。</div><div class="notion-blank notion-block-2be82747ea9a4a75bcb2b499fc5349f6"> </div><div class="notion-text notion-block-9571920c721e48af805b9156a7330eea">然后就会发现，好了没有其他漏洞。是的，这道题的漏洞就只有这一个可以覆盖inuse标志位为0的漏洞，那么现在我们就要想办法看看能不呢使用什么方法来让我们能在程序中出现一个chunk既能有指针能调用，同时自身又在unsorted bin中，这样我们便可以直接通过打印这个chunk从而实现得到libc地址。</div><div class="notion-blank notion-block-fe86afed1ee34cdb92913c6c1970a707"> </div><div class="notion-text notion-block-e90a93b43019478d92d1f66774cf1f54">这里有一个需要先讲的知识点那就是当我们将数个相同的大小并且并且相邻的chunk被挂入unsorted bin中时，程序会为了后面的malloc方便会直接将这几个chunk在unsorted bin中合并成一个大的chunk，同时对于其中的之前的chunk会对其控制字段进行一定的改变，将其中的prev size会更具前面的free chunk的大小修改，同时size的inuse标志为0。</div><div class="notion-blank notion-block-c04726d4e45e423e8c59a8c33fb2ef48"> </div><div class="notion-text notion-block-ed3b4aeb08c344b2aebe9d207be43700">这里就有一个很大的问题如果我们在后期能将这个合并的大chunk，在后期将第一个chunk挂入unsorted bin中，同时有将最后一个chunk挂入其中，并修改其中的所有chunk1的控制字段与合并时相同（prev size和size的内容相同）程序会默认在unsorted bin中形成之前的那个大chunk，从而使我能对中间的那个chunk进行Double Free和泄露libc地址。</div><div class="notion-blank notion-block-c8c2620b4f314838936953d75fe61484"> </div><div class="notion-blank notion-block-ee2c7fbbd3ce4ad68b7819fe4d5015a2"> </div><div class="notion-text notion-block-0e655d98790747e0895cef52569cb46e"><b>以下由于在程序中chunk的次序是由0开始，所以这里要注意下面的第几个chunk是从0开始数的第几，不是从1开始，要注意这一点避免认错chunk</b></div><ol start="1" class="notion-list notion-list-numbered notion-block-7df24b4eadc442f9a11d45a023514993"><li>申请10个chunk</li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-29a22f33784e42509328a74f487846b8"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F4c1445c5-aa4a-4115-8fab-99c5c2717213%2FUntitled.png?table=block&amp;id=29a22f33-784e-4250-9328-a74f487846b8&amp;t=29a22f33-784e-4250-9328-a74f487846b8&amp;width=2484&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ol start="1" class="notion-list notion-list-numbered notion-block-75c937da083f40a39da7c7ac335b6afd"><li>将前6个chunk和第9个chunk，free进入tcachebin中填满，再将第6到第8个chunk，free进入unsorted bin中。这里678这3个chunk被free到unsorted bin会合并为一个大chunk，使得chunk7和chunk8的prve size 和size的值分别被修改为0x100，0x100和0x200，0x100。chunk6的size为0x300。</li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-93eebae0bba645f3a29e8d11eaa548c2"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F76c1ef76-d493-4fe9-847c-af7e6e4ec660%2FUntitled.png?table=block&amp;id=93eebae0-bba6-45f3-a29e-8d11eaa548c2&amp;t=93eebae0-bba6-45f3-a29e-8d11eaa548c2&amp;width=2482&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ol start="1" class="notion-list notion-list-numbered notion-block-54660e1b6eac41909ccb88747299c997"><li>在向程序申请10个chunk，使得chunk成新的排列。</li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1fe3a5a2e5d94dcea81af9e2c1ac8835"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F88a5b78f-0243-4b9f-a27a-685855987c16%2FUntitled.png?table=block&amp;id=1fe3a5a2-e5d9-4dce-a81a-f9e2c1ac8835&amp;t=1fe3a5a2-e5d9-4dce-a81a-f9e2c1ac8835&amp;width=2484&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ol start="1" class="notion-list notion-list-numbered notion-block-15ad66b0f8fc47b49cc0606ce1eb59ac"><li>在free前6个chunk和第7个chunk以填满tcachebin（这里最后一个填chunk8，是为了在后面可以直接申请这个从而覆盖chunk9的inuse标志位为0，让程序以为chunk8也是free chunk），再将chunk7也free掉使其进入unsorted bin，同时这样也能修改chunk7的inuse标志位也为0，</li></ol><ol start="2" class="notion-list notion-list-numbered notion-block-36446bbcaf454ebfbfd611e6cba79258"><li>再向程序malloc一个chunk，程序会将上一个中chunk8拿给我们使用（chunk8在tcachebin的第一位，第一个分配）这里直接使用漏洞修改chunk9中的inuse标志位，使其认为上一个chunk为free。</li></ol><ol start="3" class="notion-list notion-list-numbered notion-block-b0993e23be87410db5de485ac0131a2a"><li>free掉chunk6的chunk用于填满tcachebin中刚刚分配的那一个，然后在free掉chunk9的chunk。</li><ol class="notion-list notion-list-numbered notion-block-b0993e23be87410db5de485ac0131a2a"><div class="notion-text notion-block-9c527eb2766343a4a21e567d900f58af">这里由于之前我们通过第二步的3个chunk的合并，使得上面第3步后的chunk789的chunk中的prev size和size都被修改了。然后在第4步时我们又将chunk7 free进unsorted bin，这样使得chunk8中的size的inuse标志位为0。此时这两个chunk的控制字段与第2步的相同了，此时我们在free掉chunk9的chunk，正常情况下由于chunk8在第5步时不是free chunk了，所以这里chunk9的size的inuse标志位为1。即使我们在这里free了chunk9也不会有什么问题发生，但是由于我们在第5步时将chunk9的size的inuse标志位覆盖为0了，于是这里我们在将chunk9 free时就会使程序中的unsorted bin中又出现第2步的3个合并的大chunk，但是chunk8却在第5步时被程序拿给我们了。</div></ol></ol><ol start="4" class="notion-list notion-list-numbered notion-block-feb82cfa4085472d8fec02479db61d6d"><li>将tcachebin中的7个chunk和unsorted bin中的第一个chunk7的chunk都malloc出来那此在程序中。unsorted bin的第一个hunk便是以第3歩中的chunk8为起始地址，但是在新的chunk0中记录的正好就是chunk8的指针。</li></ol><ol start="5" class="notion-list notion-list-numbered notion-block-29489a31a6a142cf9350097ac3c6c237"><li>打印chunk0的内容，从而得到libc的地址。</li></ol><div class="notion-blank notion-block-dacdd529904e4b358814cc80ff6552f2"> </div><div class="notion-text notion-block-45de6f0855e745c48f2d31ee00c567e0">以上就是这道题中关于libc的泄露，只是基本步骤，具体的有时间再仔细分析一下，这个方法还是很奇妙的，利用到unsorted bin中chunk的合并，从而使的程序中误认为有大free chunk的出现。</div><div class="notion-blank notion-block-976cff8adcee49e2827beca22ebd1b1b"> </div><div class="notion-text notion-block-2813c99a9d3d454f82c0b3506106b0af">这道题我写的比较简陋，只是为了我自己方便研究这个方法，更好的推荐看这个地方<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://ctf-wiki.org/pwn/linux/user-mode/heap/ptmalloc2/tcache-attack/#_3">Tcache attack - CTF Wiki (ctf-wiki.org)</a>和上面提到的大佬的博客讲的更加直观与详细。</div><div class="notion-blank notion-block-26110cb8315d42a2bddbab929815d022"> </div><div class="notion-blank notion-block-ceb31a48f96142e1b4e25c4ce9d6e3fd"> </div><div class="notion-text notion-block-16cc7f54e12d43beb6ec5de692db3eec"><b>HITCON 2018 PWN baby_tcache</b></div><div class="notion-text notion-block-2f3a3d588e8549feb9a84f0f29daaf12">又来讲一讲题的新的新做法，其实也不新，不过是之前那道题的plus版本，并且这到题我感觉重点其实在于通过IO_FILE输出的方式进行泄露libc地址，这种方法我现在学的也不是很懂。这道题到写这篇文章的时候，我能把libc的地址泄露出来，但问题在于我这里泄露之后程序就好像不能再继续进行下去了之后的堆申请这些都进行不下去，很好奇为什么，等之后有时间将这个IO_FILE系列的在仔细学一下，在回来解决这个问题。</div><div class="notion-blank notion-block-d8e04f0c8d994613b4ffc3b223b844c6"> </div><div class="notion-text notion-block-3cb8dc7dc9894fe3bcead66d5280e01a">这里虽然我没有彻底将这道题整完，不过到把libc泄露出来之后后面的就是几步的事情，所以这道题最大的问题就与如何将这libc的地址泄露出来。</div><div class="notion-blank notion-block-32e577c3b5b4457ab841bef834c14332"> </div><div class="notion-text notion-block-2a6b16dbe6dc422689da8fe44cef8088">这里还是先讲一下知识点，在之前我们提到了有关于unsorted bin的合并这个点，之前好像写的有点问题，那就是合并的时候中间的chunk是不用关注是否有prev size和size是否满足free的条件的。只要在unsorted bin中有一开始的那个chunk，然后我们要合并的大chunk的最后一个chunk的prev size和size的条件是满足这个合并的要求的就行。我们要对最后一个chunk的修改时prev size要修改为前面的chunk的总大小，size的最后一位要为0（inuse标志位）。这样修改好后我们先将最前面的chunk free掉，在free我们修改的这个chunk（必须要保证这两个chunk的大小都是能直接进入unsorted bin的，中间的chunk大小可以不管），这样程序变会直接在unsorted bin中形成一个大chunk。</div><div class="notion-blank notion-block-6550edca2bc74f1abb9a805eb98d1946"> </div><div class="notion-text notion-block-d7f2dc4dfd7a40a8891194e81307e8cd">关于IO_FILE输出的方式进行泄露libc地址这个方法的原理我还不太清楚这里先讲一下怎么使用吧。</div><div class="notion-text notion-block-c02ef36795b04384922c386e4a4741b7">先来看正常情况下我们修改的地方</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-8a4d6b1c60d9495eaa8c2349a0e4459a"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F39d52a0b-94b9-497b-bcbc-1ffdd9e69c4b%2FUntitled.png?table=block&amp;id=8a4d6b1c-60d9-495e-aa8c-2349a0e4459a&amp;t=8a4d6b1c-60d9-495e-aa8c-2349a0e4459a&amp;width=903&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-830557cb13f74a398fa79d7b696fda18">这个_IO_2_1_stdout_就是我们要修改的地方，现在是正常的情况下（这里可以直接使用x/20gx stdout 这个命令查这个这个地址），而我们对于要泄露libc的修改条件为</div><ul class="notion-list notion-list-disc notion-block-2e87dcbd95b244968a7ee4ac005f2760"><li>_IO_2_1_stdout_=0xfbad1800</li></ul><ul class="notion-list notion-list-disc notion-block-b22b8b44e14d42529c8d1dad023a1f0f"><li>_IO_2_1_stdout_+8=0</li></ul><ul class="notion-list notion-list-disc notion-block-6a0b13556cd74a52b17ddddd37687d41"><li>_IO_2_1_stdout_+16=0</li></ul><ul class="notion-list notion-list-disc notion-block-4ccd961d004d476cb70bfd6bd33a922c"><li>_IO_2_1_stdout_+24=0</li></ul><div class="notion-text notion-block-c5d721872676483abbc59c5c17767c96">还有这个_IO_2_1_stdout_+32这个地址的修改是最复杂的，这里我们只修改这个地址的最后一个字节，其他的都不修改，这个的修改要更具情况来看，修改为执行一个又libc地址的地方，这里我们选择为c8（这里修改的地址程序会直接从这里开始打印内容，具体为什么，等我后面彻底学会了在来解释）。</div><div class="notion-blank notion-block-460d78e0fd3f4ba78474a299c47d19c8"> </div><div class="notion-text notion-block-bdaa36d7ee314b7f92d1c59357fefc81">这就是修改后的样子</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-972997da580f43f5a06e8fa658f1dfe8"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F423dcd6d-bca4-4bc0-b86d-f4259732afe5%2FUntitled.png?table=block&amp;id=972997da-580f-43f5-a06e-8fa658f1dfe8&amp;t=972997da-580f-43f5-a06e-8fa658f1dfe8&amp;width=859&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4aa0ad246c9d4ab18c9457d7d51bfaa0"> </div><div class="notion-text notion-block-a5184cd5b8aa4d7884c897d5a2b6fe7e">就这样修改后程序变回从0x7b3dae5ec7c8开始打印一直到遇到那个0a结束。</div><div class="notion-text notion-block-495460f63c7b4cf8b491a2ead5f6a2cf">这里会有一个问题我们都不知道程序的libc地址，我们还怎么修改这个_IO_2_1_stdout_的内容？这里又是一个新的想法和思路，我们知道对于处于unsorted bin中的chunk，只要你是第一个chunk就会在fd指针指向main_arena+96这个地址，如图</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-ffab4b1afbc848c5bf06091f5c51fcdc"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:700px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F03ff315b-9b32-4333-9824-ec32edb2b077%2FUntitled.png?table=block&amp;id=ffab4b1a-fbc8-48c5-bf06-091f5c51fcdc&amp;t=ffab4b1a-fbc8-48c5-bf06-091f5c51fcdc&amp;width=700&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-c994820bf4564cbb9a08f9f033854ab4"> </div><div class="notion-text notion-block-e495998bd84b43e4b0a533d4a9b02ceb">这里你仔细看会发现这个main_arena+96的地址为<code class="notion-inline-code">0x7b3dae5ebca0</code>，而_IO_2_1_stdout_的地址为<code class="notion-inline-code">0x7b3dae5ec760</code>这两个地址的差别就在于最后4为数。main_arena+96为<b>bca0</b>，_IO_2_1_stdout_为<b>c760</b>。这里虽然程序有地址随机化这个保护，但这里程序对与最后4位数字是不会改变的，因此我们只要将unsorted bin中的chunk的fd指针指向的main_arena+96的地址的最后4为数字修改为c760，这样就可以知道_IO_2_1_stdout_的地址。</div><div class="notion-blank notion-block-41d0243b25e14c6084a653d8b9b75164"> </div><div class="notion-text notion-block-d6035bde42264536a743384d6930caa7">这里有一个很奇妙的方法，我们知道在tcachebins中对bk指针指向的chunk没有太多的检查（这道题的环境是libc.2.27，前面好像忘记说了，这里讲的利用方法都是基于libc.2.27这个版本来的），我们既然要修改_IO_2_1_stdout_地址的内容，那这里就要想是不是可以通过将这个地址成为tcachebins中chunk的bk指针，然后就可以直接通过申请chunk来使程序将那块地址分配给我当chunk使用，这样我们就可以直接修改那块地址内容。</div><div class="notion-blank notion-block-c186a5b3773a44a3b5b1e1c37e18b810"> </div><div class="notion-text notion-block-bb382d657d7546bfb7bc6da10bb49d01">结合上面说的，我们可以现在程序中选定一块chunk，先将这块chunk free进tcachebins中。然后在通过修改这块chunk的前后chunk，使得联通这个chunk一起在unsortedbin中形成一个大chunk。然后向unsortedbin中申请chunk使得之前我们选定的chunk成为unsortedbin的第一个chunk，这样程序为因为这个chunk在unsortedbin为第一个chunk从而向其中的bk指针注入main_arena+96（0x7b3dae5ebca0），同时因为这个chunk还在tacahebins中，故在tacahebins中又会有我们选定的chunk的bk指针执向main_arena+96（0x7b3dae5ebca0）的结构，如图</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-4fbd4eaf8961426f857c0ef08eaee65d"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F7a30c2ca-feca-4350-9be9-b30c9d8402ad%2FUntitled.png?table=block&amp;id=4fbd4eaf-8961-426f-857c-0ef08eaee65d&amp;t=4fbd4eaf-8961-426f-857c-0ef08eaee65d&amp;width=703.3333740234375&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-1eb9dd2f65f74f51b44341a9126239d7"> </div><div class="notion-text notion-block-fa1b1c6bcba84600b1f270c6448c5350">这里我们选定chunk同时在unsortedbin和tcachebins都有。这里我还要修改unsorted bin中的chunk的fd指针指向的main_arena+96的地址的最后4为数字修改为c760，这里我们可以像unsortedbin中申请一个chunk（注意这里申请的chunk的大小一定要注意，必须大于tcachebins中的大小，使得程序能从unsortedbin中分配这个chunk）然后我们在修改我们申请的chunk的bk位得最后4个数字，使得其指向_IO_2_1_stdout_。如图</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-5f3c9e0d7bc34c2e88d0edb99daa1f79"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F44041401-85ee-4f8e-b1b9-d190513ea109%2FUntitled.png?table=block&amp;id=5f3c9e0d-7bc3-4c2e-88d0-edb99daa1f79&amp;t=5f3c9e0d-7bc3-4c2e-88d0-edb99daa1f79&amp;width=754&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-c75b737515ea42dc9556774a7783996f"> </div><div class="notion-text notion-block-e54195223271411d86d4fcd641ba17ca">这样就可以使_IO_2_1_stdout_的地址出现在我们程序中。我们在这里向程序连续两次申请chunk，就可以得到以_IO_2_1_stdout_为chunk地址的chunk，从而做的我们的修改的目的。</div><div class="notion-blank notion-block-83368b8aaf8248eab0c3f59a1f50ab7c"> </div><div class="notion-blank notion-block-0f099fdeed7b4fcfbd9f3533c24206f0"> </div><div class="notion-text notion-block-d1a01875f3cf4de2a76d4ecad3489f78">知识点讲完了，来简单说一下这道题的流程。</div><ol start="1" class="notion-list notion-list-numbered notion-block-e43cae97448a425da57b367ea9ebe401"><li>申请7个chunk，最终大小（带控制字段）分别为0x500,0x40,0x50,0x60,0x70,0x500,0x80</li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-70fdfa0a3a3f4df193a4f404240f82df"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:516px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fc2ac42c1-dad4-475a-83b5-b9319d9dab91%2FUntitled.png?table=block&amp;id=70fdfa0a-3a3f-4df1-93a4-f404240f82df&amp;t=70fdfa0a-3a3f-4df1-93a4-f404240f82df&amp;width=516&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ol start="1" class="notion-list notion-list-numbered notion-block-dbf2d7204a8645f0a4def3cc6713bc6a"><li>将第4个chunk（从0开始数）大小为0x70的chunk free掉，在申请出来用于修改第5个chunk的prev size为0x660（前面的chunk总和0x500+0x40+0x50+0x60+0x70=0x660），在将size的inuse标志位覆盖为0</li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-b78e39ea0f624cd5b2e7fdeda44eee6b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:589px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F6271ace9-0aa5-44a1-88fc-e7c462ae598b%2FUntitled.png?table=block&amp;id=b78e39ea-0f62-4cd5-b2e7-fdeda44eee6b&amp;t=b78e39ea-0f62-4cd5-b2e7-fdeda44eee6b&amp;width=589&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ol start="1" class="notion-list notion-list-numbered notion-block-04fd97af3867458f886612a29aea4dd6"><li>free掉第2个chunk，使其进入tcachebins。在依次free第0个chunk和第5个chunk，使其在unsortedbin中形成从chunk0到chunk5的大chunk</li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-44b40488ad27440d93f6beb90353b214"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Faba11110-d8cc-403b-975a-98035c9634ce%2FUntitled.png?table=block&amp;id=44b40488-ad27-440d-93f6-beb90353b214&amp;t=44b40488-ad27-440d-93f6-beb90353b214&amp;width=703.3333740234375&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ol start="1" class="notion-list notion-list-numbered notion-block-b87fd258dd844e6eb0cbf90e59c82312"><li>在申请相依大小的chunk（我这里为0x530注意控制字段的影响）从unsortedbin出来，使chunk2成为unsortedbin的头chunk。</li><ol class="notion-list notion-list-numbered notion-block-b87fd258dd844e6eb0cbf90e59c82312"><div class="notion-text notion-block-fdff9d6f8c2244f187aab53ae00a54e2">从而在chunk2的bk中有main_arena+96的地址，并在tcachebins中有链表指针</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-cab25ead17a84698ae1025b241dc0020"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F3546a197-6faa-40ad-868a-90fc42ae807a%2FUntitled.png?table=block&amp;id=cab25ead-17a8-4698-ae10-25b241dc0020&amp;t=cab25ead-17a8-4698-ae10-25b241dc0020&amp;width=838&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-8ede53ed9afd4bf2906cfd338a775e12"> </div></ol></ol><ol start="2" class="notion-list notion-list-numbered notion-block-5b50c3085a2a42f683e401730c012c39"><li>在将第4个chunk，free进tcachebins中，使得我们之后从unsortedbin中申请chunk修改地址后，chunk4的bk指针又在tcachebins中出现于第4步的情况。为libc泄露后修改hook做准备。</li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-05cbeddc154a46028f27aa5e9157bcea"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F45646f8d-d457-46d8-9396-d9cc3a0ac0a7%2FUntitled.png?table=block&amp;id=05cbeddc-154a-4602-8f27-aa5e9157bcea&amp;t=05cbeddc-154a-4602-8f27-aa5e9157bcea&amp;width=838&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ol start="1" class="notion-list notion-list-numbered notion-block-a13885487c3143be816032ea3b0c1bac"><li>申请相应的chunk大小（0xa0）,修改tcachebins中chunk2的bk指针的最后4个数字为<b>c760</b>，使其指向_IO_2_1_stdout_的地址。同时也让chunk4成为unsortedbin的头地址，出现于第4步的情况。</li></ol><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-7a55d95d81ce4fcfadae7d3f0d462f71"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F0bc90334-34ec-4d91-b15e-34b0c4481e92%2FUntitled.png?table=block&amp;id=7a55d95d-81ce-4fcf-adae-7d3f0d462f71&amp;t=7a55d95d-81ce-4fcf-adae-7d3f0d462f71&amp;width=790&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><ol start="1" class="notion-list notion-list-numbered notion-block-ab857c94893b4d2390e85f01a79c6e6f"><li>在连续申请两次大小为0x40的chunk（最终大小满足0x50），使得在第二次时程序将_IO_2_1_stdout_的地址当做chunk给我们使用。并修改。</li><ol class="notion-list notion-list-numbered notion-block-ab857c94893b4d2390e85f01a79c6e6f"><div class="notion-text notion-block-13b260a13c74476d89dfa5854388ab8c">在修改</div><ul class="notion-list notion-list-disc notion-block-1eae0d717a0f4dce826bbc232bc873da"><li>_IO_2_1_stdout_=0xfbad1800</li></ul><ul class="notion-list notion-list-disc notion-block-6246ae0297e5442ebe944835a92ae6d9"><li>_IO_2_1_stdout_+8=0</li></ul><ul class="notion-list notion-list-disc notion-block-37587a4dcbe248dc8d4e0e4b7b95d252"><li>_IO_2_1_stdout_+16=0</li></ul><ul class="notion-list notion-list-disc notion-block-55ce9318db094019816270c3bf4f5f9d"><li>_IO_2_1_stdout_+24=0</li></ul><ul class="notion-list notion-list-disc notion-block-e355fb25269346c691aae2ae7c348f13"><li>_IO_2_1_stdout_+32的最后两个数字为c8</li></ul><div class="notion-text notion-block-5e655ac68f9246c6bac81af6a2ead8e3">第一次申请</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1a8e58a24f96440093d44931b60a60d7"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fbde3cdab-02e3-46e5-a3b1-320c594f88af%2FUntitled.png?table=block&amp;id=1a8e58a2-4f96-4400-93d4-4931b60a60d7&amp;t=1a8e58a2-4f96-4400-93d4-4931b60a60d7&amp;width=802&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-4dd1419db0bf49aba8549e537efd4a7a">第二次申请，</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-887ad6f4c4044b45a237e460d32113c2"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fca396deb-b3b5-4cce-bfb1-7ef51b973381%2FUntitled.png?table=block&amp;id=887ad6f4-c404-4b45-a237-e460d32113c2&amp;t=887ad6f4-c404-4b45-a237-e460d32113c2&amp;width=892&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure></ol></ol><ol start="2" class="notion-list notion-list-numbered notion-block-9bfdeb25eae64c68acf92316a652ee10"><li>当程序执行完这个后没救会把从0x78b2103ec7c8到0x78b2103ec7e3的数据都打印出来。这里打印的前8个数据（0x78b2103eba00）这个与libc基地址的距离是固定的（0x3Eba00，这个最好根据程序来看）。这样我们就可以应该不使用puts等函数将libc的基地址打印出来。</li><ol class="notion-list notion-list-numbered notion-block-9bfdeb25eae64c68acf92316a652ee10"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-026e805346e34d2683ba313ebb6c4460"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fdf837aff-d481-4e94-82ac-29b72e3d4f87%2FUntitled.png?table=block&amp;id=026e8053-46e3-4d26-83ba-313ebb6c4460&amp;t=026e8053-46e3-4d26-83ba-313ebb6c4460&amp;width=892&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-a38644e43bf64fa7a718ba8f462eed37">这里我不知道为什么我的程序打印结束后就卡在这里了，后面直接不执行了，等我以后把这个流程的具体学会了在回来解释。</div></ol></ol><ol start="3" class="notion-list notion-list-numbered notion-block-f544e90b699d4b7dafa27cbfb2f94010"><li>后面的就很简单了，还记得chunk4这个吗，我们之前让他在tcachebins又在unsortedbin，形成double free。这样我们只要先从unsortedbin中把他申请出来，并修改bk指针为free_hook的地址，使得在tcachebins形成一个新的链表。</li></ol><ol start="4" class="notion-list notion-list-numbered notion-block-d242ac67fe8a4a0f8d07ab8eee8c3298"><li>然后在从tcachebins中申请两次使得free_hook的地址成为一个chunk供我们使用，在向其中注入one_gadget地址，在调用free函数，从而执行one_gadget拿到shell</li></ol><div class="notion-blank notion-block-d77516453b1e45a98d245c1263bc9bc3"> </div><div class="notion-text notion-block-589f8bf0f3b74b3db30b5ad4ca5cdefc">这里总感觉我的修改_IO_2_1_stdout_的内容从而泄露libc的过程又点问题，同时这个的原理也不清楚，等以后再找来学一学，重新整一下这个题。不过这里有管tcachebins和unsortedbin中同时出现一个chunk，从而修改bk指针的方法还是很奇妙的值得一学。</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[堆（随便写一写，当笔记用）]]></title>
            <link>https://tangly1024.com/article/c28dcdc3-869a-4a3a-a026-e74af539c139</link>
            <guid>https://tangly1024.com/article/c28dcdc3-869a-4a3a-a026-e74af539c139</guid>
            <pubDate>Tue, 30 Jul 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-c28dcdc3869a4a3aa026e74af539c139"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-ac47e3d8c0d846eeb581ce0ec8748b28">开始学习堆的知识，便整这个博客当笔记用用，将平时视频里看到的东西记录一下。</div><div class="notion-blank notion-block-fde78eeef74145f784678b6d8ae1dcf7"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-7be870be69db45eba87d995607690aa3" data-id="7be870be69db45eba87d995607690aa3"><span><div id="7be870be69db45eba87d995607690aa3" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7be870be69db45eba87d995607690aa3" title="arena"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>arena</b></span></span></h2><div class="notion-text notion-block-573e4a4444b04b4488faca38f89a2153">内存分配区，可以理解为堆管理器所持有的内存池</div><div class="notion-text notion-block-91b45933920145a9813cb4464e46ae04">操作系统 --&gt; 堆管理器 --&gt; 用户</div><div class="notion-text notion-block-c5f30e31be664c60ab3b14a0e15a44d8">物理内存 --&gt; arena --&gt; 可用内存</div><div class="notion-text notion-block-0a6fe59f3e5043d6a068a3267a3d2167">堆管理器与用户的内存交易发生于arena中，可以理解为堆管理器向操作系统批发来的有冗余的内存库存</div><div class="notion-blank notion-block-fdd26324cbf84807ba90a66791c9c121"> </div><div class="notion-text notion-block-a8a25e21bb474dcd9552ae7861f33fff">相当于使用操作系统有的是物理内存，堆管理器只在操作系统与用户之间，用来使用户利用堆的一个东西，</div><div class="notion-text notion-block-992f8ed8de1d480f97dbde2336ae302f">在用户使用堆管理器开始利用堆时，堆管理器便会将物理内存中的可用片段放入arena中，在收到堆管理器的所需大小，便将其中的物理内存转换为可用内存供用户使用。arena中的内存的大小是大于用户所需要的内存的。</div><div class="notion-blank notion-block-6988156c7fae4b579bc790a11f59904f"> </div><div class="notion-text notion-block-61d92929824c4b3c916d251b26d246e2">如果在C语言中使用malloc这个函数如：</div><div class="notion-text notion-block-a4434b8057dd4182b7b645933144a134">当执行完这行代码后堆管理器便会在arena中找到一块大小为0x100的区域作为分配给用户的堆的区域</div><div class="notion-text notion-block-f4101702bafb4b95a3ba9249b49675ad">同时我们所获得这个ptr是个指针，指向是通过malloc（）后得到的一块内存区域chunk的中间。</div><div class="notion-text notion-block-d145267dcaff48c2a8a72110b82c8ed7"><b>每次 malloc 申请得到的内存指针，其实指向 user data 的起始处</b></div><div class="notion-blank notion-block-9a257d8ea2644788897e709ce0af7136"> </div><div class="notion-blank notion-block-45a1e2f623b44d82a9cd77edf2e260a0"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-d041619a9649463f82f0414516f6f93b" data-id="d041619a9649463f82f0414516f6f93b"><span><div id="d041619a9649463f82f0414516f6f93b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d041619a9649463f82f0414516f6f93b" title="chunk"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>chunk</b></span></span></h2><div class="notion-text notion-block-d65347470e7d477fbf2c9dd78bba5ebe">用户申请内存的单位，也是堆管理器管理内存的基本单位</div><div class="notion-text notion-block-0c6aa5d898e74a96984fad022476feaf">malloc()返回的指针指向一个chunk的数据区域</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-144f2247438e43eb80eb268c18aa02a5"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F985d9354-dc68-4bf3-bbdb-a2f121507156%2FUntitled.png?table=block&amp;id=144f2247-438e-43eb-80eb-268c18aa02a5&amp;t=144f2247-438e-43eb-80eb-268c18aa02a5&amp;width=1363&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-93a0a0d95270434685c91fc1a7cc0d18"> </div><div class="notion-text notion-block-2715d0b249194f589592545e54b359c6">chunk相当于一段内存区域的状态，在不同的时候有不同的chunk，如下</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-98ab9f57c9524074849ac63e6cb63167"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F2faa66c5-b530-4692-9180-364e55db0b61%2FUntitled.png?table=block&amp;id=98ab9f57-c952-4074-849a-c63e6cb63167&amp;t=98ab9f57-c952-4074-849a-c63e6cb63167&amp;width=1267&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-331f76a26ed84ac9852add2a45d273a1"> </div><div class="notion-text notion-block-b53d8c294e824abfbccdd85a575c93b2">像在C语言中执行</div><div class="notion-text notion-block-4644b1c280f4458ba60c5ec777fbea24">完这行代码后对于malloc分配的0x100便是chunk，而此时的chunk状态便是malloc chunk，而再执行</div><div class="notion-text notion-block-4a5c2cdb55fd4e0988650d730a2e1764">将这段内存释放，那这段内存区域也就是chunk便会成为 free chunk的状态。这段内存区域并不会消失</div><div class="notion-blank notion-block-1d1006e5b84b4d71985022d5cb83e52e"> </div><div class="notion-text notion-block-7cd8c8db10c14d6da5d0f4913955631a">相当于用户在通过堆管理器获得一段内存空间作为堆，在使用完成之后，用free将其释放。</div><div class="notion-text notion-block-5b50d7e162ca47fe98057caa24cf2d69">这段内存区域，在malloc之后从原本的物理内存变为malloc chunk，以供使用，在free后并不会直接还原为物理内存，而是继续存放在堆管理器中以便下次使用，为了方便的存放，这段内存区域便会变为free chunk的状态存放在堆管理器中。（也是为了节约时间，内存还为物理内存需要进行系统调用）</div><div class="notion-blank notion-block-00149e73c7a44c39bbfc431ad826ede4"> </div><div class="notion-text notion-block-1f9a7574486f4570b96fc5bdf03e457b"><em>先来看看malloc chunk的结构</em></div><div class="notion-text notion-block-152476222acf4f549b9b82260d1f49d6">分为3个部分，prev siz，size和剩下的存放数据的地段</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-ca0ebf6d8e114522987019de33a65b4c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fa6d58baf-d5ed-4be2-abd9-48297fea4509%2FUntitled.png?table=block&amp;id=ca0ebf6d-8e11-4522-9870-19de33a65b4c&amp;t=ca0ebf6d-8e11-4522-9870-19de33a65b4c&amp;width=1050&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-38001233fbb247238502b4e4f6b98448"> </div><div class="notion-text notion-block-724c86bee4524fcabb1cd255fb8eeb18">在理论上size的最后3个位置应该都是，并且是固定的0，无论这个chunk怎么变，都应该是0，于是这3个位置便被利用起来，用分别存放AMP。</div><div class="notion-blank notion-block-3381be66488a4d558ef190cff70b9b08"> </div><div class="notion-blank notion-block-ab4482012e284919b145b0f665839f7b"> </div><div class="notion-text notion-block-de1653314832405ebd3133b14ecba46f"><em>在看看free chunk的结构</em></div><div class="notion-text notion-block-7c39919727d74358b00964564e35b97d">对于free chunk他就是之前那个malloc chunk在通过free函数后将其释放后的堆管理器，其构造与malloc chunk的差别在于在size与数据段中间多了fd和bk这部分。其他的相同（free chunk有很多种，这只是其中一种）</div><div class="notion-text notion-block-753d851b44304391ae283b50a333d908">先来看看在chunk中共有的<b>P</b>位置所存放的数据及其含义。</div><div class="notion-text notion-block-12a46f5b53b14c69a6f86fed973873ad">这里的p存放的是用来检测这一个chunk的上一个chunk的含义，所返回的数据。</div><div class="notion-text notion-block-9eae242d71044912bc7c5469113c8738">如果检测到这个chunk的上一个是一个malloc chunk和其他的数据，变回返回一个1，存放在这个位置，</div><div class="notion-text notion-block-171361e9f5d34ae5b2a27d1de921cc1f">如果检测到这个chunk的上一个是一个free chunk的话变回返回一格0，存放在这位置</div><div class="notion-text notion-block-d9e98cb6d09540268468aab0b556208b">而当这个p的值为0，便可以知道当前这个chunk以及上面的chunk都是free chunk，此时这两个chunk变回合并为同一个free chunk，将下面的chunk从管理器中去除，整体变为上一个chunk的数据段，上一个chunk中的size则扩大到上下两个chunk合并后的整个chunk的大小。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-97cc7ced49f54fcc9e7020c677fbe261"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Faf89de0e-21eb-4e81-8633-a2bb524fba9b%2FUntitled.png?table=block&amp;id=97cc7ced-49f5-4fcc-9e70-20c677fbe261&amp;t=97cc7ced-49f5-4fcc-9e70-20c677fbe261&amp;width=881&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-a0b7284a631b4c2dbbf2482250e29797"> </div><div class="notion-text notion-block-96578dbabe1e4506917a94523c3fb45d">free chunk出了这种结构之外还有两种另外的结构</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-7cc5a1ef8bb24237a9f11b104f93ad83"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fbb0ee182-d408-4399-a0e5-084211b19722%2FUntitled.png?table=block&amp;id=7cc5a1ef-8bb2-4237-a9f1-1b104f93ad83&amp;t=7cc5a1ef-8bb2-4237-a9f1-1b104f93ad83&amp;width=1119&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-05d218213d63420fb4408be12ee2728a"> </div><div class="notion-text notion-block-96064506299d4056a633311e9b6b3eb0">chunk在代码段的实现</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-5ca7a0941ce14c3a8695ec73398d7176"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F23e8314e-ad32-4717-8aeb-78fb039b690a%2FUntitled.png?table=block&amp;id=5ca7a094-1ce1-4c3a-8695-ec73398d7176&amp;t=5ca7a094-1ce1-4c3a-8695-ec73398d7176&amp;width=1415&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-95d27a26f5b04d71a3e99dce682664ac"> </div><div class="notion-text notion-block-8114b1fbfea54b50b109e44f358f2588">理论上来说所有的chunk的出现都需要这几行代码的经过产生相应的区域，但由于程序为了节约时间对于不同的时间与不同状态的chunk其结构并不相同，并不是全部都包含由这些结构。不同的chunk有不同的结构，在上文中有所显示。</div><div class="notion-blank notion-block-dc639ca1f12e4e60841bb8ac4a5b3c9f"> </div><div class="notion-text notion-block-429be5cca9a34b2f9a89afee9fdd5819"><em>在chunk中，其存储数据的方式和栈的存储方式相反，堆的存储方式为由高地址向低地址不断存储的图，但在堆的chunk中，其结构最上方prev size为最低的地址然后依次向下增大</em>，输入的数据在数据段中从低到高不断增大的地址存放</div><div class="notion-blank notion-block-ed07087ff8604a9780fbea243aa92fd1"> </div><div class="notion-text notion-block-b1a23a7543a54aacb3d3eea04d72c032">在前文中得到的ptr指针所指向的便是控制字段size往下的数据段的开头，方便数据的直接存放。</div><div class="notion-blank notion-block-c0655a4302fe41c18a770f0aab0a5fb6"> </div><div class="notion-text notion-block-c9a0383d9e2c4b778687851f53e5450c">在一个申请的有堆的程序中，在执行完malloc后的各各段的地址如下</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-7556078fd9064580996b42c7d68aec2a"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F767353cb-11e5-49ae-bf20-c7e35782f7b7%2FUntitled.png?table=block&amp;id=7556078f-d906-4580-996b-42c7d68aec2a&amp;t=7556078f-d906-4580-996b-42c7d68aec2a&amp;width=1048&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-bb1e9640ed264c678892f9b3c9ace154"> </div><div class="notion-text notion-block-2783f95b00b94bf9a71768f8ba7ea5f6">蓝色字体便是程序中的堆的所在地址和长度，其位置在data段的正上方，紧邻这data段中的的bss区（前提是其堆的大小不算太大）</div><div class="notion-blank notion-block-1f016a87b4ad4fe3b26ea1cf094fec0e"> </div><div class="notion-blank notion-block-e6bd0c45fd914d188649f9d82048ff0a"> </div><div class="notion-text notion-block-737e1027466144d7948ab6c3f51b9d43">在程序中如果我们申请了一块长度为0x100的堆，那当程序执行完malloc函数后我们所得到的chunk的大小并不就是0x100，一般是0x111，这多出来的0x11包括8字节的prev size和size这两个控制字段，已经一个在size的末尾的p（在上文中有介绍）。</div><div class="notion-blank notion-block-92797dceed6d40c5badd6216c4dbfb7e"> </div><div class="notion-text notion-block-63b027e7b25c417c8d53041a32c95053">因此指向堆的指针所指向的并不是chunk的开头，而是chunk中的数据段的开头</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-14684d98710d4396a2f2f85b80d45b4f"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:454px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fa3011b5b-145a-443c-b542-0ee0cf303f44%2FUntitled.png?table=block&amp;id=14684d98-710d-4396-a2f2-f85b80d45b4f&amp;t=14684d98-710d-4396-a2f2-f85b80d45b4f&amp;width=454&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4adc4587b80f461d9869793e1b757a80"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-5f4a87413dbd48ad8a3c0001610b4597" data-id="5f4a87413dbd48ad8a3c0001610b4597"><span><div id="5f4a87413dbd48ad8a3c0001610b4597" class="notion-header-anchor"></div><a class="notion-hash-link" href="#5f4a87413dbd48ad8a3c0001610b4597" title="prev size的复用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>prev size的复用</b></span></span></h2><div class="notion-text notion-block-a1bc520d8527425faf67a47a73f8747d">在chunk中的开头的第一个prev size的控制字节是用来存放这个chunk的上面一个free chunk的大小的，它有且只有这一个作用。在一个程序中如果一开始申请的是0x20的长度的堆，那程序中会分配相应大小的chunk用来使用，然后在使用完这个chunk后将其释放，这个chunk便回成为free chunk存放在堆管理器中，方便以后的使用。</div><div class="notion-blank notion-block-5b40ac1a83794c548cd6ec637c3e5ccd"> </div><div class="notion-text notion-block-78ade41dc71a40898cc47a118ce40dd9">在这之后如果我们在程序中再次申请一个堆，程序会先在已有的chunk中寻找有没有适合的free chunk，然后将这个free chunk变为能使用的chunk用于使用，如果此时我们向程序申请一个大小为0x28的长度的堆，似乎之前我们申请的那个堆长度不够不能再使用了。但实际上，在程序中所有的chunk是放在一起的，也正因此才回有prev size的使用。当程序发现现在我们需要的chunk的大小与之前那个已经有的chunk只差一个字段，刚好是prev size等一个控制字段的大小，然后当我们把之前申请的那个chunk从free chunk转化为malloc chunk后，后发现一个问题，此时下一个chunk的开头prev size没有用了，他的上面不是free chunk 然后他刚好在上一个chunk的数据段的下面，而此时的数据段刚好差这一个长度，因此程序会将他直接转化为上一个chunk的数据段，以满足其的使用。这边是prev size的复用。</div><div class="notion-blank notion-block-897884a3516d42469e5828bd0581cf9b"> </div><div class="notion-text notion-block-ed9106cbcb7a43a4882729741ef51f9f">简单来说便是，在程序中一开始申请了长度为x的堆，后来把他释放了，之后在申请一个长度为x到x+8的堆，程序会将之前申请的那个chunk再次使用，两次使用的chunk会是同一个chunk</div><div class="notion-blank notion-block-e23beccce0d0435aa055a20714e2a706"> </div><div class="notion-blank notion-block-7cb7b6bee3b146b993846725fa8644f1"> </div><div class="notion-text notion-block-5087c51151b444f4bc5aa70a05d2d62d"><b>物理链表</b></div><div class="notion-text notion-block-f0586b9062594c3a8a226eff7e38f64b">在chunk中第一个控制字段prev size用于存放上一个chunk的长度，再结合自身的位置便回，可以知道上一个chunk的初始位置，一个chunk知道上一个chunk的初始地址，构成物理链表</div><div class="notion-blank notion-block-166466b757a34c38a05ea6d9e311a6fb"> </div><div class="notion-text notion-block-45e61cb784df4960bc2edd6032a4431e"><b>bin中的逻辑链表</b></div><div class="notion-text notion-block-52271f9faf394b52b3dd5d7a1c4554b2">管理 arena 中空闲 chunk 的结构，以数组的形式存在，数组元素为相应大小的 chunk 链表的链表头，存在于 arena 的 malloc_state 中</div><div class="notion-blank notion-block-baecb0b6b4a14e12849747d4151c83df"> </div><div class="notion-text notion-block-ad1f370fd84745109bb379566a495fbb">bin的结构是一个数组，有一个又一个的指针构成，每一个指针都指向一个相应大小的free chunk的初始位置，在被指向的free chunk中有一个fd控制字段，这个控制字段也存放的是一个指针，执向的是与这个chunk大小相同的的chunk初始位置。在bin作为最开始的指针指向相应大小的chunk，fd在指向相同大小的chunk，这个便是逻辑链表，如图（释放的顺序的从下往上释放，最下面的那个fd段为0的chunk为第一个释放的chunk）</div><div class="notion-blank notion-block-8f3a314d949549458a62796f1103f0b6"> </div><div class="notion-text notion-block-968db9c71ede4d56a3001484f36ceabd">这个bin的地址中的指向是刚刚释放的chunk，如最下面的chunk在释放后，bin的指向就这是他，等着后面的chunk在次被释放后bin的指向便会改变为新的释放的chunk。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-79a0e02bc5a94539ba3690cf64858d03"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:693px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F92edb766-290f-417b-9e75-1cc081cf64ed%2FUntitled.png?table=block&amp;id=79a0e02b-c5a9-4539-ba36-90cf64858d03&amp;t=79a0e02b-c5a9-4539-ba36-90cf64858d03&amp;width=693&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-d28cdae6cad547ccb4a43fbc4aa63a85"> </div><div class="notion-text notion-block-a5584c7336904b5b8b4d3a3552eeb1ba">用指针的方式将相同大小的chunk连接起来，存放在bin中方便之后的寻找</div><div class="notion-blank notion-block-f922656beef344ad84b9b2e6a6f31abb"> </div><div class="notion-text notion-block-4a8b2671bd98419b8cb9095d95f957a0">在bin中还有一种双向链表，将相同的大小的的chunk互相链接起来，以便使用，其基本结构如下，通过两个bin指针与chunk中fd，bk的不断指向构成，其中在使用中，为依次使用，从靠近bin的顺序被依次调用。</div><div class="notion-blank notion-block-f55c694bb9b54494869b03416718aa26"> </div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d39725874d824903b8f4ee5e96d2d9ab"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:537px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fc7bd1034-cab7-43ac-86c6-3bd9e114171f%2FUntitled.png?table=block&amp;id=d3972587-4d82-4903-b8f4-ee5e96d2d9ab&amp;t=d3972587-4d82-4903-b8f4-ee5e96d2d9ab&amp;width=537&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-3e7de823a90149f287c5e4c5ec464d0c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F2e8ae998-5d6b-41c4-929d-729d47e81da0%2FUntitled.png?table=block&amp;id=3e7de823-a901-49f2-87c5-e4c5ec464d0c&amp;t=3e7de823-a901-49f2-87c5-e4c5ec464d0c&amp;width=1450&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-c3ce4d1c48584e4487e0d194a86122bc"> </div><div class="notion-text notion-block-9147df9c39604fc9b5585930f9f74440">LIFO指其中的chunk的调用和栈上的调用方式一样，先进先出。</div><div class="notion-text notion-block-df171a217eef4f11a3bb67981d7d5afa">管理的free chunk在64位的程序下位32位的程序的两倍的大小</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-ed79add49030407b98ba628f3588797c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F84c7766b-c336-4f3c-b411-96ac9cf590e4%2FUntitled.png?table=block&amp;id=ed79add4-9030-407b-98ba-628f3588797c&amp;t=ed79add4-9030-407b-98ba-628f3588797c&amp;width=1467&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-f76649c61b854be78ac07b27b1ddf07a"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fec8ea017-7581-4ecc-bfe3-80a494b96880%2FUntitled.png?table=block&amp;id=f76649c6-1b85-4be7-8ac0-7b27b1ddf07a&amp;t=f76649c6-1b85-4be7-8ac0-7b27b1ddf07a&amp;width=1019&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-92e27a97c68b4024b1984a565e50d12d"> </div><div class="notion-blank notion-block-6221ab7495f74d639f5284459733ba20"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-2045348158df45faaeebf9801ffc46de" data-id="2045348158df45faaeebf9801ffc46de"><span><div id="2045348158df45faaeebf9801ffc46de" class="notion-header-anchor"></div><a class="notion-hash-link" href="#2045348158df45faaeebf9801ffc46de" title="堆的再分配机制"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>堆的再分配机制</b></span></span></h2><div class="notion-text notion-block-c370ab3cfd2042a4af177b52f86be4c3">在程序中的有关与堆的分配机制中，在后期有关于新的堆的寻找的中会先去寻找在之前生成chunk得程度够不够当前的malloc所需的长度，只要在之前的malloc的有过长度长出当前需要的malloc的长度，并且之前的那个chunk已经被free了，那程序便会直接将之前的那个free chunk 在现在的malloc中将其转化为可有的chunk，如果之前的那个chunk的长度超过当前的chunk这需要的长度，程序依然会将这个free chunk转化为新的chunk，但是只会使用需要的长度，对于之前那个chunk里的多余的长度，则会在分配之后自动生成一个新的free chunk。prev size和size等控制字段会在其中自动填充形成一个新的free chunk。</div><div class="notion-blank notion-block-842f03aeb5ee401db8f5a40d296cb78d"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-00a06dffed554250a857e70056d1fe7a" data-id="00a06dffed554250a857e70056d1fe7a"><span><div id="00a06dffed554250a857e70056d1fe7a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#00a06dffed554250a857e70056d1fe7a" title="use after free"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>use after free</b></span></span></h2><div class="notion-text notion-block-5d2a83ac6a6d4317bbacae104c840dc6">使用一个低权限的指针，指向一块存放重要数据的地方，使得可以利用这个非法的指针，对所指向的重要数据进行修改。</div><div class="notion-blank notion-block-941d93cb91cd4ac1b9e0c442fdc627f7"> </div><div class="notion-text notion-block-aaf89fa7a3074e87b1e85f8810557e27">在很多情况下我们会使用<code class="notion-inline-code">char* ptr = malloc(0x100)</code>这个命令用于申请一个堆块，这样ptr便会返回一个指向chunk中数据区的指针，我们便可以通过这个指针向这个chunk的数据区中读入数据，当我们不在需要这个堆时，便可以使用<code class="notion-inline-code">free(ptr)</code>这个命令将我们刚刚申请这个堆块释放掉，但是此时有一个必须要注意的一点是，虽然此时之前的chunk已经被free掉了，但是ptr这个指针并没有被释放，它以然指向的是之前的那个chunk的数据段，虽然由于此时的free chunk，并不能被利用，但在后面如果我们再次申请一个长度小于或等于之前的那个堆的长度时，更具堆的再分配机制，程序会将之前的那个chunk从free的状态转化为能正常使用的状态，那么由于在之前分配的堆的指针并没有被我们清零，那个指针执向着之前的那个chunk 的数据区，在这里将之前那个free chunk转化为能用的chunk，由于ptr指向的位置不变，依然是这个chunk的数据区，故在这里prt这个指针也同时执向了这个新的堆的数据区，并拥有对其读写的功能。在有的题目中我们可能没有操作新的这个指针的能力但我们可以通过操作之前那个没有被清理的指针对当下这个对于这个指针进行修改。</div><div class="notion-blank notion-block-353d323cbf354e8ba8387e58eecd1786"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-39693b22b98d4075a95549b34387613a" data-id="39693b22b98d4075a95549b34387613a"><span><div id="39693b22b98d4075a95549b34387613a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#39693b22b98d4075a95549b34387613a" title="双重释放漏洞"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>双重释放漏洞</b></span></span></h2><div class="notion-blank notion-block-cafab803b5e14bf9be1b6a08ddb6b29f"> </div><div class="notion-text notion-block-77ccf2a2bab24cc182002b2a27463862">对同一个堆块进行两次释放，导致在再申请时，两个不同的指针指向了同一个堆块。</div><div class="notion-blank notion-block-5750b636864a4f89b9bd6f83572fbc21"> </div><div class="notion-text notion-block-8f1fc21c69fa469f828532e3732e7bb5">在一个程序中先申请了3个堆块，A·B·C，大小都为8，我们在使用之后将其free掉，但是在free的过程中时，由于这些堆块的大小为8，故在被free调后会被放入到fast bin中，在这里这些堆的排列方式与栈上数据的排列方式相反，先进先出，后进后出。我们在使用完A,B,C这中3个堆块后，先free（A），此时A这个堆块便会被放入fast bin中，然后在free（B），B这个堆块变会被放入A堆块的下方，然后再我们在free（A），虽然我们在之前已经free过了，但这里程序并不会报错而是继续执行下去，导致在fast bin中出现一下情况</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-5ee99169018b4f969c38bd042e8f0449"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fdda297f8-7499-43d0-9fd9-251e263e9f45%2FUntitled.png?table=block&amp;id=5ee99169-018b-4f96-9c38-bd042e8f0449&amp;t=5ee99169-018b-4f96-9c38-bd042e8f0449&amp;width=914&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-783f0f757a7549b3bda5cd51da88dfdd"> </div><div class="notion-text notion-block-1ccd260811664a698a4fdf49faf79f7d">在fast bin有两个A堆块（这里并不能直接对A堆块连续free两次，中间还是要加上一个其他堆块的），由之前的关于堆的分配，我们这里如果在向程序申请3个堆块并且大小相同的情况下，程序会直接从fast bin中分配出去，这里假设我们再次申请，D,E,F，3个大小都为8的堆块。根据fast bin中后进后出的顺序，程序会从上往下对fast bin在分配，于是问题便出现了，在fast bin中有两个A堆块，但是程序不知道，于是程序便会，将这段A地址进行两次分配。导致D和F分配的堆块都是之前的A的地址，这两个指针也同时指向这个地址，使得我们可以使用其中一个对宁外一个指针的内容进行修改，从而到达我们漏洞的使用。</div><div class="notion-blank notion-block-493fa57307044af6bf8315fb7b5115c0"> </div><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-da0c73933da847b0890bfb83757f2b71" data-id="da0c73933da847b0890bfb83757f2b71"><span><div id="da0c73933da847b0890bfb83757f2b71" class="notion-header-anchor"></div><a class="notion-hash-link" href="#da0c73933da847b0890bfb83757f2b71" title="使用这种方式攻击栈"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>使用这种方式攻击栈</b></span></span></h3><div class="notion-text notion-block-c3045b99afb24515abba34611c6c1d69">在之前的第二次对堆块的申请中，如果我们申请两次将fast bin下面的A和B申请掉，导致fast bin中还有一个A堆块，但是由于我们之前已经将A堆块申请为D的堆块，那么此时fast bin中的指针和D这个指针会同时指向原本的A的堆块的地址，而我们通过D指针对A进行修改时，会同时对fast bin指向的地址一起修改。</div><div class="notion-blank notion-block-b722ae7ffee941d08c64f92e8beca6b7"> </div><div class="notion-text notion-block-aa76b9932a36418389937b0ce6766caf">由于在fast bin中堆块的链接是通过其中的fd控制字段指向下一个堆块的起始地址从而实现链接的。</div><div class="notion-blank notion-block-f32d1ec60202486982dbebeed0dc561c"> </div><div class="notion-text notion-block-1bcd4ef9ab184a1d95c49e7639a661d0">这里虽然fast bin和D指向的是同一块地址区域，但是由于D指向的是一块能使用的chunk，而fast bin指向的是一块free chunk，这两者的区别就在于free chunk多了一个fd的控制字段，在fast bin中用于指向下一个free chunk的起始地址。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-c2cf73ad1f5546de880034ac92ad2ef3"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fa566a42e-4947-477c-8370-81495785a935%2FUntitled.png?table=block&amp;id=c2cf73ad-1f55-46de-8800-34ac92ad2ef3&amp;t=c2cf73ad-1f55-46de-8800-34ac92ad2ef3&amp;width=845&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-354c57bcf4934f4abc9d9ecf5ae3dddc"> </div><div class="notion-text notion-block-b55302018a5c41fd946422d83372bc58">但是在D中的chunk由于不是free chunk，没有fd字段，程序为了最大的利用率于是变会在将A堆块分配给D是将fd字段一同加入到数据段中，因此我们在通过D指针对A堆块进行修改时，最先输入的字节的内容在fast bin指向的A堆块中会自动被识别为fd的值，作为指向下一个free chunk的指针。这里D指针指向的和fast bin中的A堆块是同一个地址，故我们在使用D指针修改时能同时修给fast bin中的值。</div><div class="notion-blank notion-block-695f6993f3e745e1ae7b3d059181091c"> </div><div class="notion-text notion-block-be629eaa65824a848164d982ddc11c77">这里由于程序不会对我们输入fd进行检查，于是我们便可以对我们输入到A堆块的最开始的字节的数据做手脚，从而是fast bin中的链接的free chunk的值再多一个，而这多出来的便是我们自行输入修改的。</div><div class="notion-blank notion-block-1ed6bf00f509424db0ccc830de200f96"> </div><div class="notion-text notion-block-4bf1427c64a346ff9d60a5c2becb24d1">假设我们需要对栈上的某一块地址进行修改，我们便可以先使用D指针向A堆块输入<b>要修改的栈的地址的上两个字节的地址</b>，然后在fast bin中A堆块的便会将fd字段也修改成那个栈上的地址。导致程序误以为在fast bin中多了一个free chunk，然后当我们再向程序申请堆块时，如果申请的长度与A的大小相同，程序变回将fast bin中的A再次分配出去，然后我们再一次申请堆块时，由于fast bin中A堆块已经分配出去，而原本A堆块中fd字段指向的是栈上的地址，于是这一次对堆的申请，程序会将fast bin中最近是栈的地址空间当做可用的free chunk，从而分配出去。以供我们进行修改，但是由于这里程序依然是将栈上的地址作为堆块分配出去，然后fd这个字段指向的地址是堆块的开头地址，因此栈上的地址依然会有两个字节被程序认为是chunk的prev size和size字段，而不能使用，只有两个字节下面的地址才是数据段，才能被我们所修改。因此我们在对A堆块fd修改时，要输入的是要修改的栈上地址的上面两个字节的地址才能在后面malloc到栈上地址，修改时修改到我们需要的数据。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-c8358a15f77444a18c5eb0c5f032d9a5"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F48e586df-0664-484b-aa30-8b354847fcc6%2FUntitled.png?table=block&amp;id=c8358a15-f774-44a1-8c5e-b0c5f032d9a5&amp;t=c8358a15-f774-44a1-8c5e-b0c5f032d9a5&amp;width=955&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-a363c707ce3a4c489d591aad4a656870"> </div><div class="notion-text notion-block-4d434ac2ad6942a6aeb77c4925fecf55">大致的结构如上图，通过对A中的fd的修改，使得fast bin中能指向栈上地址，然后通过对fast bin中的堆的申请，从而申请到栈上的地址做为堆块用于使用，对这个堆块修改，从而间接修改栈上的内容。</div><div class="notion-blank notion-block-2abe8ca31a2649b4ba50807f48c68321"> </div><div class="notion-blank notion-block-e4a2825755de450cabf2701751e1787e"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-13cfacbf23bc4ba2a02523fa93529486" data-id="13cfacbf23bc4ba2a02523fa93529486"><span><div id="13cfacbf23bc4ba2a02523fa93529486" class="notion-header-anchor"></div><a class="notion-hash-link" href="#13cfacbf23bc4ba2a02523fa93529486" title="house_of_force"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>house_of_force</b></span></span></h2><div class="notion-text notion-block-dc4be00b92894f5ca59842b956e1b8e5">通过堆溢出，将top chunk的大小标记为整个地址空间。然后在通过malloc到我们需要修改的地址空间，再此malloc使程序将我们需要修改的地址空间当做chunk分配给我们，然后修改。</div><div class="notion-blank notion-block-14d147d4d169435ca62d9cac653bb05e"> </div><div class="notion-text notion-block-656382fd394d47b5a99bdb604e8b203a"><b>top chunk</b></div><ul class="notion-list notion-list-disc notion-block-f8ff4ad81a054ae8aa508c7d54862b54"><li><b>概念：</b>当一个chunk处于一个arena的最顶部(即最高内存地址处)的时候，就称之为top chunk。</li></ul><ul class="notion-list notion-list-disc notion-block-3071f8e8eaad41558e7391c22b33ac56"><li><b>作用：</b>该chunk并<b>不属于任何*</b><em>bin</em>，而是在系统当前的所有free chunk(无论那种bin)都无法满足用户请求的内存大小的时候，将此chunk当做一个应急消防员，分配给用户使用。</li></ul><ul class="notion-list notion-list-disc notion-block-5630cdac4e9d43e59480ec63536828c0"><li><b>分配的规则：</b>如果top chunk的大小比用户请求的大小要大的话，就将该top chunk分作两部分：1）用户请求的chunk；2）剩余的部分成为新的top chunk。否则，就需要扩展heap或分配新的heap了——在main arena中通过sbrk扩展heap，而在thread arena中通过mmap分配新的heap。</li></ul><div class="notion-blank notion-block-ea07da083b8b41b589d582345b0285be"> </div><div class="notion-text notion-block-7226b6d8eeaf4304b603b60d214cf75b">一般来说当我们在程序中malloc一个堆块后，程序分配给我们的chunk其上方就是top chunk的区域，其中包含的就是空闲状态的chunk，方便下次需要chunk时能快速调用。这两个chunk在程序中分配图如下：</div><div class="notion-text notion-block-091229bf2a724a58a0482d5074f05fa8">在chunk中数据的填入，与下图中的箭头方向相同，从下往上填入。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-dcd8e557c9cf4fa491cabcea86e3d392"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F28b36cb0-3815-46de-9699-da91abac1e47%2FUntitled.png?table=block&amp;id=dcd8e557-c9cf-4fa4-91ca-bcea86e3d392&amp;t=dcd8e557-c9cf-4fa4-91ca-bcea86e3d392&amp;width=729&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-d3d3ed28b8af4cf6ae0ca9f000f7ba81"> </div><div class="notion-text notion-block-c1d353f7d5c54c70aca7561a9e5b6276">如果在我们得到的这个chunk中有堆溢出漏洞的发生，那么我填入的数据便会一直向上填入，在填入的过程中便会将top chunk的原数据覆盖，由于在top chunk中不会对数据进行检查判断是否被篡改，因此当我们填入的数据将top chunk中的size值覆盖为程序整个地址空间大小（32位是4gb，64位是8gb）时，程序会认为整个地址空间都是top chunk，导致我们在下次malloc时，程序在top chunk中寻找是否满足大小时，由于top chunk的size已经被我们修改为程序的整个地址空间了，于是程序会认为整个地址空间都是能被分配的chunk，于是我们在第二次malloc时无论需要的chunk大小是多少程序都会在分配给我们。</div><div class="notion-blank notion-block-bf51754b137d4686a51833d06c3ab371"> </div><div class="notion-text notion-block-8e407ad4ef1b4fcda9878bbac001cce4">于是我们便可以直接从原本的top chunk的地址malloc一个新的chunk，并使这个新的chunk长度为从top chunk的起始地址到我们需要修改的栈上地址的起始空间的前两个字节的长度（在下一次malloc中需要两个字节作为prev size和size，使得我们需要修改的地方能直接成为我们chunk中的数据段，从而直接修改），使得程序将这一段空间作为chunk分配给我们（主要是为了下一次malloc时能直接将要修改的地址分配给我们使用不用将中间的数据区别覆盖·，这个起到一个垫脚石的作用），然后再malloc一段空间，使得程序将栈上的空间作为chunk提供给我们使用。，我们向这个chunk输入数据，从而修改栈上的数据到达目的。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-d45cfa61ea094c1ba0c52993ac59236b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F0d9c3cce-1913-45c2-8ba9-370d8181b2e3%2FUntitled.png?table=block&amp;id=d45cfa61-ea09-4c1b-a0c5-2993ac59236b&amp;t=d45cfa61-ea09-4c1b-a0c5-2993ac59236b&amp;width=1047&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-be2b62bd63cf469d8dba6984d825fe37"> </div><div class="notion-text notion-block-6db0570fea6243cb86e7edfbcc9e545b">如果我们要修改得时date段的数据，那便要malloc的长度将使一个负数(date段的数据在chunk的下方)，由于我们在之前的覆盖中已经将top chunk中的size的大小表为整个地址空间，于是我们在malloc一个负数时，程序会将top chunk的起始地址向下移动这个负数的长度。然后我们再malloc一个正数时，程序便会从我们刚刚移动过的top chunk的头地址可是分配一个相应大小的chunk以供使用。</div><div class="notion-blank notion-block-0dacac0d2d514e82b6609796c8a569b8"> </div><div class="notion-blank notion-block-9ef0863369b94850a113c8ba78156a62"> </div><div class="notion-text notion-block-dd61dc7477b64b9e87c4e6c88b1ce9e0">因此我们只在栈溢出后malloc一个负数，其大小就是从top chunk的起始地址到要修改的date段地址的下两个字节的距离的负数（两个字节作为下个chunk的前两个控制字段），然后再malloc一个正数的chunk，输入数据便可以达到我们的目的。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-a7a11575e5b64832a6a013c1574f11c8"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F4f6dd985-27ec-4e23-95bc-d51b20f4bc05%2FUntitled.png?table=block&amp;id=a7a11575-e5b6-4832-a6a0-13c1574f11c8&amp;t=a7a11575-e5b6-4832-a6a0-13c1574f11c8&amp;width=1193&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-74527f7babea4c7f97b19c37ae7dbdbb" data-id="74527f7babea4c7f97b19c37ae7dbdbb"><span><div id="74527f7babea4c7f97b19c37ae7dbdbb" class="notion-header-anchor"></div><a class="notion-hash-link" href="#74527f7babea4c7f97b19c37ae7dbdbb" title="有关于各个bin的chunk进入与分配结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>有关于各个bin的chunk进入与分配结构</b></span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-edea49fa3a6844da8a1e9c909fa7f02c" data-id="edea49fa3a6844da8a1e9c909fa7f02c"><span><div id="edea49fa3a6844da8a1e9c909fa7f02c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#edea49fa3a6844da8a1e9c909fa7f02c" title="tcachebins:"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><em>tcachebins</em>:</span></span></h3><div class="notion-text notion-block-7a3492aa2cfd46f597a00088a2196b74">先进后出，后进先出</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1c4a7455f30f4afcb3ad46bd93670a01"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fc66e2ed3-ff74-4567-9aa0-68165d174f0f%2FUntitled.png?table=block&amp;id=1c4a7455-f30f-4afc-b3ad-46bd93670a01&amp;t=1c4a7455-f30f-4afc-b3ad-46bd93670a01&amp;width=1022&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4f28b98aa233413081ec5a1100857adf"> </div><h4 class="notion-h notion-h3 notion-h-indent-2 notion-block-1711067e8b784d71a790acdb19068f88" data-id="1711067e8b784d71a790acdb19068f88"><span><div id="1711067e8b784d71a790acdb19068f88" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1711067e8b784d71a790acdb19068f88" title="分配的时候将从chunk4开始分配依次分配到chunk1。"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>分配的时候将从chunk4开始分配依次分配到chunk1。</b></span></span></h4><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-7656071125fa41f89d616636b98f99ac" data-id="7656071125fa41f89d616636b98f99ac"><span><div id="7656071125fa41f89d616636b98f99ac" class="notion-header-anchor"></div><a class="notion-hash-link" href="#7656071125fa41f89d616636b98f99ac" title="unsortedbin："><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><em>unsortedbin</em>：</span></span></h3><div class="notion-text notion-block-d288e4280c8647ac90c61389d8aea86c">先进先出，后进后出。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-c0c8b4ab5b534c50b1a5f26bdb21c78c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fd7fb83dd-19b1-4dfb-bcca-a7c5c3ad3728%2FUntitled.png?table=block&amp;id=c0c8b4ab-5b53-4c50-b1a5-f26bdb21c78c&amp;t=c0c8b4ab-5b53-4c50-b1a5-f26bdb21c78c&amp;width=1045&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-1cbd58b81eb2472c87c9f987cadba938"> </div><div class="notion-text notion-block-cffba5c8e8774c79a271a6c1d44aef11">分配的时候从chunk1开始依次分配到chunk4。（要注意这几个chunk如果大小相同，并且相临，那么进入到unsortedbin后会直接合并为一个大chunk，然后在要分配时直接切割这个大chunk）</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-6f87c43436ef47c7bdaa32adc82a5d42" data-id="6f87c43436ef47c7bdaa32adc82a5d42"><span><div id="6f87c43436ef47c7bdaa32adc82a5d42" class="notion-header-anchor"></div><a class="notion-hash-link" href="#6f87c43436ef47c7bdaa32adc82a5d42" title="📝 主旨内容"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📝 主旨内容</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-0d07ca8f6b5f420c90ac238ce01fbf0a" data-id="0d07ca8f6b5f420c90ac238ce01fbf0a"><span><div id="0d07ca8f6b5f420c90ac238ce01fbf0a" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0d07ca8f6b5f420c90ac238ce01fbf0a" title="观点1"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">观点1</span></span></h3><blockquote class="notion-quote notion-block-69b1e3518732407685686e9e6d68be4f"><div>引用的话语</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-91aeb03180864ce2a80c14b3f0154af0" data-id="91aeb03180864ce2a80c14b3f0154af0"><span><div id="91aeb03180864ce2a80c14b3f0154af0" class="notion-header-anchor"></div><a class="notion-hash-link" href="#91aeb03180864ce2a80c14b3f0154af0" title="观点2"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">观点2</span></span></h3><blockquote class="notion-quote notion-block-29a752bd8ba64d74a37a5fdbf4edb6d1"><div>引用的话语</div></blockquote><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-dc64e99974e7468dabc7f26c4faf4799" data-id="dc64e99974e7468dabc7f26c4faf4799"><span><div id="dc64e99974e7468dabc7f26c4faf4799" class="notion-header-anchor"></div><a class="notion-hash-link" href="#dc64e99974e7468dabc7f26c4faf4799" title="🤗 总结归纳"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🤗 总结归纳</span></span></h2><div class="notion-text notion-block-6062b89a76fb42fe806dcfe3482cb206">总结文章的内容</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-20b72bfc3c084c7c9f546b1c87868422" data-id="20b72bfc3c084c7c9f546b1c87868422"><span><div id="20b72bfc3c084c7c9f546b1c87868422" class="notion-header-anchor"></div><a class="notion-hash-link" href="#20b72bfc3c084c7c9f546b1c87868422" title="📎 参考文章"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📎 参考文章</span></span></h2><ul class="notion-list notion-list-disc notion-block-f2878d660df04333b515d54813a6c5a3"><li>一些引用</li></ul><ul class="notion-list notion-list-disc notion-block-777eb88c964c4125ac0f5a09f09f2d49"><li>引用文章</li></ul><div class="notion-blank notion-block-ae461c73f991464a9b90183fb7fb81dd"> </div><div class="notion-callout notion-gray_background_co notion-block-b97f1592a3654a25a837fdada84b47c8"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text">有关Notion安装或者使用上的问题，欢迎您在底部评论区留言，一起交流~</div></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[数组越界]]></title>
            <link>https://tangly1024.com/article/53a3a43c-bebf-4b80-8e20-7ee075133714</link>
            <guid>https://tangly1024.com/article/53a3a43c-bebf-4b80-8e20-7ee075133714</guid>
            <pubDate>Tue, 30 Jul 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-53a3a43cbebf4b808e207ee075133714"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-5bf1a3da6f7f41009d558e7093ec4be6">昨天在攻防世界刷题的时候，无意之间找到一道题，不算难，就是一道很基础的栈溢出的题目，不过这个栈溢出的方式在我之前做的题里边还没怎么遇见，今天把他全部整出来了，故写这篇博客记录一下这方法和这道题的wp</div><div class="notion-blank notion-block-317e283b7c6a44eeb57e98186db8127d"> </div><div class="notion-text notion-block-0f00ef00d0004f3fa0fd3d41dc77d50a">放一下题目的连接<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://adworld.xctf.org.cn/challenges/list">攻防世界 (xctf.org.cn)</a>，是这里面pwn的stack2题目</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-285a099ca415440c948783c6b138885b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F245e69f6-4cb3-4474-ae1a-ccefc33a6cbb%2FUntitled.png?table=block&amp;id=285a099c-a415-440c-9487-83c6b138885b&amp;t=285a099c-a415-440c-9487-83c6b138885b&amp;width=1079&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-32f3255e08a94f40896b5ee2eef24a9e"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-cf49a0e340d642ddbaae8ff35f73087b" data-id="cf49a0e340d642ddbaae8ff35f73087b"><span><div id="cf49a0e340d642ddbaae8ff35f73087b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#cf49a0e340d642ddbaae8ff35f73087b" title="知识点"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>知识点</b></span></span></h2><div class="notion-blank notion-block-0d208b0d5f544aa29d0229f8027f4ea1"> </div><div class="notion-text notion-block-657d4aa3fdf54a4fa45bba9340cfcc73">在这道题中用到的栈溢出的方法便是这篇博客的题目，<em>数组越界</em>，</div><div class="notion-blank notion-block-8c117de592784f9eae88ecd7e7f1215b"> </div><div class="notion-text notion-block-15500461bc27448fb58abf5e228bed83">我们知道在C语言之中有一种叫数组的东西，就像<code class="notion-inline-code">int a[9]=0</code>,这样的（字母[数字]）便叫数组，数组一般在定义的时候变会在栈上规划好一片空间，用于专门放数组内的数，一般来说，我们如果在调用数组的时候要对数组中的数进行我们需要的定义时，会可能使用如下的定义方式</div><div class="notion-text notion-block-cf2bbfdba4034c5fad486cc3d854b116">即对于数组的第几位和大小都由自己进行定义，这样的定义虽然很方便，但有一个巨大的问题在于在我们一开始的时候便对数组已经下好了定义，而程序在下定义时便已经将栈上的空间分配好了，而我们定义的数组也是只有固定的大小，就像在上面的代码中我们定义的数组是<code class="notion-inline-code">int a[10]=0</code>，那么便只有a[0]到a[9]的长度是在栈上用于存放这个数组的长度的，其他的栈空间，都有属于他们自己的命令与作用，</div><div class="notion-blank notion-block-4cd3ca4d02a44bfe8f6bfc567fb370f5"> </div><div class="notion-text notion-block-76e796e8ef3b4c339ba223f7012d89e4">但是，如果在程序中使用了如上的自定义数组的方式，由于C语言对我们有很大的信任，这样的定于在编译时是不会报错的，但如果我们在定义第几个数组i的这里超过了本来定义好的数组的长度，程序中没有对这个进行长度检查的方式，于是程序会直接就按你发送的长度在栈上找到相应的地方将你之后输入的内容存放进去。</div><div class="notion-blank notion-block-bcddb4d3fbda4c2e99b8815256f8bbe7"> </div><div class="notion-text notion-block-680055f20ede4d688396ccc049e97ebe">于此，数组越界的利用方式便出来了，当我们可以对数组的第几个数进行自定义时，程序并不会检查是否超过数组的长度，而是依然在栈上寻找输入的相应的地址将要存放的内容存放进去，但是我们知道在数组定义之初，栈上的空间便是以经分配好的了，出了数组相应的空间，栈上的其他空间都存放有相应的数据与命令，而数组越界让我们有了将栈上其他空间的数据改变的能力。</div><div class="notion-blank notion-block-b16ccb77a8cc4254b958724bbd6205c2"> </div><div class="notion-text notion-block-7923ca88e8d44aa082cf9c56168aaaeb">当数组越界发生时，只要我们知道发生越界的这个数组开头与我们需要改变的栈上的数据的地址的距离，便可以在一开始输入数组个数时将距离输入，程序变回自动将这个距离指向的地址找到，然后我们在输入要存放数据，程序变会将会那个地址里存放的内容改为我们输入的数据，但是栈上存放的很大一部分是我们在后面需要执行的数据，特别像<code class="notion-inline-code">ret</code>等命令执行完成之后，esp寄存器所指向的便是程序要执行的命令所存放的地址如下，程序在执行ret命令之前变回将下一步的命令的地址放在esp寄存器中</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-aa8f673b9be8467db3dec10f891545e6"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F0033b96c-1b79-4457-b344-97df4465d3b4%2FUntitled.png?table=block&amp;id=aa8f673b-9be8-467d-b3de-c10f891545e6&amp;t=aa8f673b-9be8-467d-b3de-c10f891545e6&amp;width=1174&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4e3a5b020cbd42d7bc8b3441bdfdefa7"> </div><div class="notion-text notion-block-81631f5f1142490bae1e20b63b2f97e8">因此，只要我们在知道程序中数组的开头地址，与在执行完这一段包含数组的命令的最后ret命令时，esp寄存器的值，算出差值，在程序执行的过程中将差值输入其中并将其内容改为需要执行的数值，便完成对程序执行的控制，达成栈溢出的目的。</div><div class="notion-text notion-block-fe7d405d93444b87bb8a338bc27e0432">
以上便是关于栈溢出中数组越界的基本知识点与利用，如果你看了还是不太明白，你可以选择在网上看看其他大佬写的，以上只是我个人的理解与想法，或许有不对的欢迎指出。</div><div class="notion-text notion-block-3198f04744aa40bea2f18701dd6a50bf">接下来便以一道题来做解。</div><div class="notion-blank notion-block-3fa3c9b15960477e912d483a6614b5cc"> </div><div class="notion-blank notion-block-116b926293a0437abe235ee9b210db5b"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-f69b316bd3b84de5bf339cd771c6f07f" data-id="f69b316bd3b84de5bf339cd771c6f07f"><span><div id="f69b316bd3b84de5bf339cd771c6f07f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#f69b316bd3b84de5bf339cd771c6f07f" title="stack2的wp"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title"><b>stack2的wp</b></span></span></h2><div class="notion-text notion-block-863465b4a34c439f8a82588cb57b661a">来吧，来看看这道关于数组越界的题怎么样，老规矩先checksec一下</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-371d095de48440238e10db92edab6269"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:551px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fab909e50-d14d-48f1-acb2-43513937dde0%2FUntitled.png?table=block&amp;id=371d095d-e484-4023-8e10-db92edab6269&amp;t=371d095d-e484-4023-8e10-db92edab6269&amp;width=551&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-4374f4eca66d48ebb4989e9ae4aff6ae"> </div><div class="notion-text notion-block-90bbcc656e8a46b895bdf7541b4eb9ed">还好pie没开，放到ida里看看</div><div class="notion-text notion-block-f8a80a11767b44cf94355b4ec8d0fe99">这道题的主函数在这里，但同时这道题是有后门函数存在的，</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-58ffe542cbf44501bc2c8ca906525626"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:420px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F2aad2a02-bdf9-4116-aa22-0720fb04ad2d%2FUntitled.png?table=block&amp;id=58ffe542-cbf4-4501-bc2c-8ca906525626&amp;t=58ffe542-cbf4-4501-bc2c-8ca906525626&amp;width=420&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-b077a906105946388126df6bd53f6b7a"> </div><div class="notion-text notion-block-c5a98653d160475fbbc62fb3571a0d6d">便不再需要自己去构造后门函数，还算方便，只要能将函数的执行劫持到这个后门函数的这里便能得到shell。这里仔细看会发现有一个问题，system函数执行的内容是/bin/bash而不是/bin/sh，如果这直接跳转到这里其实是不能拿到shell的，这里看了网上的说法，好像是因为这个题的出题人整错了，才出现的这个问题， 不过也能做，就是将程序的执行过程进行构造，将sh直接传入system函数中也能像执行system（/bin/sh）一样拿到shell。并且这个程序是32位的程序，不用使用寄存器进行传值，直接传就行，</div><div class="notion-blank notion-block-4223f1a02d0a431e938cc36344c4762a"> </div><div class="notion-blank notion-block-3b6b2b4b2a0d4ab9813c8f8574937b56"> </div><div class="notion-text notion-block-7db43194e9464332943b5be6e0729719">最开始做的时候便是将这个忘了，整成先是sh后是system，这里说明一下。</div><div class="notion-blank notion-block-1ea9ba94f4a24d6f8dc31a429ab7caa9"> </div><div class="notion-text notion-block-62f5f771399f44cb8dd71c2c729dbdc1">这道题的大致思路就是，在一开始时先输入我们要输入的数的个数，然后便开始依此输入我们要输的数，只后便会出现5个选项，1是将我们输入的数打印在屏幕上，2是增加一个新的数，4是直接将我们输入的数据的和打印在屏幕上，5是结束程序，还有一个3便是我们的漏洞所在。</div><div class="notion-blank notion-block-4c63546d3aec4be996bb3136f5cd32b7"> </div><div class="notion-text notion-block-e33facce0b164e3680bb45f6c4902691">这里如果进入3的选项，用于改变之前输入的数据，首先让我们输入我们要改变的数据的位置，既我们要改变的数据在之前输入的数据中排第几，然后便让我们输入改变后的数据，</div><div class="notion-blank notion-block-a204e2c69a6b4a859698ae60e4eca462"> </div><div class="notion-text notion-block-e2622a5aab574733b0a17978314348a0">这里看起来好像没有什么问题，但仔细看看会发现这里是要我们先输入要改变的数据在之前输入的数据中所排的位置然后在输入要改变的数据，这里有个巨大的问题在于程序并没有对我们输入的位置进行检测，而是完全信任我们输入的位置，因此理论上来说我们可以输入无限大的数据，程序都会为我们找到我们输入的大小在程序中相对最开始我们输入的数据的存放位置的偏移，然后再录入我的新数据。形成上文中的数组越界漏洞。</div><div class="notion-blank notion-block-112df8e00c8842c592583743f9502cfd"> </div><div class="notion-text notion-block-9b54114e47f84fdba9e9a37697e92fe7">因此在这里只要我们能找到在最开始我们输入的数据存放的最开始的地方，与之后程序ret要到的地方，计算这两个地方的偏移量，然后以及改变ret后要到的地方的地址为我们要执行的程序的地址，便可以形成shell。</div><div class="notion-text notion-block-fbc6e6b866b1472abd90d1b4b601103f">在修改后要执行的程序在前文中已有提及，便是</div><div class="notion-text notion-block-0dfaea48e1dd457f846a7a6b12cb651a">这两个数据都是很好拿倒的，现在的问题在于寻找最开始输入的数据的存放位置，与我们要改变的数据的位置。</div><div class="notion-blank notion-block-82467c8ed1904aa193f3abb1cf566157"> </div><div class="notion-text notion-block-ca06b060a3c1416a8db72ffc6e6e1aa4">0xffffd03c</div><div class="notion-blank notion-block-3d534903c6a9461fb2de8b929d0f2e68"> </div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-43dd09dfb7bb4edf881a06701cd6544b" data-id="43dd09dfb7bb4edf881a06701cd6544b"><span><div id="43dd09dfb7bb4edf881a06701cd6544b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#43dd09dfb7bb4edf881a06701cd6544b" title="📝 主旨内容"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📝 主旨内容</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-3102844fdbe64f9da18f170d9addba5c" data-id="3102844fdbe64f9da18f170d9addba5c"><span><div id="3102844fdbe64f9da18f170d9addba5c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#3102844fdbe64f9da18f170d9addba5c" title="观点1"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">观点1</span></span></h3><blockquote class="notion-quote notion-block-270ff3f064504966bd14f5775dafdb88"><div>引用的话语</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-e9b34db35670460fa5e5e31a76c0ac49" data-id="e9b34db35670460fa5e5e31a76c0ac49"><span><div id="e9b34db35670460fa5e5e31a76c0ac49" class="notion-header-anchor"></div><a class="notion-hash-link" href="#e9b34db35670460fa5e5e31a76c0ac49" title="观点2"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">观点2</span></span></h3><blockquote class="notion-quote notion-block-0f1c3d4ba7af464b8638da2fddfe48dc"><div>引用的话语</div></blockquote><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-ff2a964f87d04922a6ccf6660e0f5911" data-id="ff2a964f87d04922a6ccf6660e0f5911"><span><div id="ff2a964f87d04922a6ccf6660e0f5911" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ff2a964f87d04922a6ccf6660e0f5911" title="🤗 总结归纳"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🤗 总结归纳</span></span></h2><div class="notion-text notion-block-8664ac483c3b4ce98b0e9980a0d4d058">总结文章的内容</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-ddb09f9bc1ca437b8a231aefb46af50d" data-id="ddb09f9bc1ca437b8a231aefb46af50d"><span><div id="ddb09f9bc1ca437b8a231aefb46af50d" class="notion-header-anchor"></div><a class="notion-hash-link" href="#ddb09f9bc1ca437b8a231aefb46af50d" title="📎 参考文章"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📎 参考文章</span></span></h2><ul class="notion-list notion-list-disc notion-block-a5084281087d494982691149a783de99"><li>一些引用</li></ul><ul class="notion-list notion-list-disc notion-block-72941fb4e3e2416bad7b54df03908d62"><li>引用文章</li></ul><div class="notion-blank notion-block-d4a3bf49b3aa4126842f78cc5bc2710e"> </div><div class="notion-callout notion-gray_background_co notion-block-e5dda60dc57a41e7ad90c7e7a3749a23"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text">有关Notion安装或者使用上的问题，欢迎您在底部评论区留言，一起交流~</div></div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[博客之痛]]></title>
            <link>https://tangly1024.com/article/c27354d4-fc7a-460d-8992-5453ac19e011</link>
            <guid>https://tangly1024.com/article/c27354d4-fc7a-460d-8992-5453ac19e011</guid>
            <pubDate>Tue, 30 Jul 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-c27354d4fc7a460d89925453ac19e011"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><div class="notion-text notion-block-04b0dd7b51ac41aebb20c1991f7907cc">历时三天终于把这个破博客给搭出来了</div><div class="notion-text notion-block-f3561f7edd0b4bf191e226a099725178">地址：</div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-5d973142dd2c4c61a5724c775910d356" href="https://2023478.github.io/"><div><div class="notion-bookmark-title">纲的blog</div><div class="notion-bookmark-description">之前在堆的基础解法那里简单说了一下有关于堆的利用，从这里开始新起一章，这章主要讲一讲有关于house of的各各系列的手法与对应的libc版本。</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/http%3A%2F%2F7xkj1z.com1.z0.glb.clouddn.com%2Fhead.jpg?table=block&amp;id=5d973142-dd2c-4c61-a572-4c775910d356&amp;t=5d973142-dd2c-4c61-a572-4c775910d356" alt="纲的blog" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://2023478.github.io/</div></div></div></a></div><div class="notion-row notion-block-61b4e1df3c6b459aaad52e41aab01aae"><div class="notion-column notion-block-44f5be094013485c9639df99ed816c13" style="width:calc((100% - (1 * min(32px, 4vw))) * 0.5)"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-cbde61c2adfd4b4cafd2fb563a72678b"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:336px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F59d8071d-74b7-458d-bc9f-0243f5cb2844%2Fimage-20240327213022031-17115462250291.png?table=block&amp;id=cbde61c2-adfd-4b4c-afd2-fb563a72678b&amp;t=cbde61c2-adfd-4b4c-afd2-fb563a72678b&amp;width=336&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure></div><div class="notion-spacer"></div><div class="notion-column notion-block-12bad5dd7f6b4645ab2e9f5207a78da7" style="width:calc((100% - (1 * min(32px, 4vw))) * 0.5)"><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-60f4644cf3c64697a01c3668f11c6dbc"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:163px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fe6d55e01-7c6d-4d1e-a6ae-5c0395768510%2Fimage-20240327213044821.png?table=block&amp;id=60f4644c-f3c6-4697-a01c-3668f11c6dbc&amp;t=60f4644c-f3c6-4697-a01c-3668f11c6dbc&amp;width=163&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure></div><div class="notion-spacer"></div></div><div class="notion-blank notion-block-642f5800930240158850ffa3c743a67c"> </div><div class="notion-blank notion-block-21d1c5f7a4774ab5b77223e3d1383b1a"> </div><div class="notion-blank notion-block-3f90a9868f594f8d95cfcca73a8f40fd"> </div><div class="notion-text notion-block-7dd7e1baf405467c9b2bdb01da3872bf">已算是把之前最开始进实验室叫搭博客，用了其他人的服务器直接整了一个从而混过去的债给还上了</div><div class="notion-text notion-block-ca93330173f64153b75f1c90d4bf1298">不过这博客搭起来是真的麻烦，前前后后花了3天的晚上才整好（白天上课加玩去了）</div><div class="notion-text notion-block-d0b8363061794b48bedda686ed0df138">这次整的博客用的主体是hexo+github整的一个静态博客，不得不说这个静态博客确实不如之前找同学整的那个动态的好，发文章也麻烦，问题还一大推，是真的烦。所幸最终还是把大概的给整出来了，也还算可以。</div><div class="notion-text notion-block-5d5f5fdfd6554066980f60ccb8f95ca6">就用这遍文章将遇到大概写一下吧，当然主要还是将那些大佬的文章记录一下。</div><div class="notion-blank notion-block-2cb92ad4a46244dd8fd189c54be41fdc"> </div><div class="notion-text notion-block-c666f4d899b949af8c11bc821920c0b6"><em>2.关于图片没有办法显示的</em></div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-d38e057cbe254a67bb3211cb34ca1e5c" href="https://zhuanlan.zhihu.com/p/265077468"><div><div class="notion-bookmark-title">zhuanlan.zhihu.com</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fzhuanlan.zhihu.com%2Ffavicon.ico?table=block&amp;id=d38e057c-be25-4a67-bb32-11cb34ca1e5c&amp;t=d38e057c-be25-4a67-bb32-11cb34ca1e5c" alt="zhuanlan.zhihu.com" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://zhuanlan.zhihu.com/p/265077468</div></div></div></a></div><div class="notion-text notion-block-1561f9236dbc49969ed3cc5e1039e725">这个是大佬，我用这个办法一下就成</div><div class="notion-blank notion-block-0f0f449541ec41549a0411db37897f18"> </div><div class="notion-blank notion-block-d9e0832cefb74d4480e9665625e10ef7"> </div><div class="notion-text notion-block-e41f8473637d415fa0c93152ef13b985"><em>3.关于换主题的</em></div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-67dcc4d601eb4ebcad3953fa029a3cda" href="https://zhuanlan.zhihu.com/p/385525053"><div><div class="notion-bookmark-title">zhuanlan.zhihu.com</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fzhuanlan.zhihu.com%2Ffavicon.ico?table=block&amp;id=67dcc4d6-01eb-4ebc-ad39-53fa029a3cda&amp;t=67dcc4d6-01eb-4ebc-ad39-53fa029a3cda" alt="zhuanlan.zhihu.com" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://zhuanlan.zhihu.com/p/385525053</div></div></div></a></div><div class="notion-text notion-block-53b4c1649ecc48d5b82da959de09133c">这个也是一遍好文，我当时想直接通过，命令下，不过不成，就直接下压缩包，解压le</div><div class="notion-blank notion-block-576fa5a5594f4f2aa39d0732b8f73b2d"> </div><div class="notion-blank notion-block-72929f0ccd414a09b989ac82243afd01"> </div><div class="notion-text notion-block-758efe66a45049f28c764e08a6a1210b"><em>4.关于搭博客的基本</em></div><div class="notion-text notion-block-174e4deff63f4bba893bd6bb33b329fb">这个有很多了就不多写，放几篇好一点的</div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-347a66dff265466890bd22c3c957f98e" href="https://cloud.tencent.com/developer/article/1520557"><div><div class="notion-bookmark-title">这可能是迄今为止最全的hexo博客搭建教程-腾讯云开发者社区-腾讯云</div><div class="notion-bookmark-description">这是阮一峰在博客中写到的关于 Blog 的想法，而这里的第三阶段的实现就是利用 GitHub Pages 搭建博客。</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fcloud.tencent.com%2Ffavicon.ico?table=block&amp;id=347a66df-f265-4668-90bd-22c3c957f98e&amp;t=347a66df-f265-4668-90bd-22c3c957f98e" alt="这可能是迄今为止最全的hexo博客搭建教程-腾讯云开发者社区-腾讯云" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://cloud.tencent.com/developer/article/1520557</div></div></div><div class="notion-bookmark-image"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fcloudcache.tencentcs.com%2Fopen_proj%2Fproj_qcloud_v2%2Fgateway%2Fshareicons%2Fcloud.png?table=block&amp;id=347a66df-f265-4668-90bd-22c3c957f98e&amp;t=347a66df-f265-4668-90bd-22c3c957f98e" alt="这可能是迄今为止最全的hexo博客搭建教程-腾讯云开发者社区-腾讯云" loading="lazy" decoding="async"/></div></a></div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-b319bcb80f9e42938d80b230f70a43a6" href="https://zhuanlan.zhihu.com/p/60578464"><div><div class="notion-bookmark-title">zhuanlan.zhihu.com</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fzhuanlan.zhihu.com%2Ffavicon.ico?table=block&amp;id=b319bcb8-0f9e-4293-8d80-b230f70a43a6&amp;t=b319bcb8-0f9e-4293-8d80-b230f70a43a6" alt="zhuanlan.zhihu.com" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://zhuanlan.zhihu.com/p/60578464</div></div></div></a></div><div class="notion-blank notion-block-682196e1cb02484e9251b7b36c210603"> </div><div class="notion-blank notion-block-f8a09605e5a3487ba50e6dba536ef794"> </div><div class="notion-text notion-block-73aaaba1b89e4fe294d45b5ef0f74acf"><em>5.关于第一次无法上传到github</em></div><div class="notion-text notion-block-d600dde8f3c9440f98e87a047b3b24a6">这个真的是个大麻烦，当时怎么整都没有传上去，最后在有篇文章的评论里找到（真的离谱）</div><div class="notion-row"><a target="_blank" rel="noopener noreferrer" class="notion-bookmark notion-block-3cc845108da747ac9b920644fbff0837" href="https://zhuanlan.zhihu.com/p/60578464"><div><div class="notion-bookmark-title">zhuanlan.zhihu.com</div><div class="notion-bookmark-link"><div class="notion-bookmark-link-icon"><img src="https://www.notion.so/image/https%3A%2F%2Fzhuanlan.zhihu.com%2Ffavicon.ico?table=block&amp;id=3cc84510-8da7-47ac-9b92-0644fbff0837&amp;t=3cc84510-8da7-47ac-9b92-0644fbff0837" alt="zhuanlan.zhihu.com" loading="lazy" decoding="async"/></div><div class="notion-bookmark-link-text">https://zhuanlan.zhihu.com/p/60578464</div></div></div></a></div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-35be50dcf06640cdb696ce04072ae19e"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2F70373bba-8421-4e76-ae77-bae760c9000b%2FUntitled.png?table=block&amp;id=35be50dc-f066-40cd-b696-ce04072ae19e&amp;t=35be50dc-f066-40cd-b696-ce04072ae19e&amp;width=1107&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-0c1448d8df0344439e4e4526d422dd4c"> </div><div class="notion-blank notion-block-838a41be1d7b46bf8785f5659d8975f7"> </div><div class="notion-text notion-block-1fb6c52b2b9749ef966b5eb1844cfcef">好了这篇文章到这里差不多就结束了，如果以后再遇到问题，就在更这篇文章，</div><div class="notion-text notion-block-452b526353dc438e91cdd7319fa3110a">不过我的博客好像有点简陋，ε=(´ο｀*)))唉，先不管，等以后有时间再慢慢整，</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-167c8e4f384a4a04acc349e925ad3ff8"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:65px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Fda515f5f-b436-4f3c-a437-eddf07ccd715%2FUntitled.png?table=block&amp;id=167c8e4f-384a-4a04-acc3-49e925ad3ff8&amp;t=167c8e4f-384a-4a04-acc3-49e925ad3ff8&amp;width=65&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-8b9825c054e54621ad38196bfd75bf30">痛，太痛了</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-a4219de6cb4344dc9fae86f421e34659"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:640px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Ffe8ecdad-1d45-45a0-ac06-d6be39edfbff%2FUntitled.png?table=block&amp;id=a4219de6-cb43-44dc-9fae-86f421e34659&amp;t=a4219de6-cb43-44dc-9fae-86f421e34659&amp;width=640&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-acb69cdbd328462eb464fe3395e77784"> </div><div class="notion-blank notion-block-bbe8058d721e4677b2f62f818d097195"> </div><div class="notion-text notion-block-9274220371814849972716de426eb52c">好家伙，刚刚准备将这篇文章上传，然后准备润，就给我来了个大的，痛，痛，痛</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-823fadb376ed4223ade75afb662c70fe"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Feea2be9b-1ef6-45c8-9f04-468c4ed56ffd%2FUntitled.png?table=block&amp;id=823fadb3-76ed-4223-ade7-5afb662c70fe&amp;t=823fadb3-76ed-4223-ade7-5afb662c70fe&amp;width=866&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-blank notion-block-47f3b0a05be94954ab928d1dc33ce7db"> </div><div class="notion-text notion-block-9a04e5cbe6de44fca007617991edafc6">行吧，在将这个问题解决一下，像这种一看就是在文章的开头写基本信息那出问题了，一般不是空格，就是英文符号整成中文的了，改吧，真的麻烦。所以关于这些空格和英文符号得好好整。啊！啊！第二次才改好。痛，痛，痛。</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-98786a035a9d4951954307cd3e33e95c"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:690px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2Ff2f53f7d-cda0-4a19-835b-0b91cf27394e%2Ff2a848f2-d499-4381-a608-e3553fdfe34a%2FUntitled.png?table=block&amp;id=98786a03-5a9d-4951-9543-07cd3e33e95c&amp;t=98786a03-5a9d-4951-9543-07cd3e33e95c&amp;width=690&amp;cache=v2" alt="notion image" loading="lazy" decoding="async"/></div></figure><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-b87625d16cd1446ab9381544cc5065b7" data-id="b87625d16cd1446ab9381544cc5065b7"><span><div id="b87625d16cd1446ab9381544cc5065b7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b87625d16cd1446ab9381544cc5065b7" title="📝 主旨内容"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📝 主旨内容</span></span></h2><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-8d2b73346c364a4893f95274c846a1b5" data-id="8d2b73346c364a4893f95274c846a1b5"><span><div id="8d2b73346c364a4893f95274c846a1b5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#8d2b73346c364a4893f95274c846a1b5" title="观点1"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">观点1</span></span></h3><blockquote class="notion-quote notion-block-3b8da388386d4c66b4f998c714d20af7"><div>引用的话语</div></blockquote><h3 class="notion-h notion-h2 notion-h-indent-1 notion-block-d2c1d51a92a54062a4cc901088977914" data-id="d2c1d51a92a54062a4cc901088977914"><span><div id="d2c1d51a92a54062a4cc901088977914" class="notion-header-anchor"></div><a class="notion-hash-link" href="#d2c1d51a92a54062a4cc901088977914" title="观点2"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">观点2</span></span></h3><blockquote class="notion-quote notion-block-8b60d2ecccf440e9b20d9fd2368f49e1"><div>引用的话语</div></blockquote><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-b867ed7b902d4078a34f127cdfb635bd" data-id="b867ed7b902d4078a34f127cdfb635bd"><span><div id="b867ed7b902d4078a34f127cdfb635bd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#b867ed7b902d4078a34f127cdfb635bd" title="🤗 总结归纳"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">🤗 总结归纳</span></span></h2><div class="notion-text notion-block-719ad87d0d06449989cc286b21de4c58">总结文章的内容</div><h2 class="notion-h notion-h1 notion-h-indent-0 notion-block-0eeb272e05834dd0928703fb9c9058c2" data-id="0eeb272e05834dd0928703fb9c9058c2"><span><div id="0eeb272e05834dd0928703fb9c9058c2" class="notion-header-anchor"></div><a class="notion-hash-link" href="#0eeb272e05834dd0928703fb9c9058c2" title="📎 参考文章"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">📎 参考文章</span></span></h2><ul class="notion-list notion-list-disc notion-block-13d7f2e0cc6240b58f4db16cae77c750"><li>一些引用</li></ul><ul class="notion-list notion-list-disc notion-block-28cff013b7a14e309ca87166907153f7"><li>引用文章</li></ul><div class="notion-blank notion-block-431edcd46c684278bb6d2c45790fb3b9"> </div><div class="notion-callout notion-gray_background_co notion-block-3b6683d62ef348deb6f5c4f4fdb84b97"><div class="notion-page-icon-inline notion-page-icon-span"><span class="notion-page-icon" role="img" aria-label="💡">💡</span></div><div class="notion-callout-text">有关Notion安装或者使用上的问题，欢迎您在底部评论区留言，一起交流~</div></div><div class="notion-blank notion-block-2e2912012b2c4dd0a807cb7c832c4e75"> </div></main></div>]]></content:encoded>
        </item>
    </channel>
</rss>