[代码重构](master): 安全风控

更新 失效的访问控制
2022年9月27日19:40:54
master
土豆兄弟 2 years ago
parent fa69debf9d
commit de794dbd85

@ -0,0 +1,214 @@
# Web 漏洞挖掘与安全开发
## 0. 目录
- 失效的访问控制
- 失效的访问控制
- 路径穿越
- 敏感数据泄露
- 权限不合理
- CSRF
- 加密失败
- 忘记加盐
- 弱随机数
- 密码算法问题
- 失效的证书信任链
- 弱编码
- 加密失败
- 注入
- 注入
- 失效的输入监测
- 命令注入
- XSS
- 资源注入
- 不安全的设计
- 用户账户安全
- 报错信息
- 不安全的设计
- 安全配置错误
- 安全配置错误
- Session与Cookie
- HTTP Header
- 其他安全风险
- SSRF
- 软件和数据完整性
- 认证和授权
- 第三方组件
## 1. 失效的访问控制
### 1.1 失效的访问控制:攻击者是怎么获取到其他用户信息的?
- Curiosity killed the cat.
- 访问控制: 访问控制是一种策略,在这种策略的控制下,用户的操作不能逾越预设好的权限边界。
- 访问控制一旦失效通常会导致**未认证信息泄露、内部数据篡改、数据删除和越权操作**等后果。
- 访问控制失效型问题通常有以下几种类型:
- 系统在实现过程中违背了 **“最小权限原则” 或 “默认拒绝原则”**
- 通过修改 URL 地址、内部程序状态、HTML 页面,或者使用 Cyber 工具修改 API 请求的方式**绕过访问控制**
- 通过**提供唯一 ID 的方式**预览或者修改其他账户信息及数据;
- 未经过访问控制地**通过 POST、PUT 和 DELETE 方法访问 API**
- 通常意义上的**提权**
- 元数据操纵,比如重放或者修改 JWTJSON Web Token访问控制令牌或者**通过操纵 Cookie 的方式进行提权**
- **CORS 误配置**,可以导致来自未认证源的 API 访问
- 简单攻击场景
- 1-
- 这个应用在 SQL 调用中直接使用了未经验证的数据,并利用该数据进行信息查询:
```java
pstmt.setString(1, request.getParameter("acct"));
ResultSet results = pstmt.executeQuery();
```
- 在浏览器地址栏中修改 acct 参数,即可对 SQL 语句进行操纵,而在未经验证的情况下,该攻击者可以访问到其他账户的信息。
```txt
https://example.com/app/accountInfo?acct=notmyacct
```
- 2-
- 一个攻击者可以很轻松地修改 URL 地址,尝试去访问他的目标链接,比如这里攻击者试图通过 URL 地址修改直接访问 admin 页面:
```txt
https://example.com/app/getappInfo
https://example.com/app/admin_getappInfo
```
- 如果攻击者成功访问了第二个链接,那么说明系统在权限设计和访问控制上就是存在问题
- 3-
- 由于实现过程中未对用户访问参数设置边界,导致了很多越权问题的发生:
```txt
https://example.com/order/?order_id=2021102617429999
```
- 攻击者可以尝试修改上述 API 接口中的 order_id 参数,使其在程序接口上的输入合法,但是对于用户而言却是越权行为
- 4-
- HTTP PUT 方法最早目的用于文件管理操作,可以对网站服务器中的文件实现更改删除的更新操作,该方法往往可以导致各种文件上传漏洞,造成严重的网站攻击事件:
```shell
put /root/Desktop/shell.php
```
- 上述代码在支持 PUT 方法的环境中,上传 Webshell 进行提权;在实际运用中,若必须启用该方法,则需要对该方法涉及文件资源做好严格的访问权限控制。
- 5-
- Web 应用将身份认证结果直接存储在 Cookie 中,并未施加额外的保护措施:
```shell
Cookie: role=user --> Cookie: role=admin
```
- 通过在 Web 前端拦截 Cookie并进行 Cookie 内容修改即可提权
- 6-
- 有些开发者为了方便,直接在 Access-Control-Allow-Origin 中反射请求的 Origin 值:
```shell
add_header "Access-Control-Allow-Origin" $http_origin;
add_header "Access-Control-Allow-Credentials" "true";
```
- 这是一个错误的 Nginx 配置示例,这样的配置意味着信任任何网站,攻击者网站可以直接跨域读取其资源内容,窃取隐私数据
- 案例实战
- 1- 意外的代理访问
- 如果一个攻击者不能直接访问目标,但是一个应用可以,这时攻击者可以发送请求到应用,再让应用转发请求到最终目标。这种情况下,攻击请求看起来像
是来自应用的访问,而非真实攻击者。这种攻击的效果很直观,可以直接绕过访问控制(如防火墙)或者隐蔽恶意请求源信息。
- 在什么情况下这种功能会变成一种漏洞:
- **应用本身的权限和用户可以操纵的输入流组件所属的权限不同**;(条件 A
- **攻击者并不能够直接发送请求到最终目标资产**;(条件 B
- 攻击者能够创建一个可以被转发的请求,这个请求可能:
- **指向了未授权访问的域名、端口号、IP 以及服务**;(条件 C
- **指向了被授权访问的服务,但是请求内部包含了未授权的指令、资源等**。(条件 D
- 用简单的公式来描述的话,就是只有在“**A && B && ( C || D )**”的情况下,消息转发或者代理功能才会成为一种安全风险或者安全漏洞。
- CVE-2010-1637 漏洞
- 这个漏洞会影响,SquirrelMail 1.4.20 以及更早的版本,漏洞主要的发生点是 Mail Fetch 组件,由于该组件是 SquirrelMail 的默认组件,因此该漏洞影响力还是很大的
- mail_fetch 是在 SquirrelMail 1.4.20 版本的一个默认组件:
```txt
hunter@HunterdeiMac > ~/Downloads/squirrelmail-1.4.20/plugins > tree mail_fetc
mail_fetch
├── README
├── class.POP3.php
├── fetch.php
├── functions.php
├── index.php
├── options.php
└── setup.php
0 directories, 7 files
```
- mail_fetch 的主要功能是通过使用 fsockopen() 这个 PHP 函数来模拟 POP3 协议,并且仅支持了 POST 方式的认证,并没有对 IP 以及端口号进行检查:
```injectablephp
...
if (!isset($port) || !$port) {$port = 110;}
if(!empty($this->MAILSERVER))
$server = $this->MAILSERVER;
if(empty($server)){
$this->ERROR = "POP3 connect: " . _("No server specified");
unset($this->FP);
return false;
}
//加的注释
// 此处缺乏对于服务器IP及端口号的检查
$fp = @fsockopen("$server", $port, $errno, $errstr);
if(!$fp) {
$this->ERROR = "POP3 connect: " . _("Error ") . "[$errno] [$errstr]";
unset($this->FP);
return false;
}
...
```
- 可以发现该代码段符合“A && B && ( C || D )”的漏洞存在条件,该处应该存在失效的访问控制
- **将 SquirrelMail 变成 Nmap 扫描器**
- 服务端先返回消息的 Service比如 SSH 这种,通过**对 TCP 服务的 Banner 信息抓取** 可以了解目标资产提供的 Service
- 客户端先发送消息的 Service比如 HTTP 这种POP3 对象在建立完 TCP 三次握手之后会进入阻塞状态,**通过 fgets() 函数设置硬编码超时时间,可以判断目标端口是否开放**
- 由于仅仅支持 POST 方式认证,因此**请求是以账户为前置条件去发送的,所以 Cookie 也是需要的**。
- 那么到现在为止,我们的攻击示意图
```shell
./squirrel-nmap [Target] [IP] [TCP_PORT] [Cookie]
- Target suqiremail的URL地址 如http://target.com/sqm/
- IP 待扫描的IP地址
- TCP_PORT 尝试探测的TCP端口号
- Cookie 经过认证的Cookie
```
- 通过简单的实现,我们来看看实际的战斗威力如何:
```shell
./squirre-nmap "http://target.com/squirrelmail-1.4/" 192.168.1.4 22 "key=dTPc0"
Fetching from 192.168.1.4:22
Oops, POP3 connect: Error [SSH-2.0-OpenSSH_5.1p1 Debian-3]
```
- 可以看到能够成功地对内网 IP 进行 Service 进行探测
- 安全建设方案
- 访问控制是授权或拒绝特定用户请求的过程。这个过程只有在应用开发的初始阶段就经过良好的设计,才能避免后续问题的发生。
- **优先开始设计访问控制体系**
- 访问控制不仅是应用安全设计的一项主要事务,而且应当被设置在非常优先的位置,因为往往访问控制的设计在起步阶段是相对简单的,但是会很快随着功能点的增多快速复杂
化。所以,如果你考虑使用成熟的软件框架来完成访问控制,一定要确保其能够满足你未来的应用定制化需求
- **对用户的访问授权进行设计, 控制对外暴露的接口, 控制内网直接交互的接口**
- **强制所有请求经过访问控制检查**
- 开发一个访问控制检查层Layer然后确保所有请求都在某种程度上经过这个检查层。以 Java 的 filter 为例,许多自动化的请求处理机制都是能够帮助我们实现这种需求的技术
- **默认拒绝**
- 这是非常简单但是有效的策略,所谓默认拒绝是指,只要一个请求没有被指明是被允许的,那么它就是被拒绝的。
- **不要硬编码角色**
- 很多应用框架默认使用用户角色来进行访问控制,以下的代码形态是很常见的:
```java
if (user.hasRole("admin") || user.hasRole("Manager")) {
deleteAccount();
}
```
- 但是你要对这种 Role-Based 编码模式格外留意,因为它可能会带来以下几种风险:
- 由于这种编码自身的特性非常脆弱,很容易**出现检查错误或者检查缺失等情况**
- 由于这种编码模型**对于多租户产品非常不友好**,很容易出现用户角色一致但是权限不一致的情况;
- Role-Based 编码模型**无法适配包括以数据为核心的以及横向访问控制**
- 当项目代码量攀升并且伴随着很多访问权限控制的情况出现时,**访问控制策略的审计和验证是非常困难的**。
- 因此这里我更推荐你使用这种编码方式:
```java
if (user.hasAccess("DELETE_ACCOUNT")) {
deleteAccount();
}
```
- 以属性或者功能为核心的访问控制编码模型,从特性上来讲更易于构建功能丰富的访问控制系统。
- **记录所有的访问控制类事件**
- 所有的访问控制失效都应该有完整的记录,因为这些事件很可能成为恶意用户尝试寻找系统漏洞的线索。

@ -1215,6 +1215,18 @@ while (true) {
### 2.13 Java 消费者是如何管理TCP连接的?
## 4. Consumer

Loading…
Cancel
Save