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!

One more problem with ERC777- 1203

Daniil Ogurtsov - MixBytes    Reference →Posted 2 Years Ago
  • ERC777 is a well known token standard for Non-Fungible Token (NFT). There are hooks defined on these NFTs in order to allow for users to perform operations on either receiving or sending NFTs.
  • How are these hooks implemented though? Instead of checking the sender/receiver of the check, it looks into the ERC1820 registry contract. This is done by taking a hash of the interface then checking if the sender/receiver has added a hook for this. Once this is set, it will execute the hook at the address provided.
  • Only the owner of an address can specify these hooks. This is where the novel technique comes into play... what if you have arbitrary call to an address within the context of the contract? An attacker could set the hook for the contract!
  • This can be used as an unexpected reentrancy hook. This becomes particular troublesome with swap paths being calculated before the transaction assuming that the hook will not modify the state. Additionally, an attacker could force all transactions within the context of the contract to fail.
  • Arbitrary calls within a contract are typically very bad anyway. This registry setting is just another way to make use of it.

StackRot Linux Privilege Escalation- 1202

Ruihan Li    Reference →Posted 2 Years Ago
  • When the mmap() system call is made, the kernel generates a structure to represent this allocated memory in the Virtual Memory Area (VMA). The structure vm_area_struct contains various items for flags and properties for the memory section.
  • VMAs were previously managed by red-black trees. Now, they use Maple Trees (a B-tree data type for storing non-overlapping ranges). The reason for this change is that the Maple Trees are RCU safe.
  • Read Copy Update (RCU) is a pattern to make reads memory safe even if they are being copied or updated. This allows for read to occur concurrently to writes. Within a maple tree, a maple node either represents a VMA or a gap; there shouldn't be a gap between two intervals.
  • When during concurrent modification, there are restrictions put in place; an exclusive lock is required by all writers. For reading, the MM read-write lock can be taken, but results in slower times. Instead, a read can be performed on the section without taking the lock, which is done in performance critical situations.
  • On a stack expansion, the memory automatically grows. This requires editing the VMA maple tree to add this change. In some situations, the operation can be performed atomically, meaning that it's not a problem. But, when the neighboring node has the MAP_GROWSDOWN flag, this operation CANNOT be performed atomically. When the gap needs to be removed (aka removal of the node), a new node must be created instead of simply altering the old one. This results in the old node being destroyed in a RCU callback.
  • The RCU callback is invoked only after all pre-existing RCU critical sections have concluded. When accessing VMAs with the MM read lock held, it does not enter the critical RCU section. Why is this bad? The callback can be invoked at any time, resulting in a use after free when attempting to access it once again.
  • According to the author, this was exploited in the locked down KCTF environment. This means it's exploitable on nearly all systems. Additionally, this claims to be the first use after free by RCU bug that's happened. Super interesting post and an extremely deep bug.

GHSL-2023-139: Use After Free (UAF) in accountsservice - CVE-2023-3297- 1201

Kevin Backhouse - Github Security Labs    Reference →Posted 2 Years Ago
  • Ubuntu accountsservice is a package that allows for the querying and manipulating of user account information. This is done via D-Bus interfaces, which is an IPC mechanism used by Linux desktops.
  • After receiving a D-Bus method call, the D-Bus server normally sends back either a METHOD_RETURN for a proper call or an ERROR message to the client. Since the D-Bus API is expected to follow the standard for the libraries that utilize it, it is super important that this is correct. This is not a return value though; it appears to be set in some internal structure.
  • What happens if the specification isn't followed? Madness! In the case of user_change_language_authorized_cb, both the error handler and the proper handler were being called. The error handler was called if the $HOME is not mounted and the main path always runs.
  • Since both of the calls were decrementing the reference counter, this creates the scenario for a use after free. By forcing the $HOME check to fail by deleting the home directory and decrementing the reference counter, another call could access this to cause memory corruption shenanigans.
  • The command below would cause this to crash:
    dbus-send --system --print-reply \ 
    --dest=org.freedesktop.Accounts \
    /org/freedesktop/Accounts/User`id \
    -u` org.freedesktop.Accounts.User.SetLanguage string:'**'
    
  • On 23.04 this causes a SIGSEV crash but 22.04 doesn't crash. According to the author, this is difference in the memory allocator for Glib. Additionally, exploitation is said to be difficult to not impossible.

