Search code examples
csecuritystring-formattingexploitformat-string

Format string exploit length


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:

 int guess(char *user) {
     struct {
          int n;
          char usr[16];
          char buf[16];
      } s;

      snprintf (s.usr, 16, "%s", user);

      do {
          scanf ("%s", s.buf);
          if ( strncmp (s.buf, "DEBUG", 5) == 0) {
              scanf ("%d", &s.n);
              for ( int i = 0; i < s.n; i++) {
                  printf ("%x", s.buf[i]);
              }
          } else {
              if ( strncmp (s.buf, "pass", 4) == 0 && s.usr[0] == '_') {
                  return 1;
          } else {
              printf ("Sorry User: ");
              printf (s.usr); //#line 26 vulnerable line
              printf ("\nThe secret is wrong! \n");
              abort ();
          }
          }
      } while ( strncmp (s.buf, "DEBUG", 5) == 0);
  }

 int main(int argc, char** argv) {
      guess(argv[1]);
 }

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 15 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?


Solution

  • \x15\x45\x41\x42\x17\x45\x41\x42%16940c%7$hn%563c%8$hn does indeed refer to a sequence of 30 chars/bytes. snprintf (s.usr, 31, "%s", user); would therefore be needed to copy it.[1] The extra count is because snprintf reserves a space for a NUL.

    Since you need s.usr to be the start of a sequence of 30 characters, and you can only place 15 of the necessary characters there, your exploit can't work as-is.

    This doesn't mean that the bug can't be exploited. It may be possible to write a shorter exploit that jumps to the remaining exploit located somewhere else, e.g. in user.[2] But I don't have the necessary knowledge to asses the feasibility of this.


    1. Of course, you would also need a larger area in s.usr, at least under normal circumstances.
    2. user would contain <15-byte exploit><remainder of exploit>. The 15-byte exploit would jump to the remainder of the exploit.