首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >孤立图灵完整语言的沙箱转义?

孤立图灵完整语言的沙箱转义?
EN

Security用户
提问于 2016-03-22 16:36:11
回答 2查看 633关注 0票数 4

Ethereum的可靠文件说:

EVM虚拟机(EVM)是Ethereum中智能契约的运行时环境。它不仅是沙箱的,而且实际上是完全隔离的,这意味着在EVM中运行的代码无法访问网络、文件系统或其他进程。

限制对网络、文件系统和其他进程的访问是否足以防止图灵完整语言脱离沙箱?

EN

回答 2

Security用户

回答已采纳

发布于 2016-03-23 08:31:00

逃避沙箱不是在语言上,而是在实现上。我看到了以下VM实现:

每个实现都依赖于编译器/解释器的正确性和实现本身的正确性。攻击者可能想要逃离Ethereum,为了实现这一点,他必须利用编译器/解释器/标准库以及实现本身中的一些bug。虽然这是一项艰巨的任务,但这绝不是不可能的(很可能,涉及零日)。我认为libethereum是在C++中实现的最脆弱的.

几年后,随着Ethereum被接受,将出现一个占主导地位的实现,它将使攻击者的任务更容易(网三伞具有规范的可靠编译器)。

为了在这样的攻击中提供深入的防御,人们建议在普通的越野车内运行Ethereum沙箱.即使如此,防止攻击的主要方法仍将依靠手工检查合同:

  1. 转到EtherChain.org,获取合同的源代码。
  2. 把你要吃的字节码拿来。拆开你自己。
  3. 编译代码并与接收到的字节码进行比较。(有关细节,请参见Ethereum的这个问题 -原来是个皮塔)。
  4. ???
  5. 避免损失。
  6. 如果你看到一个恶意的合同.

注意:在这个阶段,两种图灵全语言( Serpent)和几十个编译器版本(60+ Solidity遗留版本)的存在使得维护者更难以检测恶意契约。

票数 4
EN

Security用户

发布于 2016-03-23 09:34:45

不,不,它不是,它是相当复杂的预防。

沙盒通常挂起内部API并在第3环中的最低级别执行代码。让我们首先谈谈文件API。如果您熟悉较低级别的编程语言(如C、C++等),您将了解ReadFile API。那么,让我们看看反汇编中的ReadFile。

ReadFile位于Kernel32中的EAT (Export表)中。

代码语言:javascript
复制
KERNEL32.ReadFile - FF 25 8803D674        - jmp dword ptr [KERNEL32.PssWalkSnapshot+9588] { ->KERNELBASE.ReadFile }

因此,它跳到KernelBase.dll到一个ReadFile。不要担心不理解所有的操作码,而只是对电话感兴趣。

