Saturday, December 31, 2016

Killing dragons spawned by arithmetic-related security pitfalls

In the last week, which followed my attempt to earn money with financial trading, I glanced through the Black & Scholes model.


This study resulted in the creation of OptionsCat, an open-source tool to work with European options. I faced many Arithmetic-related security pitfalls when writing this tool, which motivated me to study it and write a blog post.  

  

 I always develop my implementations for the algorithms presented throughout the finance books. That's because the writers are often careless about security pitfalls. From this article's perspective, this is a problem or dragon that can be solved by adding a chapter about validation.


Programming languages that enable direct memory access and do not provide buffer boundary checks and arithmetic numeric checks are particularly vulnerable to integer overflow attacks. An integer overflow may occur when computing the memory size to allocate a buffer, often leading to a buffer overflow.

 

 Look at the following quote: 


 "Integer overflows cannot be detected after they have happened, so there is no way for an application to tell if a result it has calculated previously is correct. This action can get dangerous if the calculation has to do with a buffer's size or how far into an array to index. Of course, most integer overflows are not exploitable because memory is not being directly overwritten, but sometimes they can lead to other bug classes, frequently buffer overflows. As well as this, integer overflows can be difficult to spot, so even well-audited code can spring surprises." 

 by blexim - Phrack Volume 0x0b, Issue 0x3c, Phile #0x0a of 0x10


Some people talk to me about the use of the Big integer library. Like LibGMP to solve it, but when you work with big int need limit that numbers, arithmetic operations with bigint when a user has input with considerable length can cause Denial of service. The use of Integers is not hard to find in the stock markets. But double is then expected and can bring you a problem if you don't control the length, for example:

#include < math.h>
#include < stdio.h> 

double mul_code(double x,double y) 
{
  double result=0;
   
  return result = x*y;
}

int main()
{
 double a=90000000000, b=20000000000000;

 printf("Result: %f\n", mul_code(a,b));
 return 0;
}

If you compile it and run it, it returns something like "1799999999999999916112.*(dirts...)". You ask me, "why to return it ?" you don't validate the operation and pass the carrying limit. This action can cause undefined behaviour and overflow.


Killing dragons in integers 


There are lots of ways for you to solve. One is validating user input. This way, you can use automatons, regular expressions, and strnlen() to limit the number of lengths. Remember phrack; the correct way to test for integer overflow during multiplication is to try before the multiplication, test if the number is negative, and replace functions like atoi() to strtol().

 

 

 Some operating systems have solutions at libraries to mitigate the problem. For example, OSX has os/overflow.h. With this header, you can do something like it:

#include < "os/overflow.h">
 
if (os_mul_overflow(m, n, &bytes)) {
    /* Overflow occured.  Handle appropriately. */
} else {
    /* Allocate "bytes" space. */

Another way to mitigate this way is from OpenBSD:

#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t)*4))
// based in OpenBSD reallocarray() function http://man.openbsd.org/reallocarray.3
void *reallocarray (void *ptr, size_t nmemb, size_t size) 
{
 if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && nmemb > 0 && SIZE_MAX / nmemb < size) 
 {
  DEBUG("integer overflow block");
  return NULL;
 }

 void *p = realloc (ptr, nmemb*size);

 if (p == NULL) 
  return NULL;

 return p;
}

Other approaches that you can see is the using libraries and different ways to write safe code with integers, sometimes calling each function safe_add()safe_sub(), safe_mul(), and safe_div() is very dull when having significant expressions, and thinking about it I wrote a solution, look my project Here!


Killing dragons in double



 The Cert C book by Robert Seacord has an example of solving the problem at the double, the derivatives and futures have a lot of operations with double, one way to detect possible bug is using the function fetestexcept() :







At inputs, don't use the atof() function. Replace to strtod(), and double look the following code here.


Thank you for reading.
Cheers!

1 comment:

The magic of bits

 Before the long tale to the course of magic bits, let's gonna for a little walk in the world of C language. Variable of type int has 4 ...