Resources

People often ask me "How did you learn how to hack?" The answer: by reading. This page is a collection of the blog posts and other articles that I have accumulated over the years of my journey. Enjoy!

“CrossBarking” — Exploiting a 0-Day Opera Vulnerability with a Cross-Browser Extension Store Attack- 1527

Guardio    Reference →Posted 1 Year Ago
  • Browser extensions have extra capabilities compared to web pages but are still sandboxed from running full code on the system. Extensions have access to some extra APIs but it's still quite restrictive.
  • Some domains and extensions have "special" privileges in the Opera browser, which is the focus of this research. For instance, the Pin add-on quickly takes a screenshot of the page but this requires extra permissions to do. The author decided to see if there were any domains in the list that were no longer registered to Opera.
  • Several domains, such as crypto-corner.op-test.net, were found not to be registered, even though they had access to these APIs. So, the authors of the bought the domains to gain the special privileges that came with them. What can we do these with privileged APIs?
  • The chrome.cookies API can be used to extract all session cookies and hijack user accounts. Additionally, the settingsPrivate allows for changing of various browser settings. An attacker can even change the DNS settings to create a Man in the Middle attack with this. Although, since most things use TLS, I'm not sure if this is very practical.
  • Opera carefully reviews on extensions before adding them to the store. So, the authors were afraid of their bug report being vetoed for this reason. Instead, they found a workaround. Opera allows for Chrome extensions to be used! So, they wrote their proof of concept as a Chrome extension that another user would download.
  • To remediate it, Opera did a few things. First, they removed content scripting on high-permission domains to prevent obfuscation I think. Next, they removed the privileges from some domains entirely. Overall, a fun vulnerability with some clever workarounds. Personally, I found that the article had a surprising order to me which confused me on my initial read though.

Hacking 700 Million Electronic Arts Accounts- 1526

Sean Kahler    Reference →Posted 1 Year Ago
  • Bug bounty is great for finding bugs that stem across multiple products at a company that have massive impact. This is one of those vulnerabilities on Electronic Arts. At the beginning of the article, they got access to one of EA's development environments for EA Desktop by finding a privileged access token in a games executable. But, they had no idea what this was used for or what they could do with it.
  • They decided to scan for API documentation to see what this token could do. On /connect, they got a 404 HTML page with a server response that made it clear that this was a reverse proxy. When connecting to /connect/api-docs, no data was returned. This indicated that a different service must exist here. After some more fuzzing, they got a swagger file with some unexpected docs.
  • EA Desktop has a GraphQL API called the Service Aggregation Layer to combine multiple backend APIs into one. The api-docs did not work on this site though, hiding a lot of routes. When querying on the testing environment, the routes are returned, giving us much more to work with. More recon!
  • This API required a specific OAuth scope. After searching around, they found some creds that worked. After fiddling around for hours, they started messing around with the /identity/pids/{pidId}/personas/{personaId} API. What's a persona? It seems to be extended account information and settings like displayName. Given that they could update their status to be banned or unbanned, this seems like it was intentional to access.
  • One of the fields was pidId for the account ID associated with this account. They decided to update this to their friend's account Id and their Steam ID. Shockingly, this worked and they had successfully gotten access to an EA account that wasn't theirs! Unfortunately, 2FA blocked the account takeover so now what?
  • To work around this limitation, they could go the other direction! Instead of adding another Steam ID to their persona, they could add another Persona to their Steam ID! This gave them the ability to ban players, steal usernames and other things. Still, we had 2FA though... it was a trusted network thing.
  • Eventually, they figured out a way around the trusted network. First, move an Xbox persona to another account that is trusted on your network. Next, log into an EA game on an Xbox using this account. Finally, login to the victims account on your network, since it is trusted from the Persona step. This leads to a complete account takeover, which is wild!
  • With anything in life that is first come first serve, you need to do something better than everyone else - this is where the real work is at. In this case, the author of this post really did his homework on recon to open up new attack surfaces that others had not seen. The understanding of the underlying system to exploit this was pretty wild and time-consuming as well. Awesome bug report!

