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!

Bypassing CSP via URL Parser Confusions : XSS on Netlify’s Image CDN- 1487

Sudhanshu Rajbhar    Reference →Posted 1 Year Ago
  • Many website uses Static Site Generators alongside an Image CDN to optimize the images on the website being loaded, such as NextJs, which this website uses. The image CDN behind the scenes has a URL parameter for the image. The allowed URLs are typically inside an allowlist with some Content-Type validation as well.
  • On Netlify, the endpoint is /.netlify/images?url=. The author placed the main paeg into this endpoint, with the requested content-type being text/html, and got a response of HTML! So, if we could find an arbitrary file upload on the site, we could achieve XSS through this endpoint.
  • For the website, all of the images are uploaded on the same CDN website. Using this, it's trivial to upload a file with arbitrary content but it must have a valid content-type. When going to the CDN, it pops an alert box. However, when trying the same through the image endpoint it doesn't work because of the CSP.
  • How does this CSP work? It turns out that it's a dynamic nginx configuration! If the location was on the /.netlify/images?url= path, then it returned script-src: 'none'. If we could trick nginx to see a different URL but have it parse the images endpoint then we would have a CSP bypass.
  • The author tried /./.netlify/images?url=... which nginx will parse differently than the underlying application. Neat! The CSP now contains a script-src that allows our script. In order to have this work in the browser, the page above needs to be URL encoded with /.netlify%2fimages though. This gives us XSS!
  • Netlify fixed the issue but the author found another bypass with an additional leading slash. For whatever reason, this has not been patched yet though. They fixed this by changing the types of files allowed on the CDN but left the parsing issue the same as before.
  • Overall, a super interesting bug report! A mix of new technology with old bugs is fun to see.

Flask-CORS allows the `Access-Control-Allow-Private-Network` CORS header to be set to true by default - 1486

flask-cors    Reference →Posted 1 Year Ago
  • Private Network Access (PNA) is a new browser security feature to prevent direct access to local networks. Segmenting the local network is important for preventing CSRF-like attacks to compromise a users network.
  • The mechanism for fixing this is Access-Control-Allow-Private-Network header. If this header is not included for a particular website, then it will reject the local network request.
  • In Flask, the default for this header was true. This effectively removed the protections of the new PNA specification. So, it just sets the default to false now.

Basic HTTP Authentication Risk: Uncovering pyspider Vulnerabilities- 1485

Yaniv Nizry - Sonar Source    Reference →Posted 1 Year Ago
  • pyspider is a web crawling framework. It has a standalone and locally hosted website. pyspider has a flag for using authentication and not using authentication. With authentication turned on, it uses Basic Auth - the username and password prompt from the browser.
  • When submitting a cross-domain request with cookies, the cookies are automatically attached to the request. At least, before the creation of the SameSite cookie flag. Additionally, there is a pre-flight request in many cases that would prevent CSRF. This works well for functionality but is scary for cross-site request forgery (CSRF) attacks, otherwise known as the session riding attack.
  • Browsers do not have any CSRF mitigations for Basic HTTP authentication. So, once you log in, all requests made will now include the credentials. If a malicious actor makes the call then it's a major issue for making calls. I'm unsure if the pre-flight request has any bearing here but I'd guess it does.
  • According to the author, it's trivial to pop a shell. The website has a request to execute arbitrary code. So, using a CSRF alongside this is leads to RCE. Sadly, the project is not longer maintained. Finding the security issue led to the project being archived. Regardless, this was completely new information to me on the Basic HTTP Authentication.

Breaking Down Barriers: Exploiting Pre-Auth SQL Injection in WhatsUp Gold- 1484

SinSinology    Reference →Posted 1 Year Ago
  • WhatsUp Gold gives a user visbility into applications, network devices and servers. To do this, it requires a lot of credentials, making it a good target for attackers.
  • While tracing out some inputs, Sina noticed that user controlled input was being placed into a SQL query. Classic SQL injection vulnerability! Now what? Credential leakage? Command injection? From understanding the configuration of the DB, they noticed that command execution wasn't possible because of a secure database configuration. Additionally, the credentials for the admin-user were encrypted.
  • Reverse engineering the application found that the encryption was fairly faulty. It was a combination of funny hardcoded keys or keys stored in another table. This made decryption inconsistent and unreliable, which was frustrating.
  • The idea was to find a primitive from the application to either decrypt the password or encrypt a user controlled password to overwrite the existing one. While browsing around, they found some code that was using the same key and encrypting arbitrary user data. This gave us an encryption oracle.
  • So, here's the full exploit chain:
    1. Use the encryption oracle to encrypt data for us that we will use as a password later.
    2. Use the SQL injection to retrieve the encrypted value. We don't know how its encrypted but we know the encrypted value!
    3. Use the SQL injection again to overwrite the admin password with the encrypted value.
    4. Login!
  • Overall, a solid post! I enjoyed the reverse engineering breakdown and the creativity to turn this into an authentication bypass.

