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!
ArrayBuffer semantics. A page can detach a typed array by transferring its underlying buffer to another context. This is a legitimate API and is used for zero-copy data transfers. ColMajorF accessing 16 array indexes, it reads 64 bytes past the end of the buffer that was just initialized. This creates an out of bounds read in the Chromium Engine.*.perplexity.ai/* domains. With this extension, arbitrary actions can be asked to be performed. A single domain compromise or XSS would lead to a compromise then.CALL_TOOL and RUN_IDLE_TEST. The former was a generalized tool executor while the latter took screenshots of the DOM of any page. Because this could handle file:// URIs, it could also read responses from arbitrary origins and local files. CALL_TOOL to see what it could do. One of them was GetContent to read the contents of a page. They tried to escalate to RCE from this tool's context but were unsuccessful.startAgentFromPerplexity command opened a websocket to the backend and forwarded the task information. The backend returns selectors based on the response and performs actions accordingly. Using this, they can get the browser to perform arbitrary actions. Good bug!forums.openai.com via postMessage. The post message handler received a URL and opened it from an arbitrary domain. So, you could send the JavaScript URI as a domain, and it would execute in the context of OpenAI. Yikes!kaur1br5 is the codename for the tool responsible for controlling the browser, including listing tabs, searching browser history and adding bookmarks. They tried adding javascript: bookmarks but this was rejected. They tried navigating to JavaScript URIs but these were rejected as well.list_tabs(). This allows for querying the full URL of the entire tab. This can leak information about browser-navigated URLs, including OAuth codes. The PoC leaks a user's GitHub OAuth token, which is pretty neat. list_tabs to not include all information about a URL. Alas, this is still bad design and we probably haven't seen the end of this browser.feColorMatrix and feDisplacementMap. to change the color/location of pixels. <fe*> typing. They take in one or more input images, apply operations to them, and output a new image. Some can load an image file. Others can move stuff around. Others can move pixels, blur, crop, expand, blend, and more. With this, it's a great list of utilities to make clickjacking more viable. feDisplacementMap flag to add blur. You ask the user to type in the code, and it looks somewhat realistic as a CAPTCHA. This isn't very useful because secret code pages like this shouldn't be iframable anyway.map in the beginning of the object used for the type of the object and offsets to its other properties. Once the object data is known, this information no longer needs to be calculated, thus speeding it up.super properties of the inline cache. With the usage of both prototypes and classes, the hierarchical information about these types is complicated. For instance, parents' prototypes can even be different from those of their children. LoadSuperIC function is used to cache super property (parent) access. The property is NOT on the receiver this but on the parent prototype. Because of this, assumptions about the object types and maps should be examined in both the receiver object and the parent protocol type object to ensure correctness. Notably, the confusion between the receiver and home_object has led to vulnerabilities in the past, such as CVE-2021-30517. This bug led to type confusion due to differences between cached and real data access.simple_api_call, used for interaction between the V8 engine and the Blink rendering engine, requires a particular byte format. When a handler is created for a property accessor, the wrong map type is used; it accidentally uses the lookup_start_object instead of the super type. Because there's a type check and the types can differ between parent and child, this creates a type confusion vulnerability. getter() can be called on an arbitrary type; this is their primitive. This type confusion is very powerful for developing further primitives.DeviceMotionEvent::interval function. By using this on the DOMMatrix type, the interval field, used to read data based on the interval data, we can specify the offset and read from there. The next primitive is getting an arbitrary objects address in order to corrupt it. The type Uint8ClampedArray in an ImageData type can be overlayed with DOMMatrix again to read the address of the code>Uint8ClampedArray array. getter of some objects sometimes returns JavaScript objects. By causing a type confusion on the value returned from the getter, an arbitrary write can be achieved. In particular, the signal property of Request returns a ScriptWrappable type. By overlaying the AudioData timestamp field with the request data, the timestamp is effectively the address of the object being returned. This is great for creating a OOB read/write primitive from an array. That's game over :)new BN(msg, 16) removes the leading zeros. When it's used later, some offset math is wrong as a result. This bug was never fixed._calc_supply() is used for generating the values of the curve. Notably, it's figuring out what the supply is from the constant-product and constant sum values. This is done with an iterative approximation to converge to a new supply. The constant product term r is recomputed each iterate as the current value multiples by the new supply and divided by the previous supply. The goal is for the smoothness of the curve to get better over as more tokens are put into the pool.sp, there are several unsafe math functions being used; this means that integer overflow protections are not enabled. In the math (l - s * r) / d it's possible to make s*r larger than l to cause an integer overflow. This mints a crazy amount of LP tokens, which they use to steal even more money. It should be noted that this is only possible to do because of the first vulnerability above.