Ethernaut Zeppelin 学习

https://ethernaut.zeppelin.solutions/ 网站上列出了一系列智能合约在编写过程中可能产生的问题,可以帮助初学者很好的了解智能合约

https://github.com/OpenZeppelin/ethernaut/blob/master/gamedata/descriptions/pages/help.md 帮助文档

花了一整天假装自己 AC 了所有的题目,这里把过程中的一点总结和经验记录一下,留以备忘

Hello

题目是用来帮助熟悉平台的。这里简单记录一下平台和 Remix 编辑器的基本操作

平台首先需要安装 MetaMask 插件并登陆账户,如果打开平台时没有登陆账户,那么登陆之后需要刷新页面使账户信息生效。

Remix 是非常好用的在线编辑平台,其不仅可以编译 solidity 代码生成自己的测试合约,也可以根据地址映射链上已有的合约

在顶部菜单中可以选择合约运行的环境,运行合约的账户。并且可以配置执行合约代码时所带有的 gas 和 value 相当于调用合约时的 .value().gas()

在执行了合约代码之后可以点击下方的 debug 按钮对合约代码进行调试

调试功能十分强大,可以查看运行时的栈,memory,opcode,等几乎所有的 EVM 关键信息

Read More

Bypass ACG With OpenProcess

https://bugs.chromium.org/p/project-zero/issues/detail?id=1435&can=1&q=&start=1200 p0 研究者 ifratric 提出的一种绕过 ACG 保护的方案,即通过修改同一 AppContainer 中的其他 MicrosoftEdgeCp.exe 进程的内存来阻止另一个进程开启 ACG 保护

ACG 的开启

进程的 ACG 需要调用函数 SetProcessMitigationPolicy.aspx) 或者 ZwSetInformationProcess 来开启。这里我们主要关注 SetProcessMitigationPolicy ,函数的原型如下

1
2
3
4
5
BOOL WINAPI SetProcessMitigationPolicy(
_In_ PROCESS_MITIGATION_POLICY MitigationPolicy,
_In_ PVOID lpBuffer,
_In_ SIZE_T dwLength
);

第一个参数指定要设定的缓解策略类型,第二个参数根据第一个参数指定不同的 Policy 数据,第三个参数指定第二个参数的长度。

Read More

MapViewOfSection and Shared-Memory

之前对于 UnmapViewOfFile 的分析中留了一个坑,即使用 SECTION 在进程之间共享内存的情况。拖了几个星期,终于把这个问题稍稍搞明白了一点。这里将相关的知识点记录一下。

问题描述

微软对于 UnmapViewOfFile 绕过 ACG 这种攻击方式的补丁是在 JIT 进程端移除了 VirtualAlloc/VirtualProtect 操作,从而切断了将其他属性内存转化为可执行页的路径。于是笔者产生了疑问:在不使用 VirtualAlloc/VirtualProtect 的情况下 Render 中的内存页是如何 commit 的

在打上补丁之后,内存的分配操作只剩下 AllocLocalView ,查看函数源码

1
2
3
4
5
6
AllocLocalView{
//...
process = GetCurrentProcess();
NtdllLibrary::Instance->MapViewOfSection(sectionHandle, process, &address, NULL, viewSize, &mapOffset, &viewSize, NtdllLibrary::ViewUnmap, NULL, flags);
//...
}

代码中调用 MapViewOfSection 在当前进程中为这个用来共享内存的 Section ,其中 CommitSize 参数为 viewSize。实际调试 Edge, 在这个调用上下断点 JIT 进程断在此处,此时 Render 中的虚拟内存地址已经由之前那次 Map 操作确定了,查看 Render 进程中对应的虚拟地址空间

