0

I'm preparing for an introductory information security examination in university and this is one of the examination questions on Secure Programming.

In such questions, I would usually catch for Buffer Overflow or Integer Overflow that lead to other consequences, but due to the context of the problem, I did not manage to find any vulnerabilities in this program.

Can someone help me out here with the questions? The answers are not provided by the school. Sorry in advance, the actual paper document is not formatted such that it allows copy over.

Here is the question.

Pic 1

Pic 2

  • Okay no overflow.But what if you put x or y to be negative?It will pass the if condition and then (100*x+-y).That might be vulnerable – Vipul Nair Nov 21 '19 at 19:17
  • I actually haven't tried out the interaction of putting negative values into unsigned variables. But from the looks of how 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
  • 1
    I see some bad things. What have you tried already? – Birb Nov 21 '19 at 21:44
  • I don't have the original code so I did this question by eyepower. Currently I think Integer and Buffer Overflow isn't detected here, don't detect anything else @Birb – Prashin Jeevaganth Nov 22 '19 at 1:38
2

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 As). 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.

  • Thank you for your answer. I kind of get the idea, but somehow I can't replicate the bug even with a code snippet. Do you mind adding it here to your answer? – Prashin Jeevaganth Nov 22 '19 at 11:55
  • 1
    I tried to replicate this as well, but couldn't get strcpy to keep reading. – MechMK1 Nov 22 '19 at 13:05
  • Updated the answer. – rhodeo Nov 22 '19 at 20:10
  • E_DOLLAR and E_CENTS are supposed to be implemented correctly and securily so then shouldn't they stop reading after encountering an \0 in m? In my opinion that would be the correct implementation even though it's not specifically mentioned in the algorithm. – milk Nov 22 '19 at 21:49
  • @milk how did the answer imply that the bug is in E_DOLLAR and E_CENTS? – rhodeo Nov 23 '19 at 16:07

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.