Greetings!
This was one wild week, folks! Almost $30M were stolen across 8 incidents. The stories behind these incidents seem to be taken right out of a wild west anthology.
Let’s start with the Kraken incident. Starting in late May, an attacker, later revealed to be a CertiK security researcher, started experimenting with an exploit vector called False Deposit also known as False Top-up (credit SlowMist).
The exploit targets CeFi backends which process on-chain transactions and credit internal customer accounts. Any flaws in that logic would allow bad actors to effectively print money. Many instances of this vulnerability appeared over the years ranging from Ripple’s infamous Partial Payment “feature” used to steal $570K from Beaxy, Ton’s bounce flag triggered on uninitialized contracts, false USDT deposits, and many others. The latest iteration abuses processing of reverted internal EVM transactions wrapped in a successful outer transaction.
Back to our attacker who continued hacking for days until finally succeeding on June 5th, 2024 faking a small deposit. That’s where things got interesting. Instead of reporting the exploit to Kraken and collecting a whitehat bounty, the researcher decided to continue exploitation for 4 more days with 20+ exploit transactions using ever more weaponized exploit smart contracts. The attacker even had fun with deposit amounts such as 31337 (“elite”) and cryptic 520520 (“I love you”). At the end of the exploitation spree, the attacker stole more than $3,000,000. Things got really wild with them making multiple deposits to Tornado Cash, sharing exploits with two other wallets, swapping on Uniswap and ChangeNow, and other shady behavior.
Things got even crazier when CertiK finally reported the vulnerability to Kraken on June 9th, 2024. According to Kraken, instead of coordinating the return of stolen funds, they focused on negotiating a business agreement first. Even in the wild world of DeFi hacking, greyhats don’t attempt to sell their services before negotiating the return of stolen assets.
CertiK published their side of the story stating that they wanted to not only exploit the vulnerability, but to thoroughly evaluate Kraken’s “risk controls” and “asset protection” capabilities. This thorough evaluation effectively amounts to a full blown penetration test. Such engagements may cause significant service interruptions and loss of assets. So prior agreements are usually signed to gain consent from the target and more importantly to shield one from legal action.
The most disappointing take away from this incident is just how much CertiK failed in its responsibility as a blockchain security company to set an example of ethical, positive, and constructive behavior that uplifts the industry:
The impact of money printing bugs is the full hot wallet. You don’t need to hack the target for four days with dozens of transactions and deploy ever more weaponized (flashloans) exploit contracts to prove that point. What if your onchain experiments were detected by bad actors?
The money printing bug is high severity by itself regardless of controls that may prevent withdrawals. You didn’t need to withdraw $3M+. What if you messed up and forever locked or lost funds in your custody?
Depositing assets to Tornado Cash or swapping them on ChangeNow to taint the attacker wallet tests completely different security controls. What are the chances that a grateful CISO would voluntarily engage your services to further test their AML controls after finding such an amazing bug?
Interacting with OFAC sanctioned Tornado Cash addresses to prove a point will now invite additional scrutiny and legal consequences. Was it worth it?
Bug bounty programs rely on mutual trust. Demanding a sales meeting before returning funds and fully patching the vulnerability breaks that trust. Can you even measure reputational damage caused when such tactics were exposed?
DeFi projects have endured unethical and extortionate behavior from “whitehats” for years who drain their pools, forcefully negotiate bounties and other abusive behavior. Kraken is a decade old, $10B company with enough legal firepower to take on U.S government. Did you miscalculate the amount of legal consequences they could put you through for anything even remotely less than ethical behavior?
With almost seven years in business, talented founders, and dozens of security researchers on staff, I want to believe CertiK can still have a positive impact on the ecosystem. It would be an incredible waste and loss to the crypto industry if the company spiraled down into obscurity caused by a series of missteps. However, it is time for CertiK to have an honest internal conversation about their values, mission, and figure out why it is now widely considered a rogue actor in the industry.
Continuing our weekly analysis are the two UwU exploits resulting in combined losses of $23M. The project was founded by 0xSifu (Michael Patryn aka Omar Dhanani from the QuadrigaCX fame) in 2020 by forking AAVEv2 code.
The code base passed an audit from Peckhield with flying colors in early 2023. However, just a few months later multiple reports of an unknown vulnerability affecting AAVE forks started surfacing. Over the years forked protocols suffered compromises by falling behind upstream patches, not fully understanding risks in the source codebase, or just making insecure modifications.
Unfortunately, UwU is a good case study for the latter weakness - introducing vulnerable modifications to the original codebase handling of oracle fallback logic:
AAVEOracle:
function getAssetPrice(address asset) public view override returns (uint256) {
IChainlinkAggregator source = assetsSources[asset];
if (asset == BASE_CURRENCY) {
return BASE_CURRENCY_UNIT;
} else if (address(source) == address(0)) {
return _fallbackOracle.getAssetPrice(asset);
} else {
int256 price = IChainlinkAggregator(source).latestAnswer();
if (price > 0) {
return uint256(price);
} else {
return _fallbackOracle.getAssetPrice(asset);
}
}
}
Which in turn calls the fallback oracle:
FallbackOracle:
function getAssetPrice(address asset) external view returns (uint256) {
require(address(assetToPriceGetter[asset]) != address(0), '!exists');
return assetToPriceGetter[asset].getPrice();
}
And finally the provider oracle logic:
sUSDePriceProviderBUniCatch:
function getPrice() external view override returns (uint256) {
(uint256[] memory prices, bool uniFail) = _getPrices(true);
uint256 median = uniFail ? (prices[5] + prices[6]) / 2 : prices[5];
require(median > 0, 'Median is zero');
return FullMath.mulDiv(median, sUSDeScalingFactor, 1e3);
}
[... snip ...]
function _getPrices(bool sorted) internal view returns (uint256[] memory, bool uniFail) {
uint256[] memory prices = new uint256[](11);
(prices[0], prices[1]) = _getUSDeFraxEMAInUSD();
(prices[2], prices[3]) = _getUSDeUsdcEMAInUSD();
(prices[4], prices[5]) = _getUSDeDaiEMAInUSD();
(prices[6], prices[7]) = _getCrvUsdUSDeEMAInUSD();
(prices[8], prices[9]) = _getUSDeGhoEMAInUSD();
try UNI_V3_TWAP_USDT_ORACLE.getPrice() returns (uint256 price) {
prices[10] = price;
} catch {
uniFail = true;
}
if (sorted) {
_bubbleSort(prices);
}
return (prices, uniFail);
}
function _getUSDeFraxEMAInUSD() internal view returns (uint256, uint256) {
uint256 price = uwuOracle.getAssetPrice(FRAX);
// (USDe/FRAX * FRAX/USD) / 1e18
return (
FullMath.mulDiv(FRAX_POOL.price_oracle(0), price, 1e18),
FullMath.mulDiv(FRAX_POOL.get_p(0), price, 1e18) // <-- NO NO NO!
);
}
The code snippet above shows median price calculation based on 11 different price oracles, except 5 of those were using spot prices directly from Curve pools. That is a big no no! Attackers took advantage of the flaw to to borrow assets at an artificially discounted rates and later liquidating at a premium yielding almost $20M in profit.
This would have been yet another price oracle hack yet things got even more interesting with what the attacker did next. Stolen CRV were deposited to Curve Lend which as the price started dropping created a chain of soft and later hard liquidations. The wider ecosystem impact was revealed when Curve’s founder’s, Michael Egorov, $100M in loans on UwU, Curve Lend and others also started going through liquidation. This created even more pressure on the Curve ecosystem, CRV lost almost half of its value, millions were lost to liquidations and locked away as bad debt.
In the meantime, UwU, satisfied with latest mitigations, decided to unpause the protocol and repaid bad debt. Except that attacker still owned sUSDCe used in the first exploit. Once again the attacker targeted the protocol by using that collateral to steal another $3.7M from UwU. Ouch!
Lot’s of lessons here, but let’s cover a few really big ones:
Forking and modifying protocols is tricky because you don’t have access to all of the design and security decisions made by the original developers.
Do not use live pool prices for price data! Price oracle manipulation is a well understood attack vector that should not have happened here.
Unpausing the protocol a few days after the hack is too rushed to properly audit and secure the protocol. The second hack could have been prevented.
Wider ecosystem impact can be even greater than the original exploit which can impact your protocol even if it’s normally safe. Pay attention to on-chain events.
Before we jump into the rest of the newsletter, let’s celebrate a few wins by the blockchain ecosystem treasure - ZachXBT. First he was able to assist NFTPerp with recovery recovery of about $700K on Blast chain. He was also able to provide concrete evidence linking Martin Shkreli to the scam token DJT on Solana. It’s folks like ZachXBT that provide the much needed light and inspiration. Thank you!
The premium version of the newsletter contains detailed indicators, PoCs, and write ups for Kraken false deposit, UwU oracle manipulation, NFTPerp reward manipulation, Yolo Games access control, JokInTheBox, WIF, and Crb2 logic error, and other exploits.
To gain access to comprehensive vulnerability write-ups, post-mortems, exploit proof of concepts (PoCs), attacker addresses, and additional data regarding this week’s compromises, please subscribe to the premium plan below.
Let’s dive into the news!
Keep reading with a 7-day free trial
Subscribe to Blockchain Threat Intelligence to keep reading this post and get 7 days of free access to the full post archives.