Downunderflow

Description

It's important to see things from different perspectives.

Author: joseph

Application: nc 2023.ductf.dev 30025 Downloads: downunderflow.carrow-up-right, downunderflowarrow-up-right

Analysis

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define USERNAME_LEN 6
#define NUM_USERS 8
char logins[NUM_USERS][USERNAME_LEN] = { 
	"user0", "user1", "user2", "user3", 
	"user4", "user5", "user6", "admin" 
};

void init() {
    setvbuf(stdout, 0, 2, 0);
    setvbuf(stdin, 0, 2, 0);
}

int read_int_lower_than(int bound) {
    int x;
    scanf("%d", &x);
    if(x >= bound) {
        puts("Invalid input!");
        exit(1);
    }
    return x;
}

int main() {
    init();

    printf("Select user to log in as: ");
    unsigned short idx = read_int_lower_than(NUM_USERS - 1);
    printf("Logging in as %s\n", logins[idx]);
    if(strncmp(logins[idx], "admin", 5) == 0) {
        puts("Welcome admin.");
        system("/bin/sh");
    } else {
        system("/bin/date");
    }
}

Application is simple, if you are admin you get shell, if you are use you get date. Problem is to be admin we need to get logins[7], which read_int_lower_than makes it impossible for us.

The problem in validation is, it only checks positive values if(x >= bound) [Line 17].

C is a statically types language and it's primitive types have a defined limits.

An integer overflow occurs when you attempt to store inside an integer variable a value that is larger than the maximum value the variable can hold.

In this case int is converted to unsigned short which will cause an overflow.

Doing a bit of fuzzing:

Solution

circle-check

Last updated