#include <stdio.h>#include <string.h>#include <stdlib.h>/*struct Page { long long int function_address; char page_content[0x100];}; # -> first thingtypedef int func(char *);struct Page * page[2];*/intmysterious_function(ch){system(ch);return0;}intprint_page(ch){write(1,ch,0x88);return0;}intshow_page(){puts("index:");int index=read_int();if(index !=0&& index!=1)return0; func* f=(func*)page[index]->function_address;f(page[index]->page_content);return0;}intrenew_page(){puts("index:");int index =read_int();if(index !=0&& index!=1)return0;page[index]=(struct Page*)malloc(0x88);page[index]->function_address=&print_page;}intedit_page(){puts("index:");int index =read_int();if(index !=0&& index!=1)return0;puts("Please fill the page with data:");read(0,page[index]->page_content,0x100);}voidmenu(){puts("1- Get empty page");puts("2- Write to the page");puts("3- Show the page");puts("4- Exit");write(1,"> ",2);}intread_int(){charch[10];int a;read(0,ch,8); a =atoi(ch);return a;}intmain(){setvbuf(stderr,NULL, _IONBF,0);setvbuf(stdout,NULL, _IONBF,0);int choice;while(1){menu(); choice =read_int();switch(choice){case1:renew_page();break;case2:edit_page();break;case3:show_page();break;case4:exit(0);default:break;}}return0;}//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
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 argumentlike this mysterious_function(page_content)
now renew_page()function
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()
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()
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);
}