[HackerNotes Ep.97] Bcrypt Hash Input Truncation & Mobile Device Threat Modeling

We're back with some cool news items, including a recent Okta Bcrypt vulnerability, insights into crypto bugs, and some intricacies of Android and Chrome security. We also explore the latest research from Portswigger on payload concealment techniques, and the introduction of the Lightyear tool for PHP exploits.

Hacker TLDR;

  • Okta: Passwordless Login Vulnerability for Accounts With 52+ Char Usernames: Okta used Bcrypt to hash their combination of userID + username + password. Since the password came last, if the username was too long it would reach Bcrypt’s 72 characters limitation, allowing for a passwordless login as the password would be left out of the hashing.

  • Android Chromium bugs by @ndevtk: a cool list of reports by @ndevtk, it’s a must-read for anyone who’s trying to get into mobile hacking.

  • Concealing Payloads in URL credentials: has anyone ever logged in from the url? Turns out it’s possible to hide your payloads in the http//user:[email protected]/ part of the url.

    • After discovering that location returns the URL without credentials but document.URL returns the full URL including the user:pass part, Gareth Heyes from the PortSwigger team got creative and found a few other ways to exploit this behaviour to pop some stuff.

  • Lightyear, Dom-Explorer & CaidoNotesPlusPlus:

    • Lightyear is a tool for dumping PHP files that significantly outperforms the previous SOTA tool, because it was made to fix its limitations and improve on efficiency.

    • Dom-Explorer is a convenient DOM testing tool that runs in the browser, with design and usability inspired by CyberChef’s. You just provide the HTML and start playing around with different parsers, and sanitisers, customising them and more.

    • The last one is a note-taking plugin for Caido that will be released soon. Justin Beta testers said that taking notes becomes much easier because it speeds up the process of testing + note-taking. You can switch between the plugin and the previous screen with a keyboard shortcut, link replay tabs, sync the notes with a file and a lot more.

Remote workforces are a ticking time bomb!
Hybrid and remote work expand your company's surface area of attack beyond corporate firewall boundaries. Employees’ personal computers introduce shadow IT, and home networks with default settings are easy targets, compounded by public Wi-Fi vulnerabilities.
You need to develop a strategy to stay secure while remote employees work across untrusted networks.
To learn how you can secure your company's workforce, get a free copy of the latest ThreatLocker® whitepaper on how to secure remote workforces.

Learn More About the ThreatLocker® Cyber Health Report Here

Okta found a vulnerability in their own login system which allowed for passwordless login. On October 30 they realised there was an issue with how cache keys were generated for AD/LDAP delegated authentication. Specifically, they used the Bcrypt algorithm to create cache keys by hashing a combination of userId, username, and password. But under the conditions listed below, this setup allowed users to log in without needing a password, they just had to provide the correct username and the cache key from a previous successful login.

Here are the conditions that had to be met for this to happen:

  • Okta’s AD/LDAP delegated authentication had to be in use;

  • MFA not active;

  • The username had to be 52+ chars long;

  • The user had to have logged in before, creating a cached version of their authentication;

  • The system would need to rely on this cached login first, usually happening if the AD/LDAP agent was down or unreachable, perhaps due to heavy network traffic.

For those who are not familiar with how bcrypt works, it is a hashing function primarily used for hashing passwords. It has a limitation, though, it can on only be used for passwords shorter than 72 characters.

As Okta said in their official announcement, they were hashing a combination of userID + username + password. But as we know, bcrypt can only hash and compare the first 72 characters, which means that when hashed and compared, even if the password the user entered was wrong, the hashes would still technically “match”.

Here’s a simple Python script if you want to play around with bcrypt yourself:

import bcrypt # type: ignore
length = 72 # change the legth here
combination1 = 'x' * length
combination2 = 'x' * length + '-' + "ThePasswordDoesn'tMatter"

hash_comb1 = bcrypt.hashpw(combination1.encode(), bcrypt.gensalt())
hash_comb2 = bcrypt.hashpw(combination2.encode(), bcrypt.gensalt())

def compare_hashes(combination, hash_value):
    return bcrypt.checkpw(combination.encode(), hash_value)

print("Combination 1:", combination1)
print("Combination 2:", combination2)

print("Hash Comb 1:", hash_comb1.decode())
print("Hash Comb 2:", hash_comb2.decode())

is_match = compare_hashes(combination1, hash_comb2)
print("Do the combinations match?:", is_match)

Whenever doing white box testing and/or if you see your target using Bcrypt, it’s worth keeping an eye out for vulnerabilities like this. An interesting thought by Joel was that this only occurred because they were concatenating id+user+pass. If the password had come first, it would have been a lot different.

Links:

