heapoverflow [PWN]

Overwrite Function Pointer of Chunk challenge

Chall

Let`s read source code of Program

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


/*
struct Page {
   long long int function_address;
   char  page_content[0x100];
}; 

# -> first thing

typedef int func(char *);

struct Page * page[2];

*/

int mysterious_function(ch){
	system(ch);
	return 0;
}

int print_page(ch){
	write(1,ch,0x88);
	return 0;
}

int show_page(){
	puts("index:");
	int index= read_int();
	if (index != 0 && index!=1)
		return 0;

	func* f=(func*)page[index]->function_address;
	f(page[index]->page_content);
	return 0;
}

int renew_page(){
	puts("index:");
	int index = read_int();
	if (index != 0 && index!=1)
		return 0;
	page[index]=(struct Page*)malloc(0x88);
	page[index]->function_address=&print_page;
}

int edit_page(){
	puts("index:");
	int index = read_int();
	if (index != 0 && index!=1)
		return 0;
	puts("Please fill the page with data:");
	read(0,page[index]->page_content,0x100);
}

void menu(){
	puts("1- Get empty page");
	puts("2- Write to the page");
	puts("3- Show the page");
	puts("4- Exit");
	write(1,"> ",2);
}

int read_int(){
	char ch[10];
	int a;
	read(0,ch,8);
	a = atoi(ch);
	return a;
}


int main(){
	setvbuf(stderr, NULL, _IONBF, 0);
	setvbuf(stdout, NULL, _IONBF, 0);
	int choice;
	while (1){
		menu();
		choice = read_int();
		switch(choice){
			case 1: renew_page(); break;
			case 2: edit_page();  break;
			case 3: show_page();  break;
			case 4: exit(0);
			default: break;
		}
	}

	return 0;
}

//gcc -o main task.c -no-pie

now the first thing is create struct for page have two variables function_address and page_content now the first variable for pointer to function example pointing to print_page() to print data from the page or mysterious_function() to execute commands in system now he create function pointer func(char *) to call print_page() or mysterious_function() now show_page() function its use to call function_address and print or execute data in page_content variable

func* f=(func*)page[index]->function_address;
f(page[index]->page_content);

the first line call the address of the function of page which is saved in function_address variable

and the second line is argument for function_address

example

function_address point to print_page()

and page_content have string "Hello World!"

will when you call show_page() the show_page() function will call the address have saved in function_address and use page_content as argument to the address of function saved in function_address

then will print the data have been stored in page_content like this

print_page(page_content), now if function_address point to mysterious_function() will call mysterious_function() and pass page_content as argument and will execute the command they saved in argument like this mysterious_function(page_content)

now renew_page() function

int renew_page(){
	puts("index:");
	int index = read_int();
	if (index != 0 && index!=1)
		return 0;
	page[index]=(struct Page*)malloc(0x88);
	page[index]->function_address=&print_page;
}

it create two page the page number 0 and the page number 1 if you enter index other this will the function is exit

It creates a chunk of size 0x88

and make the function_address of page point to print_page() function

now the last function edit_page()

int edit_page(){
	puts("index:");
	int index = read_int();
	if (index != 0 && index!=1)
		return 0;
	puts("Please fill the page with data:");
	read(0,page[index]->page_content,0x100);
}

now its used to edit page you created from renew_page() function the bug here is gets 0x100 of data and the size of chunk created by renew_page() is 0x88

that make me can add to data to the second chunk that make overflow

now let`s create two page and check it from heap

now this two chunks we created and this function_address of two chunks point to print_page() function

Idea of attack

we need to change the function_address pointer from print_page() to mysterious_function() function to get shell

how ?

we use chunk number 0 to send padding to the size of chunk and put 0x91 the real size and make prev_size equal to 0x0 to Avoid problems and change the address of print_page() to mysterious_function() and when change the function_address pointer from address of print_page() to address of mysterious_function() enter "/bin/sh" as data to page_content variable and call show_page() function to execute mysterious_function() function

let`s create script

run it

now we changed function_address pointer from address of print_page() to address of mysterious_function() successfully let`s call show_page()

🎉

thank you for reading my writeup.

Last updated