-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RAUdefender Research #2693
Comments
reference in ethereum's yellow paper VERSION 934279c section 12.2 (Random Numbers for Implementing Contract) |
Well, the answer is no. Currently the only secure (or considered secure) random solutions for smart contracts is Chainlink VRF, which leverages TEE and VRF to generate random values in a callback transaction. We are implementing a solution with BLS and BFT, but it is still user going, currently this random value is not suggested to be used in productive environment, because it is potentially vulnerable, (Currently all random solutions for smart contract are vulnerable to a certain degree) but not in the kind as you mentioned. Ethereum is working with IPFS on a verifiable delay function (VDF) random number solution, but not much message can be found. The attack you mentioned is called revert-after-use (yes, we found it and we named it since the moment we implement this function, if everything goes well, you will see it in our coming paper) and we proposed solutions to defend against such attack. |
Buuuuuut, thank you very much for your reminding, i need to write a manual on this random number stuff, maybe even add a warning when user calls this function. |
Random number generator for blockchain smart contract is a very tough topic, currently no real secure (decentralized) solution available, you gonna have to trust something else (centralized) aside from the blockchain. |
Yes, random number generator for blockchain is hard and I've read your random-related documents. It's very helpful to me. Is there any more infomation I can read about But I'm not talking about the random itself, I want to point the way that the random sequence generating is not good enough. Even if the contract author trust the block miner as the secure source, this chain-link way can be still vulnerable. Because |
Yes, we are 100% talking about the same thing. The basic idea of revert-after-use defender is to disable users from calling the target contract from an attack contract and makes sure that the attack transaction could not verify the random value from the script. And different transactions will generate totally different random values, therefore,,,,,,,, no one could attack getrandom by predicting the [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void FAUDRequire(int size)
{
// Disable call from another contract
ExecutionEngine.Assert(Runtime.EntryScriptHash == Runtime.CallingScriptHash, "FAUD: Contract call is not allowed.");
// Prevent malicious transaction script
ExecutionEngine.Assert((Transaction)Runtime.ScriptContainer).Script.Length <= size), "FAUD:Transaction script length error.");
} This is how we generate different random seeds for different transactions: this.nonceData = container is Transaction tx ? tx.Hash.ToArray()[..16] : new byte[16];
if (persistingBlock is not null)
{
fixed (byte* p = nonceData)
{
*(ulong*)p ^= persistingBlock.Nonce;
}
} |
I was going to show you how neoverse prevent the revert-after-use, ,,,but they banned my access to the repository~~~~~mercyless |
I've read the bytecode instead of source code and saw those checks. It checks not only the call is from EOA, but also the script size. It indeed can prevent the attack. Others like coz's PROPS toolchain can not do it well. |
My problem, i focus too much on doing research with it, will write more blogs and manuals explaining it. |
After the VRF way is implemented. I wonder if it can only generate one random number a time or a sequence. |
Wow, you read the bytecode~~~~~~~amazing......i might update my neo disassembly tool to make such things easier (currently its still very shabby). |
That will be great. Where can I find that? |
Well, we are using |
Actually, I mean that But if we choose |
When i say shabby, i really mean it,,,,, haven't update it for 3 years... i though no one is gonna need a disassembly tool, so i stopped working on it~~~ will pick it up and update it. Hope this time i can make it more useful since i have being study the neo source code for 4 years and have read every single line of the compiler and virtual machine. here is the project link: |
i dont see any difference between From a security view, they provide the same level of security promise |
In this way While if it is
This trailing code will make sure that the contract's random will be a profitable number for the attacker. |
Then who is the one to write this code? the attacker could not add such script in the transaction, the contract developer could not have access to the |
This code will be added by the attacker. Say that if the Neoverse didn't check the script size and I'm the attacker. I'll add this bytecode in my The |
you dont have access to this hash function~~~~~its not sha256 nor any hash function you can access from the virtual machine~~~~😜~~ |
The hash function is a deterministic function and I can translate it into NEOVM's bytecode since the seed used here is the networkid. |
Yes. Although Murmur128 is difficulty to produce in neovm for now, this is still a risk. |
it is not difficult, it is impossible,,,,,,,,,,the calculation will exhaust your gas~~~ way more GAS than a transaction is allowed |
And we have constrains to the size of a transaction, it is impossible to implement a Murmur128 with bytecode. |
I think that's why I have no POC in this issue 😂. |
Man, you almost got me,,,,😂😂😂😂😂 |
I'm not going to implement it. This issue is controversial for now. And I changed the title with a condition that neo/src/neo/Cryptography/Murmur128.cs Lines 55 to 74 in 41055be
https://github.com/neo-project/neo/blob/master/src/neo/Cryptography/Murmur128.cs |
You only need to be a primary node to avoid the murmur128 :) |
Even if you can implement Murmur128 with bytecode,,,,,why getrandom become vulnerable? As i told you, you have no where to put ur bytecode murmur128~~~~ |
An adversary can simply get the random value and check the execution result, why would it bother to implement a bytecode hash function~~~if we are talking about malicious contract, it has way more power to do with the random number, cause it is the one who decides how to use it anyway..... its like you assume Tencent game server is malicious,,,,,it should not be a problem for us to concern |
Threat model of getrandom is malicious consensus node, and malicious transactions~~~ smart contract is not our threat model cause contract is the one who use the random number......... |
This should have been solved by your publication Blockchain_Random_Number . I'm not sure if it can help avoiding my concern (add trailing code instead of calling from a attack contract).
nope, I'm talking about a attacker attack a normal contract that using the random |
Yes of cause. |
Again, an attacker attacks a contract from where? from another smart contract? it is disabled with ExecutionEngine.Assert(Runtime.EntryScriptHash == Runtime.CallingScriptHash, "FAUD: Contract call is not allowed."); from a transaction? it is disabled by: // Prevent malicious transaction script
ExecutionEngine.Assert((Transaction)Runtime.ScriptContainer).Script.Length <= size), "FAUD:Transaction script length error."); So, where is the attack surface |
In this way, every contract developer using |
If this size checking is mentioned in the paper and will be documented in NEO's doc, then we can safely ignore my concern. |
Leave the concern there. I see no good using |
Bro, may you please keep this issue open~~~i think your concern is valuable and your discussion is also a good treasure for this getrandom function |
But does transaction size check completely solve the problem?
might as well be less than what |
Gracias |
Simple size check can not solve this issue, that is why it has to work together with the calling script verify. Currently i dont see any situation to bypass the check, but i might be wrong. That is why i ask Mr. @dusmart to keep this issue open. |
It will easily pass in my case, the caller will still be the entry script. |
That's a great idea! |
Well~~~~~~~~emmmmmmm
wont this change the script size and |
Anyway thank you @dusmart and @roman-khimov . |
@Liaojinghui After reading the paper, I think there maybe one more scence to consider for Irrevocable Execution. Two scences (calling from delegate contract / running scripts validate outcome) have been mentioned. There is one more which is GAS manipulating. If some contract author write a different path for different random cases and forget to process the GAS difference (eg, adding GAS to a same level), then the attacker may manipulate his GAS balance in his account before that transaction. This attack can only achieve one path over another. Making the non-profitable path cheap than profitable will also be OK.
Here is a proof that these three can all be validated during pre-excution. There is no pre-execution in NEO. Therefore, one tx will be enough. Because RAUDefender has fibidden the ability to detect GAS by Can I join the RAU Defender project? This topic is so attractive. |
@dusmart I am so so so excited that you can find these issues, thank you very much. |
I think a disassembler + decompiler is cool and can be very useful. I do wonder why did you choose a ground-up solution? The alternative being a plugin for IDA+HexRays or Ghidra where you can leverage existing tools to further work with the data and cleanup the decompiled listings. I've had this idea for a long time but my IDA license is ancient by now and I don't have the bandwidth to learn how to do it in Ghidra (but hope some else does! 👀 ) |
@ixje i am open to all options, will search on that. I agree, bottom-up is silly, i stuck a lot. |
@roman-khimov Based on your idea, I finally composed a POC here with a Murmur128 on chain. 0x68b9a3cc6f8993452b771f4e2c35755988c5a98ed8663a48439aaf34290fdcd9 detail can be seen in https://github.com/lazynode/Tanya/pull/22/files
|
Introducing this predictable
random
sequence into contract can be vulnerable. Contract attackers will callGetRandom
repeatedly until the nextGetRandom
's result is profitable. This has also been integrated into coz's props toolchain here which can be exploited if the contract developer can't do it carefully.neo/src/neo/SmartContract/ApplicationEngine.Runtime.cs
Lines 252 to 256 in 41055be
As seen above, the sequence is generated in a chain way. The first random number can be used to predicate the second one.
AlthoughI've implemented a Murmur128 on chain.Murmur128
is difficulty to produce in neovm for now, this is still a risk. Whether implementingMurmur128
on NEOVM is possible is controversial for now. I'd like to leave this issue here with a condition and don't waste more time to try to implement it.The detail exploit method can be seen in #2693 (comment). Another subtle attack by roman-khimov can be seen in #2693 (comment) which bypasses the size checking. Based on the discussion, I composed a POC here #2693 (comment).
Thanks for Liaojinghui's paper, I learned an attack method called
revert-after-use
which is more dangerous and common. I'd like to call the issue mentioned herepick-before-use
. The protection (size checking) forrevert-after-use
by Liaojinghui may also protect contracts frompick-before-use
. The protection is quoted below.Anyway, I call for choosing
random_i = Hash(random_{i-1}, counter_i)
for sequence generating instead ofrandom_i = Hash(random_{i-1})
.Inspired by the paper's Irrevocable Execution, there maybe one more scence to be considered. GAS manipulating #2693 (comment)
To defend RAU, we'd better notice the developer do it carefully. Unknown code excuting should be avoided including transfering NEP-17 to some contracts because that will call the OnNep17Payment method.
The text was updated successfully, but these errors were encountered: