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!

SSRF Tricks- 1315

Corben Leo    Reference →Posted 2 Years Ago
  • The author of this Tweet has made over 500K in SSRF bugs. In this thread, they go through their best tricks. The first trick, is using other URL schemes like file:// and many others. This can lead to RCE or arbitrary file reads.
  • If you can't hit internal parts, try using alternative encodings. For instance, octal, hex, binary and others. They recommend the tool IPFuscator for doing this. Different representations of localhost like 127.0.0.1, 0.0.0.0 can make it possible to bypass these.
  • This is probably my favorite trick: if you can't hit the AWS instance 169.254.169.254 then use instance-data to resolve to this IP instead. That's pretty fire and clutch that this works on EC2 instances. On top of this, they mention knowing your technologies. Different techs have different internal endpoints to hit.
  • If you can't supply a full URL, there are still many ways to get SSRF. The @, ?, # and ; all have a sticky history with URL parsing. The SSRF bible is a good resource for thinking outside the box on this. The URL has 9 parts: protocol, user, password, subdomain, domain, top level domain, port, path, query and fragment.
  • Directory traversal can be very powerful with a relative path as well. This could allow hitting unintended endpoints on the application. Justin Gardner has even more tricks.
  • Different layers of URL encoding can cause issues. Justin mentions using 3 layers of URL encoding in an exploit. Another common issue is using a literal . within a regex. Although this seems fine, the . within a regex is actually a single character wildcard.
  • DNS rebinding attacks. If there is a TOCTOU bug then go to a public IP to begin with then a private one after the first check has been done. On the same type of thing, the When TLS Hacks You technique works good as well.

Achieving Remote Code Execution in Steam: a journey into the Remote Play protocol- 1314

Thalium    Reference →Posted 2 Years Ago
  • Steam remote play is a peer-to-peer system for playing video. The author of this video reverse engineered the protocol to understand how it worked, build a fuzzer and find fun vulnerabilities in it.
  • The remote play protocol was mostly using protobufs. Luckily for the author, many of this information was kept in a Github repo. There are various ways to perform networking, from webRTC to UDP but the author choose to use UDP because of its simplicity. For more details on how the protocol works, with headers, authentication, channels and things, read the post.
  • To interact with the project, the author built their own client and server implementation. An initial issue they ran into was that the session info for the session would have already been derived. They used a x32dbg script to automatically inject the key into the running process then use it on their client. Another issue they had was forcing the client to use the UDP connections. By changing advertising parameters to ONLY include this, the server would always choose UDP.
  • With a client and fuzzer built, the author setup a fuzzer. Since this uses protobuf, the fuzzer had to be grammer aware, which they created their own engine for. For strings, they added in weird things like paths, URLs, XML and more. For integers, they added in interesting sizes like powers of 2, negative numbers and more. They even randomly dropped random optional fields.
  • Some of the connection types were stateless while others were stateful. Because of this, they built a replay system and logging system to see what was going on. Additionally, a scenario system to test various stateful actions to interact with the system or reproduce bugs. One issue I've had with stateful fuzzing in the past is reproducing issues. It would require saving all previous inputs in order to be confident that we had the information to reproduce the issues.
  • With all of this built, they found a bunch of vulns! With fuzzing, crashes are nice and expected. However, looking for side effects is equally important for finding bugs; not all bugs are binary issues that lead to a crash. The first bug was a simple directory traversal, found by the fuzzer, that could be used to overwrite a Steam DLL to get code execution.
  • From there, they found a ton of format string issues but without %n available. Crazily enough, these were in parts of the system, like logging, that made it possible to use this as a leak. So, an attacker could steal arbitrary data from the heap and/or break ASLR on the system.
  • When calling CRemotePlayTogetherGroupUpdateMsg, there was an SSRF issue if JSON was not returned. By specifying a URL with a GET request, arbitrary data on the network could be leaked. Besides this, a few OOB reads and writes were found in player structs, audio encoding. One of the leaks allowed them to remotely read all heap data from the process, which is super cool.
  • Good read! The bugs are fun but the setup of the fuzzer and thought put into making the system testable was the most valuable thing to me. The SSRF issue which only leaked data if the data wasn't JSON was a good instance of fuzzing for bugs without memory corruption being the only goal. This requires you to be more active but will pay off in complicated systems like this one.

Levana Exploit Postmortem- 1313

