From 0bad90edb3a1e432b321832575a00c7a7292530c Mon Sep 17 00:00:00 2001
From: Leonard Kugis <leonard@kug.is>
Date: Sat, 7 Mar 2020 01:06:04 +0100
Subject: IntroSec

Added double free attack scenarios.
---
 .../introduction_to_information_security.md        | 54 +++++++++++++++++++++-
 1 file changed, 53 insertions(+), 1 deletion(-)

(limited to 'en_GB/Introduction to Information Security')

diff --git a/en_GB/Introduction to Information Security/introduction_to_information_security.md b/en_GB/Introduction to Information Security/introduction_to_information_security.md
index fbdd9ad..d1ce4fb 100644
--- a/en_GB/Introduction to Information Security/introduction_to_information_security.md	
+++ b/en_GB/Introduction to Information Security/introduction_to_information_security.md	
@@ -383,7 +383,7 @@ The password is `IntroSec`.
    so it is likely that there is no new correct char.
 4. The attacker continues, learning char by char for each processing time increase, until he got the full password.
 
-## Software Security
+## Memory management
 
 ### Buffers
 
@@ -391,6 +391,16 @@ Logically, values are assigned to variables.
 In reality, for every variable, a portion of memory on the call stack gets allocated (*buffer*), and the data gets written to that buffer.
 Data written to the buffer is written upwards from the address allocated to the buffer.
 
+### Allocation (Doug Lea)
+
+Memory is divided into chunks. These contain the user and control data (e.g. boundary tags (size, previous size)).
+Adjacent free chunks are unified to one free chunk automatically.
+Free chunks are stored in *bins*, which are connected in a double linked list, and sorted by size (ascending).  
+When a chunk is freed, `frontlink(...)` searches the *bins* list from lowest to highest size, and places the chunk in the list whenever
+the chunk in the next bin is bigger than the chunk itself, and inserts the chunk in the list in that place.  
+`unlink(...)` does the opposite. It takes the chunk specified, looks up the chunk in the bin list,
+and removes it by rearranging pointers of the next and previous bin.
+
 ## Threat scenarios
 
 No security issues without threat models! E.g. a password is considered safe without any provided threat model.
@@ -479,3 +489,45 @@ and overrides in wrong memory.
 - Protect return address using *canaries*.
   Special instructions placed before actually returning to check for correct return address.
 - Mark potential shellcode memory as non-executable.
+
+### Double Free
+
+#### Dependencies
+
+When `free(...)` is executed, `frontlink(...)` gets executed at some point transparently.  
+When `frontlink(...)` finds a place in the *bin* list to put the chunk, it sets the next pointer of the previous chunk
+and the back pointer of the next chunk to the inserted chunk.  
+If this chunk gets added another time, *the previous chunk is already the inserted chunk*!
+So the next pointer of the previous chunk gets gets linked to the inserted chunk.
+*But with the previous chunk being already the inserted chunk, the next pointer of the inserted chunk gets linked to itself.*
+Also, the back pointer of the inserted chunk gets linked to the previous chunk.
+*But with the previous chunk being already the inserted chunk, the back pointer of the inserted chunk gets linked to itself.*  
+Invoking a `malloc(...)` (and eventually an `unlink(...)`) now will result in the chunk *not being removed* from the bin list,
+due to the looping pointers on itself.
+
+#### Free-Free-Malloc-Malloc
+
+1. Prepare memory. These steps are for target and shellcode preparation. The chunks inbetween ensure, that the chunks dont get unified on `free`.  
+1.1 Allocate top memory chunk.  
+1.2 Allocate target chunk from top memory chunk.  
+1.3 Allocate top memory chunk.  
+1.4 Allocate shellcode chunk.  
+2. Perform `free` on target chunk twice.
+3. Call `malloc` with size of target chunk. We might get the target junk again, *but it won't get removed from the bin list*.
+4. Chunk is now writable. Overwrite *back* pointer with attack target address, and *next* pointer with attack target value.
+5. Call `malloc` again. `unlink` algorithm will overwrite memory at *back* with *next*.
+
+#### Free-Malloc-Free
+
+1. Allocate memory chunk *A*.
+2. `free(A)`, hope that the chunk gets unified with the following chunk.
+3. Allocate large chunk *B*, hope to get the chunk just freed.
+4. Write ghost chunk data to *B* so, that it appears to be a chunk at *A*, and an unallocated adjacent chunk.
+5. Call `free(A)` again. `unlink` is applied to ghost chunk. Unifying will overwrite a target address.
+
+#### Countermeasure: Canary
+
+Add *canary* to end of chunk, checksumming the chunks control data, signed with secret key.
+
+1. On allocation, add calculate checksum over chunk control data and add canary.
+2. On `free`, recalculate checksum. If they mismatch, throw error.
-- 
cgit v1.2.1