ATTCK v13版本战术介绍——防御规避(五)
一、引言
在前几期文章中我们介绍了ATT&CK中侦察、资源开发、初始访问、执行、持久化、提权战术理论知识及实战研究、部分防御规避战术,本期我们为大家介绍ATT&CK 14项战术中防御规避战术第25-30种子技术,后续会介绍防御规避其他子技术,敬请关注。
二、ATT&CK v13简介
MITRE ATT&CK 是一个全球可访问的基于现实世界观察的攻防战术和技术知识库。ATT&CK知识库被用作在私营部门、政府以及网络安全产品和服务社区中开发特定威胁模型和方法的基础。
2023年 4月25日,MITRE ATT&CK 发布了最新版本 V13,最大的变化是为ATT&CK中的一些技术添加了详细的检测指导,用于企业,移动数据源和两种新类型的更改日志(包括一个人类可读的详细更改日志,更具体地显示更新的ATT&CK对象中的更改,以及一个机器可读的JSON更改日志,其格式在ATT&CK的Github中描述)。
ATT&CK for Enterprise v13 包含14个战术、196个技术、411个子技术、138个组织和740个软件。
ATT&CK战术全景图(红框为防御规避战术)
三、防御规避战术
3.1 概述
防御逃避包括攻击者在攻击过程中用来避免被发现的技术,包括禁用安全软件、加密数据和脚本、利用可信进程来隐藏或伪装恶意软件。
防御规避战术包括42种技术,本期介绍第25-30种技术,逐一介绍如下:
3.2 plist文件修改(T1647)
攻击者可能会修改属性列表文件(plist文件)以启用其他恶意活动,以逃避和绕过系统防御。macOS应用程序使用plist文件,用于存储通知操作系统如何在运行时处理应用程序的属性和配置设置。Plist文件是基于Apple的Core Foundation DTD以XML格式格式化的键值对中的结构化元数据。Plist文件可以保存为文本或二进制格式。
攻击者可以修改plist文件中的键值对以影响系统行为,例如隐藏应用程序的执行或运行其他持久性命令。
3.2.1 缓解措施
ID | 缓解措施 | 描述 |
M1013 | 应用开发者指南 | 确保应用程序使用开发人员指南。 |
3.2.2 检测
ID | 数据源 | 数据组件 | 检测 |
DS0017 | 命令 | 命令执行 | 监控用于修改plist文件的带有参数的命令(例如打开常用命令行编辑器) |
DS0022 | 文件 | 文件修改 | 监控plist文件的修改,修改后的plist中任何路径指针的重大更改。 |
DS0009 | 进程 | 进程创建 | 监控新执行的进程。 |
3.3 在操作系统前启动(T1542)
攻击者可能会利用操作系统前启动机制建立持久性。在计算机的启动过程中,固件和各种启动服务在操作系统之前加载,这些程序在操作系统控制之前控制执行流程。
在操作系统前启动技术包含5项子技术,介绍如下:
3.3.1 系统固件(T1542.001)
攻击者可能会修改系统固件以建立持久性。例如BIOS(基本输入/输出系统)和统一可扩展固件接口(UEFI)或可扩展固件接口(EFI)等。
系统固件削弱了计算机的功能,并且可能被攻击者修改以执行恶意活动。
3.3.2 组件固件(T1542.002)
攻击者可能会修改组件固件以建立持久性。攻击者可能会使用复杂的手段来破坏计算机组件并安装恶意固件,这些固件将在操作系统和主系统固件或BIOS之外执行恶意代码。
3.3.3 Bootkit(T1542.003)
攻击者可以使用bootkit来持久化系统。Bootkit是一种恶意软件变体,可修改硬盘驱动器的引导扇区,包括主引导记录(MBR)和卷引导记录(VBR)。MBR是BIOS完成硬件初始化后首先加载的磁盘部分,引导加载程序的位置。对启动驱动器具有原始访问权限的攻击者可能会覆盖此区域,从而将启动期间的执行从正常启动加载程序转移到恶意代码。
MBR将引导过程的控制传递给VBR。与MBR的情况类似,对启动驱动器具有原始访问权限的攻击者可能会覆盖VBR以将启动期间的执行转移到恶意代码。
3.3.4 RommonKit(T1542.004)
攻击者可能会利用ROM监视器(ROMMON),通过加载带有恶意代码的未经授权的固件来提供持久访问。
攻击者可以使用恶意代码在本地或远程升级ROMMON镜像,并重新启动设备,以覆盖现有的ROMMON镜像。
3.3.5 TFTP启动(T1542.005)
Netbooting是引导序列中的一个选项,可用于集中、管理和控制设备镜像。攻击者可能会利用Netbooting从TFTP服务器加载未经授权的网络设备操作系统。
攻击者可以操纵网络设备上的配置,指定使用恶意TFTP服务器,该服务器可以与修改系统映像一起使用,以便在设备启动或重置时加载修改后的镜像。未经授权的镜像允许对手修改设备配置,向设备添加恶意功能,并引入后门以保持对网络设备的控制。
3.3.6 缓解措施
ID | 缓解措施 | 描述 |
M1046 | 启动完整性 | 使用受信任的启动过程,检查现有BIOS或EFI的完整性,以确定它是否容易被修改。 |
M1026 | 特权账户管理 | 确保具有适当的权限,防止特权帐户被利用。 |
M1051 | 更新软件 | 根据需要修补BIOS和EFI。 |
3.3.7 检测
ID | 数据源 | 数据组件 | 检测 |
DS0017 | 命令 | 命令执行 | 监控命令历史记录中执行的命令和参数,以确定是否使用了未经授权或可疑的命令来修改设备配置。 |
DS0016 | 驱动 | 驱动修改 | 监控MBR和VBR发生的变化,以确定可疑活动和进一步分析的指标。记录MBR和VBR的快照,并与已知的良好样本进行比较。 |
DS0027 | 驱动 | 驱动程序元数据 | 监控磁盘检查、取证实用程序和来自设备驱动程序(即进程和API调用)的数据。 |
DS0001 | 固件 | 固件修改 | 监控在操作系统前引导机制上所做的更改。 |
DS0029 | 网络流量 | 网络连接创建 | 监控新构建的网络设备配置和系统镜像,以发现对系统引导、启动配置或正在运行的操作系统的未经授权的更改。 |
DS0009 | 进程 | OS API执行 | 监控利用操作系统前引导机制的API调用。 |
3.4 进程注入(T1055)
攻击者可以将代码注入到进程中来提升特权。进程注入是一种在单独的活动进程的地址空间中执行任意代码的方法。进程注入技术包含12项子技术,介绍如下:
3.4.1 动态链接库注入(T1055.001)
攻击者可以将动态链接库Dll注入到进程中,DLL注入通常通过在调用新进程加载DLL之前将路径写入目标进程的虚拟地址空间中的DLL来执行。
3.4.2 可执行文件注入(T1055.002)
攻击者可将可执行文件PE注入到进程中,PE注入在通过新进程调用目标进程之前将代码复制到目标进程的虚拟地址空间来执行的。
3.4.3 线程执行劫持(T1055.003)
攻击者可能会将恶意代码注入被劫持的进程中来提升特权。线程执行劫持通常通过挂起现有进程,然后取消映射其内存来执行,然后可以用恶意代码或DLL的路径替换。
3.4.4 异步进程调用(T1055.004)
攻击者可以通过异步进程调用APC队列向进程注入恶意代码,排队的APC函数在进程进入可更改状态时执行。
3.4.5 线程本地存储(T1055.005)
攻击者可以通过线程本地存储(TLS)回调将恶意代码注入进程,TLS回调注入涉及操纵可移植可执行文件PE中的指针,以便将进程重定向到恶意代码。TLS回调通常由操作系统用于设置或清理线程使用的数据。
3.4.6 Ptrace系统调用(T1055.008)
攻击者可以通过ptrace进程跟踪系统调用将恶意代码注入进程,Ptrace系统调用注入涉及修改正在运行的进程。Ptrace系统调用使调试进程能够观察和控制另一个进程以及每个单独的线程,包括更改内存和寄存器值。
3.4.7 Proc内存(T1055.009)
攻击者可以通过proc文件系统向进程注入恶意代码,通过使用proc文件系统提供的内存映射覆盖目标进程的堆栈来执行。
3.4.8 EWM注入(T1055.011)
攻击者可以通过EWM将恶意代码注入进程,在创建窗口之前,基于windows的图形化进程必须注册一个windows类,新windows类的注册可以包括请求将最多40字节的EWM追加到该类的每个实例的分配内存中。EWM旨在存储特定于该窗口的数据,并具有特定的应用程序编程接口(API)函数来设置和获取其值。
3.4.9 Process Hollowing(T1055.012)
攻击者可能会将恶意代码注入暂停的进程中, 进程挖空通常是通过创建一个处于暂停状态的进程,取消映射它的内存来执行的,然后可以用恶意代码替换它。
3.4.10 Process Doppelgänging(T1055.013)
Process doppelgänging是一种在单独活动进程的地址空间中执行任意代码的方法。Process Doppelgänging分4步实现:
使用合法的可执行文件创建TxF事务,然后用恶意代码覆盖该文件。
创建内存的共享部分并加载恶意可执行文件。
撤消对原始可执行文件的更改,有效地从文件系统中删除恶意代码。
从内存的受污染部分创建一个进程并启动执行。
3.4.11 VDSO劫持(T1055.014)
攻击者可以通过vdso劫持向进程注入恶意代码,VDSO劫持涉及将调用重定向到动态链接的共享库。攻击者可能会劫持从vdso共享对象映射到进程的syscall接口代码存根,以执行syscall以打开和映射恶意共享对象。然后,可以通过通过存储在进程全局偏移表(存储映射库函数的绝对地址)中的修补内存地址引用重定向进程的执行流来调用此代码。
3.4.12 ListPlanting(T1055.015)
攻击者可利用列表视图控件将恶意代码注入被劫持的进程中,ListPlanting可以通过将代码复制到使用列表视图控件的进程的虚拟地址空间中来执行,使用该代码作为自定义回调来对列出的项目进行分类,然后可以执行邮件攻击。
3.4.13 缓解措施
ID | 缓解措施 | 描述 |
M1040 | 端点行为防御 | 在Windows10上,攻击面减少(ASR)规则可能会阻止Office应用程序进行代码注入。 |
M1026 | 特权账户管理 | 将ptrace的使用限制为特权用户来减轻基于ptrace的进程注入。其他控制涉及安全内核模块的部署,这些模块提供高级访问控制和进程限制,如SELinux,grsecurity和AppArmor。 |
3.4.14 检测
ID | 数据源 | 数据组件 | 检测 |
DS0022 | 文件 | 文件元数据 | 监控文件的标题,内容,所有者等信息。 |
文件修改 | 监控修改文件的事件。 | ||
DS0011 | 模块 | 模块加载 | 监控DLL/PE文件事件,特别是这些二进制文件的创建以及将Dll加载到进程中,查找无法识别或未加载到进程中的Dll。 |
DS0009 | 进程 | OS API执行 | 监控Windows API调用可能会生成大量数据,监控Linux特定的调用,如ptrace系统调用。 |
进程访问 | 监控进程访问事件。 | ||
进程元数据 | 监控进程和内存是否一致。 | ||
进程修改 | 监控进程修改事件。 |
3.5 反射代码注入(T1620)
攻击者可能会将代码加载到进程中,以隐藏恶意有效负载的执行。反射加载涉及直接在进程的内存中分配然后执行有效负载,或者创建由磁盘上的文件路径支持的线程或进程。反射加载的有效负载可以是编译的二进制文件,匿名文件(仅存在于RAM中),或者只是无文件可执行代码的缓冲(例如:与位置无关的shellcode)。
反射代码注入与进程注入非常相似,只是将代码加载到进程自己的内存中,而不是单独的进程。反射加载可能会逃避基于进程的检测,因为任意代码的执行可能会在合法进程中被屏蔽。
3.5.1 检测
ID | 数据源 | 数据组件 | 检测 |
DS0011 | 模块 | 模块负载 | 监控异常进程执行。 |
DS0009 | 进程 | OS API执行 | 监控与反射加载代码相关联的代码执行。 |
DS0012 | 脚本 | 脚本执行 | 监控异常的脚本执行,识别任意代码执行行为。 |
3.6 注册恶意域控制器(T1207)
攻击者可以注册恶意域控制器以启用对活动目录数据的操作。DCShadow可用于创建恶意域控制器(DC)。DCShadow是一种通过注册和模拟DC行为来操作活动目录(AD)数据的方法。一旦注册,恶意DC可能能够将更改注入并复制到任何域对象的AD基础结构中,包括凭据和密钥。
注册恶意域控制器技术还可用于更改和删除复制和其他相关元数据,以阻碍检测分析。攻击者也可以利用该技术来执行SID-History注入或操纵AD对象(例如帐户,访问控制列表,模式)以建立用于持久化的后门。
3.6.1 检测
ID | 数据源 | 数据组件 | 检测 |
DS0026 | 活动目录 | 活动目录对象创建 | 基线和定期分析AD架构的配置分区,并在创建nTDSDSA对象时告警。 |
活动目录对象修改 | 监控AD目录状态的更改,对AD对象的复制行为进行监控和告警(审核详细的目录服务复制事件EventID为4928和4929)。 | ||
DS0029 | 网络流量 | 网络流量内容 | 监控和分析DC之间以及非DC主机之间与数据复制相关的网络流量。 |
DS0002 | 用户账户 | 用户账户认证 | 监控异常的用户账户对Kerberos服务主体名称(Spn)的使用情况,恶意DC必须使用这两个Spn作为服务进行身份验证,才能成功完成复制过程。 |
3.7 使用Rootkit(T1014)
攻击者可以使用rootkit来隐藏程序、文件、网络连接、服务、驱动程序和其他系统组件。Rootkit是通过拦截和修改提供系统信息的操作系统API调用来隐藏恶意软件的程序。
Rootkit可以驻留在操作系统、更低的用户或内核级别,以包括管理程序、主引导记录或系统固件。
3.7.1 检测
ID | 数据源 | 数据组件 | 检测 |
DS0016 | 驱动 | 驱动修改 | 监控对数据存储设备的驱动所做的更改,以获取rootkit可能用于隐藏程序、文件、网络连接、服务、驱动程序和其他系统组件的意外修改行为。 |
DS0022 | 文件 | 文件修改 | 监控异常的Dll、驱动程序、设备、服务和MBR的修改事件。 |
DS0001 | 固件 | 固件修改 | 监控对固件所做的更改,rootkit保护可能内置于防病毒或操作系统软件中。有专门的rootkit检测工具来查找特定类型的rootkit行为。 |
四、总结
本期主要介绍了防御规避战术(五)及技术/子技术原理,下期将给大家介绍防御规避战术(六)涉及的技术原理。敬请关注。
相关文章:

