Closed mdulin2 closed 4 years ago
In general, the poc looks good.
However, how2heap is not just designed for a single libc build. It should be applied to different builds of the same version of libc.
I would like to see changes to get rid of hardcoded values.
For example, the least significant 3 bytes of __malloc_hook
can be calculated dynamically by __malloc_hook & 0xffffff
.
And although house of roman is usually used with malloc + one gadget
, it is not good for presentation(and still, not portable across builds).
My suggestion is to overwrite __free_hook
with system
and execute echo
to demonstrate the power of the technique. And this way, you don't need to worry that you can't find one gdaget
dynamically.
Hey Kyle, thanks for the feedback.
I agree with their being some portability needing to be added to this. There's literally no portability in this. It's difficult to get this to work (especially with the 12 bits of randomness).
However, the whole purpose of the POC is to demonstrate a leakless technique. I feel that calculating values dynamically (even if the values are not being brute forced) would confuse those who are trying to understand the technique, considering this is supposed to be a leakless technique.
Thoughts on how to work around this?
Additionally, going over the technique again, I noticed that the __free_hook being overwritten with malloc requires a leak in order to perform, which I feel defeats the novelness of the technique.
I agree with their needing to be an increase in portability but I do not want to remove the novelness of the technique.
How could we make this portable without removing the leakless aspect of it?
@mdulin2 I see. you are saying the address of unsortedbin is far away from free_hook so we have to get a leak(or bruteforce more bytes). Then use __realloc_hook then. It's right next to malloc_hook and take a pointer as the first argument. About the 12bit randomness. I think you can tell the reader that you assume that the guess is correct and emphasize it.
Yes, exactly. For the current POC, the fake fastbin chunk uses the chunk size from the __realloc_hook.
However, this is not available in the __free_hook. So, the technique used in the POC for using the free hook uses the unsorted_bin attack in order to create a 0x7f value that can be used for a fake fastbin chunk. Then, (after getting a leak to LibC) you write to the fake chunk, which is now over the free hook.
I thought of a better way to do with, without getting rid of the leakless approach (using the free hook would get rid of this).
I agree, specifying that a value would normally be random and really emphasizing it would work well (in order to make the POC work everytime).
The other thing was that instead of using the one_gadget we could overwrite the __mallochook with system. Then, upon the next call to malloc, have a size that would be the same as /bin/sh_. That would make the execution version independent and work on most boxes.
Thoughts on this Kyle? I think this is a good way to solve the portability problem and take the luck out of it.
@mdulin2 I think that's a good idea.
Okay, this exploit works on the builds of 2.23 and 2.24 that I have tested on. I removed the randomness and used system instead of a one_gadget. This was not without its troubles though.
I had some issues on 2.25. I attempted to run this on 2.25 and the __malloc_hook gets overwritten. However, the pointer to /bin/sh does not stay intact for some reason and I am unsure why.
I additionally I ran into some other trouble with the __malloc_hook is not actually a symbol that can be seen within a normal program. So, I just decided to calculate this value based upon the location of the main arena. From the testing on 2.23, 2.24 and 2.25 that I did, this worked on all of the versions.
Thoughts?
It works on ubuntu17.04.
And I checked, it is actually a bug in glibc_run.sh
. oop.s
^ ignore above. I haven't found out the reason why yet.
The reason is libc is too large so there is a huge gap between text section and data section. There is chance that the forth least significant bytes are different(according to my observation, just last bit). But the chance is not super high. This is the nature of this technique, you will suffer from it too even if you use one_gadget.
So it is the "system" pointer corrupted not the /bin/sh pointer.
Location of fastbin_victim: 0x0x55fe2d43e110
Original fd of ptr: 7f871e352bd8
__malloc_hook = 0x7f871e352af0
fd of corrupted fastbin_victim: 55fe2d43e100
Overwritten of fake_libc_chunk 7f871e352acd
Malloc_hook chunk: 0x7f871e352add
Passed step 1
Address of System: 0x7f871dffa410
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x7f871effa410
──────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "house_of_roman", stopped 0x7f871effa410 in ?? (), reason: SIGSEGV
Okay, interesting! I did not consider the distance being so wide. My symbols for GLibC 2.25 don't load from the glibc_run.sh script; so, I'm kind of testing blind on that version.
I get the following output (even after adding the extra byte). I even tested this by adding all of the system address and got the same output.
Location of fastbin_victim: 0x0x5590b9fd6110
Original fd of ptr: 7f6cca0e2bd8
__malloc_hook = 0x7f6cca0e2af0
fd of corrupted fastbin_victim: 5590b9fd6100
Overwritten of fake_libc_chunk 7f6cca0e2acd
Malloc_hook chunk: 0x7f6cca0e2add
Passed step 1
Address of System: 0x7f6cc9d88390
sh: �1l��: ��^V: Error 236481354
This makes me think that the pointer is getting corrupted somehow.
I can't replicate it on my local machine. But I think you may print the sh_ptr and print the value of __malloc_hook
at the end to see what's going on
Okay, that's interesting. I'm also running this on Ubuntu 16.04, just for context.
@Kyle-Kyle Did the POC's for 2.23 and 2.24 work fine for you then? Additionally, with the added bit, does it work on 2.25 for you?
Thanks for the good and willing feedback! I really appreciate it.
on ubuntu 17.10(with glibc 2.25). It works 100%.
Great! Glad to hear that.
It appears that I might just have something weird going on in my env that is causing me issues. If it works on 2.23 and 2.24 on Ubuntu 16.04 and 2.25 on Ubuntu 17.04. So, I'll just move on from that.
If it works in 2.23, 2.24 and 2.25, I feel that this is modular enough then. I think that problem has been solved 🔥
Is this ready to go or is there anything else you would like to see that added/changed in the POC?
Yeah. There is only one small thing left. It looks like your output is not clear and structured. Usually, a technique file will tell reader what is going on(what stages) through the output so user can easily identify what is going on and where to insert debug code. You may simply move some of your explanations to output and add some output like "Step1, we perform unsorted bin attack to overwrite __malloc_hook with unsorted bin address". Something like that.
Yeah, that's a great point. The output is pretty bad at the moment; I invested the bulk of time in the comments. I'll get fix the output in the next few days.
Thanks again for the feedback!
I added the guiding print statements to the code. I really like how the structure of the house_of_orange is done. When I went through this, I really enjoyed the in depth comments. Without the in depth comments (just guiding prints) it would have take me significantly longer to understand it. So, I tried to do something similar but added print statements to show the progress.
It looks good to me. Let's merge it. Thank you so much for the effort!
It looks good to me. Let's merge it. Thank you so much for the effort!
Absolutely! Thanks for the reviews and help along the way :)
Hey there, from previous mentions in https://github.com/shellphish/how2heap/issues/76 I wrote up a POC for the House of Roman.
The technique is fairly complex (and has 12 bits of randomness). So, I tried adding as many comments as I could in order to make the heap feng shui, relative overwrites and purposes of all decisions as clear as I could. Hopefully this helps those who were struggling to understand this technique.