C/C++ Secure Code Development - Heap Overflow, Memory Leak, Use After Free // International Team

Beklenmeyen Misafir

International Team Moderator
12 Ara 2021
131
121
Derya'ya Yakın Dünya'dan Uzak
Hello, we talked about the stack structure in the previous section and we talked about the stack, which is basically one of the two parts of the memory. Now, by talking about heap, I will talk about the difference between stack and heap, why we use heap, what is dynamic memory management, and the use after free weakness caused by heap overflow, memory leak, dangling pointer.

To go to the first topic : C Güvenli Kod Geliştirme - Stack Overflow Zafiyeti

What is HEAP?

As I mentioned above, our values are kept in stack and heap regions in ram. We usually allocate a certain number of bytes statically while using the stack, this area is allocated in the stack and we cannot go above this area. In other words, if we have a certain size area, we can say that we use a stack. However, when we switch to the Heap side, we come across the concept of dynamic memory management. In other words, if we are going to keep our values in the heap, this field can be an area that takes up space on the ram in a changeable way for us. So, for example, you will receive a certain list of numbers from the user and you need to allocate a certain space to keep these numbers in ram. But the amount of space to be allocated here is not fixed, if you allocate a limited capacity for this reason under the control of the user, it will cause undesirable results and the dynamism of this work will disappear. Therefore, if the user is going to enter 5 values, an automatic field should be allocated accordingly.

Remember that stack is compiler-managed and heap is developer-managed, so this is where dynamic memory management comes into play.

Memory Leak
In order to understand the memory leak event, I first want to compare the event here with the stack.
6fnr3dl.png

Now I'm inside the main functions I'm in the main scope map. I'm compiling my application, I'm driving the last application breakpoint with the parentheses on line 14, that is main use.
cx17eb7.png

In this case, I see that the x value is kept in my stack area. Isn't it a very normal situation, let's take a look at another image.
lmhl049.png

Look, when I breakpoint the end of the main field and check the existence of my x value in the stack, I see that it does not show in the locals field. So why is this happening? If you look carefully at the code, the variable x is inside main but now in a different scope because it sits in a separate bracket.
j86jxtg.png

Look, when I stop my program at line 12, I see that the yield in the relevant scope is in the stack. From here, we need to understand that our data is pushed within the scope of the stack, and when it goes out of scope, it pops up, that is, it is cleaned from the stack and does not take up space on the ram unnecessarily. Now let's manage our data with heap.
q2ctkby.png

Now here I have defined a variable named array of type int. I get element count from user and manage my array value dynamically with calloc. As the first parameter, I give the value of n, that is, the number of elements, and as the second parameter, I give the data type of these elements as int. In other words, 4 bytes of int type will be allocated for each element. When I compile the program and give the number of 3 elements, it allocates 3 elements in the ram and gives the initial values as 0. So we haven't entered the values yet, we just gave the number of elements and dynamically allocates space for 3 elements and assigns an initial value to them. When we fill in the values, these 0 values will be replaced by our values.

qk3v2rw.png

When I stop and examine my program at line 21, we can see that the value of my array is 0 in memory, and 3 elements are kept in n and i.




qttmd4w.png

Now when doing the same structure with malloc instead of calloc, malloc takes a single parameter. We multiply the number of elements by the data type and allocate space accordingly, and if we look at the result, 0 values do not appear. That is, malloc does not initially assign a value for the relevant fields. Here, briefly, malloc and calloc allocate space in memory according to the value received from the user. Now let's examine the memory leak event by making a different example.

After a data was processed in the stack, it deleted itself, so it did not continue to take up space. However, this does not work in this way when we manage the data with the heap structure. Here, while managing the memory, the software developer should pay attention to this detail, and the relevant area should be allocated and cleaned after the process is completed.
mh7s9zh.png

Now let me explain what I did here. First of all, I created a struct called POINT and gave two values. In Main, I provided the struct values to be dynamically retrieved with malloc, and after giving the relevant values in the 20th and 21st lines, I printed the values to the screen. What happened as you can see? The data written to the screen, the data we define, is quite normal. Later, I emptied this allocated memory area with this free and when I reprinted the values, I saw irrelevant values and as it can be understood from here, I emptied the relevant memory area with free and prevented the memory leak event.


Here, let me show the memory leak event on a C++ application.
rb71fk6.png

Here I create a class called X and define the moment X is created and deleted. After that, I create a scope in main and use it by creating a variable object named a from the X class in this field, and I also print the messages before and after the scope before and after the rooted parentheses.

hm3kq6y.png

This is how I got the output. So what happened? Our program started to be processed line by line in the main function. He suppressed the first message that came across. Then, by entering the relevant scope, he caught the moment when it was created through the object derived from the X class, said it was deleted when it was finished, and went out of the scope and printed the post-scope. In other words, when the scope ended, it called the destructor method and deleted the object and continued on its way. These are quite normal, we know that the data from the stack is popped when it goes out of a certain scope. Currently, there is no heap structure here, there is no dynamic memory, so this data is kept on the stack.