AWS CDK Risk: Exploiting a Missing S3 Bucket Allowed Account Takeover- 1525

AquaSec    Reference →Posted 1 Year Ago
  • Bucket Snipping is a class of AWS integration vulnerabilities that stems from S3 buckets being globally scoped. The idea is to possess readable and writable access to an S3 bucket used by another account then use this control to perform malicious things in the account.
  • The AWS Cloud Development Kit (CDK) is a framework for infrastructure as code. This allows using programming languages like Python to translate into configurations in AWS. CDK has a one time initialization step called bootstrap. This one time command creates the necessary roles for CloudFormation and CDK in the account, an S3 bucket and other resources.
  • The bucket named can be changed but has a default format of cdk-{qualifier}-assets-{account-ID}-{Region}. The qualifier has a default value of hnb659fds, the region is guessable and the account Id is the only somewhat secret value but may be learned through other means.
  • Because the bucket is somewhat predictable and S3 is global, it can be registered ahead of time. They call this out as a DoS which to me is BS - this is like saying that me frontrunning the creation of a domain is a DoS! You can literally just change the name slightly and it's fine.
  • Sometimes, resources get deleted from AWS accounts, especially with quota limits. If this happens, another user can create the S3 bucket because it's global. By default, the CloudFormationExecuteRole used by CDK has admin privileges to the account, making the ability to overwrite a template very, very bad. Does this work? Yes it does!
  • The attack assumes that the user has CDK initialized in their account, deleted the S3 bucket and has a predictable qualifier:
    1. Attacker recreates the deleted S3 bucket in the account using the predictable name. On this bucket, the attacker sets a permissive resource-level policy.
    2. On the S3 bucket, configure a Lambda function to inject the malicious admin role into any CloudFormation template that gets loaded. There are hooks for S3 bucket operations that make this possible.
    3. User runs cdk deploy in their account.
    4. Upon triggering the build, the template gets written to the attackers S3 bucket, which gets backdoored. Since the template has been updated, it will deploy the resources that the attacker specifies.
    5. What does an attacker do with this? They crate a Backdoor IAM role that can be assumed by an account that they control! At this point, they have admin rights in the account.
  • How likely is this to happen though? This is where I find the article interesting! First, they checked if a particular IAM account existed using a known technique which is surprising to me that it works. They created a scanner that looked for the existence of the S3 bucket name for 38,000 known accounts. If the role existed but the S3 bucket didn't, the attack was on!
  • From the 38K accounts analyzed, 2% of them used CDK. Of these accounts, 10% of the accounts were found to be vulnerable to this attack vector. According to AWS, about 1% of CDK users were affected by this issue. An account takeover in AWS from simply deleting a bucket is pretty bad news!
  • To remediate the vulnerability, newer versions of CDK ensure bucket ownership by the account. Additionally, AWS added some docs to not use the default qualifier. Since previously bootstrapped users are still potentially vulnerable to this attack, AWS added messages in the CLI terminal with a big error message that this still affected them.
  • Overall, a good writeup on a classic AWS bucket snipping vulnerability. It amazes me that these are still being found in AWS products after all of these years.

Let's PWN WTM!- 1524

