1)
m s
+-----------------+-------------------------------------+
|AAAAAAAAAAAAAAAAA| |
+-------------------------------------------------------+
^ ^
| |
+ +
src dest
If m
contains exactly 100 bytes and is not null-terminated, then what will happen after strcpy(s, m)
?
After 100 bytes are copied:
m s
+-----------------+-------------------------------------+
|AAAAAAAAAAAAAAAAA|AAAAAAAAAAAAAAAA| |
+----------------------------------+--------------------+
^ ^
| |
+ +
src dest
As there is no null-byte at src
, it will keep copying:
m s
+-----------------+-------------------------------------+
|AAAAAAAAAAAAAAAAA|AAAAAAAAAAAAAAAA|AAAAAAAAAAAAAAAAAAAA|
+-----------------+----------------+--------------------+
^ ^
| |
+ +
src dest
and it will keep copying like this until it finds a null-byte (which it obviously never will) and will destroy the stack and will continue copying until it runs into an unmapped address and causes a segmentation fault.
2) Free'\0'$1.50
. x
will be 1
, y
will be 50
, but strcpy(s, m)
will copy Free
to s
.
3) Free'\0'$0.50000
. x
will be 0
, which will pass the check at L10
, but y
will be 50000
, and L13
will yield 100*0 + 50000
, or $500
.
Updated answer for 1:
You are probably having trouble replicating it because the size of m
and s
are not actually 100 and 200 but something like 112 and 208 (depending on the preferred stack boundary of your compiler). So s
does not start exactly where m
ends. And if there happens to be no leftover data from previous stack operations in that extra space, then this will not work. The question mentions 'potentially' crashing the process, as this will not work in all platforms and in all contexts.
The key thing to note here is that running strcpy
on a src
buffer that may not be null-terminated is an unsafe operation. For example, as m
and s
are uninitialized, there might be leftover data from previous stack operations which will then cause strcpy
to go berserk. Example snippet:
#include <stdio.h>
#include <unistd.h>
#include <string.h>
void randomstuff()
{
unsigned char buf[400];
for (int i = 0; i < 400; i++)
buf[i] = 'A';
buf[399] = '\0';
}
void vuln()
{
unsigned char m[100];
unsigned char s[200];
read(0, m, 10);
strcpy(s, m);
printf("%s\n", m);
}
int main(void)
{
randomstuff();
vuln();
return 0;
}
Here, we are making sure there is some stuff on the stack where m
and s
resides (a string of 399 A
s). Note that we are reading only 10 bytes into the 100 byte m
buffer. Yet literally provide any input to read
to watch this program burn.
E_DOLLAR
is implemented, if there is no successive numeric character right after $, it will return 0. So -$300.00 or $-300.00 shouldn't crash the program – Prashin Jeevaganth Nov 21 '19 at 19:30