1
2
3
4
5
6
7
8
9
0:001> dd 1ec`e6240000
000001ec`e6240000 ???????? ???????? ???????? ????????
000001ec`e6240010 ???????? ???????? ???????? ????????
000001ec`e6240020 ???????? ???????? ???????? ????????
000001ec`e6240030 ???????? ???????? ???????? ????????
000001ec`e6240040 ???????? ???????? ???????? ????????
000001ec`e6240050 ???????? ???????? ???????? ????????
000001ec`e6240060 ???????? ???????? ???????? ????????
000001ec`e6240070 ???????? ???????? ???????? ????????

执行这次函数调用,再次查看 Render 进程地址,发现此时对应的虚拟地址已经映射了物理地址

1
2
3
4
5
6
7
8
9
0:001> dd 1ec`e6240000
000001ec`e6240000 00000000 00000000 00000000 00000000
000001ec`e6240010 00000000 00000000 00000000 00000000
000001ec`e6240020 00000000 00000000 00000000 00000000
000001ec`e6240030 00000000 00000000 00000000 00000000
000001ec`e6240040 00000000 00000000 00000000 00000000
000001ec`e6240050 00000000 00000000 00000000 00000000
000001ec`e6240060 00000000 00000000 00000000 00000000
000001ec`e6240070 00000000 00000000 00000000 00000000

Read More

Bypass ACG With UnmapViewOfFile

https://bugs.chromium.org/p/project-zero/issues/detail?id=1435&can=1&q=&start=1200 p0 研究者 ifratric 提出的一种绕过 ACG 保护的方案,即通过调用函数 UnmapViewOfFile 来预先修改内存块内容,从而在可执行页上加入攻击者自定义代码。

Remote JIT

开启了 ACG 保护之后进程将不能够申请未签名代码页。但是现代浏览器为了提高响应效率,都提供了 JIT 功能用于把 JS 代码编译成本地代码。该功能的实现依赖于在进程空间中动态的生成未签名的代码页。为了同时支持 ACG 和 JIT,Chakra 将其 JIT 功能移动到一个单独的进程中,该进程在其独立的沙箱中运行。JIT进程负责将 JavaScript 编译为本地代码并将其映射到请求进程。渲染进程本身不允许直接映射或修改其自己的JIT代码页。

JIT 地址管理

(由于笔者对于 ACG 的分析基于的 Edge 版本较老因此,可能有些地方不匹配)
远程分配的地址空间来源于本进程中的 PreReservedSectionAllocWrapper 对象,该对象在 JIT 进程启动时进行初始化,专门负责管理那些远程保留空间。对象的结构简单表示如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class PreReservedSectionAllocWrapper
{
BVStatic<PreReservedAllocationSegmentCount> freeSegments; //0x00 // 用于索引整块内存空间,检查内存状态
LPVOID preReservedStartAddress; //0x200 // 当前应该分配出去的地址
CriticalSection cs; //0x208
|- PRTL_CRITICAL_SECTION_DEBUG DebugInfo; //0x208
|- LONG LockCount; //0x210
|- LONG RecursionCount; //0x214
|- HANDLE OwningThread; //0x218 from the thread's ClientId->UniqueThread
|- HANDLE LockSemaphore; //0x220
|- ULONG_PTR SpinCount //0x228
HANDLE process; //0x230 // 远程进程句柄
HANDLE section; //0x238 // 远程地址 section 句柄
EnsurePreReservedRegionInternal(); // 用于检查是否还存在可管理的 RESERVE 属性内存,若不存在,则在分配之
};

Read More

Visual Studio 注释扩展

在阅读大型工程源代码的时候经常需要根据自己的理解为代码添加某些注释,直接在源码文件中的修改有可能会导致工程重新编译,git 更新代码时产生冲突等情况,更有甚者一旦代码通过 git 更新之后,自己添加的注释将不会出现在新代码中;如果将注释写在源码之外的文件中,在以后查阅和对照时又会有其他新的麻烦。基于以上需求,笔者实现了一个 Visual Studio 中的注释插件,可以在源码文件之外独立添加注释,并且在查看源码时会在对应的位置显示注释。

效果如图所示

在编写过程中参考了这篇文章 中插件的实现。感谢这位作者的分享。

Visual Studio Extension

