I'm new to Software security and I'm studying it now at the university. I had some doubts about the Format String exploit, in particular how to count the length (in number of bytes) of a format string exploit.

Suppose that I have the following vulnerable code:

04 int guess(char *user) {
05     struct {
06          int n;
08          char usr[16];
09          char buf[16];
10      } s;
12      snprintf (s.usr, 16, "%s", user);
14      do {
15          scanf ("%s", s.buf);
16          if ( strncmp (s.buf, "DEBUG", 5) == 0) {
17              scanf ("%d", &s.n);
18              for ( int i = 0; i < s.n; i++) {
19                  printf ("%x", s.buf[i]);
20              }
21          } else {
22              if ( strncmp (s.buf, "pass", 4) == 0 && s.usr[0] == '_') {
23                  return 1;
24          } else {
25              printf ("Sorry User: ");
26              printf (s.usr);
27              printf ("\nThe secret is wrong! \n");
28              abort ();
29          }
30          }
31      } while ( strncmp (s.buf, "DEBUG", 5) == 0);
32  }
34 int main(int argc, char** argv) {
35      guess(argv[1]);
36 }

And the code is compiled in an IA-32 architecture (32 bit) with cdecl calling convention and there's no attack mitigation implemented (no stack canary, no ALSR etc..., I'm in a complete vulnerable machine)

At line 26 there's a format string vulnerability since the placeholder is missing ( printf (s.usr); ).

I'd like to overwrite the EIP with the address of an environmental variable that contains my shellcode.

I'm supposing (this is a theoretical exercise, I'm aware that in practice there are many other implications) that the address of my environmental variable is 0x44674234, the address of the EIP is 0x42414515 and the displacement on the stack of my format string is 7.

So my format string exploit will be \x15\x45\x41\x42\x17\x45\x41\x42%16940c%7$hn%563c%8$hn, I'll place it into user and then it will be copied into s.usr and executed by printf (s.usr);

Now what I noticed is that only 16 characters are copied into s.usr from user.

Is my format string not exploitable? I counted 30 characters in my exploit, therefore the strcpy will copy only half of my exploit.

Is the number of characters I counted correct? How should I count them?

  • There appear to be other vulnerabilities besides a format string that may allow for code execution. – multithr3at3d Jul 7 '20 at 1:02

snprintf (s.usr, 16, "%s", user); copies at most 15 bytes from user to s.usr, and appends a null byte. So printf (s.usr) only has a format string of 15 bytes at most.

Even if line 12 copied more, the subsequent scanf ("%s", s.buf); would overwrite at least byte 16. If you control the program's standard input, you can plant things on the stack, but they won't be part of the format string at line 26 since s.usr is guaranteed to be null-terminated. Of course, if you control the input, you can directly overwrite the stack through it as long as you don't need a null byte.

If you only control user, I'm pretty sure that's enough for an exploit. You could pad your shellcode so as to only have to write the higher bytes of the target address. Then you'd only need a single %c and a single %hn.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.