Apparently, the solution has something to do with the [Chinese Remainder Theorem][1], because I found and [stackexchange entry][2]. I spent some more time reading up on the CRT but unfortunately did not learn how to solve the problem.
[1]: https://en.wikipedia.org/wiki/Chinese_remainder_theorem
-[2]: https://math.stackexchange.com/questions/2689987/solving-cubic-congruence
\ No newline at end of file
+[2]: https://math.stackexchange.com/questions/2689987/solving-cubic-congruence
+
+
+
+## Securealloc (Warm-up, pwn)
+
+### Description
+ The key to success in the battlefield is always the secure allocation of resuorces!
+ nc 76.74.177.238 9001
+
+Archive with
++ libc.so.6
++ libsalloc.so
++ securalloc.elf
+
+We are given a binary and a library together an specific version of libc. The binary runs on a remote host and takes input on port 9001. Upon connecting to the host/port we are given a menu with the following options:
+ 1. Create - asks for size, allocates memory of given size
+ 2. Edit - write to the allocated memory
+ 3. Show - print content of memory
+ 4. Delete - free the memory
+
+![menu.png][menu]
+
+From that, I concluded the challenge has something to do with heap exploitation.
+
+### Attempt
+I am not that familiar with binary exploitation, I never did a heap overflow challenge and only some basic stack overflow exploits, so I did not know what to expect.
+First of all, I just played around with the binary and tried some unusual inputs to maybe produce an error, e.g. edit before create and writing more than the specified size. Both of these attempts resulted in an error, see the images below. The error `*** heap smashing detected ***: ...` was new to me, I knew that gcc prints a stack smashing error but I`ve never heard of this one. I googled the error message but did not get any results so I assumed it is a custom error message.
+
+![segfault.png][segfault]
+![heapsmash.png][heapsmash]
+
+Next, loaded the binaries into ghidra to disassamble/decompile them and look at the code. I pretty quickly found the main function, then inspected the code some more and did some variable and function renaming.
+The main function (see below) does some initialisation and then prints the menu, takes the user input and performs some action based on it in an infinite loop.
+
+```c
+void main(void)
+{
+ int extraout_EAX;
+ init_stuff();
+ do {
+ print_menu();
+ if (extraout_EAX == 2) {
+ edit();
+ }
+ else {
+ if (extraout_EAX < 3) {
+ if (extraout_EAX == 1) {
+ create();
+ }
+ else {
+LAB_00100dad:
+ puts("Invalid option");
+ }
+ }
+ else {
+ if (extraout_EAX == 3) {
+ show();
+ }
+ else {
+ if (extraout_EAX != 4) goto LAB_00100dad;
+ delete();
+ }
+ }
+ }
+ __heap_chk_fail(DAT_00302050_pointer_to_memory);
+ } while( true );
+}
+```
+To get the input from the user, the functions `userInput()` resp.`readInput(..)`are used. I took a closer look at these function because I already knew there was some kind of overflow in the code due to the errors from before. Indeed, in `readInput` (see below) there is an infinite loop that uses `read(..)` to get the user input and store it in the give buffer. The loop does not check the buffer size and only terminates after a `\n` is encountered.
+```c
+char * readInput(char *param_1)
+{
+ ssize_t sVar1;
+ char *buffer;
+ buffer = param_1;
+ while( true ) {
+ sVar1 = read(0,buffer,1);
+ if (sVar1 == 0) {
+ /* WARNING: Subroutine does not return */
+ exit(1);
+ }
+ if (*buffer == '\n') break;
+ buffer = buffer + 1;
+ }
+ *buffer = '\0';
+ return buffer + -(long)param_1;
+}
+```
+
+
+I also noticed that the `init_stuff()`,`create()` and `delete()` functions use the functions `secure_init(..)`, `secure_malloc(..)` and `secure_free(..)` from the `libsalloc.so` library, so I took a look at them. The `secure_init` function appears to read `8*8` bytes from `/dev/urandom`, performs a bitwise `and` with the value `0xffffffffffffff00` and saves the result at a fixed address or offset which I named `canary`. As to why, that will be clear shortly.
+The other two appear to be wrappers for their respective functions of the c library, namely `malloc` and `free`.
+
+```c
+void secure_init(void)
+{
+ FILE *__stream;
+ int local_14;
+ __stream = fopen("/dev/urandom","rb");
+ if (__stream == (FILE *)0x0) {
+ /* WARNING: Subroutine does not return */
+ exit(1);
+ }
+ local_14 = 0;
+ while (local_14 < 8) {
+ fread(&canary,8,1,__stream);
+ local_14 = local_14 + 1;
+ }
+ fclose(__stream);
+ canary = canary & 0xffffffffffffff00;
+ return;
+}
+```
+`secure_malloc` actually allocates `0x10` bytes more than specified by the user and then returns a pointer that does not point to the start of the memory region but 2 addresses in. This is done because at the beginning, the `size` given from the user is stored. At the end of the memory region ( at `puVar1 + 8 + param_1`, which I think should be enough space for `8 * sizeof(unit)`), the value at the address `canary` is stored. That is the value that was written by the `secure_init` function.
+```c
+uint * secure_malloc(uint param_1)
+{
+ uint *puVar1;
+
+ puVar1 = (uint *)malloc((ulong)(param_1 + 0x10));
+ if (puVar1 == (uint *)0x0) {
+ /* WARNING: Subroutine does not return */
+ __abort("Resource depletion (secure_malloc)");
+ }
+ *puVar1 = param_1;
+ puVar1[1] = param_1 + 1;
+ *(undefined8 *)((ulong)param_1 + 8 + (long)puVar1) = canary;
+ return puVar1 + 2;
+}
+```
+
+At the end of the main loop, there is a call to `__heap_chk_fail(pointer)` which is defined in `libsalloc.so`. This is the function that prints the error message `*** heap smasing detected ***: ...`.
+It appears that the function checks if the given pointer contains the value of the `canary` at a certain offset. I did not really make sense of all the pointer arithmetics but from that I concluded that the `secure_*` functions basically implement `stack canaries` but for the heap. That´s also the reason I renamed the variable `canary`.
+
+```c
+void __heap_chk_fail(long param_1)
+{
+ if (((param_1 != 0) && (*(int *)(param_1 + -4) - *(uint *)(param_1 + -8) == 1)) &&
+ (*(long *)(param_1 + (ulong)*(uint *)(param_1 + -8)) != canary)) {
+ /* WARNING: Subroutine does not return */
+ __abort("*** heap smashing detected ***: <unknown> terminated");
+ }
+ return;
+}
+```
+
+To summarise, I new that I could allocate memory of arbitrary size (actually + 0x10 bytes), free the memory and write to it. I could also overflow that buffer by writing more bytes than the actual size. So I had to either somehow leak the canary or otherwise circumvent the heap canary check to exploit the vulnerability.
+Unfortunately, I did not know what to do with that so I started reading up on how memory management works and how to do heap exploitations [1] [2] [3] [4] [5]. Understanding how malloc works was relatively easy but took some time. On the other hand, applying the new knowledge proved quite difficult and I did not really know where to start because it looks like there is no holy grail of heap exploits which allows you to perform certain steps which always result in a successful exploit. So after working on the challenge for about 1 and a half days I saw myself defeated and had to give up.
+
+
+[1]: https://sourceware.org/glibc/wiki/MallocInternals
+[2]: https://sploitfun.wordpress.com/2015/02/10/understanding-glibc-malloc/
+[3]: https://sploitfun.wordpress.com/2015/02/26/heap-overflow-using-unlink/
+[4]: https://sploitfun.wordpress.com/2015/03/04/heap-overflow-using-malloc-maleficarum/
+[5]: https://github.com/shellphish/how2heap
+
+[menu]: ./asis19/menu.png
+[segfault]: ./asis19/segfault.png
+[heapsmash]: ./asis19/heapsmash.png