Levana    Reference →Posted 2 Years Ago
  • Osmosis is a very popular blockchain in the Cosmos ecosystem. Levana in a perpetual swap built on Cosmos (CosmWasm?). On December 26th, a large chain congestion occurred via a bad set of configurations. This timing was enough for a hacker to profit though.
  • Levana uses the Pyth oracle to keep prices and things up to date. Usually, this occur on a per block basis but some leeway is allowed depending on the previous price. The market contract allow for a 120 second lag. If the market was highly volatile, this is plenty of attack to exploit the difference in price.
  • This difference in price comes down to a price delta attack. In this, the attacker waits for the difference between the actual price and the marked price to be large enough that an attacker could profit solely from the trade. If the price is up, open a long. If it's short, then a low. Once the update goes through from Pyth, sell to get the profit with no risk.
  • The system had many mitigations in place to prevent hits. First, the updates being so spread apart is just unlikely; normal trading would update the price. Second, there were maintainers with bots who were pushing these updates regularly from Pyth info.
  • Now, the delta attack is simply a limitation of the design. However, the circumstances of the market are what led to this being viable. In particular, Osmosis was experiencing large congestions from insufficient fee errors. This came from the newly added fee mark mechanism. Apparently, at the same time, a DDoS attack was occurring on the Levana platform as well.
  • During this timeframe, the authors launched a bot that was always updating the chain prices. Even with the bot and high gas prices, it was still not high enough to push it through. They also paused all markets. How do we actively mitigate this though?
  • The team assumed that that they could land all on-chain price updates, which ended up not being the case in the high congestion times. So, they've decided to decouple these where there will be placing and execution in separate calls. By doing this, the Python update MUST occur within a given timeframe, or the call will timeout. This prevents the exploit above.
  • Developers make assumptions about how a system runs. In these difficult times, it's important to think of worst case scenarios and extreme edge cases to ensure that the product is completely unhackable. Good read!

msg.data Hashing is bad- 1312

ddimtrov22    Reference →Posted 2 Years Ago
  • In Solidity, msg.data is the incoming data in the request as defined by the ABI. Using a hash of this for some cryptographic operation is a real bad idea. But why?
  • The original issue with this existed in the V1 ABI encoder. When encoding information, all data bytes are 32 bytes when sent in the unpacked format. However, some of the bits may be dropped with datatypes, such as uint8s first 31 bytes.
  • Since the truncation occurs with unused bytes, it does not affect any of the actual values but changes the hash. According to Solidity Github issue this only works on the V1 ABI encoder and not the V2 version, which is the default in Solidity 8.0.0+.
  • Regardless of this, there are other ways to abuse this. For instance, you can append arbitrary data to the end of the msg.data that will simply be ignored to change the hash. Additionally, some things, like dynamic data types, have infinite ways they can be encoded.
  • Overall, interesting Solidity quirk that many people may not consider. Thanks for calling this out.

IBC Rate Limits: Introduction and State of the Art (1/3)- 1311

Andres Monty    Reference →Posted 2 Years Ago
  • Bridges are an important piece of the blockchain ecosystem. Being able to move assets from one chain to another is a necessary requirement in the modern web3 space. However, doing bridges securely is difficult to do. In Cosmos, interblockchain communication (IBC) allows for Cosmos blockchains to talk together in a standardized format. In this article, the authors discuss bridge security and how to make IBC more secure.
  • Most security is put into the pre deployment of applications, such as pentests, code review and more. However, equal importance needs to be on the post-deployment protections. The authors mention four different mechanisms for on-chain post-deployment: circuit breakers, rate limits, settlement delayers and redundancy.
  • Circuit breakers simply pause a system when certain conditions occur or manually. This acts as a kill switch to be able to stop functionality when something bad is happening. The Cosmos SDK circuit module is a good example of this but it must be manually done and it's per message.
  • Rate limits disable functionality once a threshold has been passed. This can be a value rate limit such as a dollar amount or a volume rate limit. The second one is similar to API rate limits. This helps to limit the damage of attacks but doesn't prevent them entirely.
  • Delayers impose a delay window between certain transactions. This allows for incident response a time window to revert things if they are malicious. For instance, a 1hr delay may be imposed on a transaction of $1M or more. This is common on governance proposals but can be used in other places as well.
  • Bridge Redundancy Protocols are a consist relay of message over several bridge protocols. If one is effected by a bug, that doesn't matter! To me, having diversity in software is good, like how JumpCrypto is making an alternative validator for Solana.
  • The focus of the article was how the Osmosis blockchain implemented rate limiting on IBC. They have a rate limit on the amount of token assets that can be moved into the ecosystem. This is done with by static periods and net flow of assets moving. This rate limiting is implemented in a CosmWasm smart contract that interacts with the IBC middleware package as a wrapper around ICS20.
  • To be more specific on the Cosmos side, the rate limits are implemented on a given channel and denom. This allows for a standard transfer to occur between two blockchains, without interfering with others. These rate limits measure the inflow and outflow of tokens on a given channel. These are setup in different intervals but appear to be configurable.
  • There are other examples of rate limiting. On the Stride Cosmos SDK blockchain, they do IBC rate limiting based upon the amount of tokens transferred on a channel for a 24 hour window. The Wormhole governor, after a large hack in 2022, implemented functionality as well. They have two types of transactions: small and large. A large transaction has a finality delay of 24 hours while both transaction types of a daily quoted of funds that can be sent.
  • Overall, good post on different on chain protections can be done to reduce the risk.

