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!
key ability. A verifier is ran to ensure that the ID is unique per object. So, where's the bug at? Still more background!AbstractState::join() function. This function merges and updates state values iteratively like we mentioned before. For each local variable in the incoming state, it compares the value to its current value. If the two valeus are unequal, then the changed flag is added to perform a AbstractValue::join() call and to go over this iteratively again. AbstractState::join() may indicate a change due to the differing new and old values but the state value after the update might remain the same. This occurs because the AbstractState is processed before the AbstractValue. By triggering this state, it's possible to initiate an infinite analysis loop. toolgate, the protocol for communicating between the guest and host. TG_REQUEST_FAVRUNAPPS) is made to the host to notify it of the app.Info.plist of the application. DYLD_INSERT_LIBRARIES to force an arbitrary dylib file. Still though, this isn't enough for execution just yet. So, they were looking for arbitrary file write vulnerabilities to write a dylib file themselves then execute it. The best place to look for these bugs would be a shared folder service. ../, has symlinks or anything else. It looks perfect. Except, there is a time of check time of use (TOCTOU) bug here that allows for the circumvention of this check. Web.config to see how the routing was working.
api/sitecore/{controller}/{action}. While digging around into what they could instantiate with only a few restrictions; it ensures that the object is .NET type and implements the IController interface. A super large attack surface!Sitecore.Mvc.DeviceSimulator.Controllers.SimulatorController had the action Preview with the parameter previewPath. This was calling Server.execute under the hood with the parameter that we control. This allows for arbitrary redirects within the application itself without fancy 302s. Damn, that creates a pretty neat authorization bypass!Server.Execute had no restrictions on where it could redirect to. All it had to be was something within the webroot. This function does not rerun the HTTP pipeline (including auth), allowing for bypasses of the IIS setup. Using this, they were able to leak the Web.config file by reading backups. /sitecore/shell/Invoke.aspx caught their eye for obvious reasons. This allows for the arbitrary instantiation of a class and execute any method, with restrictions. In particular, no static items were allowed, a user had to be authenticated and it could only take string parameters. They decided to look for sinks for RCE gadgets. DeserializeObject() within the Telerik UI. They followed this back up to find a method that sets this value within a class! Now, they can send in a deserialization method once again to get code execution. They wanted this to be unauthenticated though. A third similar deserialization issue exists as well.EXM mailing list, the user is set to the Renderer User. They used the Server.execute issue from before to hit this code to trigger the second deserialization attack mentioned above. Neat!50/2 + 175/2=$112.5 in isolation. But, if we consider the compounding asset to this, it's different. A 50% loss and a 75% gain gives us 87.5% of the value. This is the same in the other direction as well. The effects of compounding on gaining back the wealth are devastating. This is based upon the Kelly Criterion optimal betting strategy.(2 * sqrt(fee))/sqrt(3) and 2sqrt(fee). What's going on here? If the asset is too volatile or doesn't move at all, you're better off keeping the asset. Within that middle zone, we can stop volatility drag and make a profit from it though.librenderdoc.so is LD_PRELOADed into the application using a library load function. This works by creating a directory with /tmp/Renderdoc/ and calling open on a log file in this location with append mode. However, there is no validation on who owns the file, in the case that a malicious user wins this race. fgets() within the systemd processing that only get 512 bytes at a time. By sending a very long string, we can use only our data on a given line..config/user-dirs.defaults with SYSTEMD=.config/systemd to create a systemd directory in a user controlled location. By writing to a configuration file in this directory, code execution is trivial to achieve. To bypass the head issue again, the authors abuse a different in deliminators (\r) to add their own lines. mprotected for more security. This section is close to the libraries but there is a gap in memory.
free() on an mmap chunk, the chunk isn't put into a free list; it's literally unmapped with munmap(). Arbitrarily mapping and unmapping memory is an incredibly powerful primitive. The munmap and mmap calls are the attack method but there is very crazy strategy to it. munmap() call to succeed. The goal is to punch a hole of exactly 8MB+4KB, which is the size of a threat stack and its guard page. _vote() function counts votes that are proportional to the amount of tokens they have. After enough time the proposal is either accepted or rejected.mint() and burn() functions are common for adding liquidity and removing it from the protocol. mint() will create LP tokens from the provided asset token provided. burn() will destroy the LP token and give back the original asset token. These tokens are used for portions of the pool rewards.burn() function, all of the users tokens are burned. Then, based upon the amount of tokens burned and their share in the pool, it will give them the underlying token back. The code for this is below:
uint256 burnt = _balanceOf[address(this)]; _burn(address(this), burnt); poolTokensObtained = pool.balanceOf(address(this)) * burnt / totalSupply_;
balance of the pool. This leads the pool to the pool sending more tokens to a user than they should. Crazily enough, these donated funds are not lost though! An attacker can call mint(), which will use the difference between the balance and the cached pool. So, the inflation of the amount of tokens being sent to the attacker doesn't cost them anything. balanceOf() was not vulnerable. eject() function to take all of the funds. They learned a few lessons from this warroom. First, having a pause() would have allowed them to explore their options without an attack being viable. Second, the contract is not upgradable but uses the code>eject() functionality to recover funds. By having the ability to upgrade contracts, restoring the protocol would have been much easier.libssh and not openssh, meaning that we cannot simply log into other people's servers.pki_verify_data_signature is used during the public key authentication check. In particular, it's checking to see if we've provided the proper signature to authenticate. At the beginning of the function, the rc (return code) is set to SSH_ERROR in order to prevent accidentally returning the improper value in case of a jump to the end.rc for various calls. But, this comes with a problem: if we can get rc returned with the code assuming that it's set to the original default value, we could spoof a success! In several places, there is a goto that assumes this. A good find for code snippets is here. But, in what cases?shift() to rebalance the contracts assets for the Jimbo Controller.