Reputation: 1608
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?
Upvotes: 3
Views: 880
Reputation: 385647
\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.
s.usr
, at least under normal circumstances.user
would contain <15-byte exploit><remainder of exploit>
. The 15-byte exploit would jump to the remainder of the exploit.Upvotes: 3