Due to the use of msg.value in for loop, anyone can drain all the funds from the THORChain_Router contract- 1483

Code4Rena    Reference →Posted 1 Year Ago
  • Thorchain is a cross chain bridging platform with DeFi elements. In the Thorchain router on EVM, there is a call made to an arbitrary contract with a low level call. If this fails, then an ETH transfer is attempted to be made to the target. If this fails, then the msg.sender is simply refunded. Naturally, the refund amount is just msg.value.
  • There are two functions that can trigger this functionality: transferOutAndCallV5 and batchTransferOutAndCallV5. When calling this function in a loop, it will reuse msg.value multiple times and refund this to the user. This allows all ETH from the contract to be stolen.
  • The vulnerability was only rated as medium by the judges instead of high like the author proposed. My guess is that the router shouldn't normally have ETH, making it a way to steal value when people send it their by accident. Besides the stealing of funds, it leads to a self-DoS is more than one revert occurs and there is no funds in the contract.
  • Using msg.value in loops is bad practice because of this. Instead, the amount of funds being sent should be kept in a separate variable and should not be more than the value passed in originally. Regardless, a great find and a solid write up!

ThorChain will be informed wrongly about the unsuccessful ETH transfers due to the incorrect events emissions- 1482

Code4Rena    Reference →Posted 1 Year Ago
  • Cross chain bridging platforms require on-chain and off-chain components. For Ethereum, the common practice is emitting an event in the EVM, which will be processed off-chain. After the processing of the event is done, it can be sent to the destination chain. Of course, the event emission must be 100% correct for this to work.
  • In Thorchain, if a transaction fails a refund is triggered. This is done by handling the failed contract call then emitting an event to acknowledge that the transfer happened. When the failure happens, it gets placed into a vault contract.
  • The bug is that the TransferOut event is emitted for a successful transfer. When in reality, the rollback to the user should have occurred. This leads to funds being lost for the user. To fix the bug, the event should only be emitted when the transfer to the target is successful.
  • Cross chain stuff is hard! Solidity error handling is also hard. Put this together and we have a lot of bugs I'm sure.

Government Emails at Risk: Critical Cross-Site Scripting Vulnerability in Roundcube Webmail- 1481