haxxin    Reference →Posted 1 Year Ago
  • In a previous post, the author broke the firmware encryption that was using Wireless Trusted Module (WSM) on a printer. This time, they target WSM itself.
  • They didn't have a root shell on the device from their friends previous backdoor. So, they looked around and used an N-day reported by Synacktiv. The lbtraceapp binary has setuid permissions and functions similar to ftrace. By passing it a program, such as /bin/bash, you get root for free. Unfortunately, root doesn't mean all access with capabilities.
  • The lbtraceapp ran as root but didn't have the CAP_SYS_MODULE capability. When looking around at various processes, they found that some shellscript executes sleep which DOES have the capability we need. Since we are root, we can write to the location in /proc/pid/mem with some shellcode to hijack the process.
  • With this, it was time to poke around at the WTM module for real. They didn't feel like cross compiling though. So, they wrote a small daemon that forwards TCP traffic from their machine via the wtm Python client to the device. At first glance, the commands look almost identical to the Trusted Platform Module (TPM) specification with context loading and such.
  • WTM encryption stores customer key information in an encrypted blob on the file system that is then loaded to the chip. In theory, the chip should have a super duper secret key to make it impossible to decrypt offline. What they learned is that some data is preserved between execution of stores and loads of the context.
  • This is super helpful! The file system encryption key is actually wrapped by a different key other than the super duper master key. Since this key is still leftover on the chip, we're able to leak the wrapped key. Why is this helpful? This gives us the ability for offline root filesystem decryption.
  • Can we get code execution in the kernel firmware itself? It turns out that the chip does NOT have its own decided DRAM! By simply writing to /dev/mem, we can overwrite the processor code itself! To do this, they overwrote a virtual unused command to give them an arbitrary read/write primitive that could be accessed via their Python client. They dumped OTP fuses that shouldn't be dumpable. The next step would be dumping the super duper secret AES key!
  • Overall, an awesome series of blog posts on the kernel. To me, it was eye-opening to see how important the permissions of files, memory and other things were for security. If these basic things are messed up then you're in a world of hurt.

Retrofitting encrypted firmware is a Bad Idea- 1523

haxxin    Reference →Posted 1 Year Ago
  • Lexmark is a common printer brand that the author had looked at before. In a recent update, the Firmware encryption process was changed so they decided to take a look at it after being nudged from a friend. After putting in a persistent backdoor and upgrading the firmware, they were ready to reverse engineer the system.
  • In the previous version, it was using an AES key stored at some location on the file system. When trying the old script, the decryption failed. After exploring the OS on the newly upgraded system, they found references to WTM. After some snooping around, they eventually found out that WTM is the Wireless Trusted Module that handles trusted boot.
  • On Lexmark printers, there was a rustlang init binary and a rustlang kernel module for interacting with the chips WTM interface. The WTM client interacts via netlink sockets. They really didn't want to deal with reversing the kernel driver though. So, instead, they patched the netlink sockets to use regular sockets in the PLT table. Why? Just to make it easier.
  • Using good ol' TCP, we could implement the kernel side server for the client. More importantly, this allows for emulation of the init binary, giving us a better test env. After simulating a good amount of the kernel driver over TCP, the client sends the kernel driver the key! Yep, it was that simple - intercept traffic to see the key.
  • The vendor did a better job at adding encryption to the device. The problem is that a previously pwned device already has access to it. Retrofitting a new process to an old device doesn't work because of this reason. Interesting post!

Live Chat Blog #1 - Misconfigured User Auth Leads to Customer Messages- 1522

Rojan Rijal - Ophion Security    Reference →Posted 1 Year Ago
  • Chatbots on websites are becoming more and more popular. They usually come in three flavors: GenAI bot fed customer data to answer questions, simple FAQ on internal and external information and a live agent chat. Most of these are done via some service provider and not rolled in house.
  • The service provider of Live Chat systems requires some sort of authentication, naturally. The article has a nice diagram for it. At a high level, the backend will generate a HMAC digest that contains the user identifier. This hash is communicated to the live chat agent backend, allowing the user to make requests.
  • They tested various organizations for integrations with the Live Chat platforms. In one of the integrating organizations, they found a signing oracle. The email in the cookies was being used as the input without any checks to see if the user owned the account or not. Since an authentication token was created, they could view the chat logs of the message.
  • A fairly simple vulnerability but it required understanding the integrating of complex parts, making it more interesting.

Ordinal Theory + BRC20- 1521

