Home
Github
  • 👋Welcome !
  • 🚩CTF Writeups
    • SKR CTF
      • Binary
        • Auth Me 2.0
      • Misc
        • Schrodinger's Cat 2
      • Reverse Engineering
        • Nogard 3
    • osu!gaming CTF 2024
      • pwn
        • betterthanu
    • Crackmes
      • PieIsMyFav
      • Plain Sight
    • WolvCTF 2024
      • pwn
        • babypwn
    • TexSAW CTF 2024
      • rev
        • Catch The White Rabbit
      • Forensics
        • Malicious Threat
        • MalWhere?
    • SwampCTF 2024
      • Misc
        • Lost Some Magic
        • The Time Equations
    • pwnable.kr
      • Toddler's Bottle
        • fd
    • Codegate CTF 2024
      • ai
        • ai_warmup
    • Junior Crypt CTF 2024
      • Misc
        • Terms of Use
      • Forensics
        • Admin Rights
        • Confusion
      • PPC
        • l33t
    • IHack 2024 Qualification
      • DFIR
        • Happy SPLUNKing
      • Malware
        • Confusing Javascript
    • Malcore Challenge
    • Intern Task
      • SQLI
  • 📮Room/Machine
    • HTB - Sherlock
      • DFIR
        • Brutus
        • Unit42
        • Jingle Bell
  • 📚Notes
    • CTF Related
      • pwn
        • pwntools
        • Format String Vulnerability
        • Integer Overflow
        • Executable Properties
        • gdb-gef
        • Template Script
      • b2r/koth
    • Assembly Language
    • x86 Architecture
  • 🛠️Tools
    • DFIR
    • Malware Analysis
    • Essentials
  • 👽Threat Hunting
    • Intro
    • Common Tactics
    • Methodologies
    • Types of threat hunting
  • 😸whoami
    • About Me
    • Other
      • FYP
  • Archives
    • 3108 CTF
      • Kategori
        • Tugasan Utama : Warkah Untuk Perwira
          • Tugasan I : Seruan Perwira
          • Tugasan II : Tali Barut
          • Warkah Akhir
        • Web
          • Lemah
          • Pantun Pantul
          • Wantujus
          • Wantusom
        • Reverse Engineering
          • Pa+rio+ik
          • Sarawak
        • Network
          • Johan
          • Lagi-lagi Johan
        • Misc
          • 3108 CTF Town
          • Mencari Rahsia Si Dia
        • Cryptography
          • 1957bit
          • Nasihat
          • Selamat Malam
        • OSINT
          • Pertemuan Kapisata : Babak I
          • Pertemuan Kapista : Babak II
          • Pertemuan Kapista : Finale
    • Curtin CTF 2023
      • Pwn n Rev
        • Classic Bufferoverflow
        • Intro to Buffer Overflow
        • Don't Go Overboard
        • Don't Go Overboard 2
        • Let The Random Games Begin1
        • Let The Random Games Begin 2
        • Let The Random Games Begin 3
    • 1337UP LIVE CTF
      • Pwn
        • Floor Mat Store
    • HTB University CTF 2023
      • Reverse Engineering
        • Windows Of Opportunity
Powered by GitBook
On this page
  • Format function
  • Format Parameter
  • Example
  • Tips
  1. Notes
  2. CTF Related
  3. pwn

Format String Vulnerability

Definition : bug that take advantage of an easily avoidable programmer error. If the programmer passes an attacker-controlled buffer as an argument to a printf (or any of the related functions), the attacker can perform writes to arbitrary memory addresses

Format function

Definition : Is a function which converts a primitive variable of the programming language into a human-readable string representation

Below is an example of Format Function that vulnerable to Format String Attack :

Format Function

fprint

printf

sprintf

snprintf

vfprintf

vprintf

vsprintf

vsnprintf

Format Parameter

Definition : like %x %s defines the type of conversion of the format function

Below is an example of Format Parameter that can be useful for you :

Parameter
Output
Passed as

%%

character

reference

%p

External representation of a pointer to void

reference

%d

decimal

value

%c

character

%u

unsigned decimal

value

%x

hexa

value

%s

string

reference

%n

Writes the number of characters into a pointer

reference

Example

Let's take the example from PicoCTF.

Challenge Name : Stonk Market

vuln.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#define FLAG_BUFFER 128
#define MAX_SYM_LEN 4

typedef struct Stonks {
        int shares;
        char symbol[MAX_SYM_LEN + 1];
        struct Stonks *next;
} Stonk;

typedef struct Portfolios {
        int money;
        Stonk *head;
} Portfolio;

int view_portfolio(Portfolio *p) {
        if (!p) {
                return 1;
        }
        printf("\nPortfolio as of ");
        fflush(stdout);
        system("date"); // TODO: implement this in C
        fflush(stdout);

        printf("\n\n");
        Stonk *head = p->head;
        if (!head) {
                printf("You don't own any stonks!\n");
        }
        while (head) {
                printf("%d shares of %s\n", head->shares, head->symbol);
                head = head->next;
        }
        return 0;
}

Stonk *pick_symbol_with_AI(int shares) {
        if (shares < 1) {
                return NULL;
        }
        Stonk *stonk = malloc(sizeof(Stonk));
        stonk->shares = shares;

        int AI_symbol_len = (rand() % MAX_SYM_LEN) + 1;
        for (int i = 0; i <= MAX_SYM_LEN; i++) {
                if (i < AI_symbol_len) {
                        stonk->symbol[i] = 'A' + (rand() % 26);
                } else {
                        stonk->symbol[i] = '\0';
                }
        }

        stonk->next = NULL;

        return stonk;
}

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\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");

        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);

        // TODO: Actually use key to interact with API

        view_portfolio(p);

        return 0;
}

Portfolio *initialize_portfolio() {
        Portfolio *p = malloc(sizeof(Portfolio));
        p->money = (rand() % 2018) + 1;
        p->head = NULL;
        return p;
}

void free_portfolio(Portfolio *p) {
        Stonk *current = p->head;
        Stonk *next = NULL;
        while (current) {
                next = current->next;
                free(current);
                current = next;
        }
        free(p);
}

int main(int argc, char *argv[])
{
        setbuf(stdout, NULL);
        srand(time(NULL));
        Portfolio *p = initialize_portfolio();
        if (!p) {
                printf("Memory failure\n");
                exit(1);
        }

        int resp = 0;

        printf("Welcome back to the trading app!\n\n");
        printf("What would you like to do?\n");
        printf("1) Buy some stonks!\n");
        printf("2) View my portfolio\n");
        scanf("%d", &resp);

        if (resp == 1) {
                buy_stonks(p);
        } else if (resp == 2) {
                view_portfolio(p);
        }

        free_portfolio(p);
        printf("Goodbye!\n");

        exit(0);
}

Have a look at the code given. Do you notice something?

Line 88-92 is vulnerable to Format String Attack

So we need to enter the Format Parameter like %x-%x-%x-%x-%x-%x into the program to leak some of the memory

  1. If you don't get the leaked memory that you need, just spam the Format Parameter a lot. Yes, a lot. It can be up to hundreds but you should get what you want in just a few.

  2. Let say you want to display just a certain part of the memory, try using this %n$p . n is an index of the memory that you want. This certainly help you.

  3. When you got the memory leaked (some will be in hex or depends on what parameter you put), put that in Cyberchef and let it cook. If you don't see what you want yet, just remember that binary number can change the translated data. So, don't be shy to remove the binary one by one until it reveal itself.

Last updated 1 year ago

Yeah that's how you use it

Tips

If i got another, i will write here

📚
😎
👍
📋
🤝
See where the memory got leaked?