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!

What’s That Coming Over The Hill? (Monsta FTP Remote Code Execution CVE-2025-34299)- 1795

Watchtowr    Reference →Posted 3 Months Ago
  • Monsta FTP is a web-based FTP client that let's users manage and transfer files on remote servers through the web browser. A vulnerability was found in it - making it an N-day, that they decided to review. Once of these was an arbitrary file upload that leads to RCE. An SSRF and RCE weren't initially fixed, although reported in the CVE database. After going through lots of lots of versions, they found some input validation functions that were trying to prevent path traversal. Hurray, they found the patch!
  • The SSRF vulnerability that was reported still worked... so, was the RCE bug patched? Maybe the developers didn't understand what/where to patch. They were curious if the patch was sufficient. After looking at a large switch statement, they realized that DownloadFile didn't have any checks on it for directory traversal. By spinning up a malicious SFTP server that exploited the directory traversal, it allowed them to write the file to anywhere on the server.
  • They don't mention an authentication bypass... but, they claim this leads to an unauthenticated RCE on Monsta FTP. For me, there are two takeaways. First, not all patches are sufficient. Second, many of the time there are other variants of vulnerabilities lurking if you check those out. Overall, a good blog post on finding security issues once issues are already known.

N-able N-central: From N-days to 0-days- 1794

Zach Hanley    Reference →Posted 3 Months Ago
  • N-Central is N-able's remote managing and monitoring solution. There was two vulnerabilities in the software. While reviewing the software, they found two more. This reports on all four of them.
  • CVE-2025-8875 was an insecure deserialization bug. ObjectInputStream is used to create an object from raw bytes. Using user controlled data, this could be used to create arbitrary objects. Although not explicitly stated, this commonly leads to RCE in Java-based products. CVE-2025-8876 was a simple command injection from input provided directly to Runtime.getRuntime().execute(). Both of these were on legacy APIs but required valid sessions.
  • They found that authentication could be bypassed via some pre-configured authentication information for various appliances. So, many authenticated endpoints, besides the SOAP ones, could be triggered using this. This opened up much more attack surface for them to work with and a partial authentication bypass.
  • While using grep for functions that use XML, they found a parser that wasn't configured with secure defaults. So, this led to an XXE issue. They used this vulnerability to retrieve arbitrary files on disk. In all likelihood, this would lead to a complete compromise of the system via extracting configuration, backup and database information with credentials.
  • Overall, a great chain of vulnerabilities to go from unauthenticated to taking over the machine directly. Great work!

Preventing attacks on a user's history through CSS :visited selectors- 1793

Mozilla     Reference →Posted 4 Months Ago
  • CSS can style visited links differently than unvisited links. From a security perspective, this is a problem because a web page can review a user's complete history this way for other sites. This post provides a summary of the problem and proposes a solution.
  • Website authors can use the getComputedStyle function to determine if a link has been visited or not. An easy way to fix this would be to make this API lie. In practice, this approach doesn't work because the CSS styling itself can vary, including colors, spacing, and other elements.
  • To fix the above issue, a limitation would need to be put in place to limit the ability to style pages on whether links were visitd or not. Many CSS selectors will always act as if they've been visited. Additionally, the CSS properties applied to links should be limited to a few select options.
  • A few limitations of this approach are discussed, highlighting the importance of the mitigating threat model for these types of features. First, this is NOT intended to resolve attacks that require user interaction via clicks. Second, fine-grained timing attacks - they hope this prevents most practical ones. Finally, this doesn't intend to avoid browser cache-based attacks.
  • Overall, a great post on a proposed browser mitigation for a well-known attack vector while keeping as much functionality as possible.

HTTP Cache Cross-Site Leaks- 1792

sirdarckcat     Reference →Posted 4 Months Ago
  • The Same Origin Policy (SOP) is meant to prevent one website from requesting information on another website. In practice, data can be leaked from websites in other ways. A major one of these is timing of loading a resource.
  • An original vector was described by Chris Evans against Yahoo! Mail, where you can search the inbox of a website to see if results are returned or not based on the amount of time it takes. Later, this was coined as XSSearch with hard statistics on timing. Based on timing, a list of attack methods, such as frame counting, is becoming increasingly popular due to "browser misfeatures".
  • One of these methods that the author wants to bring to our attention is around browser caching. This can be used for timing attacks to understand if something was cached or not for the browser history. geographic information or general fingerprinting. Their variation is as follows:
    1. Delete the cache for a specific resource.
    2. Force the browser to render to a website as the user.
    3. Check if the browser cached the resource.
  • They first check out Facebook for issues relating to this. According to them, URLs are signed, so it's not a simple cache or no cache problem. A good question to ask is " Does the image X get cached when the profile page is loaded?" By reviewing the cache, this could potentially be checked.
  • Another variant of this on Facebook is checking for user access to some resource, such as a private group. In this case, it requires that something cachable be loaded in some cases, such as a legitimate search, but not in an illegitimate search. When searching Facebook messages, an extra pop-up appears to confirm before any JavaScript loads, preventing this attack. Facebook has some pretty neat protections against these types of attacks!
  • How do we invalidate a cache entry? By making a POST request to the resource or issuing a Fetch API with a cache that returns an error from the server, such as a large HTTP referrer header. The final trick is quite simple: delete the cache, reload the page, and query the cache for the information. Crazy - the never-ending curse of caching.
  • They end the post with some caveats on exploitation and a note of a Wiki page with all known Cross-Site leak techniques. Great post!