Casey Rodarmor    Reference →Posted 1 Year Ago
  • Ordinals are a numbering system for all Satoshi's (small unit of a Bitcoin) on the Bitcoin network. They can be referenced in a few different ways, such as the block.satoshi or just a decimal number. In reality, this gives every satoshi a serial number.
  • The ordinals themselves can have interesting rarity metrics. There are events that happen on Bitcoin with different rarity metrics. Blocks, difficulty adjustments, halvings, and cycles. This change appears to be an extension on top of the Bitcoin core protocol.
  • Inscriptions, made of the data after a script, have their own special formatting. First, the OP_FALSE opcode is used to make the script always fail. After that, the data is wrapped in an IF statement that will never execute. The data itself is added via PUSH instructions to create an envelope. With ordinals, ord is pushed first, followed by the content type and data. Different values being pushed, such as 1 for Content Type, signify the data being added on the ordinals.
  • Inscriptions use the TapRoot script type, which has two transactions: a commit and a reveal. The inscription content is contained within the input of a reveal transaction. The inscription itself it made on the first sat of its input.
  • The specification appears to have a deploy, mint and transfer for BRC20 tokens. The inscription string being added is minimized JSON. The fields include the type, inscription mark, operation and amount being transferred. Of course, this begs the question - how do we limit the amount of tokens, false transfers and such? I'm still trying to figure this out :)

BRC20 Pinning Attack- 1520

Many Researchers    Reference →Posted 1 Year Ago
  • BRC20 tokens are a non-fungible asset on the Bitcoin network. The tokens are embedded into a Satoshi using Ordinal Theory. The ordinals protocol can assign more information on top of a satoshi called an inscription. The Satoshis each have an ID, which is ordered by how they were mined on the Bitcoin network.
  • The Ord data is stored in a Taproot script-path spend script. The Ord is the reference of a particular Satoshi. The Inscription is the information about the token itself, which can be an image, text, or anything else. Commonly, the metadata is stored in the witness data of the transaction. It should be noted that the Bitcoin itself hasn't changed - just how people are viewing said Bitcoin.
  • BRC20 has three operations: deploy, mint (create) and transfer. The inscribed operations are not executable actions. They leverage the OP_RETURN OPCODE in a bitcoin transaction that is not spendable then add arbitrary data to the end of the script, called an Inscription which contains a JSON payload to specify what is happening.
  • The transfer requires two transactions:
    1. Inscribe the JSON-style content into a satoshi marked with a unique sequence number. This is sent to yourself.
    2. Execute the actual transfer by sending the previous inscription to the receiver.
  • The BRC20 token balance structure has three values: available balance, transferrable balance and overall balance. Available balance is what a user can freely spend. Transferrable balance is a token that has been inscribed in a token transfer but hasn't been sent to the user yet. The overall balance is just the sum of these two.
  • I don't fully understand how this system works tbh. Here are a two articles: one and two.
  • The attack targets the transferable balance field. When a token transfer is initiated via an inscription, the tokens move from available to transferrable, waiting for pending transactions to be confirmed. First, an attacker sends a bunch of false transfers from the target to the user. When doing this, they make the first tx with the inscription update happen but make the second one have a very low fee to guarantee it will not happen for a long time.
  • By doing this, the system is locked up. The requests for usage appear to require sequential transactions. So, if there's a transfer happening to you then you are unable to perform any actions. By intentionally getting the transactions stuck for long periods of time, it locks your targets wallet as well. They ran this locally then on a popular wallet used on Binance. I personally think that testing a live system like this without notifying the party first is completely unethical.
  • I'm still confused on how the tracking of BRC20 tokens works. None-the-less, this was an interesting vulnerability that abused multiple parts of how Bitcoin and BRC20 function, which is cool. This was a systemic issue on Bitcoin which is pretty crazy. Overall, I wish more context was provided on token tracking but an interesting vuln!

Are you serious?- 1519

