3

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?

12
  • 1
    Is your question why snprintf (s.usr, 16, ...) only copies 16 bytes into s.usr? (It copies only 15, actually, since it saves space for a NUL.) Commented Jul 6, 2020 at 19:03
  • 2
    I love everything about this post, your effort , the preciseness of your problem statement, etc. But putting the line numbers in makes it harder than it needs to be for someone to paste your code into their compiler and run it. You can mark `line 26 eg by marking it with a comment. +1 Commented Jul 6, 2020 at 19:04
  • @ikegami No, my question was: 1) Am i still able to "perform" my format string exploit? Since only 15 character/bytes are copied inside s.usr. 2) Is my counting of the length of my format string exploit correct? Is it 30 bytes/characters long as i thought? Commented Jul 6, 2020 at 19:07
  • 1
    Re "my question was: 1) Am i still able to "perform" my format string exploit?", Obviously no. If you need 30 bytes, and you have 15, it's not going to work. /// But if you're asking if it's possible to exploit it by some other means, then I don't know. Is 15 bytes long enough to jump to a location in the larger user? Commented Jul 6, 2020 at 19:10
  • 2
    Re "2) Is my counting of the length of my format string exploit correct?", It is 30 chars/bytes long. You would need snprintf (s.usr, 31, "%s", user); to copy it all. Commented Jul 6, 2020 at 19:13

1 Answer 1

3

\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.
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.