Starting point
The supplied C source made the bug visible: the program read an API token into user_buf, then called printf(user_buf). Because user input became the format string, %x specifiers could cause printf to print values it was never meant to expose.
Route through the challenge
I sent repeated %x specifiers to the challenge service and converted the returned hexadecimal words to text. Some four-byte groups appeared reversed because the machine stored and printed the words in little-endian order. Reordering those bytes exposed the flag.
Outcome and context
The safe programming pattern is printf("%s", user_buf): the fixed format string makes the token data rather than instructions for printf. The screenshots below show the lab output.
Walkthrough and screenshots
Stonks
This challenge is a binary exploitation challenge, we are provided with a source code file written in C, and then we are able to netcat to a server running the binary in an attempt to retrieve the flag is we can successfully exploit.
Description
I decided to try something no one else has before. I made a bot to automatically trade stonks for me using AI and machine learning. I wouldnโt believe you if you told me itโs unsecure! vuln.c nc mercury.picoctf.net 6989
First of all, letโs look through the C source code looking where user input is provided in hopes it is either handled incorrectly or we can somehow manipulate the response.
int buy_stonks(Portfolio *p) {
if (!p) {
return 1;
}
char api_buf[FLAG_BUFFER];
FILE *f = fopen("api","r");
if (!f) {
printf("Flag file not found. Contact an admin.\n");
exit(1);
}
fgets(api_buf, FLAG_BUFFER, f);
int money = p->money;
int shares = 0;
Stonk *temp = NULL;
printf("Using patented AI algorithms to buy stonks\n");
while (money > 0) {
shares = (rand() % money) + 1;
temp = pick_symbol_with_AI(shares);
temp->next = p->head;
p->head = temp;
money -= shares;
}
printf("Stonks chosen\n");
// TODO: Figure out how to read token from file, for now just ask
char *user_buf = malloc(300 + 1);
printf("What is your API token?\n");
scanf("%300s", user_buf);
printf("Buying stonks with token:\n");
printf(user_buf); //format string vuln
// TODO: Actually use key to interact with API
view_portfolio(p);
return 0;
Now that we have found the vulnerable part of the code we can use netcat to connect to the host and send our payload. To craft our payload we will need to understand what a Format string vulnerability is, why it occurs and what we can do.
First of all, we need to understand what are some format functions? the โfโ stands for format

Now we know that kind of function is vulnerable to a format string vulnerability how do we exploit it? in C you can send specific parameters to return different values:

Now we know a little bit about the type of vulnerability lets test our theory
By supplying a user input of %x we will be returned a hex value. The user input that is vulnerable is the API key input.

Using python we can craft multiply our %x to save time typing it manually

I sent the payload to the server and attempted to decrypt the hex value using xxd -r -p

From the output, I can see our flag but it is in the wrong format, every 4 letters are backward this is to do with the endian and how the bytes are stored on the stack.
With this in mind, we can use cyber chef to automate some of this process.
as we know our backward strings start with an o that is 6F in hex we can use this information to help filter through the hex values