Signature Validation Bypass Leading to RCE In Electron-Updater- 1791

Lorenzo Stella - DoyenSec    Reference →Posted 4 Months Ago
  • Electron-Builder is marketed as a package and build system for Electron Apps with auto-update support. On MacOS and Windows, there is code signing and verification support built into it.
  • While reviewing the update mechanism of Electron-Builder for a client, they noticed that the validation failed open if the PowerShell command used signature validation failed. If there was a parse error, the command would still succeed silently. By claiming the file name contained a single quote, the parse error would return a valid result. Practically, this also had a command injection, which is less than ideal as well.
  • The command injection issue was eventually resolved, but the fail-open design remained. Since the expansion led to both a parse error and a command injection issue, this was sufficient for both problems. In reality, the fail-open design is still bad, and there are likely other ways to trigger this same issue.

Abusing Chrome's XSS auditor to steal tokens- 1790

Gareth Heyes - Portswigger Labs     Reference →Posted 4 Months Ago
  • XSS auditor was a Chrome feature that allows for the header X-XSS-Protection: 1 to block XSS attacks. If an XSS attack is found, then Chrome will clear the entire page. The author of this post decided to look at this feature for potential security issues.
  • XSS auditor attempted to find reflected XSS attacks. This was done by reading the request body and seeing if DOM-tree was created directly from input in the URL. This paper discusses some transforms that try to comply with, such as PHP magic quotes and Unicode normalizations. Any larger transformations cannot be caught.
  • The post linked in this report is all about creating an oracle based on whether the XSS auditor is present or not to leak data off the page. Since the number of iframes on a page can be read across windows, this can be used in conjunction with the removal of the iframe as an oracle. The page isn't IN the iframe, but the iframe serves as an oracle to determine whether the page is loaded correctly or not.
  • Their first idea was to read a user ID character by character by using fake XSS payloads. First, they include a fake XSS payload that looks something like <script>uid = 1337;</script> in the URL. This is what the page normally looks like, though. Now, you put the data that you want to check into the URL. For instance, <script>uid = 1;</script>. Since this is NOT on the page, nothing happens. You can iterate on the UID over and over again until the XSS auditor finds the string match and blocks.
  • Another mechanism this was on was form actions. By having a named parameter in an HTML form, such as x=123456, the form can be injected as the "fake input" to search through this character by character. XSS auditor ignores 0's for some reason. So, some extra logic that assumes that something is a zero if no matches are found is used instead. Knowledge about the value being used, such as its length and character, can also be helpful.
  • If the page isn't framable, then this becomes harder to do using new windows. It just requires checking load times and doing some timeout checks.
  • The history of this fix is pretty funny, according to this article. Initially, only the dangerous scripts were removed. But, this was insecure because security features may be deactivated this way, so the whole page was blocked. Then, to fix the bug in this report, it was reverted back to blocking only the dangerous scripts again.
  • Besides the security leak mentioned in this post, the same idea of a fake payload was used to remove arbitrary scripts from the page by placing the information in the URL with the deactivation setting. Eventually, the feature was removed from Chrome altogether because of the issues it created that were unsolvable. Overall, an interesting feature with a lot of awesome bypasses!

Bypassing SOP using the browser cache - 1789

Aleksei Tiurin    Reference →Posted 4 Months Ago
  • Many times, websites have subdomains that need to communicate with each other. Because of the Same Origin Policy (SOP), this isn't usually possible. Some technologies allow for this, a formerly popular one being JSON with Padding (JSONP).
  • How does this work? If you have blog.example.com and account.example.com, then the account page would have a JSONP endpoint. This works because of the cookies on the current page that get used. To prevent cross-data leakage, the endpoint verifies that the Referer header is whitelisted.
  • The browser cache works similarly to most things. When a browser gets a GET request response, it checks for caching information in the headers. Notably, Cache-Control, Expires and Last-Modified.
  • Now, put these things together: JSONP endpoint with browser caching. Because the browser caching doesn't consider the Referer header, it will return the response to this request without doing the check! This becomes an authentication issue as a result.
  • The author claims that this issue also happens with Cross-Site-Script-Inclusion. To fix this, just be careful with your Cache-Control headers. I personally hadn't considered browsing caching as a security issue but it is in this case!

Is the Move Language Secure? The Typus Permission-Validation Vulnerability- 1788