LibreOffice Arbitrary File Write (CVE-2023-1883) - 1200

Greg - Secfault Security     Reference →Posted 2 Years Ago
  • Libre Office is an open source Microsoft office alternative. Libre Office has a word processor, spreadsheet, presentation tool and a desktop database. The author decided to take a look at the database part.
  • The saved file was a .odb output was simply a zip archive with various folders and files. With looking through the files, the author noticed the database/script file with SQL statements inside of it. Arbitrary SQL queries could potential lead to file writes and code execution!
  • The author found the SCRIPT statement, which allows us to write to an arbitrary file. However, the file cannot exist already in order to write it. Additionally, the content is somewhat controlled but not fully controlled.
  • How do we exploit this then? The author was reading their ~/.bashrc file when they noticed that both ~/.bash_aliases and ~/.dircolor did not exist. So, these were files that were being executed from the ~/.bashrc and we could write to them!
  • What can we write to the file though? After playing around with different database settings they realized that CREATE SEQUENCE "PAYLOAD HERE" would output the content to the file we choose. Then, when a user logs in, it would eventually get executed.
  • The author doesn't say the fix but says the bug was fixed. If I was the developer, killing the SCRIPT command in this context would make sense. Overall, a quick and easy issue!

How does the NEW Ethereum work?- 1199

Preethi Kasireddy    Reference →Posted 2 Years Ago
  • The old Ethereum was proof of work. Now, the system is proof of stake, where stake is an amount of money they are putting as collateral if they act maliciously. Anybody can stake 32 ETH to become a staker to select blocks, earn rewards and so on. The staking makes sybil (multi-voter) attacks impossible as well. This article is about the nitty-gritty details of how this works - Gasper.
  • Once a user stakes the 32 ETH to become a validator, they are put into a waiting queue. This is done in order to prevent network congestion on voting and preventing an attacker with sufficient funds from instantaneously making a big impact.
  • Once a user is in the network and voting, Gasper has slots of 12 seconds and epochs that last 32 slots (6.4 minutes). For every slot, one validator is selected at random to be the block proposer. The proposer constructs the block from the pending transactions in the mempool. The purpose of the epoche is that a validator does not vote on every block. Instead, a committee is made where a validator votes on one block per epoche.
  • What are validators even validating?
    • They validate checkpoint blocks (start of epoche) within previous epoches and the current ones.
    • The list of validators on the voting committee.
    • The data of the block. In particular, the slot, index, root hash of the block and some other data.
    • Signature.
  • On top of the coordination above, there is other fancy networking occurring to reduce network overhead further. This is about dividing the network into regional subnets which will then communicate with the main network. This is possible by crazy math that combines signatures then broadcasts this to the rest of the network.
  • When does a block become final? In Bitcoin, this is once 6 blocks have passed. With Ethereum, it is once another block has been verified (justified). A block becomes justified once 2/3 of staked Ether votes in favor of a block. What happens when a fork occurs? The network will always choose the fork with the most backed votes. Theoretically, independent users could fork the chain and bring it back later, only to confuse the users though.
  • To confirm that the system works as intended, there needs to be incentives and rewards/punishments. A user has two balances: effective and actual balance. The actual balance is the amount deposited for staking, plus rewards and minus value from penalties. The effective balance is derived from the actual balance in some way with a cap of 32 ETH and is what is used for picking validators.
  • The rewards are given based upon the actions performed. Attesting a block, proposing a new block and participating in a sync committee. The article has numbers for who gets what. However it's proportional to the amount of funds that a user has in the protocol.
  • For penalties, it depends on what went wrong. For missing an attestation, they lose the amount they would have been rewarded. There are several other benign issues as well. If a validator engages in malicious behavior, then they are slashed; forcing them to leave the network or a large monetary penalty. One of the validators must be a whistleblower in order to do this and receives a reward for doing so.
  • The penalties depend on how active the network is. For instance, if a single user does perform an action, then the penalty is small. If NONE of the users perform the assigned actions, then the penalty gets larger. The idea is that the inactive users on a stopped blockchain (from inactivity) will be removed fast so that others can validate properly.
  • Overall, an awesome post on the great merge to Proof of Stake. Many great details showcasing the innerworkings of the blockchain eco-system.

