HackerOne and the OWASP Top 10 for LLM: A Powerful Alliance for Secure AI
Browse by LLM vulnerability:
'블록체인' 카테고리의 다른 글
HamsterWheel SUI (0) | 2023.06.21 |
---|---|
ETH Basic to Advance Smart Contract Hacking for web3 in 2023 (0) | 2023.05.08 |
Browse by LLM vulnerability:
HamsterWheel SUI (0) | 2023.06.21 |
---|---|
ETH Basic to Advance Smart Contract Hacking for web3 in 2023 (0) | 2023.05.08 |
https://cryptoslate.com/sui-awards-500k-to-certik-for-uncovering-critical-hamsterwheel-vulnerability/
https://www.certik.com/ko/resources/blog/3TuPZ1LnPTwkzXZQcEJ3aR-the-hamsterwheel-an-in-depth-exploration-of-a-novel-attack-vector-on-the-sui
CertiK’s Skyfall team identified and disclosed a series of denial of service vulnerabilities in the Sui blockchain. Among these vulnerabilities, a new type of bug stood out due to its critical severity implications which could cause the Sui network to not be able to process new transactions, effectively causing a total network shutdown. This unique attack, different from previous known ones, allows an attacker to induce an infinite loop in the validator node by merely submitting a small payload of approximately 100 bytes. Moreover, this attack creates persistent damage that endures even after the validator network reboots. We've dubbed this unique type of attack "HamsterWheel.”
Upon discovery, we responsibly reported this vulnerability to Sui through their bug bounty program. Sui's response was prompt and efficient. They confirmed the critical severity of the vulnerability and took steps to address the issue before the network’s mainnet launch. In addition to fixing this particular vulnerability, Sui also implemented preventative mitigations to lessen the potential damage caused by exploitation.
In appreciation for the responsible disclosure, Sui network awarded a $500,000 bounty award to CertiK Skyfall team.
In this blog post, we will disclose the technical aspects of this critical vulnerability, shedding light on its root cause and potential impact.
In Move-based blockchains, such as Sui and Aptos, the safeguarding mechanism against malicious payloads rests heavily on static verification techniques. These techniques inspect user-submitted payloads before a contract is either published or upgraded on the chain. With checkers ensuring both structural and semantic correctness, the Move runtime presumes their soundness.
Figure 1: The threats of malicious payloads on Move-based chains
Sui implements a memory model that is distinct from the original Move design, deploying a customized version of Move VM for contract development. Sui goes the extra mile in strengthening its safety measures against malformed payloads. It introduces additional, customized verifiers, dubbed as Sui verifiers. These specialized verifiers cater to Sui's unique features, such as object safety and global storage access safety, among others.
Figure 2: Sui's sequence of checks against the payload
Most verifiers conduct structural assessments against the CompiledModule, the runtime representation of user-provided contract payloads. For instance, duplication-checker ensures no duplicate entries in each section, while limits-checker affirms the upper bounds of entries allowed in each section. However, more complex analyses are necessary for static checking to guarantee the semantic soundness of the untrusted payloads.
The Abstract Interpreter, furnished by Move, is a framework specially designed for executing complex security analysis on bytecode via abstract interpretation. This mechanism enables a more refined and accurate verification process, with each verifier being allowed to define their unique abstract state for the analysis.
Beginning its operation, the Abstract Interpreter constructs Control Flow Graphs (CFGs) from compiled modules. Each Basic Block within these CFGs maintains a set of states, namely, pre-state and post-state. The pre-state offers a snapshot of the program prior to the execution of a Basic Block, while the post-state provides an image of the program after the Basic Block's execution.
When the Abstract Interpreter encounters no backedge (or loop) in the Control Flow Graph, it follows a simple linear execution. Each BasicBlock is analyzed in sequence, with the pre-state and post-state calculated based on the semantics of each instruction within the block. The result is an accurate snapshot of the program's state at each point in the execution, which aids in verification of the program's safety properties.
Figure 3: Move Abstract Interpreter’s workflow
However, when loops are present in the control flow, the process becomes more complex. Backedges, which signal the presence of loops, require the Abstract Interpreter to carefully manage the merging of states. This is due to the interdependence between the state at the start of the loop (the pre-state of the loop header) and the state at the end of the loop (the post-state of the loop footer).
In handling backedges, the Abstract Interpreter meticulously merges the pre-state of the target Basic Block with the post-state of the current Basic Block. If discrepancies are detected in the resulting merged state, the Abstract Interpreter initiates a re-analysis, beginning from the target Basic Block with the updated merged state.
This iterative analysis process continues until the loop's pre-state stabilizes. In other words, the process is repeated until the pre-state of the loop header no longer changes between iterations, indicating that a fixed point has been reached and the analysis of the loop is complete.
Sui's blockchain platform introduces a unique object-centric global storage model, which differentiates it from the original Move design. A distinctive feature of this model is that any struct with a 'key' ability must initiate with an ID field with the ID type. The ID field is immutable and cannot be transferred to other objects, as each object must have a unique ID. To ensure this, Sui utilizes custom analysis built upon the Abstract Interpreter.
The IDLeak Verifier, alternatively known as the id_leak_verifier, operates in concert with the Abstract Interpreter to conduct its analysis. It forms its distinct AbstractDomain, termed as AbstractState, to oversee the status of each local variable using an AbstractValue. This value denotes whether the ID is fresh. During the process of struct packing, the IDLeak Verifier checks that only a fresh ID is allowed to be packed into a structure. It meticulously traces the data flow of local states to ensure that no existing ID is transferred to other objects.
The IDLeak Verifier integrates with the Move Abstract Interpreter by implementing the AbstractState::join function. This function plays integral roles in state management, notably in merging and updating state values. Let's examine these functions in detail to understand their operation.
In AbstractState::join, the function takes another AbstractState as input and attempts to merge its local state with the current object's local state. For each local variable in the incoming state, it compares the variable's value to its current value in the local state (with a default value of AbstractValue::Other if not found). If the two values are unequal, it sets a 'changed' flag and updates the local variable's value in the local state by calling AbstractValue::join.
In AbstractValue::join, the function compares its value with another AbstractValue. If they are equal, it returns the incoming value. If not, it returns AbstractValue::Other.
However, the conjunction of these functions can lead to a potential inconsistency. Although AbstractState::join may indicate a change (JoinResult::Changed) due to differing old and new values, the state value after the update might remain the same. This anomaly occurs due to the order of operations: the determination of changed status in AbstractState::join happens before AbstractValue::join, which doesn't reflect the genuinely updated state value. Besides, in AbstractValue::join, AbstractValue::Other dominates the joined result. Thus, if the old value is AbstractValue::Other and the new value is AbstractValue::Fresh, the updated state value remains unchanged as AbstractValue::Other.
Figure 4: A concrete example illustrating the inconsistency in State Join
This introduces an inconsistency where the Basic Block state is marked as changed, but the state value itself remains unchanged. Such inconsistency can potentially have significant implications. To understand why, it's crucial to recall the abstract interpreter's behavior in the presence of a loop within the Control Flow Graph (CFG). When encountering a loop, the abstract interpreter employs an iterative approach to merge the target (backedge) and current state. If the joined state changes as a result of this merge, the abstract interpreter triggers a reanalysis.
However, if the join operation falsely flags the state as changed, when in reality no change in value has occurred, it could lead to an endless cycle of reanalyses.
Leveraging this inconsistency, an attacker could craft a malicious control flow graph that tricks the IDLeak verifier into an infinite loop. The crafty control flow graph would consist of three basic blocks, BB1 and BB2, BB3. We intentionally introduce a backward edge from BB3 to BB2.
Figure 5: Malicious CFG + State construction that can cause deadloop inside IDLeak verifier
The process starts with BB2, where the AbstractValue for a particular local variable is set to ::Other. After executing BB2, the flow moves to BB3, where the same variable is set to ::Fresh. At the end of BB3, there's a backward edge that leads back to BB2.
Here's where inconsistency plays a crucial role. When the backward edge is processed, the AbstractInterpreter attempts to join the post-state of BB3 (where the variable is 'Fresh') with the pre-state of BB2 (where the variable is 'Other'). The AbstractState::join function notices the difference and sets the 'changed' flag, signaling that reanalysis of BB2 is necessary. However, the dominating behavior of 'Other' in AbstractValue::join means that the actual state of the variable remains 'Other'.
So, when the verifier continues to reanalyze BB2, along with all its successors (BB3 in this case). This looping process, once initiated, continues indefinitely. The verifier consumes all available CPU cycles, effectively causing a deadlock in transaction processing – a situation that persists even after a validator reboot. This cleverly crafted vulnerability, which we've termed the "HamsterWheel" attack, effectively brings the Sui validator to a halt.
With the conceptual attack scenario delineated and all pre-assumed verifier checkers validated, we successfully demonstrate the exploit by constructing a concrete example using the following Move bytecodes:
The demonstration highlights the vulnerability in practice. It showcases how, through the careful crafting and manipulation of bytecodes, an attacker can trigger an infinite loop in the IDLeak verifier, where a mere 100 byte payload can consume all available CPU cycles, effectively blocking the processing of new transactions and resulting in a denial of service on the Sui validator.
According to the bug bounty conditions set by Sui, for a vulnerability to reach the level of critical severity, it must exhibit a capacity to bring the entire network to a halt, impeding new transaction confirmations and requiring a hard fork for resolution. Lesser impacts, such as partial denial of service, can at best qualify as medium or high severity based on the parameters of the bug bounty program.
The HamsterWheel attack discovered by the CertiK Skyfall team carries an immense threat due to its potential to shut down the entire Sui network, an impact that earns it the classification of critical severity. To understand the gravity of this flaw, it is necessary to comprehend the intricate architecture of Sui's backend system, specifically the steps leading up to the publishing or upgrading of a transaction on the chain.
Figure 6: Outline of interactions to commit a transaction in Sui
Initially, user transactions are directed towards the Sui authorities via a Frontend RPC and pre-validation process. The Sui authorities are responsible for validating the incoming transactions. Following successful validation of the user's signature, the transactions are converted into the formation of transaction certificates.
These certificates, integral to the functioning of the network, are then propagated across the validator nodes. Before the transaction can be published or upgraded on the chain, the validator nodes scrutinize these certificates for validity. It's during this crucial stage of verification that the discovered 'deadloop' vulnerability can be exploited.
When the flaw is triggered, it leads to an indefinite hang in the verification process. It effectively hampers the ability of the system to process new transactions, causing a total network shutdown. The criticality of this vulnerability is further magnified as it persists even after a validator reboot, meaning conventional mitigations are insufficient. The exploitation of this vulnerability hence leads to a 'persistent damage' scenario, leaving a lasting impact on the entire Sui network.
In response to the vulnerability, Sui confirmed the vulnerability in a timely manner and released a fix to address the critical flaw. The fix ensures consistency between the state change and the changed flag, eliminating the critical impact caused by the critical HamsterWheel attack.
In order to eliminate the aforementioned inconsistency, Sui's fix consisted of a minor but crucial adjustment to AbstractState::join function. Instead of determining the changed result prior to the execution of AbstractValue::join, this fix ensures that the AbstractValue::join is carried out first. Subsequently, the changed flag is set by comparing the result of AbstractValue::join with the old_value. This way, the changed flag correctly represented whether a change was made in the final state value.
In addition to fixing this specific vulnerability, Sui also deploys mitigations to reduce the impact of future verifier vulnerabilities. According to Sui’s reply in the bug report, the mitigation is involved with a feature called Denylist.
“However, validators have a node config file that allows them to temporarily denylist certain classes of transactions. This config can be used to temporarily disable processing publishing and package upgrades. Since the bug happens while running the Sui verifier before signing a publish or package upgrade tx, and denylisting will stop the verifier from being run + drop the malicious tx on the floor temporarily denylisting these tx types is a 100% effective mitigation (though it will temporarily interrupt service for folks attempting to publish or upgrade code).
As a side note, we have had this tx denylist config file for awhile, but we also added one for certificates as a follow up item to the "validator deadloop" bug you previously reported. With this mechanism in place, we would be much more resilient to that attack: we would use the certificate denylist config to make validators forget about the bad cert (breaking the crash loop), and the tx denylist config to disable publishing/upgrades and thus prevent creation of new transactions of death. Thanks for making us think about this!”
Validators have a finite number of "ticks" (different from gas) to spend on bytecode verification before signing a transaction, if all bytecode being published in a transaction cannot be verified in that many ticks, the validator will refuse to sign the transaction, preventing it from being executed on the network. Previously, metering only applied to a chosen set of complicated verifier passes. In response to this issue, we extended metering to every verifier pass, to guarantee a bound on the work a validator performs during verification per tick. We also fixed the underlying infinite loop bug in the ID Leak verifier pass.
To summarize, the Denylist enables validators to temporarily circumvent the verifier routine by disabling the publishing or upgrading processes, effectively preventing some potential disruptions from problematic transactions. Given the Denylist mitigation in place, validators should remain operational with only a portion of their functionality disabled when facing verifier panics.
In this blog post, we delved into the technical aspects of the HamsterWheel attack identified by the CertiK Skyfall team. We explained how this innovative form of attack leverages a critical vulnerability to result in a complete network shutdown of the Sui blockchain. Additionally, we took a closer look at Sui's timely responses to fix this critical issue, sharing their approach to mitigate the Sui blockchain against future threats.
HackerOne and the OWASP Top 10 for LLM: A Powerful Alliance for Secure AI (0) | 2024.04.15 |
---|---|
ETH Basic to Advance Smart Contract Hacking for web3 in 2023 (0) | 2023.05.08 |
Smart Contract defines as “a set of promises, specified in digital form, including protocols within which the parties perform on the other promises.”
In terms of Ethereum: “smart contracts” to refer to immutable computer programs that run deterministically in the context of an Ethereum Virtual Machine as part of the Ethereum network protocol — i.e., on the decentralized Ethereum world computer.
The function’s arguments, encoded according to the rules for the various elementary types defined in the ABI specification.
web3.utils.sha3("withdraw(uint256)");
soliditylang.org
A procedural (imperative) programming language with a syntax similar to JavaScript, C++, or Java. The most popular and frequently used language for Ethereum smart contracts.
A more recently developed language, similar to Serpent and again with Python-like syntax. Intended to get closer to a pure-functional Python-like language than Serpent, but not to replace Serpent.
A newly developed language, influenced by Erlang, with explicit state transitions and without iterative flows (loops). Intended to reduce side effects and increase auditability. Very new and yet to be widely adopted.
LLL, Serpent
Official Solidity Documentation website : CLICK HERE
sudo add-apt-repository ppa:ethereum/ethereum
sudo apt-get update
sudo apt-get install solc
//you can also install solidity using npm:
npm install -g solc
To check it has installed properly or not, check version;
solc --version
We use the — bin and — optimize arguments of solc to produce an optimized binary of our example contract developed in my previous article of this series. Learn Ethereum smart contract basics for web3 development 2023 https://medium.com/@web3doctor/learn-ethereum-smart-contract-basics-for-web3-2023-611dcc1caff9
solc --optimize --bin DollarFactory.sol
ABI = application binary interface ; defines how data structures and functions are encoded and decoded into OR out of machine code
Purpose of ABI: define functions, describe how function will accept arguments and return result.
It will be helpful when you try to solve, Ethernaut CTFs first part.
To interact with deployed contract, an application needs ; an ABI and address of contract.
solc --abi DollarFactory.sol
Constructor is executed as a part of contract creation only once then it is discarded.
Selfdestruct : it should not be in a contract code as it can be used to delete contract and withdraw all money
Function Modifiers: special function, use to create conditions that apply to many functions within a contract
contract inheritance: extend base contract with additional functionality, inherits all the methods, functions, and variable of parent, support multiple inheritance by comma separated contract names ; contract child is Parent1, Parent2 {}
Events: completed transaction produce a receipt, contains log enteries, provide information about action occurred during the execution of transaction.
event Withdrawal(address indexed to, uint amount);
event Deposit(address indexed from, uint amount);
emit: incorporate the event data in the transaction logs
function withdraw(uint _amount) public {
msg.sender.transfer(_amount);
emit withdraw(msg.sender, _amount);
}
receive () external payable {
emit Deposit(msg.sender, msg.value);
}
Now you have understood the very basics of Solidity Programming, use above learned points to understand below security and hack leading codes.
While it is usually quite easy to build software that works as expected, it is much harder to check that nobody can use it in a way that was not anticipated.
all smart contracts are public, and any user can interact with them simply by creating a transaction, Any vulnerability can be exploited, and losses are almost always impossible to recover.
Smart Contract Security Risk and Antipatterns: Be familiar with most common security risks
call delegatecall useful to modularize the code, call is run in context of external contract/function, delegatecall executed at the targeted address is run in context of calling contract and msg.sender and msg.value remain unchanged.
“Mastering Ethereum by Andreas M. Antonopoulos and Dr. Gavin Wood (O’Reilly). Copyright 2019 The Ethereum Book LLC and Gavin Wood, 978–1–491–97194–9.”
Follow me on Twitter: https://twitter.com/BgxDoc
HackerOne and the OWASP Top 10 for LLM: A Powerful Alliance for Secure AI (0) | 2024.04.15 |
---|---|
HamsterWheel SUI (0) | 2023.06.21 |