ATTCK v13版本战术介绍——防御规避(五)
一、引言 在前几期文章中我们介绍了ATT&CK中侦察、资源开发、初始访问、执行、持久化、提权战术理论知识及实战研究、部分防御规避战术,本期我们为大家介绍ATT&CK 14项战术中防御规避战术第25-30种子技术,后续会介绍防御规避其他子技术…...

祁宁:社区问答是激荡企业高级智慧的头脑风暴 | 开发者说
在祁宁家里,有一套完整的赛车模拟器,他甚至还请人到国外代购了最新的 VR 设备。作为沉浸式赛车游戏发烧友,除了享受速度与激情带来的愉悦感,祁宁在玩的过程中更多的是思考如何将技术能力进行产品化的问题。 Answer.dev 就是将技术…...

linux安装
1. 准备前说明 本文采用的是CentOS6.8,64位的,虚拟机时VMvare,采用的是双网卡方式。至于双网卡的作用和nat,桥接和hostonly模式请参见我的另一篇文章。安装回环网卡&安装Linux前准备 2. 废话不多说,开始了 ◆打…...

【Go编程语言】 Go语言基础语法
Go语言基础语法 文章目录 Go语言基础语法一、注释1.单行注释2.多行注释 二、变量1.变量的定义2.变量的初始化3.理解变量(内存地址)4.变量交换5.匿名变量6.变量的作用域 三、常量1.常量的定义: const2.iota(特殊常量) 四…...

洗稿用什么软件-洗稿软件免费
洗稿文章的主要优势 洗稿文章的主要优势在于提高文章的质量和效率。以下是洗稿文章的几个主要优势: 优化结构和语言 洗稿可以删除冗余、无用和重复的内容,同时对文章的结构和语言进行优化,提高文章的可读性和吸引力。这可以使文章更加专业…...

网络请求发送
私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版,配图更多,CSDN博文图片需要手动上传,因此文章配图较少,看不懂的可以去菜鸡博客参考一下配图! 系列文章目录 前端系列文章——传送门 后端系列文章——传送…...

微信小程序开发
文章目录 1 开发准备工作2 小程序开发工具使用3 初始化项目4 index页静态搭建5 数据绑定5.1 初始化数据5.2 使用数据5.3 修改数据 6 数据绑定---小程序,Vue,React7 事件绑定7.1 事件分类7.2 绑定事件7.3 向事件对象传参7.4 补充:事件流的三个…...

number类型超出16位的问题(前端、后端处理)
目录 1、前端解决方案 1.1 甩链接 1.2 接口返回数据过程中将数据处理为字符串(过过嘴瘾) 1.3 对返回的json字符串进行数据预处理代码如下 2、后端解决方案 2.1 toString、String、 、new String() 自己悟、就是要改的地方多。 2.2拦截器 (可能超出…...

【高并发】网络模式
I/O 多路复用 多线程创建 服务器的主进程负责监听客户的连接,一旦与客户端连接完成,accept() 函数就会返回一个「已连接 Socket」,这时就通过 fork() 函数创建一个子进程,实际上就把父进程所有相关的东西都复制一份,…...

springboot+dubbo+zookeeper 项目实战
现在有一段代码再前台,后台系统中都存在,都需要这段代码,存在这种情况,我们可以选择将这段代码提取出来作为一个服务,让前台和后台系统作为消费者远程调用这段代码,提高了代码的复用性。 springboot集成dub…...

PHP学习笔记第一天
前言 作者简介:不知名白帽,网络安全学习者。 博客主页:不知名白帽的博客_CSDN博客-网络安全,CTF,内网渗透领域博主 网络安全交流社区:https://bbs.csdn.net/forums/angluoanquan 目录 PHP语法 基本的PHP语法 PHP的数据类型 PH…...

案例研究|萤石网络通过JumpServer解决安全运维难题
杭州萤石网络股份有限公司(以下简称为萤石网络)于2015年在杭州成立,是安全智能生活主流品牌,核心产品包括智能家居摄像头、智能门锁、智能服务机器人等。2021年,萤石网络家用摄像头占国内出货量市场份额的25%ÿ…...

即时聊天app开发-即时通讯app开发方案分析
如今,即时聊天APP层出不穷,它已经成为人们日常生活中密不可分的社交工具。如今,即时聊天APP不仅是聊天工具,也是企业营销的利器。我们经常可以在聊天主页上看到一些广告。如有必要,用户可以直接点击广告了解详情。即时…...

js为什么会阻塞渲染, 什么是异步?
javaScript 是单线程执行的语言,它的执行机制是基于事件循环模型的。当 JavaScript 执行代码时,如果遇到阻塞(如执行时间较长的代码、同步的网络请求、计算密集型操作等),则会阻塞 JavaScript 引擎的执行,直…...

Nuvoton NK-980IOT开发板 u-boot 编译
前言 最近搭建了 Nuvoton NK-980IOT开发板 的开发编译环境,记录一下 u-boot 的 编译流程 Nuvoton NK-980IOT开发板 资源还是比较的丰富的,可以用于 嵌入式Linux 或者 RT-Thread 的学习开发 开发板上电比较的容易,两根 USB 线即可࿰…...

OpenCL使用CL_MEM_USE_HOST_PTR存储器对象属性与存储器映射
随着OpenCL的普及,现在有越来越多的移动设备以及平板、超级本等都支持OpenCL异构计算。而这些设备与桌面计算机、服务器相比而言性能不是占主要因素的,反而能耗更受人关注。因此,这些移动设备上的GPU与CPU基本都是在同一芯片上(So…...

浅谈osgEarth操控器类的createLocalCoordFrame函数如何将局部坐标系的点转为世界坐标系下的Martix(ENU坐标)
在osgEarth操控器类的EarthManipulator中的如下函数: void EarthManipulator::setLookAt(const osg::Vec3d& center,double azim,double pitch,double range,const osg::Vec3d& posOffset) {setCenter( center );.... //…...

PHP程序员和Python程序员的职业前景怎么样?我来聊聊自己的体会
大家好,今天我们来聊一下程序员这个职业的特点。在讲这个话题之前,我先说一下我自己的情况:我在福州和深圳做了8年左右的程序员,然后回到老家,在家里面为福州的一个公司做远程开发。目前已经在老家做了将近3年。 今天…...

【MATLAB图像处理实用案例详解(8)】—— 图像数字水印算法
目录 一、背景意义二、基本原理三、算法介绍3.1 数字水印嵌入3.2 数字水印提取 四、程序实现 一、背景意义 数字水印技术作为信息隐藏技术的一个重要分支,是将信息(水印)隐藏于数字图像、视频、音频及文本文档等数字媒体中,从而实现隐秘传输、存储、标注…...

最全的免费SSL证书申请方式
在SSL广泛普及的今天,申请一张免费的SSL证书是一件非常容易的事情。这里为大家总结当前阶段(2023年)拥有一张免费SSL证书的方式。首推的方式为来此加密网站,文章后面会有详细的介绍。 下面介绍几种获取免费SSL证书的方式,大家可以根据自己的…...

Ceph入门到精通-CrushMap算法概述
下面是伪代码object到osd的伪代码 locator =object_name obj_hash =hash(locator) pg =obj_hash %num_pg OSDs_for_pg =crush(pg) # returns a list of OSDs primary =osds_for_pg[0] replicas =osds_for_pg[1:] defcrush(pg): all_osds=[osd.0,osd.1,osd.2,...] resu…...

如何利用API做好电商,接口如何凋用关键字
一.随着互联网的快速发展,电子商务成为了众多企业的首选模式,而开放API则成为了电商业务中不可或缺的部分。API(Application Programming Interface),即应用程序接口,是软件系统不同组件之间交互的约定。电…...

Give me a logic game idea about economics
Here’s an logic game idea about economics: Game name: “Economics Tycoon” Game Objective: Build an economic empire and grow from a small business owner to a global tycoon. Gameplay: Start with a small business and limited resources. Manage your compa…...

测试之路,2023年软件测试市场领域有哪些变化?突破走得更远...
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 Python自动化测试&…...

配置Windows终端直接执行Python脚本,无需输入“python“
配置Windows终端直接执行Python脚本,无需输入"python" 1. 将Python加入环境变量2. 将Python后缀加入环境变量PATHEXT中3. 修改Python脚本的默认打开方式4. *将Python脚本命令加入环境变量*5. 测试 在Linux系统中,在Python脚本的开头指定Python…...

IDEA快捷键
文章目录 快捷键介绍重点掌握CtrlAltShiftCtrl AltCtrl ShiftAlt ShiftCtrl Shift Alt其他 快捷键介绍 重点掌握 psvmmain函数sout输出soutv带变量名输出.sout变量.调用 输出变量值.if布尔值.调用 生成if语句.for数组类型变量.for 生成for语句.var补全接收的变量&#x…...

关于c++指针数组的要设置初值的情况
在大多数情况下,都应该对指针数组进行初始化,以避免出现未知的值和潜在的未定义行为。指针数组在定义时必须指定元素个数,如果未指定元素值,则需要对其进行显式初始化。如果未初始化数组,则未知的值可能指向无效的内存…...

泰克RSA306B频谱分析仪测试信道功率方法
泰克RSA306B实时频谱分析仪是一种用于无线信号分析的仪器。它可以实时监控无线信号的频谱,帮助用户分析信号特征,掌握信号的功率、频率、调制等关键信息。在无线通信中,信道功率是一个非常重要的指标,它反映了信号在传输过程中的强…...
深度学习技巧应用12-神经网络训练中批归一化的应用
大家好,我是微学AI,今天给大家介绍一下深度学习技巧应用12-神经网络训练中批归一化的应用,在深度学习中,批归一化(Batch Normalization,简称BN)是一种重要的技巧,它在许多神经网络中都得到了广泛应用。本文将详细介绍批归一化的原理和应用,并结合PyTorch框架构建一个简…...

Masonry使用以及源码解析(未完待续
文章目录 Masonry使用约束约束优先级 以及 intrinsicContentSize相关问题 Masonry:iOS12Masonry源码解析下面是使用make.width点语法后的全部内部调用过程: Masonry使用 约束 在写Masonry之前,我想先来聊聊约束的基础知识,我们首先要了解一…...