├── README.md ├── final-one.c ├── final-two.c ├── final-zero.c ├── format-four.c ├── format-one.c ├── format-three.c ├── format-two.c ├── format-zero.c ├── heap-one.c ├── heap-three.c ├── heap-two.c ├── heap-zero.c ├── malloc-2.7.2.c ├── net-one.c ├── net-two.c ├── net-zero.c ├── stack-five.c ├── stack-four.c ├── stack-one.c ├── stack-six.c ├── stack-three.c ├── stack-two.c └── stack-zero.c /README.md: -------------------------------------------------------------------------------- 1 | # Phoenix 2 | 3 | This repository contains the level files for https://exploit.education/phoenix/ 4 | -------------------------------------------------------------------------------- /final-one.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * phoenix/final-one, by https://exploit.education 4 | * 5 | * Even more format string fun! 6 | * 7 | * The world's leading expert on European wasps walks into a record shop. He 8 | * asks the assistant “Do you have ‘European Vespidae Acoustics Volume 2? I 9 | * believe it was released this week.” 10 | * 11 | * “Certainly,” replies the assistant. “Would you like to listen before you buy 12 | * it?” 13 | * 14 | * "That would be wonderful," says the expert, and puts on a pair of 15 | * headphones. 16 | * 17 | * He listens for a few moments and says to the assistant, “I'm terribly sorry, 18 | * but I am the world's leading expert on European wasps and this is not 19 | * accurate at all. I don't recognize any of those sounds. Are you sure this is 20 | * the correct recording?” 21 | * 22 | * The assistant checks the turntable, and replies that it is indeed European 23 | * Vespidae Acoustics Volume 2. The assistant apologizes and lifts the needle 24 | * onto the next track. 25 | * 26 | * Again the expert listens for a few moments and then says to the assistant, 27 | * "No, this just can't be right! I've been an expert in this field for 43 28 | * years and I still don't recognize any of these sounds." 29 | * 30 | * The assistant apologizes again and lifts the needle to the next track. 31 | * 32 | * The expert throws off the headphones as soon as it starts playing and is 33 | * fuming with rage. 34 | * 35 | * "This is outrageous false advertising! I am the world's leading expert on 36 | * European wasps and no European wasp has ever made a sound like the ones on 37 | * this record!" 38 | * 39 | * The manager of the shop overhears the commotion and walks over. 40 | * 41 | * "What seems to be the problem, sir?" 42 | * 43 | * "This is an outrage! I am the world's leading expert on European wasps. 44 | * Nobody knows more about them than I do. There is no way in hell that the 45 | * sounds on that record were made by European wasps!" 46 | * 47 | * The manager glances down and notices the problem instantly. 48 | * 49 | * "I'm terribly sorry, sir. It appears we've been playing you the bee side." 50 | */ 51 | 52 | #include 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | #include 59 | 60 | #define BANNER \ 61 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 62 | 63 | char username[128]; 64 | char hostname[64]; 65 | FILE *output; 66 | 67 | void logit(char *pw) { 68 | char buf[2048]; 69 | 70 | snprintf(buf, sizeof(buf), "Login from %s as [%s] with password [%s]\n", 71 | hostname, username, pw); 72 | 73 | fprintf(output, buf); 74 | } 75 | 76 | void trim(char *str) { 77 | char *q; 78 | 79 | q = strchr(str, '\r'); 80 | if (q) *q = 0; 81 | q = strchr(str, '\n'); 82 | if (q) *q = 0; 83 | } 84 | 85 | void parser() { 86 | char line[128]; 87 | 88 | printf("[final1] $ "); 89 | 90 | while (fgets(line, sizeof(line) - 1, stdin)) { 91 | trim(line); 92 | if (strncmp(line, "username ", 9) == 0) { 93 | strcpy(username, line + 9); 94 | } else if (strncmp(line, "login ", 6) == 0) { 95 | if (username[0] == 0) { 96 | printf("invalid protocol\n"); 97 | } else { 98 | logit(line + 6); 99 | printf("login failed\n"); 100 | } 101 | } 102 | printf("[final1] $ "); 103 | } 104 | } 105 | 106 | int testing; 107 | 108 | void getipport() { 109 | socklen_t l; 110 | struct sockaddr_in sin; 111 | 112 | if (testing) { 113 | strcpy(hostname, "testing:12121"); 114 | return; 115 | } 116 | 117 | l = sizeof(struct sockaddr_in); 118 | if (getpeername(0, (void *)&sin, &l) == -1) { 119 | err(1, "you don't exist"); 120 | } 121 | 122 | sprintf(hostname, "%s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 123 | } 124 | 125 | int main(int argc, char **argv, char **envp) { 126 | if (argc >= 2) { 127 | testing = !strcmp(argv[1], "--test"); 128 | output = stderr; 129 | } else { 130 | output = fopen("/dev/null", "w"); 131 | if (!output) { 132 | err(1, "fopen(/dev/null)"); 133 | } 134 | } 135 | 136 | setvbuf(stdout, NULL, _IONBF, 0); 137 | setvbuf(stderr, NULL, _IONBF, 0); 138 | 139 | printf("%s\n", BANNER); 140 | 141 | getipport(); 142 | parser(); 143 | 144 | return 0; 145 | } 146 | -------------------------------------------------------------------------------- /final-two.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * phoenix/final-two, by https://exploit.education 4 | * 5 | * This level is linked against ftp://gee.cs.oswego.edu/pub/misc/malloc.c 6 | * version 2.7.2, with a SHA1 sum of 407329d164e4989b59b9a828760acb720dc5c7db 7 | * 8 | * Can you get a shell via heap corruption? 9 | * 10 | * A man drives train for a living in Bulgaria. He absolutely loved his job, 11 | * and it had been his dream job ever since he was a child. One day, he falls 12 | * asleep driving, and runs over someone walking on the tracks. Well, his case 13 | * goes to court, and the court finds him guilty of murder, as had he not been 14 | * asleep, he could have sounded the horn, or stopped for the person. The 15 | * punishment for such recklessness is the death penalty. So, he's on death row 16 | * and the executioner approaches him. 17 | * 18 | * "What would you like for your last meal?" 19 | * 20 | * "I would like a banana please." 21 | * 22 | * The executioner thinks it's weird, but shrugs and gives him a banana. The 23 | * guy eats his banana, waits awhile, and gets strapped into the electric 24 | * chair. When the flip the switch, nothing happens! In Bulgaria, an act of 25 | * divine intervention means you get released. 26 | * 27 | * A few months go by, and the train driver has been working for a new company. 28 | * Well, old habits die hard, and he falls asleep again. This time, he killed 2 29 | * people. Bulgarian courts have no patience for recklessness, so he ends up on 30 | * death row again. After awhile, the same executioner from last time 31 | * approaches him. 32 | * 33 | * "You again? Shit. What do you want this time?" 34 | * 35 | * "Two bananas please." 36 | * 37 | * The executioner shrugs and hands him two bananas. A bit weird, but whatever. 38 | * There's no way he can cheat death twice! But, when they flip the switch, 39 | * nothing happens again. The train driver walks a second time. 40 | * 41 | * Some time passes, and the executioner is very busy. After another few 42 | * months, the same dude shows up, apparently having run over 3 people with a 43 | * train. Exacerbated, the executioner approaches him for the third time. 44 | * 45 | * "Let me guess. Three bananas?" 46 | * 47 | * "Actually yes! How did you know?" 48 | * 49 | * "Too bad! This has gone on long enough. No more bananas! Today you fry." 50 | * 51 | * So, the train driver gets strapped into the chair with no last meal. But, 52 | * when they flip the switch, nothing happens again. 53 | * 54 | * "I dont get it," says the executioner. "I didnt let you eat any bananas!" 55 | * 56 | * "Its not the bananas. It's just that I'm a bad conductor." 57 | */ 58 | 59 | #include 60 | #include 61 | #include 62 | #include 63 | 64 | #define REQSZ 128 65 | 66 | #define BANNER \ 67 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 68 | 69 | void check_path(char *buf) { 70 | char *start; 71 | char *p; 72 | int l; 73 | 74 | /* 75 | * Work out old software bug 76 | */ 77 | 78 | p = rindex(buf, '/'); 79 | l = strlen(p); 80 | if (p) { 81 | start = strstr(buf, "ROOT"); 82 | if (start) { 83 | while (*start != '/') start--; 84 | memmove(start, p, l); 85 | } 86 | } 87 | } 88 | 89 | void get_requests(int in_fd, int out_fd) { 90 | char *buf; 91 | char *destroylist[256]; 92 | int dll; 93 | int i; 94 | 95 | dll = 0; 96 | while (1) { 97 | if (dll >= 255) break; 98 | 99 | buf = calloc(REQSZ, 1); 100 | if (read(in_fd, buf, REQSZ) != REQSZ) break; 101 | 102 | if (strncmp(buf, "FSRD", 4) != 0) break; 103 | 104 | check_path(buf + 4); 105 | 106 | dll++; 107 | } 108 | 109 | for (i = 0; i < dll; i++) { 110 | write(out_fd, "Process OK\n", strlen("Process OK\n")); 111 | free(destroylist[i]); 112 | } 113 | } 114 | 115 | int main(int argc, char **argv, char **envp) { 116 | printf("%s\n", BANNER); 117 | fflush(stdout); 118 | 119 | get_requests(0, 1); 120 | return 0; 121 | } 122 | -------------------------------------------------------------------------------- /final-zero.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * phoenix/final-zero, by https://exploit.education 4 | * 5 | * The aim is to change the contents of the changeme variable. 6 | * 7 | * A woman has twins and gives them up for adoption. 8 | * 9 | * One of them goes to a family in Egypt and is named Amal. The other goes to a 10 | * family in Spain. They name him Juan. 11 | * 12 | * Years later, Juan sends a picture of himself to his birth mother. Upon 13 | * receiving the picture, she tells her husband that she wishes she also had a 14 | * picture of Amal. He responds, "They're twins! If you've seen Juan, you've 15 | * seen Amal." 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define BANNER \ 25 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 26 | 27 | char *gets(char *s); 28 | 29 | /* 30 | * Read the username in from the network 31 | */ 32 | 33 | char *get_username() { 34 | char buffer[512]; 35 | char *q; 36 | int i; 37 | 38 | memset(buffer, 0, sizeof(buffer)); 39 | gets(buffer); 40 | 41 | /* Strip off trailing new line characters */ 42 | q = strchr(buffer, '\n'); 43 | if (q) *q = 0; 44 | q = strchr(buffer, '\r'); 45 | if (q) *q = 0; 46 | 47 | /* Convert to lower case */ 48 | for (i = 0; i < strlen(buffer); i++) { 49 | buffer[i] = toupper(buffer[i]); 50 | } 51 | 52 | /* Duplicate the string and return it */ 53 | return strdup(buffer); 54 | } 55 | 56 | int main(int argc, char **argv, char **envp) { 57 | char *username; 58 | 59 | printf("%s\n", BANNER); 60 | fflush(stdout); 61 | 62 | username = get_username(); 63 | printf("No such user %s\n", username); 64 | } 65 | -------------------------------------------------------------------------------- /format-four.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/format-four, by https://exploit.education 3 | * 4 | * Can you affect code execution? Once you've got congratulations() to 5 | * execute, can you then execute your own shell code? 6 | * 7 | * Did you get a hair cut? 8 | * No, I got all of them cut. 9 | * 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define BANNER \ 19 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 20 | 21 | void bounce(char *str) { 22 | printf(str); 23 | exit(0); 24 | } 25 | 26 | void congratulations() { 27 | printf("Well done, you're redirected code execution!\n"); 28 | exit(0); 29 | } 30 | 31 | int main(int argc, char **argv) { 32 | char buf[4096]; 33 | 34 | printf("%s\n", BANNER); 35 | 36 | if (read(0, buf, sizeof(buf) - 1) <= 0) { 37 | exit(EXIT_FAILURE); 38 | } 39 | 40 | bounce(buf); 41 | } 42 | -------------------------------------------------------------------------------- /format-one.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/format-one, by https://exploit.education 3 | * 4 | * Can you change the "changeme" variable? 5 | * 6 | * Why did the Tomato blush? It saw the salad dressing! 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define BANNER \ 16 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 17 | 18 | int main(int argc, char **argv) { 19 | struct { 20 | char dest[32]; 21 | volatile int changeme; 22 | } locals; 23 | char buffer[16]; 24 | 25 | printf("%s\n", BANNER); 26 | 27 | if (fgets(buffer, sizeof(buffer) - 1, stdin) == NULL) { 28 | errx(1, "Unable to get buffer"); 29 | } 30 | buffer[15] = 0; 31 | 32 | locals.changeme = 0; 33 | 34 | sprintf(locals.dest, buffer); 35 | 36 | if (locals.changeme != 0x45764f6c) { 37 | printf("Uh oh, 'changeme' is not the magic value, it is 0x%08x\n", 38 | locals.changeme); 39 | } else { 40 | puts("Well done, the 'changeme' variable has been changed correctly!"); 41 | } 42 | 43 | exit(0); 44 | } 45 | -------------------------------------------------------------------------------- /format-three.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/format-three, by https://exploit.education 3 | * 4 | * Can you change the "changeme" variable to a precise value? 5 | * 6 | * How do you fix a cracked pumpkin? With a pumpkin patch. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #define BANNER \ 16 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 17 | 18 | int changeme; 19 | 20 | void bounce(char *str) { 21 | printf(str); 22 | } 23 | 24 | int main(int argc, char **argv) { 25 | char buf[4096]; 26 | printf("%s\n", BANNER); 27 | 28 | if (read(0, buf, sizeof(buf) - 1) <= 0) { 29 | exit(EXIT_FAILURE); 30 | } 31 | 32 | bounce(buf); 33 | 34 | if (changeme == 0x64457845) { 35 | puts("Well done, the 'changeme' variable has been changed correctly!"); 36 | } else { 37 | printf( 38 | "Better luck next time - got 0x%08x, wanted 0x64457845!\n", changeme); 39 | } 40 | 41 | exit(0); 42 | } 43 | -------------------------------------------------------------------------------- /format-two.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/format-two, by https://exploit.education 3 | * 4 | * Can you change the "changeme" variable? 5 | * 6 | * What kind of flower should never be put in a vase? 7 | * A cauliflower. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define BANNER \ 17 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 18 | 19 | int changeme; 20 | 21 | void bounce(char *str) { 22 | printf(str); 23 | } 24 | 25 | int main(int argc, char **argv) { 26 | char buf[256]; 27 | 28 | printf("%s\n", BANNER); 29 | 30 | if (argc > 1) { 31 | memset(buf, 0, sizeof(buf)); 32 | strncpy(buf, argv[1], sizeof(buf)); 33 | bounce(buf); 34 | } 35 | 36 | if (changeme != 0) { 37 | puts("Well done, the 'changeme' variable has been changed correctly!"); 38 | } else { 39 | puts("Better luck next time!\n"); 40 | } 41 | 42 | exit(0); 43 | } 44 | -------------------------------------------------------------------------------- /format-zero.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/format-zero, by https://exploit.education 3 | * 4 | * Can you change the "changeme" variable? 5 | * 6 | * 0 bottles of beer on the wall, 0 bottles of beer! You take one down, and 7 | * pass it around, 4294967295 bottles of beer on the wall! 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define BANNER \ 17 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 18 | 19 | int main(int argc, char **argv) { 20 | struct { 21 | char dest[32]; 22 | volatile int changeme; 23 | } locals; 24 | char buffer[16]; 25 | 26 | printf("%s\n", BANNER); 27 | 28 | if (fgets(buffer, sizeof(buffer) - 1, stdin) == NULL) { 29 | errx(1, "Unable to get buffer"); 30 | } 31 | buffer[15] = 0; 32 | 33 | locals.changeme = 0; 34 | 35 | sprintf(locals.dest, buffer); 36 | 37 | if (locals.changeme != 0) { 38 | puts("Well done, the 'changeme' variable has been changed!"); 39 | } else { 40 | puts( 41 | "Uh oh, 'changeme' has not yet been changed. Would you like to try " 42 | "again?"); 43 | } 44 | 45 | exit(0); 46 | } 47 | -------------------------------------------------------------------------------- /heap-one.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/heap-zero, by https://exploit.education 3 | * 4 | * Can you hijack flow control? 5 | * 6 | * Which vegetable did Noah leave off the Ark? 7 | * Leeks 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define BANNER \ 17 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 18 | 19 | struct heapStructure { 20 | int priority; 21 | char *name; 22 | }; 23 | 24 | int main(int argc, char **argv) { 25 | struct heapStructure *i1, *i2; 26 | 27 | i1 = malloc(sizeof(struct heapStructure)); 28 | i1->priority = 1; 29 | i1->name = malloc(8); 30 | 31 | i2 = malloc(sizeof(struct heapStructure)); 32 | i2->priority = 2; 33 | i2->name = malloc(8); 34 | 35 | strcpy(i1->name, argv[1]); 36 | strcpy(i2->name, argv[2]); 37 | 38 | printf("and that's a wrap folks!\n"); 39 | } 40 | 41 | void winner() { 42 | printf( 43 | "Congratulations, you've completed this level @ %ld seconds past the " 44 | "Epoch\n", 45 | time(NULL)); 46 | } 47 | -------------------------------------------------------------------------------- /heap-three.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/heap-three, by https://exploit.education 3 | * 4 | * This level is linked against ftp://gee.cs.oswego.edu/pub/misc/malloc-2.7.2.c 5 | * version 2.7.2, with a SHA1 sum of 407329d164e4989b59b9a828760acb720dc5c7db 6 | * more commonly known as "dlmalloc", Doug Lea Malloc 7 | * 8 | * Can you hijack flow control, and execute winner()? Afterwards, how 9 | * about your own code? This level is solvable on Linux i386 easily enough, 10 | * as for other architectures, it may not be possible, or may require some 11 | * creativity - let me know what you come up with :) 12 | * 13 | * My friend told me that nothing rhymes with orange. 14 | * I told them, "No, it doesn't". 15 | * 16 | * Or, more seriously, https://www.youtube.com/watch?v=lPcR5RVXHMg 17 | * 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | void winner() { 28 | printf("Level was successfully completed at @ %ld seconds past the Epoch\n", 29 | time(NULL)); 30 | } 31 | 32 | int main(int argc, char **argv) { 33 | char *a, *b, *c; 34 | 35 | a = malloc(32); 36 | b = malloc(32); 37 | c = malloc(32); 38 | 39 | strcpy(a, argv[1]); 40 | strcpy(b, argv[2]); 41 | strcpy(c, argv[3]); 42 | 43 | free(c); 44 | free(b); 45 | free(a); 46 | 47 | printf("dynamite failed?\n"); 48 | } 49 | -------------------------------------------------------------------------------- /heap-two.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/heap-two, by https://exploit.education 3 | * 4 | * This level examines what can happen when heap pointers are stale. This level 5 | * is completed when you see the "you have logged in already!" message. 6 | * 7 | * My dog would, without fail, always chase people on a bike. As soon as he saw 8 | * someone, he would immediately take off. I spoke to the vet to see if they 9 | * could be of any help, but they weren't. I spoke to several different dog 10 | * behaviouralists to see if they have any ideas on how to stop getting him 11 | * chasing people on a bike. The dog behaviouralists were unable to help. I 12 | * searched high and low to work out ways to find a way to stop him from 13 | * chasing people on a bike, to no avail. Eventually, I had no choice but to 14 | * take the bike away from him. 15 | */ 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define BANNER \ 24 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 25 | 26 | struct auth { 27 | char name[32]; 28 | int auth; 29 | }; 30 | 31 | struct auth *auth; 32 | char *service; 33 | 34 | int main(int argc, char **argv) { 35 | char line[128]; 36 | 37 | printf("%s\n", BANNER); 38 | 39 | while (1) { 40 | printf("[ auth = %p, service = %p ]\n", auth, service); 41 | 42 | if (fgets(line, sizeof(line), stdin) == NULL) break; 43 | 44 | if (strncmp(line, "auth ", 5) == 0) { 45 | auth = malloc(sizeof(struct auth)); 46 | memset(auth, 0, sizeof(struct auth)); 47 | if (strlen(line + 5) < 31) { 48 | strcpy(auth->name, line + 5); 49 | } 50 | } 51 | if (strncmp(line, "reset", 5) == 0) { 52 | free(auth); 53 | } 54 | if (strncmp(line, "service", 6) == 0) { 55 | service = strdup(line + 7); 56 | } 57 | if (strncmp(line, "login", 5) == 0) { 58 | if (auth && auth->auth) { 59 | printf("you have logged in already!\n"); 60 | } else { 61 | printf("please enter your password\n"); 62 | } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /heap-zero.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/heap-zero, by https://exploit.education 3 | * 4 | * Can you hijack flow control, and execute the winner function? 5 | * 6 | * Why do C programmers make good Buddhists? 7 | * Because they're not object orientated. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define BANNER \ 17 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 18 | 19 | struct data { 20 | char name[64]; 21 | }; 22 | 23 | struct fp { 24 | void (*fp)(); 25 | char __pad[64 - sizeof(unsigned long)]; 26 | }; 27 | 28 | void winner() { 29 | printf("Congratulations, you have passed this level\n"); 30 | } 31 | 32 | void nowinner() { 33 | printf( 34 | "level has not been passed - function pointer has not been " 35 | "overwritten\n"); 36 | } 37 | 38 | int main(int argc, char **argv) { 39 | struct data *d; 40 | struct fp *f; 41 | 42 | printf("%s\n", BANNER); 43 | 44 | if (argc < 2) { 45 | printf("Please specify an argument to copy :-)\n"); 46 | exit(1); 47 | } 48 | 49 | d = malloc(sizeof(struct data)); 50 | f = malloc(sizeof(struct fp)); 51 | f->fp = nowinner; 52 | 53 | strcpy(d->name, argv[1]); 54 | 55 | printf("data is at %p, fp is at %p, will be calling %p\n", d, f, f->fp); 56 | fflush(stdout); 57 | 58 | f->fp(); 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /net-one.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/net-one, by https://exploit.education 3 | * 4 | * Why aren't octal jokes funny? 5 | * Because 7 10 11 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define BANNER \ 18 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 19 | 20 | int main(int argc, char **argv) { 21 | uint32_t i; 22 | char buf[12], fub[12], *q; 23 | 24 | setvbuf(stdout, NULL, _IONBF, 0); 25 | setvbuf(stderr, NULL, _IONBF, 0); 26 | printf("%s\n", BANNER); 27 | 28 | if (getrandom((void *)&i, sizeof(i), 0) != sizeof(i)) { 29 | errx(1, "unable to getrandom(%d bytes)", sizeof(i)); 30 | } 31 | 32 | if (write(1, &i, sizeof(i)) != sizeof(i)) { 33 | errx(1, "unable to write %d bytes", sizeof(i)); 34 | } 35 | 36 | if (fgets(buf, sizeof(buf), stdin) == NULL) { 37 | errx(1, "who knew that reading from stdin could be so difficult"); 38 | } 39 | buf[sizeof(buf) - 1] = 0; 40 | 41 | q = strchr(buf, '\r'); 42 | if (q) *q = 0; 43 | q = strchr(buf, '\n'); 44 | if (q) *q = 0; 45 | 46 | sprintf(fub, "%u", i); 47 | if (strcmp(fub, buf) == 0) { 48 | printf("Congratulations, you've passed this level!\n"); 49 | } else { 50 | printf("Close, you sent \"%s\", and we wanted \"%s\"\n", buf, fub); 51 | } 52 | 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /net-two.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/net-two, by https://exploit.education 3 | * 4 | * Shout out to anyone who doesn't know what the opposite of in is. 5 | * 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define BANNER \ 17 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 18 | 19 | int main(int argc, char **argv) { 20 | int i; 21 | unsigned long quad[sizeof(long)], result, wanted; 22 | 23 | setvbuf(stdout, NULL, _IONBF, 0); 24 | setvbuf(stderr, NULL, _IONBF, 0); 25 | printf("%s\nFor this level, sizeof(long) == %d, keep that in mind :)\n", 26 | BANNER, (int)sizeof(long)); 27 | 28 | if (getrandom((void *)&quad, sizeof(quad), 0) != sizeof(quad)) { 29 | errx(1, "unable to getrandom(%d bytes)", sizeof(quad)); 30 | } 31 | 32 | result = 0; 33 | for (i = 0; i < sizeof(long); i++) { 34 | result += quad[i]; 35 | if (write(1, (void *)&quad[i], sizeof(long)) != sizeof(long)) { 36 | errx(1, "Why have you foresaken me, write()"); 37 | } 38 | } 39 | 40 | if (read(0, (void *)&wanted, sizeof(long)) != sizeof(long)) { 41 | errx(1, "Unable to read\n"); 42 | } 43 | 44 | if (result == wanted) { 45 | printf("You have successfully passed this level, well done!\n"); 46 | } else { 47 | printf("Whoops, better luck next time. Receieved %lu, wanted %lu\n", wanted, 48 | result); 49 | } 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /net-zero.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/net-zero, by https://exploit.education 3 | * 4 | * What did the fish say when he swam head first into a wall? 5 | * Dam! 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define BANNER \ 18 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 19 | 20 | int main(int argc, char **argv) { 21 | uint32_t i, j; 22 | 23 | setvbuf(stdout, NULL, _IONBF, 0); 24 | setvbuf(stderr, NULL, _IONBF, 0); 25 | printf("%s\n", BANNER); 26 | 27 | if (getrandom((void *)&i, sizeof(i), 0) != sizeof(i)) { 28 | errx(1, "unable to getrandom(%d bytes)", sizeof(i)); 29 | } 30 | 31 | printf("Please send '%u' as a little endian, 32bit integer.\n", i); 32 | 33 | if (read(0, (void *)&j, sizeof(j)) != sizeof(j)) { 34 | errx(1, "unable to read %d bytes from stdin", sizeof(j)); 35 | } 36 | 37 | if (i == j) { 38 | printf("You have successfully passed this level, well done!\n"); 39 | } else { 40 | printf("Close - you sent %u instead\n", j); 41 | } 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /stack-five.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/stack-five, by https://exploit.education 3 | * 4 | * Can you execve("/bin/sh", ...) ? 5 | * 6 | * What is green and goes to summer camp? A brussel scout. 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define BANNER \ 15 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 16 | 17 | char *gets(char *); 18 | 19 | void start_level() { 20 | char buffer[128]; 21 | gets(buffer); 22 | } 23 | 24 | int main(int argc, char **argv) { 25 | printf("%s\n", BANNER); 26 | start_level(); 27 | } 28 | -------------------------------------------------------------------------------- /stack-four.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/stack-four, by https://exploit.education 3 | * 4 | * The aim is to execute the function complete_level by modifying the 5 | * saved return address, and pointing it to the complete_level() function. 6 | * 7 | * Why were the apple and orange all alone? Because the bananna split. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define BANNER \ 17 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 18 | 19 | char *gets(char *); 20 | 21 | void complete_level() { 22 | printf("Congratulations, you've finished " LEVELNAME " :-) Well done!\n"); 23 | exit(0); 24 | } 25 | 26 | void start_level() { 27 | char buffer[64]; 28 | void *ret; 29 | 30 | gets(buffer); 31 | 32 | ret = __builtin_return_address(0); 33 | printf("and will be returning to %p\n", ret); 34 | } 35 | 36 | int main(int argc, char **argv) { 37 | printf("%s\n", BANNER); 38 | start_level(); 39 | } 40 | -------------------------------------------------------------------------------- /stack-one.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/stack-one, by https://exploit.education 3 | * 4 | * The aim is to change the contents of the changeme variable to 0x496c5962 5 | * 6 | * Did you hear about the kid napping at the local school? 7 | * It's okay, they woke up. 8 | * 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define BANNER \ 18 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 19 | 20 | int main(int argc, char **argv) { 21 | struct { 22 | char buffer[64]; 23 | volatile int changeme; 24 | } locals; 25 | 26 | printf("%s\n", BANNER); 27 | 28 | if (argc < 2) { 29 | errx(1, "specify an argument, to be copied into the \"buffer\""); 30 | } 31 | 32 | locals.changeme = 0; 33 | strcpy(locals.buffer, argv[1]); 34 | 35 | if (locals.changeme == 0x496c5962) { 36 | puts("Well done, you have successfully set changeme to the correct value"); 37 | } else { 38 | printf("Getting closer! changeme is currently 0x%08x, we want 0x496c5962\n", 39 | locals.changeme); 40 | } 41 | 42 | exit(0); 43 | } 44 | -------------------------------------------------------------------------------- /stack-six.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/stack-six, by https://exploit.education 3 | * 4 | * Can you execve("/bin/sh", ...) ? 5 | * 6 | * Why do fungi have to pay double bus fares? Because they take up too 7 | * mushroom. 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #define BANNER \ 17 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 18 | 19 | char *what = GREET; 20 | 21 | char *greet(char *who) { 22 | char buffer[128]; 23 | int maxSize; 24 | 25 | maxSize = strlen(who); 26 | if (maxSize > (sizeof(buffer) - /* ensure null termination */ 1)) { 27 | maxSize = sizeof(buffer) - 1; 28 | } 29 | 30 | strcpy(buffer, what); 31 | strncpy(buffer + strlen(buffer), who, maxSize); 32 | 33 | return strdup(buffer); 34 | } 35 | 36 | int main(int argc, char **argv) { 37 | char *ptr; 38 | printf("%s\n", BANNER); 39 | 40 | #ifdef NEWARCH 41 | if (argv[1]) { 42 | what = argv[1]; 43 | } 44 | #endif 45 | 46 | ptr = getenv("ExploitEducation"); 47 | if (NULL == ptr) { 48 | // This style of comparison prevents issues where you may accidentally 49 | // type if(ptr = NULL) {}.. 50 | 51 | errx(1, "Please specify an environment variable called ExploitEducation"); 52 | } 53 | 54 | printf("%s\n", greet(ptr)); 55 | return 0; 56 | } 57 | -------------------------------------------------------------------------------- /stack-three.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/stack-three, by https://exploit.education 3 | * 4 | * The aim is to change the contents of the changeme variable to 0x0d0a090a 5 | * 6 | * When does a joke become a dad joke? 7 | * When it becomes apparent. 8 | * When it's fully groan up. 9 | * 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define BANNER \ 19 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 20 | 21 | char *gets(char *); 22 | 23 | void complete_level() { 24 | printf("Congratulations, you've finished " LEVELNAME " :-) Well done!\n"); 25 | exit(0); 26 | } 27 | 28 | int main(int argc, char **argv) { 29 | struct { 30 | char buffer[64]; 31 | volatile int (*fp)(); 32 | } locals; 33 | 34 | printf("%s\n", BANNER); 35 | 36 | locals.fp = NULL; 37 | gets(locals.buffer); 38 | 39 | if (locals.fp) { 40 | printf("calling function pointer @ %p\n", locals.fp); 41 | fflush(stdout); 42 | locals.fp(); 43 | } else { 44 | printf("function pointer remains unmodified :~( better luck next time!\n"); 45 | } 46 | 47 | exit(0); 48 | } 49 | -------------------------------------------------------------------------------- /stack-two.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/stack-two, by https://exploit.education 3 | * 4 | * The aim is to change the contents of the changeme variable to 0x0d0a090a 5 | * 6 | * If you're Russian to get to the bath room, and you are Finnish when you get 7 | * out, what are you when you are in the bath room? 8 | * 9 | * European! 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define BANNER \ 19 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 20 | 21 | int main(int argc, char **argv) { 22 | struct { 23 | char buffer[64]; 24 | volatile int changeme; 25 | } locals; 26 | 27 | char *ptr; 28 | 29 | printf("%s\n", BANNER); 30 | 31 | ptr = getenv("ExploitEducation"); 32 | if (ptr == NULL) { 33 | errx(1, "please set the ExploitEducation environment variable"); 34 | } 35 | 36 | locals.changeme = 0; 37 | strcpy(locals.buffer, ptr); 38 | 39 | if (locals.changeme == 0x0d0a090a) { 40 | puts("Well done, you have successfully set changeme to the correct value"); 41 | } else { 42 | printf("Almost! changeme is currently 0x%08x, we want 0x0d0a090a\n", 43 | locals.changeme); 44 | } 45 | 46 | exit(0); 47 | } 48 | -------------------------------------------------------------------------------- /stack-zero.c: -------------------------------------------------------------------------------- 1 | /* 2 | * phoenix/stack-zero, by https://exploit.education 3 | * 4 | * The aim is to change the contents of the changeme variable. 5 | * 6 | * Scientists have recently discovered a previously unknown species of 7 | * kangaroos, approximately in the middle of Western Australia. These 8 | * kangaroos are remarkable, as their insanely powerful hind legs give them 9 | * the ability to jump higher than a one story house (which is approximately 10 | * 15 feet, or 4.5 metres), simply because houses can't can't jump. 11 | */ 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define BANNER \ 19 | "Welcome to " LEVELNAME ", brought to you by https://exploit.education" 20 | 21 | char *gets(char *); 22 | 23 | int main(int argc, char **argv) { 24 | struct { 25 | char buffer[64]; 26 | volatile int changeme; 27 | } locals; 28 | 29 | printf("%s\n", BANNER); 30 | 31 | locals.changeme = 0; 32 | gets(locals.buffer); 33 | 34 | if (locals.changeme != 0) { 35 | puts("Well done, the 'changeme' variable has been changed!"); 36 | } else { 37 | puts( 38 | "Uh oh, 'changeme' has not yet been changed. Would you like to try " 39 | "again?"); 40 | } 41 | 42 | exit(0); 43 | } 44 | --------------------------------------------------------------------------------