Skip to content

Latest commit

 

History

History
 
 

Memory_Exploits

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Memory Exploits

Memory Corruption

  • Unbounded data copying is bad.

  • Lots of APIs:

    • strcpy()
    • strcat()
    • sprintf()
    • gets()

strcpy

  • Memory corruption basic example:
int vul_fc(char *userstring)
{
    char buf[128];
    strcpy(buf, userstring);
    /*..*/
}

strncp and NULL byte

  • Better APIs can be not used properly, for eample strncpy(), it the parameter to limit lenght is not understood:
int vuln_function(char *userstring)
{
	char buf[128];
	strncp(buf, usertring, strlen(userstring));
	/*..*/
}
  • If the lenght does not account for NULL termination: the amount of data to copy is greater than or equal to size of buf, no NULL byte will be placed:
int vuln_function(char *userstring)
{
	char buf[128];
	strncp(buf, usertring, sizeof(buf));
	/*..*/
}
  • The correct would be sizeof(buf)-1.

  • C string functions need to have a NULL byte to know where the string ends. Later in the code, it will assume that the string is only as long as the sizeof(buf) when in reality the string is as long as wherefer the next NULL is in memory.

  • This could be an adjacent piece of memory the attacker controls, such as another buffer declared on the stack.

strncat

  • For example string concatenation strcat(). This function appends a string from the source buffer to the destination buffer, adding to the end of an existing C strng in dest.

  • The size parameter does not account for daa already in the destination buffer:

int vuln_function(char *string)
{
	char buf1[256];
	strncat(buf1, "static data", sizeof(buf1) - 1);
	/*..*/
	strncat(buf1, string, sizeof(buf1)-1);
}
  • If there is already data in buf1, it can overwrite beyond the buffer!

Wide-characters

  • Many misunderstandings with wide-characters such as wchar_t.

  • Under win32, wchar_t is 16 bits (UTF-16 code unit). On linux, wchar-t is 32 bits (UTF-32).

  • Size miscalculation can happen by not considering that sizeof() returns count of 8 bit chars and wchar_t is larger than that:

int vul_funcion(char *string1)
{
	wchar_t buf1[256];
	mbstowcs(buf1, string1, sizeof(buf1)-1);
}
  • The size lenght is given as sizeof(), however the size argument for mbstowcs() is the count of wide characters to write. Wide characters are bigger than bytes:
wchar_t buf1[256];
mbstowcs(buf1, string1, sizeof(buf1)-1);
  • On Windows, where wchar_t is 16 bits, sizeof(buf) is 512. In the above code, a copy of 511 wide-characters is copied into the destination buffer, when it was intended to be 255.

Data Type Signedness

  • Primitive data types (32 bit):

    • signed char/unsigned char
    • signed short/unsigned short
    • signed int/unsigned int
  • Redefinitions used for sizes:

    • size_t (unsigned)
    • size_t (signed)
  • By default all data types are signed unless specifically declared otherwise.

  • Many functions which accept size arguments take unsigned values.

  • char y=-1 has the same bit representation than unsigned char x=255.

  • A large value in the unsigned type (highest bit set) is a negative value in the signed type.

  • Function read() takes only unsigned values for lenght. So if this value is negative, from a if comparison, it will overflow.

  • For example, if lenght is -1 (which is 0xFFFFFFF), when the length check is performed, it is asking if -1 is less than a MAXNUMBER. Then, when the lenght is passed to read, it is converted to unsigned and becomes the unsigned equivalent of -1 (which for 32 bits is 42949672965).


Integer overflow

  • Exceeding the amount of data in integer will result in wrapping. In the example below, x will be 0:
x = 255;
x += 1;
  • Pointer overflow: pointers are unsigned integers:
int StrStuff(int sock, char *buf, size_t buflen)
{
	size_t dataSize;
	char *maxpoint = buf + buflen;
	dataSize = readDataSize(sock);
	if (buf + dataSize < maxpoint)
	{
		read(sock, buf, dataSize);
		return 0;
	}
return 1;
}

Integer Overflow Exploitation

  • In the code below, buf is intend to have enough space +1 to store a NULL byte for a string.
  • If the network data supplied is 0xFFFFFFF (max 32 bit value), when 1 is added, it will wrap to 0. This means that the length passed to malloc is zero bytes.
  • malloc() will return an under-sized buffer that allows memory corruption in read().
int getData(int sock)
{
	unsigned int len;
	char *buf = NULL;
	len = getDataLen(sock);
	buf = malloc(len + 1);
	read(sock, buf, len);
	buf[len+1] = 0x0;
}


Metacharacter Injection

  • In shell: quotes and semi-collon are metacharacters.

  • Example, a command to unzip some input file could lead to a second executable command if the input has a ;:

void extractUserZip(char *userFile)
{
	char command[1024];
	snprintf(command, 1023, "unzip %s", userFile);
	system(command);
	return;
}


Auding Tips

  • grep for malloc() and other memory allocation functions.
  • look at the data types for size calculation.
  • look at values used for size checks: are they signed?
  • what happens if negative values are provided.
  • look for eval functions such as system().

Folders

Assembly

  • Shell spawn

Buffer Overflows

  • Stack overflow examples

Integer Overflows


Tools


C-codes

  • Get env variable

Disclaimer

Some of these scripts are older and some of them are not mine. If you see code you recognize here please let me know in a Issue so I can assign proper credit.