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!

Cross-Site ETag Length Leak- 1855

Takeshi Kaneko (arkark)Posted 2 Months Ago
  • The author of this post found an unintended way to solve a CTF challenge by exploiting a new cross-site leak (XSLeaks) technique. So, they made this into a standalone challenge for this CTF. The challenge had a single solve.
  • The setup is a note-taking app where GET / returns the notes, with a search parameter in query, and a note can be created via POST /new, which is vulnerable to CSRF. One of the notes on the bot contains the flag, and it's your job to steal it from another JavaScript tab. The timeout is 60s but there's no HTML injection, no sorting, no CSS and no other loaded resources.
  • The ETag header is an HTTP response header that acts as a unique identifier for a specific version of a web resource. It's useful for caching data more effectively. Mozilla docs. The application sets the tag via jshttp/etag, which formats the content size in hex as a prefix. The ETag length can differ by 1 depending on the response size and is controlled because of the CSRF bug.
  • This is the beginning of the primitive. What can you do with this? If a response includes the ETag header, subsequent requests will use the same URL with the If-None-Match header containing the ETag. Many web servers have a maximum size for request headers and will output a 431 Request Header Fields Too Large error if exceeded.
  • By padding the URL so that the overall header size is right at the threshold, the extra If-None-Match byte can be the difference between a 200 Ok and a 431. Using the search, this can be abused to check whether the searched bytes match or not, cross-origin. But, can you see this? Cross-origin status codes are opaque!
  • Chrome has a behaviour where the browser may or may not push an entry to the page history. If the same URL is accessed twice in a row but the second navigation fails, only one history event is added. If they both succeed, then two events are added. By looking at the number of entries in the page history, we can determine whether the navigation succeeded or failed.
  • Putting this altogether, the exploit has a few steps:
    1. Use the CSRF creation of notes to fine-tune the number of bytes on a page to be on the boundary.
    2. URL pad the SECOND request near the Node's header-size threshold.
    3. Measure the history.length of the frame to see whether the second navigation occurred or not.
    4. Repeat character by character until the flag is leaked.
  • In the unintended solution of another challenge, they used the presence of an ETag header to cause the same issue.
  • Overall, a great post on a new XS-Leaks technique! These are always really complicated and really subtle, so I appreciated the new write-up for it.