October 16, 2021
Exploiting heap based vulnerabilities tends to be difficult, complex and requires a deep knowledge of the library itself. As years go by, new techniques are discovered for exploiting the allocator, as well as changes being made to make the allocator more secure. The never ending cat-and-mouse game that is cybersecurity.
In 2020, several techniques were published in the House of IO that required rare primitives to achieve. Among these, the House of IO - Underflow allowed for the returning of arbitrary memory addresses from Malloc with a buffer underflow vulnerability. This could even bypass pointer mangling/encryption! In his article, we will discuss a primitive improvement to the House of IO - Underflow that may be useful in real world exploitation: a single buffer overflow with careful heap alignment. A proof of concept can be found at House of IO - Heap Reuse if you would like to follow along.

September 26, 2021
The root cause of many vulnerabilities are from the mishandling of numbers. The standard int type can go from 0x7FFFFFFF all the way to -0x80000000 (notice the negative) with an integer overflow. Or, it can be truncated and change the number from positive to negative. Integers can be a nightmare in C and have caused many memory corruption vulnerabilities over the years.
Recently quite a few findings have caught my attention that fall into the integer bug classes. A few to call out are the integer truncation bug in the Linux kernel found by Qualys, the signedness conversion bug (issue 2) in the BSD hypervisor by GHSL and an integer overflow in the Kindle on a buffer allocation size found by Checkpoint. Then, my hacking buddy seiraib found an integer overflow bug fuzzing but we could not find where the overflow actually occurred at. All of this got me wondering: "Can these bug classes be discovered at compilation or immediately crash at runtime?"
Yes, yes they can! GCC and Clang have compilation flags to find several bug classes at compile time. Additionally, there are some runtime protections that can cause crashes to make root causing MUCH easier. This blog post is about finding vulnerabilities via compiler warnings and dynamic instrumentation. All of the source code snippets with extra examples can be found at mdulin2/integer_ compilation_flags.
The goal is to change a number in a way that the program does not expect to cause memory corruption down the road. There are three number (but mainly integer) vulnerability classes in C that will be focused on:
0x7FFFFFFF all the way to -0x80000000. The underflow goes in the opposite direction and happens when subtracting values instead. uint64_t to uint32_t would cut the storage capacity of the number in half. This has the potential to drastically change the value and signedness of the number. unsigned int and int for example). Going between these can have terrible consequences when converting from a negative signed number to an unsigned number or a very large unsigned number to a signed number. For instance, an unsigned integer of 0xFFFFFFFF converted to a signed integer would be -1 instead of a very large number. August 25, 2021
The web is full of user reviewed rating websites that we trust with our lives every day. Glassdoor allows us to see inside a company; Amazon reviews allow us to see what it is like to own a product; Yelp for restaurants... this is just the world that we live in.
But, what if you could sway the rating system? On Yelp, you could make a restaurant appear at the top of every search! Like in a dream, everyone would flock to your restaurant. Or, you could kill a competitors business, making yours look more appealing. This would be an amazing weapon to gain a competitive advantage on the rest of the market. In this article, we discuss a business logic vulnerability that was able to skew the ratings systems on a popular location-based ratings site.
The company asked to remain anonymous and to have no screenshots of the bug. So, we will get creative! To demo the bug, we will look at Juice Shop; the bug from OWASP Juice Shop is essentially the same as the real site. For those not familiar, OWASP Juice Shop is an intentionally vulnerable site from the Open Web Application Security Project (OWASP). In fact, this was one of my main resources for learning prior to becoming a security engineer at my current company.
OWASP Juice Shop has a customer feedback functionality, which is normal for many applications. This ratings system is on a scale of 1-5 where a sliding scale can be set to choose the rating. On the backend request, this is simply an integer being sent. What if we changed this to something that is NOT 1,2,3,4 or 5? The request for the customer feedback is shown in Figure 1 below within Burp.