Sonos Era 100 Secure Boot Bypass Through Unchecked setenv() call- 1310

Alex Plaskett - NCC Group    Reference →Posted 2 Years Ago
  • The Sonos Era 100 speakers uses UBoot for the basic boot process. UBoot is a common microcontroller boot framework that has a lot of existing functionality but can be crafted for whatever you need. The Sonos team created a custom sonosboot command that loads the kernel image, does the signature check then passes execution over to the bootm command.
  • bootm command uses environment variables from UBoot for various configurations. In order to ensure that only trusted parameters are used, the implementation calls setenv(). However, the error message is NOT checked for this call. Can we abuse this?
  • By interacting with the UBoot console or modifying the eMMC memory directly, we can control these variables. Normally, these would be overwritten. UBoot allows for the setting of environment variables as read only though. This can be done with bootargs=something then setting the flags with .flags=bootargs:sr. Now, going forward, any future writes to bootargs will fail.
  • Now, as an attacker, we can set any of the ENV variables we want then make them read only to ensure that the setenv() call fails. The authors set the initrd variable to control the initramfs image that was loaded, hijacking the boot process.
  • I really enjoy vulnerabilities that result in things failing in weird ways like this. Not handling errors can have devastating consequences even when it seems impossible that something would fail. Good article!

Cookie Bugs - Smuggling & Injection- 1309

