aboutsummaryrefslogtreecommitdiff
path: root/en_GB/Introduction to Information Security
diff options
context:
space:
mode:
Diffstat (limited to 'en_GB/Introduction to Information Security')
-rw-r--r--en_GB/Introduction to Information Security/introduction_to_information_security.md54
1 files changed, 53 insertions, 1 deletions
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.