微软为 vs 扩展的开发者提供了一套完整的开发文档,以便开发者可以根据自己的需求扩展 Visual Studio 的功能。理论上而言可用的扩展点如下

  • 命令和菜单
  • 工具窗口
  • 编辑器窗口
  • 语言服务
  • 项目扩展
  • 用户设置
  • 属性和属性窗口
  • Visual Studio 独立 Shell

其他更多关于 VS 扩展的内容可以参见上面的开发文档,其中提供了大量的例子可以参考。

实现

下面笔者将一步一步记录下整个插件的编写过程,以便之后改进和复现。

Read More

也谈 “Spectre” CPU 漏洞

元旦回来 P0 就放出了 2018 年的第一个大新闻,多款处理器被曝出存在安全漏洞可以泄露某些敏感信息,P0 将其分别命名为 “Spectre” 和 “MeltDown”。其中 “Spectre” 漏洞是由于 CPU 的分支预测进而导致的缓存信息泄露,其效果可以越界读取某些内容。

根据原理上来说 “Spectre” 是可以并且比较容易在浏览器中通过 js 相关技术实现攻击的,在 P0 的论文后也附加了一个 C 语言实现的 demo。出于对这种攻击理论上的认可我们开始尝试通过 js 来实现 “Spectre” 的漏洞利用。经过四天的研究我们终于 “全球首发” “Spectre” 漏洞在线检测工具,虽然依然很不完善但是效果却出乎我们所有人的意料。检测工具地址

实现的代码全是 JS 因此可以直接通过前端获取,经过 Exp-sky 师傅的润色代码也大体上可读(ps:如果知道要放出来的话变量命名写的时候就不会那么随意了~ orz)。这里记录一下代码编写过程中的几个问题,以备以后查询。

Read More

Decrypt PYC

PYC

PYC 是 Python 文件经过编译之后形成的一种文件格式,可以提高加载效率用来为其他 Python 程序提供函数接口等功能。

其文件格式如下,主要由头部四字节的 Magic 字段和 4字节的 timestap 以及 r_object 结构组成。r_object 对象是 PYC 文件的主要内容,包括了 python 文件所编译形成的 Opcode、常量、值等一系列信息。其更具体的信息可以在 python 自带的 marshal 库中找到 Python/marshal.c

Read More

Bypass CFG Through MRDATA

http://alex-ionescu.com/publications/euskalhack/euskalhack2017-cfg.pdf

这是 Alex 大神的一篇演讲,介绍了一种新的绕过 CFG 的思路

MRDATA

从 Win8.1 开始微软为 CFG 的 bitmap 添加了保护机制,将 bitmap 指针等一系列全局变量放置于文件的 .mrdata 区段,这是一个新的 PE 区段,用于保存那些易变的只读数据。

这个区段在模块加载时被标记为 PAGE_READONLY ,理论上无法被修改。

但是某些时候 ntdll 需要去修改 .mrdata 区段中的某些数据。为此Windows 提供了一个新的 API : LdrProtectMrdata( bProtect )函数用于设置 .mrdata区段是否开启保护 ,参数传入 0 表示 unprotect,传入 1 表示 protect。

很明显在模块加载和卸载时都会调用这个函数来设置一些数据,然而有些函数在运行时也会调用这个 API。

例如SetProtectedPolicyGetProtectedPolicy就会用到它。这两个函数用于设置和获取进程的保护策略,这些策略保存在通过 LdrMrdataHeap 分配的内存中,即策略处于 .mrdata 区段

Read More

RaspBerry Pi 折腾笔记

开箱

从 salt 大佬那里拿到一个树莓派,开始开箱进行折腾。

首先要进行系统的安装,这里选择的是树莓派上的一个 Ubuntu 系统

download

一开始准备使用 PowerISO 直接把这个系统当作一个 PE 烧到 sd 卡里,但是烧进去了之后发现没有办法成功启动,所以只好老老实实使用官方推荐的工具 Win32DiskImager 来安装

Read More