Ankur Sundara    Reference →Posted 2 Years Ago
  • Cookies are a core part of browser mechanics. Understanding how they work is important when escalating existing issues. In this article, the author dives into quirks of various frameworks and browsers on cookies.
  • First, when are cookies sent? This depends on the domain attribute of a cookie. If the domain is set for example.com, then all subdomains will send this as well. If the cookie is set from a subdomain onto the parent, it will be sent with the parent as well. It's interesting that this is allowed to be set.
  • Cookies are ordered on Chrome and Firefox by first the path length then the last updated time. So, if you have a vulnerability that allows you to set a cookie, you can get yours parsed first by setting it with a longer path.
  • Browsers allow for cookies with an empty name. For instance, =test value; is a valid cookie that can be set. When rendered, this will break the parsing of the cookies by most web servers. So, we can set arbitrary cookies that are not secure or host cookies.
  • A new attack vector presented in this post is cookie smuggling. The idea is to break the parsing of cookies when you have control over some of them. If you can add a double quote (") to a cookie, then some items will follow the RFC2616 standard while others will follow RFC2965. Why does this matter? The double quote changes the meaning of the cookies being parsed. Using this HTTPOnly cookies could be smuggled or some cookies could be outright set.
  • Going deeper into the parsing issues, we need to ensure that everything parses cookies the same. In Java Undertow, they found that that parsing for a cookie begins right after a double quote. So, if we have a cookie with double quotes, it will then parse the rest of the data as our cookie, smuggling in our cookie!
  • Python stdlib http.cookie.SimpleCookie and http.cookie.BaseCookie suffer from a same issue. If a space is found in the cookie, then it will start parsing this as a new cookie, using it as a delimiter. Since the Python library has this issue, all frameworks using it are vulnerable as well. Cookie injection is bad where cookie based CSRF protections are used, spoofing secure or host cookies and authorization bypasses where things check for specific cookies.
  • Although they contacted many of the projects, only Jetty actually responded. So, many of these issues will exist going forwards! Overall, good article on cookie quirks that I had no idea about!

IppSec Search Engine- 1308

IppSec    Reference →Posted 2 Years Ago
  • IppSec is a YouTuber with great hacking videos. This is a search engine for timestamps in their videos. So, if you need a video example of a bug class, this is a great resource.

Tricks for Reliable Split-Second DNS Rebinding in Chrome and Safari- 1307

Daniel Thatcher - Intruder.io    Reference →Posted 2 Years Ago
  • DNS rebinding is a fairly well-known attack used in various situations. The idea is to trick the browser on the origin of the website by changing IP address between DNS requests. For instance, if it's 1.2.3.4 initially but an internal IP afterwards, like 127.0.0.1, then we can make requests to localhost and bypass the same origin policy.
  • Historically, these were used for accessing internal networks of users within the browser. With the invention of headless browsers, this has became a good attack method on it as well. In a previous post by the authors, they used this to get access to EC2 metadata credentials on their product. They could run this as long as they wanted, with no time constraints. However, what if we don't have unlimited time?
  • The main constraint of DNS rebinding is the time between DNS lookups. Since browsers cache DNS, we need a way to force a new lookup. A popular way to force a new lookup is by flushing the cache by overloading it with so many entries, which takes about 10 seconds. However, other things like Ubuntu will take 5 minutes or VPNs take 30.
  • In previous research, Craig Heffner performed DNS rebinding by relying with multiple A records for the same domain in the same response. The 2 records were a public IP and a private IP. To make this exploitable, the browser must use the public IP first then the private one later. To force the usage of the second (private) entry a TCP RST was sent to the browser on the original IP address would fallback to the second one, which was a private IP.
  • With this in mind, they decided to look various browsers to see if new techniques could be discovered. On Safari, the private record is prioritized. Additionally, the requests for the A record and AAAA records were done in parallel. Once the first DNS response is received, regardless of the ipv4 or ipv6 status, this will be used for the DNS request.
  • Putting this information together, a slight delay on the private IP will lead to a quick DNS rebind. First, return the public IP for the website in one of the responses, but faster than the other. Once the private IP is returned, the browser will use this one instead. Now, we have a super faster DNS rebinding attack on Safari.
  • On Chrome, it has a priority list: local IPv6, public IPv6, local IPv4 and public IPv4. When Chrome knows about multiple IP addresses, it will try a different IP address as soon as one of the servers resets the connection. So, putting this all together, we can attack the browser as follows:
    1. Load the website.
    2. Have an A record pointing to the local network and an AAAA (IPv6) pointing to a public website that you control.
    3. Chrome will use the IPv6 for the initial request.
    4. Shutdown the public server. This will send a reset.
    5. The loaded page will now use the private IPv4 address instead of the IPv6, allowing for a SOP bypass.
  • Private Network Access (PNA) is a specification for blocking pages loaded over HTTP to make request to private networks. This prevents the exploitability of DNS rebinding because we can no longer access private IPs. However, in Chrome where this is implemented, this is NOT done on iFrames yet.
  • The attack is exactly the same as the previous Chrome issue except with a twist of using an iFrame in the middle of it. From the previous step 5, instead of making the request to localhost directly, we do this inside of an iFrame. Load the private URL in an iFrame. After this has been done, inject a script into the loaded iFrame. Now, you can make requests successfully with the DNS rebinding.
  • Overall, an amazing list of techniques to make DNS rebinding more exploitable. This is one of the best articles I've read in a long time and is just amazing research. Thank you Daniel!

SSH ProxyCommand == unexpected code execution (CVE-2023-51385)- 1306

Vin01    Reference →Posted 2 Years Ago
  • The SSH ProxyCommand is used for proxying SSH connections. In particular, custom commands can be used to connect to the server. Within these commands are variables, such as %h for the hostname or %p for the port.
  • These parameters are not being sanitized when used within the SSH command scripts. So, a malicious host, port or many others could be used to get command injection in the SSH proxying setup.
  • At first, I didn't understand where this came from. They provided a command from Github for a PoC. In this example, the submodule files contain ssh://`open -aCalculator`foo.example.com/bar, which creates a command injection on the proxy setup.
  • Be careful what you download! This could have been exploited to torch people using git in many different ways. Awesome, yet simple bug in an everyday system.