Now let's keep this on the heap.
gcpwh23.png

Here we keep our value in the heap field using the new keyword. Now let's see the result.
38xtaal.png

Look what happened It came before scope, entered scope and created the object, went out of scope, but passed after scope without processing the destructor method that deleted the object. In other words, going out of scope did not delete the data because we, the developer, need to delete it in the heap. When kept on the stack, the compiler did it for us. As you can see here, we left a memory leak vulnerability while keeping our data in the heap. This memory space has been allocated but continues to take up space because it is not deleted when it is finished. This will cause a serious performance issue.
rp7yarl.png

Here, after defining the value in the heap, the variable p keeps the address that the relevant value points to, and we delete it by deleting it. If we look at the output, the object is created, it is deleted as soon as it goes out of scope.


Heap Overflow Vulnerability
Heap overflow, as in stack overflow, is a vulnerability that occurs as a result of overflowing the allocated space for memory management.
dvgw18b.png

I wrote a simple application about it. Now let's comment our related code blocks. We have a source variable of char type that takes 200 bytes. This source variable is kept in the stack. Just below it, there is the char-type dest variable, and with malloc, heap takes 10 bytes. The values received from the user with the fgets method are kept in the source variable, that is, in the stack. Note that it is imported with fgets and the capacity of the source variable will not exceed 200 bytes, because fgets checks this in the second parameter it receives. In other words, a weakness caused by the stack base is prevented here. But the matter does not end here, of course. The strcpy method will copy the data kept in the source to the dest area, that is, to the area limited to 10 bytes in the heap. E source can take up to 200 bytes of data, but dest only takes up to 10 bytes and if a value larger than 10 bytes is given to dest, an overflow occurs in the base of the heap.

mm1qzx3.png

As you can see, I sent too many a characters, maybe 500, but we need to know that the source can keep the 200 byte limit, so at the end of the day, if I send 1000, the source will take a maximum of 200 bytes and write a maximum of 200 bytes to the dest variable in the heap, which is also the application's enough reason for the heap to overflow.
mggik17.png

Now, to make my application safe, I use the strncpy method and as the 3rd parameter, I tell it to include 5 characters from the source to be kept in the heap and avoid overflow by not exceeding the 10 byte limit. At the same time, after copying the data on the heap and ending my process, I free up my space with free within the memory leak measure.

Use After Free Vulnerability
Now let me explain this weakness in theory. We allocate some memory to store a message using malloc which returns a pointer called ptr. Then we used the data stored at the address shown by the ptr, and when we were done, we cleaned it with free. Then we created the ptr2 pointer again using malloc. This information was written to the region where the address pointed by the ptr pointer, which was just emptied, was written, and the address of the relevant block was returned to ptr2. So ptr and ptr2 are starting to store the same block address. This is what we call use after free.
r0uh6is.png

Look, after allocating 5 integer values on the heap with malloc, I empty it with free. If you pay attention to the address of the last value, namely 126, after creating one more integer value in heap with malloc, you can see that it shows the same address as the first freed memory address. So now there are two different values pointing to the same memory address. This is the demonstration of the use after free event in practice. So malloc allocates the memory address, while free frees the allocated memory address. The event here is also called dangling pointer. So our ip pointer is now a dangling pointer. We freed up space with Free but it continues to point to a freed memory address.
54kh3pe.png


Look at the addresses I marked in red, that is, the values 1 and 126 continue to point to the same memory address. What we need to do here is to free the memory address as well as update the value of the pointer to NULL.
rn9u9kf.png

Freele, then update to NULL.



Thank you for reading.

Video Lecture



Original Subject:: https://www.turkhackteam.org/konula...-overflow-memory-leak-use-after-free.2014350/
 
Üst

Turkhackteam.org internet sitesi 5651 sayılı kanun’un 2. maddesinin 1. fıkrasının m) bendi ile aynı kanunun 5. maddesi kapsamında "Yer Sağlayıcı" konumundadır. İçerikler ön onay olmaksızın tamamen kullanıcılar tarafından oluşturulmaktadır. Turkhackteam.org; Yer sağlayıcı olarak, kullanıcılar tarafından oluşturulan içeriği ya da hukuka aykırı paylaşımı kontrol etmekle ya da araştırmakla yükümlü değildir. Türkhackteam saldırı timleri Türk sitelerine hiçbir zararlı faaliyette bulunmaz. Türkhackteam üyelerinin yaptığı bireysel hack faaliyetlerinden Türkhackteam sorumlu değildir. Sitelerinize Türkhackteam ismi kullanılarak hack faaliyetinde bulunulursa, site-sunucu erişim loglarından bu faaliyeti gerçekleştiren ip adresini tespit edip diğer kanıtlarla birlikte savcılığa suç duyurusunda bulununuz.