Visakan Veerasamy    Reference →Posted 1 Year Ago
  • The world is full of people who don't take their world and life seriously. As humans, it's hard to optimize for anything besides the pleasures in front of us. This article talks about how unserious the world is and the benefits of being serious.
  • Being labeled as serious takes time. If somebody claims to be serious, how can we be so sure? People may believe they are serious about something but may change their minds soon enough.
  • How do we stay around for a long time? You can't take yourself too seriously. If you hit too much of a roadblock that you can't shake off, you'll eventually quit. So, being able to enjoy what you're doing enough to where the consequences don't affect your being is crucial. Richard Feynman loved physics until he had to do it professionally. Once he stopped the whole "do important work" and just started tickering, he had all of the breakthroughs. I found this to be quite true in my own life.
  • According to the author, humans are not a serious species. We don't do enough to prepare ourselves for things that are hard, like marriage. We don't prepare ourselves because we don't want to know the truth of the matter. What's this person like in difficult times? What are their pet peeves and flaws? Do we have similar perspectives for kids? All hard things that should be asked but we don't.
  • The final gem in this article is to be honest with yourself about how serious you are. If you say your serious about something but you're really not, then you're wasting your time and others.

Escaping the Chrome Sandbox Through DevTools- 1518

ading2210    Reference →Posted 1 Year Ago
  • All untrusted code in Chrome, especially JavaScript on websites and within browser extensions, runs in a Sandbox. Practically, this means that the code is limited to the set of APIs instead of system calls. The raw Chromium Gui, called WebUI with the chrome:// URL protocol, can interface with the raw C++ code and are privileged sections that run outside a sandbox.
  • Being able to execute code within the chrome:// is usually game over with UXSS or some other bug. So, keeping this clean of malicious code is important to the security of the browser. With this knowledge, our story begins with looking at Enterprise Policies in Chromimum. These are a way for an administrator to enforce certain settings by devices owned by a school or company.
  • These policies are downloaded remotely to a JSON file then placed in /etc/opt/chrome/polices for usage. Since it's annoying to write these policies by hand, the developers created a policy testing WebUI page at chome://policy. In particular, it shows a list of provided policies, logs them and allows for exportation.
  • Oddly enough, you can't edit these policies. After some digging, they found an undocumented API for editing these. There is a feature check for whether it is possible to do this. Unfortantely, the check is faulty and always returns true for all builds of Chrome. At this point, we can only call the API from the privileged WebUI pages. Convincing somebody to copy JS into the console to execute is unlikely. So, how can we escalate this? Chrome extension sandbox escape!
  • The previous vulnerability had been reported in the devtools Chrome extension APIs. When calling chrome.devtools.inspectedWindow.eval(), the command is stored. If the tab is crashed then moved to another page, since as a WebUI page, it gets executed! The key to this attack was sending a request to eval before Chrome decides to disable the devtools API but while you are on a WebUI page. Classic race condition!
  • The author wondered if any variants of this vulnerability existed. They checked out the chrome.devtools.inspectedWindow.reload() function to try to do a similar thing. To the authors surprised, it worked! They could continually spam reload() requests with JavaScript and switch the tab to a WebUI page. This exploits a race condition between the communication of processes on killing the devtools API. Neat!
  • What's the worst thing that we can do with the chrome://policy page? The enterprise policies have a setting for Legacy Browser Support called Browser Switcher. This is meant to launch an alternative browser when a user visits specific URLs in Chrome that are not supported. In particular, the AlternativeBrowserPath can be used to execute an arbitrary command with arbitrary commands. This gives us a shell if we can execute it!
  • At this point, they have a shell but the race condition only works like 70% of the time with only a single chance to hit it. They were curious if the same revival trick from the original bug report would work. To their surprise, calling the debugger twice in a row results in a crash. At this point, the code is stored and will be launched upon recovery. However, it's at this point that we update the tab itself to a different location. Now, this is 100% reliable.
  • So, what's the fix? Funnily enough, Google had fixed this vulnerability originally then added a special case that exempted reload() from this patch. Originally, they just cleared all pending messages unless it was a reload.
    • Adding a loaderId on the renderer side. Ensures that a pending command is only valid on a single page.
    • Fix the feature flag for test policies.
    • Prevent the crash from happening in devtools. Idk how they did this though
  • I absolutely love this blog post. The bugs are not super complex, they have simple to understand code snippets yet it's still high impact. To me, this really shows up complexity opens up the attack surface is crazy ways.