flag: flag{im_alive_and_so_are_the_servers}
Source Code (With my comments):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main()
{
char command[16]; //length of command
char way_too_small_input_buf[8]; //length of input = 8 characters
strcpy(command, "ls");
puts("Hi! would you like me to ls the current directory?");
read(0, way_too_small_input_buf, 24); //reads your input with a buffer size of 8, and max size of 24 characters
if (!strcmp(way_too_small_input_buf, "no\n")) { //checks if you said no, otherwise, runs the ls command
puts("Oh, ok :(");
exit(0);
}
puts("Ok, here ya go!\n");
system(command); //executes command
}
Command to access challenge: nc chals.2022.squarectf.com 4100
Saying yes will show us the files in the current directory
The following code is our exploit
read(0, way_too_small_input_buf, 24); //reads your input with a buffer size of 8, and max size of 24 characters
The buffer size is 8, so if we input characters above this threshold we can override/overwrite the ls command
We can test this:
Once we pass the 8 character buffer size, we can overwrite the ls command and input our own command. In this case, I used whoami, we can see the user is pwnable_user
We can use this to peek into the folders in the directory
We have a problem, the length of the folder the_flag_is_in_here exceeds the length allowed by the code below
read(0, way_too_small_input_buf, 24);
The max length allowed is 24 characters| 8 (buffer) + 19 (length of folder = 27 > 24 (allowd # of chars) We also look at the ez-pwn-1 folder to see if that contains anything interesting…. nope
At this point, I am thinking of ways to shorten my command to that I can peek into the folder containing the flag We can take a guess that inside the folder there is a text document titled flag.txt, but I want to be thourough with my investigation
After some reasearch I found this command: __cd /__ and thought maybe it can be used with ls. *Spoiler: It does. (ls */)
(*) is a global pattern or commonly called a wildcard 1. I like to think about it as a loop: It loops through all the directories in your working directory. When used in combination with ls it effectively lists all the files in the working directory.
Using ls */ along with the 8 char buffer
ez-pwn-1 has no files, but the_flag_is_in_here has one! [Flag.txt]
How to we read the file? Simple enough
We use the command *cat */flag.txt** () gives us a global file list, (/) allows us to select one of the many files
flag: flag{congrats_youve_exploited_a_memory_corruption_vulnerability} ___
Source Code:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
void hex_string_to_byte_array(char *hex_str, char *byte_arr, int size)
{
int byte_ind = 0;
for (int count = 0; count < size; count += 2)
{
sscanf(&hex_str[count], "%2hhx", &byte_arr[byte_ind]);
byte_ind++;
}
}
// this can also easily be used for memory leaks
void print_buf(unsigned char *buf, int sz)
{
for (int i = 0; i < sz; i++)
{
printf("%02X", buf[i]);
}
puts("\n");
}
void this_function_literally_prints_the_flag()
{
char flag[64];
int fd = open("flag.txt", O_RDONLY);
read(fd, flag, 64);
puts(flag);
close(fd);
}
void gimme_pointer()
{
char *leak_addr;
char this_buffer_is_definitely_too_small_for_that_read[17];
printf("You are here: %p\n Give me an address and I will grant you 8 leaked bytes:\n", this_buffer_is_definitely_too_small_for_that_read);
read(0, this_buffer_is_definitely_too_small_for_that_read, 64);
hex_string_to_byte_array(this_buffer_is_definitely_too_small_for_that_read, (char *)&leak_addr, 16);
printf("Here are the contents of %p:\n", leak_addr);
print_buf(leak_addr, 8);
}
int main()
{
puts("Hi! I am the Stack Oracle.\n");
while (1)
{
gimme_pointer();
}
}
Command to access challenge: nc chals.2022.squarectf.com 4101
| Files: | ez-re-1_elf | ez-re-1_macho | | — | — | — |
Files: elf binary, macho binary [link them]
Square CTF made the challenges available as docker images, so I’m posting writeups from practicing these, while looking at the solutions when needed
https://www.tecmint.com/use-wildcards-to-match-filenames-in-linux/ ↩