代码语言:javascript
复制
KERNELBASE.ReadFile - 8B FF                 - mov edi,edi
KERNELBASE.ReadFile+2- 55                    - push ebp
KERNELBASE.ReadFile+3- 8B EC                 - mov ebp,esp
KERNELBASE.ReadFile+5- 6A FE                 - push -02 { 254 }
KERNELBASE.ReadFile+7- 68 A806D576           - push KERNELBASE.ReadFile+B8 { [FFFFFFFE] }
KERNELBASE.ReadFile+C- 68 5098D576           - push KERNELBASE.OutputDebugStringA+C0 { [8B55FF8B] }
KERNELBASE.ReadFile+11- 64 A1 00000000        - mov eax,fs:[00000000] { 0 }
KERNELBASE.ReadFile+17- 50                    - push eax
KERNELBASE.ReadFile+18- 83 EC 18              - sub esp,18 { 24 }
KERNELBASE.ReadFile+1B- 53                    - push ebx
KERNELBASE.ReadFile+1C- 56                    - push esi
KERNELBASE.ReadFile+1D- 57                    - push edi
KERNELBASE.ReadFile+1E- A1 683BE076           - mov eax,[KERNELBASE.dll+C3B68] { [1EB677D9] }
KERNELBASE.ReadFile+23- 31 45 F8              - xor [ebp-08],eax
KERNELBASE.ReadFile+26- 33 C5                 - xor eax,ebp
KERNELBASE.ReadFile+28- 50                    - push eax
KERNELBASE.ReadFile+29- 8D 45 F0              - lea eax,[ebp-10]
KERNELBASE.ReadFile+2C- 64 A3 00000000        - mov fs:[00000000],eax { 0 }
KERNELBASE.ReadFile+32- 89 65 E8              - mov [ebp-18],esp
KERNELBASE.ReadFile+35- C7 45 E0 00000000     - mov [ebp-20],00000000 { 0 }
KERNELBASE.ReadFile+3C- C7 45 E4 00000000     - mov [ebp-1C],00000000 { 0 }
KERNELBASE.ReadFile+43- 8B 75 14              - mov esi,[ebp+14]
KERNELBASE.ReadFile+46- 85 F6                 - test esi,esi
KERNELBASE.ReadFile+48- 74 06                 - je KERNELBASE.ReadFile+50
KERNELBASE.ReadFile+4A- C7 06 00000000        - mov [esi],00000000 { 0 }
KERNELBASE.ReadFile+50- 8B 5D 08              - mov ebx,[ebp+08]
KERNELBASE.ReadFile+53- 83 FB F4              - cmp ebx,-0C { 244 }
KERNELBASE.ReadFile+56- 0F83 60D30400         - jae KERNELBASE.InterlockedExchangeAdd+528C
KERNELBASE.ReadFile+5C- 8B 7D 18              - mov edi,[ebp+18]
KERNELBASE.ReadFile+5F- 85 FF                 - test edi,edi
KERNELBASE.ReadFile+61- 75 71                 - jne KERNELBASE.ReadFile+D4
KERNELBASE.ReadFile+63- 57                    - push edi
KERNELBASE.ReadFile+64- 57                    - push edi
KERNELBASE.ReadFile+65- FF 75 10              - push [ebp+10]
KERNELBASE.ReadFile+68- FF 75 0C              - push [ebp+0C]
KERNELBASE.ReadFile+6B- 8D 45 E0              - lea eax,[ebp-20]
KERNELBASE.ReadFile+6E- 50                    - push eax
KERNELBASE.ReadFile+6F- 57                    - push edi
KERNELBASE.ReadFile+70- 57                    - push edi
KERNELBASE.ReadFile+71- 57                    - push edi
KERNELBASE.ReadFile+72- 53                    - push ebx
KERNELBASE.ReadFile+73- FF 15 5C66E076        - call dword ptr [KERNELBASE.dll+C665C] { ->ntdll.NtReadFile }
KERNELBASE.ReadFile+79- 8B C8                 - mov ecx,eax
KERNELBASE.ReadFile+7B- 81 F9 03010000        - cmp ecx,00000103 { 259 }
KERNELBASE.ReadFile+81- 0F84 B9D30400         - je KERNELBASE.InterlockedExchangeAdd+5310
KERNELBASE.ReadFile+87- 85 C9                 - test ecx,ecx
KERNELBASE.ReadFile+89- 0F88 380A0000         - js KERNELBASE.GetModuleHandleExW+277
KERNELBASE.ReadFile+8F- 85 F6                 - test esi,esi
KERNELBASE.ReadFile+91- 74 05                 - je KERNELBASE.ReadFile+98
KERNELBASE.ReadFile+93- 8B 45 E4              - mov eax,[ebp-1C]
KERNELBASE.ReadFile+96- 89 06                 - mov [esi],eax
KERNELBASE.ReadFile+98- B8 01000000           - mov eax,00000001 { 1 }
KERNELBASE.ReadFile+9D- 8B 4D F0              - mov ecx,[ebp-10]
KERNELBASE.ReadFile+A0- 64 89 0D 00000000     - mov fs:[00000000],ecx { 0 }
KERNELBASE.ReadFile+A7- 59                    - pop ecx
KERNELBASE.ReadFile+A8- 5F                    - pop edi
KERNELBASE.ReadFile+A9- 5E                    - pop esi
KERNELBASE.ReadFile+AA- 5B                    - pop ebx
KERNELBASE.ReadFile+AB- 8B E5                 - mov esp,ebp
KERNELBASE.ReadFile+AD- 5D                    - pop ebp
KERNELBASE.ReadFile+AE- C2 1400               - ret 0014 { 20 }

因此,下一级API是位于NtReadFile中的ntdll.dll。

代码语言:javascript
复制
ntdll.NtReadFile - B8 05001A00           - mov eax,001A0005 { [0] }
ntdll.ZwReadFile+5- 64 FF 15 C0000000     - call fs:[000000C0]
ntdll.ZwReadFile+C- C2 2400               - ret 0024 { 36 }
ntdll.ZwReadFile+F- 90                    - nop 

这是一种特殊类型的调用,名为syscall,然后转到SSDT (System Service Descriptor Table),它具有位于0环中的低级API,该API不能通过暴露的syscall以外的环3直接访问。

因此,沙箱可以使用一系列挂钩方法,但最常见的方法是:

  • 内存迂回(JMP,推送RET等等)
  • 连接IAT表
  • VEH (不太可能,因为对性能有很大的影响)

所以,为了知道发生了什么,我们会将NtReadFile连接起来,这将跳转到我们的代码中,并且我们可以完全控制执行的内容。例如,假设您要过滤掉任何名为SteveEnix的文件。在我们的蹦床函数中( NtReadFile已经被钩住并跳转到其中),我们可以读取参数并决定是否调用它。所以,看起来是这样的:

代码语言:javascript
复制
NTSYSAPI NTSTATUS NTAPI t_NtReadFile(
                  IN HANDLE               FileHandle,
                  IN HANDLE               Event OPTIONAL,
                  IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
                  IN PVOID                ApcContext OPTIONAL,
                  OUT PIO_STATUS_BLOCK    IoStatusBlock,
                  OUT PVOID               Buffer,
                  IN ULONG                Length,
                  IN PLARGE_INTEGER       ByteOffset OPTIONAL,
                  IN PULONG               Key OPTIONAL )
{

// Your check on buffer to filter files or whatever you want and return an error or call the original function

}

如果内部应用程序可以访问使用VirtualProtect API,或者读取和写入内存区域,那么这些钩子就可以很容易地删除。

但是,如果您更进一步到SSDT (在x64上有PatchGuard以防止这些钩子),那么沙箱通常不会接触SSDT,那么您需要一个驱动程序来加载到系统中,以便能够解除SSDT的补丁或用自己的钩子修补它。

票数 2
EN
页面原文内容由Security提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://security.stackexchange.com/questions/118268

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档