This next one will be quick on our part because @ndevtk’s writeups are absolutely worth reading in full, especially for those trying to get into mobile hacking. One of the coolest things about reading reports like this is that we get a better understanding of mobile attack vectors and also get the opportunity to take a peek at how someone progressively tests things. Our phones are connecting to so many other things all the time that we have infinite possibilities in our hands when it comes to generating attack vectors. Checking his writeups is definitely a good starting point!

You’ll find a ton of stuff from him focused on Android Chromium, including an intent:// bypass, adding fav sites to home screen spoof, and even a method for controlling the victim’s clock app (yeah wtf).

The writeups can be found at:

Last year Johan Carlsson discovered a method to conceal payloads inside the credentials part of the URL. Nerdsniped by this, Gareth Heyes went on a quest to find even more stuff. One of the first surprising findings was that document.URL does not always match location.

<https://rhyno:1337p@ss>[email protected]
alert(location) = <https://ctbb.show/>
alert(document.URL) = <https://rhyno:1337p@ss>[email protected]/

It turns out that document.URL contains the credentials part of the URL but location doesn’t. This means that the URL can be used inside an event to grab the payload from the credentials, as demonstrated here.

<https://alert>(1)@ctbb.show/
<img src onerror=alert(URL.slice(8,16))>

Further investigation into character encoding within URL credentials revealed that Firefox doesn’t url-encode single quotes and it is particularly relevant for DOM XSS scenarios, especially when websites remove the query string and hash from URLs. Such behaviour potentially enables the exploitation of certain vulnerabilities in Firefox when the payload is provided in the URL like this: https://'-alert(1)-'@example.com

function getBase(url) {
   return url.split(/[?#]/)[0];
}
document.write(`<script>const url='${getBase(document.URL)}';<\\/script>`);

This technique can also be used to control the username or password properties of anchor links. Every anchor has these properties, which store the credentials from the URL. If it’s a relative link, it inherits the parent credentials, allowing for value clobbering, as demonstrated in this POC.

It can be combined with DOM Clobbering to gain control over objects with username or password properties. Even a blank href enables control over username or password via the URL:

<https://user:pass@example.com>
<a href id=x>test</a>
<script>
eval(x.username)//user
eval(x.password)//pass
</script>

This research is incredibly valuable because it digs into something that is not affected by WAF whatsoever, as the WAF doesn’t even see it.

Impressive stuff by Gareth, as always.

Links:

PHP filter chains are great attack vectors for us hackers, enabling various kinds of exploits such as file disguise, content manipulation, byte-by-byte file dumping through memory exhaustion and a lot more. This new tool called Lightyear represents a breakthrough in attacking blind file read primitives in PHP, surpassing the capabilities of its predecessor, php_filter_chains_oracle_exploit.

php_filter_chains_oracle_exploit (did Joel name this tool?) dumps PHP files using blind file read and memory exhaustion. It used to be the state-of-the-art for blind file dumping in PHP. For details, see this blogpost.

Here are some of the limitations the tool had and that Lightyear claims to have solved:

  • Large payloads limit GET parameter dumps to ~135 characters

  • Inefficient character value determination process

  • Character swapping can trigger PHP warnings, causing errors in modern frameworks

  • Slow execution due to gradual memory allocation

Lightyear solves and improves upon a lot of these things:

  • Dumping large files with compact payloads

  • Efficient byte value determination using the dichotomy

  • Faster execution without memory exhaustion

  • Error-free operation

It results in larger file dumps with faster execution, we can’t even imagine how much work was put into this, and even though none of us went through the process of reading and understanding the entire thing (hahah) it really deserves the shoutout here.

So as the boys said in the pod, if you can’t study and learn this right now, save it somewhere and come back to it whenever needed. Oftentimes we’ve gotta pick and choose what we learn in order to effectively keep up with everything that happens, especially in our niche.

Links:

Dom-Explorer is a tool inspired by Cyberchef, its main purpose is to help hackers understand how the browsers parse HTML and potentially find some mXSS. The author @BitK even recommends using this tool while checking the HTML Living Standard so we can detect some weird behaviours and play around with them.

So, if you’ve used CyberChef before you’ll feel right at home, you paste in your HTML, create your custom pipeline and it will give the expected output.

This tool runs right in the browser without requiring any additional config from us, very convenient and easy to use.

Links:

Tanner Barnes a.k.a. @StaticFlow is developing an extension for both Burp and Caido with a lot of cool features like markdown, native integration with replay so you can link a replay tab right in your notes, sync with specific files, and keybindings so we don’t have to interrupt the flow grabbing the mouse to switch between stuff, and some other things.

The Burp version is still going to take a while but the Caido version will be released soon (maybe it’s already out), so don’t forget to check his stuff on GitHub!

As always, keep hacking!