Silo Finance Logic Error Bugfix Review- 1198

Immunefi    Reference →Posted 2 Years Ago
  • Silo Finance creates isolated lending markets. This is done by having every token asset in its own lending market. Additionally, it is paired against the bridge assets ETH and XAI (Silo's over-collateralized stablecoin). By doing this, lenders are only exposed to the risk of ETH and XAI at any point as a result.
  • The Base Silo contract handles the core logic of the protocol. Users call deposit() to add collateral to the protocol so that they can borrow. In return, the contract mints a pro-rata share that is stored in _assetStorage[_asset].
  • Users who have deposited collateral can call borrow() to temporary gain access to the new asset. On this call, the accrued interest rate is updated and the loan-to-value (LTV) ratio is checked. In loan based protocols, the interest rate is calculated based upon the utilization of the asset.
  • By making the contract believe it has borrowed more than 100%, the math goes crazy. How is this possible though? Donations! By adding more value to the contract than what is being tracked, the utilization trade goes through the roof. Using this, the value of the loan is much higher than it should be, allowing for us to take almost all of the funds.
  • Practically, these are the steps to exploit this assuming that the market has 0 total deposits for one of the assets in a market:
    1. Become the main shareholder by depositing a little amount of the asset, such as 10^5 wei of WETH.
    2. Donate additional WETH to the market. To get even higher utilization, the bulk of the funds should be here.
    3. Use another account to deposit a seperate asset into the protocol.
    4. When accrueInterest() is called, the utilization rate of the deposit is over 100%, creating an insane interest rate.
    5. Our initial deposit (collateral) is now valued more than is should be. As a result, all of the funds can be borrowed from the protocol to steal it.
  • To fix this problem, there is now a cap on the utilization rate. However, I find it odd that the donation attack was possible at all. To me, it makes more sense to have the liquidity and borrowed funds amount match what's actually available. Weird report!

The HamsterWheel An In-Depth Exploration of a Novel Attack Vector on the Sui Blockchain- 1197

Certik    Reference →Posted 2 Years Ago
  • Move blockchains are pretty rare about this point. There are only Sui and Aptos that are using it to my knowledge. Move by itself is not completely safe from cross-contract alterations and other weird problems. To resolve this, there is a static verifier running at compile time.
  • Sui implements a distinct memory model compared to the original Move implementation by using a customized version of the Move VM. Upon adding these features, Sui decided to add custom verifiers to ensure the safety of the programs being executed such as the bounds checker. All of this is achieved with the high level concept of the abstract interpreter framework designed for doing security analysis on bytecode.
  • The abstract interpreter contains a control flow graph with an understanding of the states that it may jump to prior to the execution of a basic block. If there are no loops, the linear execution is simple for validating simple flow. With a loop, the merging of states is done.
  • The Sui blockchain contains an object-centric global storage model, which is different than the original Move design. Objects can have a unique ID with the key ability. A verifier is ran to ensure that the ID is unique per object. So, where's the bug at? Still more background!
  • The verifier integrates with the Move Abstract Interpreter in the 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.
  • There is an order of operations problem here though. 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.
  • This infinite loop would bring the network to a complete halt. To fix this, a hard fork of the software would be required. As a result, this leads to a critical severity issue. To fix this problem, Sui changed the order of operations between the AbstractValue and AbstractState. On top of this, the verifier can now timeout as well, mitigations impacts of these types of bugs in the future.

Escaping Parallels Desktop with Plist Injection- 1196

pwn.win    Reference →Posted 2 Years Ago
  • Parallels Desktop is a virtualization platform on macOS. Obviously, being able to escape this would be a huge deal! They started by looking into toolgate, the protocol for communicating between the guest and host.
  • Toolgate requests are sent to the host by writing to a physical address that corresponds with a specific I/O port. There are restrictions on what Toolgate messages userland processes can send to the host using Parallel Tools. The only operations that are allowed are file system operations to the host.
  • Shared Applications are a Parallels feature that allow the opening of files on a Mac in a guest application, and vice versa. A file extension and URL scheme can be related to this application, with shortcuts even being created. Parallels handles syncing of running guest apps to the host. This is done as follows:
    1. Parallel Tools detects that an application is launched in the guest.
    2. A toolgate request (TG_REQUEST_FAVRUNAPPS) is made to the host to notify it of the app.
    3. If a helper exists, then the helper app is launched. If not, a new bundle is created.
    4. The app bundle is created from a template, which is filled with information supplied by the guest. This information is written to several areas, including the Info.plist of the application.
  • This sounds like a classic attack. Privileged entity is taking in information then adding it to a location. If the input is properly santitized, it could be possible to inject malicious content into it. In turns out, that two of the fields were not sanitized of XML document data. As a result, the guest user could inject arbitrary data into the plist file.
  • Why is this useful? The initial attack vector the author went after was LSEnvironment key to set 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.
  • The shared folders are implemented using the Toolgate functionality as well. The only thing we really have access to here is the opening, reading and writing to files. When performing these operations, there are validations that the path doesn't contain a ../, 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.
  • Using this bug, an attacker can read or write to arbitrary files on the host! To bring these bugs together, we can use the arbitrary file write to create a dylib file of our choosing at a known location. Then, we can use the first bug to execute this dylib file. Damn, that's a pretty hype chain!
  • A novel plist injection technique into a classic TOCTOU bug. Good finds and good chaining! I wonder if there are other bugs in this part of the eco-system; my guess is that there are.

The OverlayFS vulnerability CVE-2023-0386- 1195

Datadog Security Labs    Reference →Posted 2 Years Ago
  • The overlay file system (OverlayFS) allows a user to merge file systems together to create a single unified file system. There are different types of mounts with OverlayFS: lower, upper and overlay in this order. The overlay is the overarching item of the setup. If you write to the lower directories, it will be copied to the upper ones. If you write to the upper, it doesn't go to the lower though. This is a design feature for isolation, it appears. If changes are made through the overlay, they are only reflected in the upper directory.
  • Recap: lower->overlay, upper<->overlay and lower->upper. When a kernel copies a file from the overlay file system to the upper directory, there is no validation on the owner of this file within the current namespace. Using this oversight, a lower directory could smuggle a SETUID binary into the upper directory using OverlayFS.
  • How could this be exploited? Let's are below:
    1. Create a FUSE file system. This will allow us to create a binary owned by root with the setuid bit on it.
    2. Create a new namespace.
    3. Create a new OverlayFS mount with the lower directory within the FUSE FS from the previous step.
    4. Trigger a copy of our SETUID binary from the overlay FS to the upper directory. This can be done by simply creating the binary. We now have a setuid binary under the upper directory, even though this was from the OverlayFS setup.
    5. Exit the user namespace from step 2 to execute the SETUID binary!
  • The vulnerability allows for a privilege escalation to root by not handling namespaces correctly. This is why defense-in-depth with limiting syscalls and other things is important. Good writeup!

Bypass IIS Authorisation with this One Weird Trick - Three RCEs and Two Auth Bypasses in Sitecore 9.3- 1194

AssetNote    Reference →Posted 2 Years Ago
  • Sitecore is a CMS written in .NET. They pwned this in 2019 but wanted to see if any new bugs had been added or if they missed anything big years ago. To start with, they do a large amount of recon to look at the functionality without authentication. Additionally, they looked into the Web.config to see how the routing was working.
  • The Sitecore APIs had a standard MVC setup, where the executed route was 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!
  • The class 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's dependency Telerik UI had a known CVE for deserialization that requires knowledge of the Telerik encryption keys. However, since we have this from the backup, we can exploit a deserialization bug to get RCE.
  • While auditing the code base for more things, the path /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.
  • Eventually, they came to 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.
  • Anonymous users couldn't hit the shell endpoint. The endpoint did allow for ANY user to hit the endpoint. If the user wasn't authenticated, the page was still ran but the execution still happened. Within 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!
  • I had no idea about the internal redirects causing so many problems. It is super interesting seeing the subtle flaws that can be built with .NET applications. Good read!