easyctf-2017/heaps_of_knowledge/heaps_of_knowledge.c
2017-03-15 20:54:31 -05:00

208 lines
5.7 KiB
C

//gcc -m32 -std=c99 -Wall -fno-stack-protector heaps_of_knowledge.c -o heaps_of_knowledge
#define _GNU_SOURCE
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
struct chapter {
struct chapter *prev_chapter;
struct chapter *next_chapter;
char *title;
char *content;
void (* print_ch)(int, struct chapter *);
};
typedef struct chapter chapter;
typedef struct book {
char *title;
int num_chapters;
chapter *first_chapter;
} book;
book *create_book(char *title) {
book *b = malloc(sizeof(book));
b->title = strdup(title);
b->first_chapter = NULL;
b->num_chapters = 0;
return b;
}
void print_chapter(int num, chapter *ch) {
printf("---------------\n");
printf("Chapter %i: %s", num, ch->title);
printf("---------------\n");
printf("%s\n", ch->content);
}
int success = 0x1337;
void validate(int ans) {
if ((ans ^ 0xDEADBEEF) == 0xDEADBEAF) {
success = 0x13371337;
}
}
void give_flag() {
if (success==0x13371337) {
FILE *f = fopen("flag.txt", "r");
gid_t gid = getegid();
setresgid(gid, gid, gid);
if (f != NULL) {
char c;
while ((c = fgetc(f)) != EOF) {
putchar(c);
}
fclose(f);
}
else {
printf("Failed to open flag file!\n");
}
}
else {
printf("nope! \n");
}
}
int i;
int num_ch;
char option[4];
int option_val;
int main(int argc, char *argv[]) {
printf("Please enter the title of the book you would like to write: ");
char title[50];
char text[256];
fgets(title, 50, stdin);
//get rid of newline
title[strlen(title)-1] = '\0';
printf("You have started writing the book '%s'. Please select an option to get started!\n", title);
book *book = create_book(title);
while(1) {
printf("1. Edit chapter\n");
printf("2. Delete chapter\n");
printf("3. Publish book\n");
i=0;
num_ch = book->num_chapters;
chapter *curr_ch;
fgets(option, 4, stdin);
option_val = atoi(option);
switch(option_val) {
case 1: //edit
printf("Enter chapter number to edit: ");
fgets(option, 4, stdin);
option_val = atoi(option);
if (option_val > 0 && option_val <= num_ch) {
printf("Editing chapter\n");
printf("Enter new chapter text: \n");
curr_ch = book->first_chapter;
for (i=1; i<option_val; i++) {
curr_ch = curr_ch->next_chapter;
}
gets(curr_ch->content);
}
else if (option_val == num_ch+1) {
printf("Adding new chapter\n");
printf("Enter chapter title: \n");
fgets(title, 50, stdin);
printf("Enter chapter text: \n");
fgets(text, 256, stdin);
chapter *ch = malloc(sizeof(chapter));
ch->title = strdup(title);
ch->content = strdup(text);
ch->print_ch = &print_chapter;
curr_ch = book->first_chapter;
book->num_chapters++;
if (curr_ch == NULL) {
book->first_chapter = ch;
}
else {
while (curr_ch->next_chapter != NULL) {
curr_ch = curr_ch->next_chapter;
}
curr_ch->next_chapter = ch;
ch->prev_chapter = curr_ch;
}
}
else {
printf("Invalid chapter number!\n");
return 0;
}
break;
case 2: //delete
printf("Enter chapter number to delete: ");
fgets(option, 4, stdin);
option_val = atoi(option);
if (option_val > 0 && option_val <= num_ch) {
printf("deleting chapter\n");
book->num_chapters--;
if (option_val == 1) {
chapter *old_first = book->first_chapter;
book->first_chapter = old_first->next_chapter;
free(old_first->title);
free(old_first->content);
free(old_first);
if (book->first_chapter != NULL)
book->first_chapter->prev_chapter = NULL;
}
else {
curr_ch = book->first_chapter;
for(i=2;i<option_val;i++) {
curr_ch = curr_ch->next_chapter;
}
chapter *to_del = curr_ch->next_chapter;
curr_ch->next_chapter = to_del->next_chapter;
if (to_del->next_chapter != NULL)
to_del->next_chapter->prev_chapter = to_del->prev_chapter;
free(to_del->title);
free(to_del->content);
free(to_del);
}
}
else {
printf("Invalid chapter number!\n");
return 0;
}
break;
default: //publish
printf("Book published! Here it is:\n");
printf("===============\n");
printf("%s\n", book->title);
printf("===============\n");
i = 1;
curr_ch = book->first_chapter;
while (curr_ch != NULL) {
curr_ch->print_ch(i, curr_ch);
curr_ch = curr_ch->next_chapter;
i++;
}
return 0;
}
}
return 0;
}