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!
mint() will call the ERC3525TransferHelper.doSafeTransferIn(). Eventually, this will trigger a onERC721Received() callback that calls _mint(). Once control returns, mint() is called again. So, this leads to a double mint by design. onERC3525Received() gets called on the contract after triggering a transfer via transferFrom(). The callback contains a _mint() then the control flow executes another mint(). This leads to another double-mint path.burn(). The attack is calling mint on a position, receive double the ERC20 shares, call burn to redeem the inflated shares back into SFT value and then redo the process again to profit more. It's crazy how fundamental this vulnerability is to the protocol... I imagine that the math for tokens to share was hard to reason about and it was just assumed to be working as intended, when it really wasn't. Overall, a fantastic write up on the vulnerability!bcrypt in a separate function, it returns a promise. When using this value, it performed an && operation for a boolean on the promise! Promises are always truey. So, the boolean valid was always true when a user had a bcrypt password set. It's interesting that the LLM picked out this subtle bug. This realistically should have been found via testing... a single happy and sad test case would have solved this.2^n to a single evaluation for a global check called the claimed_sum. This value is provided and MUST be part of the committed value. This issue was found 6 times in various codebases.null check within signedJWT directly before the signature verification block. If the signedJWT is not null, then verify the signature. Otherwise, do nothing. In the case of an exception in Java, the code exited. So, what does toSignedJWT() normally return?toSignedJWT() will try to parse the decrypted payload as a signed JWT. If it's a PlainJWT, which is an unsigned token, it returns null. Using this type completely bypasses JWT verification. android:exported="true". If it has a deeplink, then it makes it possible to trigger from just a single link on the web. There were several of these scopes within the context of the Bixby Launcher Activity, used for voice-activated commands.samsunginternet://com.sec.android.app.sbrowser/Task/Path?params. For the AccessWebsite task, it performs input validation on the URL before launching it. com.samsung.android.bixby.agent check. This ensures that the intent can only be triggered from a particular package. Upon finishing validation, it would call com.sec.android.app.sbrowser.SBrowserMainActivity.SBrowserMainActivity activity was also exported. The accessWebsite activity checks whether a tab exists. If not, it would open the URL in a new tab. Otherwise, it will immediately call loadUrl(str). SBrowserMainActivity is exported! So, all of the previous input validation can be ignored and this called directly. By setting the URL to be javascript:alert(origin) after loading a page, you get XSS on the loaded page! Because of how this works, this leads to XSS on ANY website. Pretty neat!/helpdesk/WebObjects/Helpdesk.woa/ajax/9.7.43.0.0.0.4.3.7.0.7.1.1.1 contains a method and params parameters in JSON. Upon seeing this, they found the method takeValueForKey(), which performs deserialization via a custom JSON-to-Java bridge. Further down the path, it's a classic setter-based deserialization attack where the attacker controls the target type. WrapperConnectionPoolDataSource contains one and this leads to RCECVE-2025-26399 was a bypass for the original SolarWinds issue. The patch added a regex-based check for which classes were NOT allowed via a blacklist. The request JSON body is decoded with Apache Commons. The same JSON is extracted via a different parser in org.json.JSONObject. They found an encoding difference between the libraries... Apache Commons didn't support short hex escape sequences (2 bytes instead of 4), but the JSONObject did. So, java\\x43lass bypassed the check.CVE-2025-26399 was exploited. The new sanitizeRequest method parses the JSON into Jackson and checks whether the Params key is there. If so, it overrides params with an empty array. Why? If the request includes parameters for AjexProxy, it strips them away. Using the same trick as before, this can be bypassed with p\\x61rams. Jackson doesn't see the \\x escape, and the sanitizer logic is bypassed. So, this creates a new zero-day on SolarWinds!wopage parameter allows selecting an arbitrary page. Using this, it's possible to access any page without authentication. Putting this together with the previous RCE bug and a new gadget, they got a pre-auth RCE. They had an additional authentication bypass that was less powerful.cookieToMap had the exact traits of a deserialization-to-RCE bug: using readObject() on user-controlled data. Except, there was a catch: the cookie must be signed. So, this seems like a dead end... the entire post is about their method for exploiting this.