By changing the rating to a non-expected value, such as -100 shown in Figure 1, we can drastically affect the overall customer ratings! This works in either the positive or negative direction. The challenge for this is titled give a devastating zero-star feedback to the store. On Juice Shop, we can change the rating value to be set to 0 in order to solve this challenge. Now, this website is meant to be vulnerable. Does this bug look the same on a real and in production website?
The target website stores information about a location and allows for ratings this specific type of location. When giving a rating on the user interface, the options are given as a collection of 5 stars. The user highlights the amount of stars for the rating (1-5) and this is the value sent to the backend. As a result, it is not possible to enter a value other than 1-5 in the UI. As demonstrated in the example above, this is not enough though! Client-side restrictions are a futile security protection.
This seemed like fertile testing ground to go through, as I remembered the Juice Shop example from years ago. I used a web app pentesters best friend Burp to proxy the request and altered the rating to be -5000. But, this failed with a 500 error, which surprised me, since the application had never thrown me a 500 error like this before. After trying increasingly smaller negative numbers, to my surprise, -500 worked! I did the same thing in the positive direction with positive 500 and this worked as well. It appears they had some sanity checking on the values but not enough. What does this actually mean though?
Most rating systems are calculated by taking the average. This average is then used everywhere on the website for finding locations to visit. In fact, this overall rating is the most important descriptor about a location to decide if people do or do not go somewhere. Being able to inject a rating of -500 or +500 would drastically raise the average rating (even past 5 stars) or drop the rating of the location significantly. Raising it could make the location extremely popular while dropping it would make the location unlikely to be visited.
In a community that relies upon the reviews of others, being able to have this large of a stake in the voting on each location allows for the rise in popularity or the downfall of a place by a single person. This compromises the people sourced system entirely; eventually, this could break the trust of the users and force them to use other services. Luckily, the fix for the bug is simple: only allow values from 1-5 on the backend.
From previous experiences, I am nervous when trying to report security vulnerabilities. As a result, I have learned to be very kind and come from the perspective of "I found this bad bug. Please let me help you fix it." If you go in guns blazing and attacking the service team with comments about how crappy the software is and how great of a hacker you are, then you are unlikely to have a good response with the team (we've all made this mistake before). Keep this in mind when reporting to companies or people without a formal bug disclosure program especially. Yes, I know testing on these sites is technically illegal; I hope that people see the good in us though, as the testing is done in good faith. In this particular case, the company had the best response I have ever received!
My initial communication with the company was to a senior engineer over LinkedIn. The company did not have a security email so this was my best course of action. Eventually, a support ticket from the support@company.com got back to me as well but hours after the initial contact with the engineer on LinkedIn.
Since the initial LinkedIn message only allows for only 300 characters, after the initial connection I sent a longer message explaining the details of the bug with a few screenshots. In particular, I sent a screenshot with the overall rating for the location being 0 stars and the next one being 9 stars, even though the limit is 5 stars. At this point, the engineer replied Oh wow, that's pretty bad. we are on it. " The engineering team fixed the bug immediately.
After this, the CTO of the company added me on LinkedIn and thanked me for the finding and responsible disclosure. The CTO let me know that a security engineering position would be opening up soon; they wanted me on the short list for the job once the position opened up. Additionally, they offered me a lifetime membership to the application! Considering I use the application quite a lot, this was very exciting for me :) A huge shoutout to the engineer and CTO for the amazing response to the finding. This makes me happy to find bugs and report them to make the internet a safer place.
Vulnerabilities are not always complicated injection attacks. Commonly, they are centered around how the logic of the site; these bugs are undetectable by scanners. Although throwing <script>alert(1)</script> may find some XSS, lots of bugs require an understanding of the applications logic and expected functionality. Prior to throwing random inputs everywhere, ensure that you understanding the business-logic of the application in test.
Feel free to reach out to me (contact information is in the footer) if you have any questions or comments about this article. Cheers from Maxwell "ꓘ"Dulin.
March 22, 2021
Have you ever discovered something amazing only to later realize that somebody else had already beaten you to it? In this article, I wanted to describe a new (rediscovered) GLibC heap exploitation method that works on all versions of the allocator. With this method, an attacker can write a heap value to an arbitrary location (WRITE-WHERE primitive).
When I started looking for new ways to exploit the allocator via the non-main arena chunks, I thought I had found a new technique! However, part way through writing this article, I reread the original post (Malloc Malefaricum) on the House of Mind only to realize that there is a fastbin variant of the attack as well. The original use case for the fastbin variant of the House of Mind writes a heap pointer to a GOT address to jump to shellcode. But, this technique to trivially pop a shell is no longer viable because of NX. With the original House of Mind being patched and the fastbin variant no longer being an auto shell, this technique was mostly forgotten about, waiting to be rediscovered for a new purpose. So, new or not, nobody seems to be talking about this technique. In this article I wanted to shed light onto the House of Mind's Fastbin Variant as a useful WRITE-WHERE primitive and discuss when it can be used.
This post will (hopefully) have a POC in how2heap; the link is currently to a pull request with all of the code. For more security related content, check out this blog for other things, such as the House of Muney heap exploitation technique.
Before we get to the meat of the technique, we will go over how the heap allocator works. I cannot stress enough how important understanding the allocator is for heap exploitation. Trying to pwn the heap without understanding the inner workings of the allocator is like trying to shot a fish in a lake.
Chunks are the main object that users interact with. There are two main states to a chunk: allocated and free. The following picture demonstrates a free chunk:

On an allocated (non-free) chunk, the third and fourth field are used as data sections. However, on a free chunk, the third field is used in order to store a pointer to other freed chunks. This field is known as the forward pointer or the Fd field. The fourth field is exactly the same, except that it stores a backwards pointer or bk.
October 8, 2020
Exploiting different heap libraries tends to be difficult, complex and requires a deep knowledge of the library itself. Recently, Qualys decided to go back and exploit a 15 year bug in QMail that was thought to unexploitable with some incredible techniques. This exploit uses a very interesting quirk of Malloc and exploit method that had not been seen before, which I have decided to name the House of Muney.
In this article, I wanted to shed more light on the exploitation method that was used by the Qualys researchers to ensure there is a well-documented location for this exploit method. In short, it is broken up into Munmaping part of LibC and to rewrite the symbol table to get code execution. There are two main perks of this technique: this bypasses ASLR entirely and works on mmap chunks in GLibC Malloc.
Just as a fair warning, this article has quite a bit of background knowledge to understand the exploit. If you think you have a good understanding a section, it is recommended you still review the section just to refamilarize yourself with the content. In this article, the following is discussed as background:
The article also comes with a working POC on version 2.31 of Malloc on my Github (mdulin2) at House of Muney if you would like to follow along. Additionally, if you want more security content, take a look at the resources or other blog posts. Now, with the introduction out of the way, let's dive into the technical details.
Chunks are the main object that users interact with. There are two main states to a chunk: allocated and free. The following picture demonstrates a free chunk:

On an allocated (non-free) chunk, the third and fourth field are used as data sections. However, on a free chunk, the third field is used in order to store a pointer to other freed chunks. This field is known as the forward pointer or the Fd field. The fourth field is exactly the same, except that it stores a backwards pointer or bk.