Slowmist    Reference →Posted 4 Months Ago
  • Typus Finance on the Sui blockchain suffered a hack recently of about 3.44M USD. This article explains the vulnerability and the exploit itself.
  • Typus Finance has an oracle that contained the following code:
    public fun update_v2(
    ...
    ) {
       // check authority
       vector::contains(&update_authority.authority, &tx_context::sender(ctx));
       version_check(oracle);
    
       update_(oracle, price, twap_price, clock, ctx);
    }
    
  • The code above attempts to update the price of an Oracle. The object UpdateAuthority contains a list of trusted updater addresses. The intention of vector::contains is to check that the caller is indeed trusted. The problem is that this doesn't revert the execution. It returns a boolean, and that's it. So, the access control check fails.
  • What's the consequence of this? If you can update the price of the oracle, then you can manipulate the entire protocol. In functions like swap(), it utilizes the oracle to determine the price of the asset, rather than the standard constant-product formula. So, an attacker would simply drop the price of the asset and execute a highly discounted trade for the desired asset.
  • They carried out this attack on 10 different pools to steal a substantial amount of funds. They then transferred the assets through CCTP to the Ethereum blockchain.
  • The vulnerability is a classic case of mishandling errors. Similar to assert() not being enabled in production builds, this lets an invalid state get through. Good write-up!

Critical RCE Vulnerability CVE-2025-11953 Puts React Native Developers at Risk- 1787

Or Peles - JFrog    Reference →Posted 4 Months Ago
  • When creating a React Native project looking, most developers use the package react-native-community/cli. This will create a project structure with proper dependencies and configuration files. To start the application, use npx react-native start.
  • When using the development server, React Native forwards commands to the @react-native-community/cli from a URL parameter in runServer.js. The added middleware handler /open-url will open a URL via the open() function in NodeJS. The whole reason behind this isn't explained in the article.
  • The open() command is very versatile - for good or for bad. On Windows, the command is passed as arguments to cmd and executed using childProcess.spawn(). This also works for URLs, thanks to the default URL scheme handler. By placing a bash command here, it's possible to achieve RCE on the development machine via a single URL parameter.
  • On Unix-like Operating system, executing open() expects separate strings for different parameters on the CLI, unlike Windows. So, this doesn't have an easy path to RCE. It can perform remote file loading via smb:// and execute a local file via file://
  • Wait, isn't this only on localhost? The dev server binds to 0.0.0.0 for some reason. What's hilarious about this is that there's a log message that says "Starting dev server on http://localhost:8081". Overall, a good post on the root cause of a pretty simple issue.

WhiteMage Target Seletion- 1786

WhiteMage    Reference →Posted 4 Months Ago
  • WhiteMage is currently #1 on Immunefi for earnings in 2025. Somebody asked about how people pick bug bounty targets. This was his response to it.
  • First, pick any topic; not target, topic. This can be specific functionality, a type of protocol or anything that is specific. The more specific the better. Next, find all projects with a bounty or a large TVL, like 20 of them. To me, this is unique. I tend to pick a project that is isolated and spend several months on it.
  • Go over each one of the projects to understand what they are doing. Notably, since they are all similar, note down how they do it and what could go wrong. To begin, just get the gist of it and don't go too deep. After a while, the same thing will be done over and over again. If something is being done differently, it's a good place to look at bugs.
  • Take time to look at suspicious things in depth. Go deeper and deeper into the intricacies of the functionality. With this, you'll gain more and more knowledge about this niche thing. These small details may lead to a bug or a wrong/sus pattern. Understand under what circumstances that this can be triggered and cause havoc. They refer to this as a almost crit.
  • At this point, you may have a lead at an issue. Save this and keep going! They have a great quote about it: " A lead is not a checklist bug, nor a vulnerability on a writeup. It's the understanding of something that on very specific scenarios can trigger a serious vulnerability."
  • Check all of the other projects for the same types of issues. It won't be exactly the same but there's a chance that similar types of mistakes were made. Now, prove that the issue leads to impact on the code. Prove this on all possible projects, write a PoC and report it.
  • For a bug on Scroll, the cross-chain messaging had a to.call(data), where the to had some magic values that shouldn't be controllable. They learned this pattern from reading bridges in the past and noticed that a particular check was missing in this code.
  • Another bug was in Story around block sizes. When Story/Omni changed the default block size maximum, this was fine. However, because the mempool is separated from the block creation in their protocol, this felt weird to the WhiteMage. A mismatch between expectations and reality seemed like a good path for a bug. Having experience with memory exhaustion and triggering node crashes seemed to help them.
  • He has a few do-nots:
    • Pick an amount of contracts that is actually doable. Don't pick all contracts on Ethereum.
    • Don't read all of the code. Only Just read the common denominator between all of the projects.
    • Don't follow checklists or writeups blindly. If it's on a checklist, it's probably been found. Feel free to use the checklist for inspiration but not much more.
  • They have a great quote at the end: "It's always some new idea around the same old concepts, but you have to do it for yourself. Then you can come up with some creative name like "read-only reentrancy" Thanks for sharing!