Oskar Zeino-Mahmalat - Sonar Source    Reference →Posted 1 Year Ago
  • Roundcube is an open source webmail software that enables users to check emails in their browser. Many government agencies use it, making it a good target for exploitation. Naturally, the biggest threat is XSS on an email.
  • Roundcube contains its own email sanitization called washtml, which they couldn't find any vulnerabilities in. Once the sanitization is done though, some modifications were being made. When rendering emails, it doesn't put the content into an iFrame - it just creates a raw HTML page. When rendering, it needs to remove all of the body, head and other tags in it though. This is where the first issue is at.
  • The replacement of tags and values is done using a simple regex. When processing the bgcolor regex, its performing attribute parsing and substitution. The regex /\s?bgcolor=["\']*[a-z0-9#]+["\']*/i handles for all possible delimiters. However, it does not consider the case that bgcolor=XXX could be placed inside of another attribute.
  • The author provides an example of a body field with <body title="bgcolor=foo" name="bar onload=alert(origin)">. The bgcolor and closing double quote are matched and removed. This leads to the new tags looking like <body title="name=" bar onload=alert(origin)">. What's interesting about the regex is that it should only work if it finds the same element (",') to open and close. However, it will happily parse the value with no quotes and close on a quote. Man, regexes are terrible!
  • Clicking on the open button for an attachment simply adds the _download=1 query parameter. The Content-Disposition header will set this as an attachment or inline it. The filename, MIME type and charset are all sent with the data. The MIME type being used has no checks and comes only from the filetype. While html and svgs are sanitized, nothing else is. The author of the post found that XML files could bypass check and still render HTML.
  • This last bug was a known issue but theoretically fixed by disabling the Open button for xml files. If it was possible to get a link to the file directly, the XSS would be possible but IMAP uses a random ID. Since Roundcube is missing good protections like CSP and sandboxing, the author looked to find a way to leak this link.
  • The main defense against CSS leaks is via a regex-based blocklist filter on the CSS text. It tries to ban usages of url() and @import for remote connections. For @import rules, the word is blocked except when followed by an a to allow for the important keyword. Notably, a stripped down version of CSS is being verified and not the full CSS page.
  • The allowance of an a for important and the normalization for verification allows for the usage of import aevil.com! Now, using previously known techniques, we can leak the UUID from the page via CSS. Using the same vulnerability, styles can be added to make a link in the email to overlay all elements that will redirect to the XML XSS page. If you don't fix the root cause of the problem, then you're going to get hit!
  • A service worker is a script stored in the browser for every HTTP request on a page. Being able to control a service worker would mean a permanent backdoor, unlike normal stored XSS. The specification tries to mitigate this risk by forcing the service worker script to be hosted on the same origin and be served with a JS content-type header. In the case of RoundCube, attackers can serve arbitrary JS files as attachments from the previous bug with the JavaScript content-type. Using one of the two XSS from above, an attacker could register a malicious service worker for a permanent backdoor. Nasty!
  • Bug 1 was fixed by properly escaping attributes and stopping usage of the bad regex. Bug 2 was fixed by changing dangerous MIME types to text/plain. Bug 3 was fixed by looking for @import and not stripping the CSS before checks. The author mentions that this would have been better if sandboxing or a good CSP was used too. Overall, an awesome post on a series of weird and novel bugs. I like the destruction of the regex parsers here - definitely something to keep an eye out for.

Aave v3 ZKSync activation issue report - 1480

Bgdlabs    Reference →Posted 1 Year Ago
  • ZKSync was launching the Aave V3 pool on their chain. While activating this they noticed a major bug. The bug only happened after a complex flow of supplying and borrowing assets. Since things looked weird, they paused the protocol to investigate.
  • The contract functioned perfectly on other chains so what was going wrong here? Their initial hypothesis was an issue with the bitmap math which had user data for 256 bits of boolean pairs. Since this bitmap was crucial to the protocol, being used for a token being collateral/borrowed, it was real bad.
  • From dynamic testing, they noticed that in situations with multiple assets enabled as collateral and borrowed, disabling the isBorrowing flag would zero out the wrong isCollateral flags. All flags to the right were being disabled for some reason.
  • They have a great example of the bug. For instance, if you have three assets that are being used as collateral and borrowed, the values would be 000...111111. If one of the debts was paid back, it should be 000...101111. In reality, this was becoming 000...100000. It believes that the user hadn't taken out a position, even though this simply isn't true.
  • From reading the compiler output, it became clear what was going on. The compiler had made an optimization that was wrong! Both parties that had reviewed it, Certora and Matter Labs, came to the same conclusion at the same time.
  • ZKSync takes the EVM bytecode and translates it to ZKSync bytecode using an intermediate representation in LLVM. The LLVM compiler had a bug in it when handling 256 bit number optimizations.
  • The code xor (shl 1, x), -1 was optimized to rotl ~1, x. When the ~1 was converted, it would turn into 2^64-1 to be zero extended instead of sign extended. The code should have been roti 2^256 - 1, x but was incorrectly turned into rotl 2^64 - 1, x.
  • I appreciate the detailed write up from the zkSync dev team. Additionally, their phased rollout of Aave to check for bugs really paid off in this case. Even though the bug wasn't the teams fault, it's still their customers funds at risk. Great write up and incident response by the ZKEra team!

Sei Protocol DoS- 1479

ExVuln    Reference →Posted 1 Year Ago
  • Sei is a popular L1 blockchain built on Cosmos that runs both EVM and CosmWasm runtimes. After a recent infinite mint and DoS, the authors decided to try to find more bugs in it.
  • The function GetRawSignatureValues decodes a BlobTx submitted by the end user. When this data is being decoded, MustFromBig can underflow, resulting in a panic. This decoding of transactions happens within the FinalizeBlock code of the ABCI, which doesn't have panic handlers. So, this takes down all Sei nodes.
  • The proof of concept is crazily simple - a transaction with z0000000000000000000000000000000000000000000000000 as the bytes. This will lead to S value of a signature underflowing and result in a crash.
  • To fix the vulnerability, a recover() should be used to catch the panic. Particular parts of Cosmos don't handle panics in important code; this does the panic handling now. Good find!

Circle's CCTP Noble Mint Bug- 1478

Ruslan Habalov - Asymmetric Research    Reference →Posted 1 Year Ago
  • USDC is one of the biggest assets in crypto by usage and TVL. Circle, the owners of USDC, created the protocol Cross Chain Transfer Protocol (CCTP). Although this is a general message passing protocol, the biggest use case is for transferring tokens (main USDC) to other chains that Circle built on top of CCTP. There is an EVM, Solana and Cosmos implementation of this on Noble.
  • On Noble, it is simply a Cosmos SDK module instead of a smart contract. Like most bridges, this works by emitting an event, having some off-chain entity attest to it and then minting the asset on the other chain. The token bridge works with an allowlisted set of sibling contracts that are owned by Circle. The message must be valid and come from the proper contract address in order to be considered legitimate.
  • When building protocols on top of each other, there are different security guarantees. CCTP validates that a cross chain message was sent on the other chain. On top of this for the token bridge, there are other things that need to be checked though. Crucially, the sibling check was missing on Noble.
  • This means that an attacker could call CCTP with a BurnMessage call from their contract and have it handled by the Noble module properly for USDC token minting. If the sibling was properly checked, this wouldn't have been possible though.
  • Great find by my co-worker! Sometimes picking on the lesser known/used implementation is the game plan. The Solana and Ethereum implementations are solid but this one went through the cracks.